1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | #include "clang/Sema/DeclSpec.h" |
13 | #include "TypeLocBuilder.h" |
14 | #include "clang/AST/ASTLambda.h" |
15 | #include "clang/AST/ExprCXX.h" |
16 | #include "clang/Basic/TargetInfo.h" |
17 | #include "clang/Sema/Initialization.h" |
18 | #include "clang/Sema/Lookup.h" |
19 | #include "clang/Sema/Scope.h" |
20 | #include "clang/Sema/ScopeInfo.h" |
21 | #include "clang/Sema/SemaInternal.h" |
22 | #include "clang/Sema/SemaLambda.h" |
23 | using namespace clang; |
24 | using namespace sema; |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | static inline Optional<unsigned> |
62 | getStackIndexOfNearestEnclosingCaptureReadyLambda( |
63 | ArrayRef<const clang::sema::FunctionScopeInfo *> FunctionScopes, |
64 | VarDecl *VarToCapture) { |
65 | |
66 | const Optional<unsigned> NoLambdaIsCaptureReady; |
67 | |
68 | |
69 | unsigned CurScopeIndex = FunctionScopes.size() - 1; |
70 | while (CurScopeIndex > 0 && isa<clang::sema::CapturedRegionScopeInfo>( |
71 | FunctionScopes[CurScopeIndex])) |
72 | --CurScopeIndex; |
73 | (0) . __assert_fail ("isa(FunctionScopes[CurScopeIndex]) && \"The function on the top of sema's function-info stack must be a lambda\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 75, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert( |
74 | (0) . __assert_fail ("isa(FunctionScopes[CurScopeIndex]) && \"The function on the top of sema's function-info stack must be a lambda\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 75, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> isa<clang::sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex]) && |
75 | (0) . __assert_fail ("isa(FunctionScopes[CurScopeIndex]) && \"The function on the top of sema's function-info stack must be a lambda\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 75, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "The function on the top of sema's function-info stack must be a lambda"); |
76 | |
77 | |
78 | const bool IsCapturingThis = !VarToCapture; |
79 | const bool IsCapturingVariable = !IsCapturingThis; |
80 | |
81 | |
82 | DeclContext *EnclosingDC = |
83 | cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex])->CallOperator; |
84 | |
85 | do { |
86 | const clang::sema::LambdaScopeInfo *LSI = |
87 | cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex]); |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | if (IsCapturingVariable && |
96 | VarToCapture->getDeclContext()->Equals(EnclosingDC)) |
97 | return NoLambdaIsCaptureReady; |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | if (LSI->ImpCaptureStyle == sema::LambdaScopeInfo::ImpCap_None) { |
116 | if (IsCapturingVariable && !LSI->isCaptured(VarToCapture)) |
117 | return NoLambdaIsCaptureReady; |
118 | if (IsCapturingThis && !LSI->isCXXThisCaptured()) |
119 | return NoLambdaIsCaptureReady; |
120 | } |
121 | EnclosingDC = getLambdaAwareParentOfDeclContext(EnclosingDC); |
122 | |
123 | assert(CurScopeIndex); |
124 | --CurScopeIndex; |
125 | } while (!EnclosingDC->isTranslationUnit() && |
126 | EnclosingDC->isDependentContext() && |
127 | isLambdaCallOperator(EnclosingDC)); |
128 | |
129 | assert(CurScopeIndex < (FunctionScopes.size() - 1)); |
130 | |
131 | |
132 | if (!EnclosingDC->isDependentContext()) |
133 | return CurScopeIndex + 1; |
134 | return NoLambdaIsCaptureReady; |
135 | } |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | |
164 | |
165 | |
166 | |
167 | |
168 | |
169 | |
170 | |
171 | |
172 | Optional<unsigned> clang::getStackIndexOfNearestEnclosingCaptureCapableLambda( |
173 | ArrayRef<const sema::FunctionScopeInfo *> FunctionScopes, |
174 | VarDecl *VarToCapture, Sema &S) { |
175 | |
176 | const Optional<unsigned> NoLambdaIsCaptureCapable; |
177 | |
178 | const Optional<unsigned> OptionalStackIndex = |
179 | getStackIndexOfNearestEnclosingCaptureReadyLambda(FunctionScopes, |
180 | VarToCapture); |
181 | if (!OptionalStackIndex) |
182 | return NoLambdaIsCaptureCapable; |
183 | |
184 | const unsigned IndexOfCaptureReadyLambda = OptionalStackIndex.getValue(); |
185 | (0) . __assert_fail ("((IndexOfCaptureReadyLambda != (FunctionScopes.size() - 1)) || S.getCurGenericLambda()) && \"The capture ready lambda for a potential capture can only be the \" \"current lambda if it is a generic lambda\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 188, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(((IndexOfCaptureReadyLambda != (FunctionScopes.size() - 1)) || |
186 | (0) . __assert_fail ("((IndexOfCaptureReadyLambda != (FunctionScopes.size() - 1)) || S.getCurGenericLambda()) && \"The capture ready lambda for a potential capture can only be the \" \"current lambda if it is a generic lambda\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 188, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> S.getCurGenericLambda()) && |
187 | (0) . __assert_fail ("((IndexOfCaptureReadyLambda != (FunctionScopes.size() - 1)) || S.getCurGenericLambda()) && \"The capture ready lambda for a potential capture can only be the \" \"current lambda if it is a generic lambda\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 188, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "The capture ready lambda for a potential capture can only be the " |
188 | (0) . __assert_fail ("((IndexOfCaptureReadyLambda != (FunctionScopes.size() - 1)) || S.getCurGenericLambda()) && \"The capture ready lambda for a potential capture can only be the \" \"current lambda if it is a generic lambda\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 188, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "current lambda if it is a generic lambda"); |
189 | |
190 | const sema::LambdaScopeInfo *const CaptureReadyLambdaLSI = |
191 | cast<sema::LambdaScopeInfo>(FunctionScopes[IndexOfCaptureReadyLambda]); |
192 | |
193 | |
194 | const bool IsCapturingThis = !VarToCapture; |
195 | const bool IsCapturingVariable = !IsCapturingThis; |
196 | |
197 | if (IsCapturingVariable) { |
198 | |
199 | |
200 | |
201 | QualType CaptureType, DeclRefType; |
202 | const bool CanCaptureVariable = |
203 | !S.tryCaptureVariable(VarToCapture, |
204 | SourceLocation(), |
205 | clang::Sema::TryCapture_Implicit, |
206 | SourceLocation(), |
207 | false, CaptureType, |
208 | DeclRefType, &IndexOfCaptureReadyLambda); |
209 | if (!CanCaptureVariable) |
210 | return NoLambdaIsCaptureCapable; |
211 | } else { |
212 | |
213 | |
214 | |
215 | const bool CanCaptureThis = |
216 | !S.CheckCXXThisCapture( |
217 | CaptureReadyLambdaLSI->PotentialThisCaptureLocation, |
218 | false, false, |
219 | &IndexOfCaptureReadyLambda); |
220 | if (!CanCaptureThis) |
221 | return NoLambdaIsCaptureCapable; |
222 | } |
223 | return IndexOfCaptureReadyLambda; |
224 | } |
225 | |
226 | static inline TemplateParameterList * |
227 | getGenericLambdaTemplateParameterList(LambdaScopeInfo *LSI, Sema &SemaRef) { |
228 | if (LSI->GLTemplateParameterList) |
229 | return LSI->GLTemplateParameterList; |
230 | |
231 | if (!LSI->AutoTemplateParams.empty()) { |
232 | SourceRange IntroRange = LSI->IntroducerRange; |
233 | SourceLocation LAngleLoc = IntroRange.getBegin(); |
234 | SourceLocation RAngleLoc = IntroRange.getEnd(); |
235 | LSI->GLTemplateParameterList = TemplateParameterList::Create( |
236 | SemaRef.Context, |
237 | SourceLocation(), LAngleLoc, |
238 | llvm::makeArrayRef((NamedDecl *const *)LSI->AutoTemplateParams.data(), |
239 | LSI->AutoTemplateParams.size()), |
240 | RAngleLoc, nullptr); |
241 | } |
242 | return LSI->GLTemplateParameterList; |
243 | } |
244 | |
245 | CXXRecordDecl *Sema::createLambdaClosureType(SourceRange IntroducerRange, |
246 | TypeSourceInfo *Info, |
247 | bool KnownDependent, |
248 | LambdaCaptureDefault CaptureDefault) { |
249 | DeclContext *DC = CurContext; |
250 | while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext())) |
251 | DC = DC->getParent(); |
252 | bool IsGenericLambda = getGenericLambdaTemplateParameterList(getCurLambda(), |
253 | *this); |
254 | |
255 | CXXRecordDecl *Class = CXXRecordDecl::CreateLambda(Context, DC, Info, |
256 | IntroducerRange.getBegin(), |
257 | KnownDependent, |
258 | IsGenericLambda, |
259 | CaptureDefault); |
260 | DC->addDecl(Class); |
261 | |
262 | return Class; |
263 | } |
264 | |
265 | |
266 | |
267 | static bool isInInlineFunction(const DeclContext *DC) { |
268 | while (!DC->isFileContext()) { |
269 | if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DC)) |
270 | if (FD->isInlined()) |
271 | return true; |
272 | |
273 | DC = DC->getLexicalParent(); |
274 | } |
275 | |
276 | return false; |
277 | } |
278 | |
279 | MangleNumberingContext * |
280 | Sema::getCurrentMangleNumberContext(const DeclContext *DC, |
281 | Decl *&ManglingContextDecl) { |
282 | |
283 | |
284 | ManglingContextDecl = ExprEvalContexts.back().ManglingContextDecl; |
285 | |
286 | enum ContextKind { |
287 | Normal, |
288 | DefaultArgument, |
289 | DataMember, |
290 | StaticDataMember, |
291 | InlineVariable, |
292 | VariableTemplate |
293 | } Kind = Normal; |
294 | |
295 | |
296 | |
297 | |
298 | if (ManglingContextDecl) { |
299 | if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(ManglingContextDecl)) { |
300 | if (const DeclContext *LexicalDC |
301 | = Param->getDeclContext()->getLexicalParent()) |
302 | if (LexicalDC->isRecord()) |
303 | Kind = DefaultArgument; |
304 | } else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) { |
305 | if (Var->getDeclContext()->isRecord()) |
306 | Kind = StaticDataMember; |
307 | else if (Var->getMostRecentDecl()->isInline()) |
308 | Kind = InlineVariable; |
309 | else if (Var->getDescribedVarTemplate()) |
310 | Kind = VariableTemplate; |
311 | else if (auto *VTS = dyn_cast<VarTemplateSpecializationDecl>(Var)) { |
312 | if (!VTS->isExplicitSpecialization()) |
313 | Kind = VariableTemplate; |
314 | } |
315 | } else if (isa<FieldDecl>(ManglingContextDecl)) { |
316 | Kind = DataMember; |
317 | } |
318 | } |
319 | |
320 | |
321 | |
322 | |
323 | bool IsInNonspecializedTemplate = |
324 | inTemplateInstantiation() || CurContext->isDependentContext(); |
325 | switch (Kind) { |
326 | case Normal: { |
327 | |
328 | |
329 | if ((IsInNonspecializedTemplate && |
330 | !(ManglingContextDecl && isa<ParmVarDecl>(ManglingContextDecl))) || |
331 | isInInlineFunction(CurContext)) { |
332 | ManglingContextDecl = nullptr; |
333 | while (auto *CD = dyn_cast<CapturedDecl>(DC)) |
334 | DC = CD->getParent(); |
335 | return &Context.getManglingNumberContext(DC); |
336 | } |
337 | |
338 | ManglingContextDecl = nullptr; |
339 | return nullptr; |
340 | } |
341 | |
342 | case StaticDataMember: |
343 | |
344 | if (!IsInNonspecializedTemplate) { |
345 | ManglingContextDecl = nullptr; |
346 | return nullptr; |
347 | } |
348 | |
349 | LLVM_FALLTHROUGH; |
350 | |
351 | case DataMember: |
352 | |
353 | case DefaultArgument: |
354 | |
355 | case InlineVariable: |
356 | |
357 | case VariableTemplate: |
358 | |
359 | return &ExprEvalContexts.back().getMangleNumberingContext(Context); |
360 | } |
361 | |
362 | llvm_unreachable("unexpected context"); |
363 | } |
364 | |
365 | MangleNumberingContext & |
366 | Sema::ExpressionEvaluationContextRecord::getMangleNumberingContext( |
367 | ASTContext &Ctx) { |
368 | (0) . __assert_fail ("ManglingContextDecl && \"Need to have a context declaration\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 368, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ManglingContextDecl && "Need to have a context declaration"); |
369 | if (!MangleNumbering) |
370 | MangleNumbering = Ctx.createMangleNumberingContext(); |
371 | return *MangleNumbering; |
372 | } |
373 | |
374 | CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class, |
375 | SourceRange IntroducerRange, |
376 | TypeSourceInfo *MethodTypeInfo, |
377 | SourceLocation EndLoc, |
378 | ArrayRef<ParmVarDecl *> Params, |
379 | const bool IsConstexprSpecified) { |
380 | QualType MethodType = MethodTypeInfo->getType(); |
381 | TemplateParameterList *TemplateParams = |
382 | getGenericLambdaTemplateParameterList(getCurLambda(), *this); |
383 | |
384 | |
385 | |
386 | if (Class->isDependentContext() || TemplateParams) { |
387 | const FunctionProtoType *FPT = MethodType->castAs<FunctionProtoType>(); |
388 | QualType Result = FPT->getReturnType(); |
389 | if (Result->isUndeducedType()) { |
390 | Result = SubstAutoType(Result, Context.DependentTy); |
391 | MethodType = Context.getFunctionType(Result, FPT->getParamTypes(), |
392 | FPT->getExtProtoInfo()); |
393 | } |
394 | } |
395 | |
396 | |
397 | |
398 | |
399 | |
400 | |
401 | DeclarationName MethodName |
402 | = Context.DeclarationNames.getCXXOperatorName(OO_Call); |
403 | DeclarationNameLoc MethodNameLoc; |
404 | MethodNameLoc.CXXOperatorName.BeginOpNameLoc |
405 | = IntroducerRange.getBegin().getRawEncoding(); |
406 | MethodNameLoc.CXXOperatorName.EndOpNameLoc |
407 | = IntroducerRange.getEnd().getRawEncoding(); |
408 | CXXMethodDecl *Method |
409 | = CXXMethodDecl::Create(Context, Class, EndLoc, |
410 | DeclarationNameInfo(MethodName, |
411 | IntroducerRange.getBegin(), |
412 | MethodNameLoc), |
413 | MethodType, MethodTypeInfo, |
414 | SC_None, |
415 | , |
416 | IsConstexprSpecified, |
417 | EndLoc); |
418 | Method->setAccess(AS_public); |
419 | |
420 | |
421 | |
422 | Method->setLexicalDeclContext(CurContext); |
423 | |
424 | FunctionTemplateDecl *const TemplateMethod = TemplateParams ? |
425 | FunctionTemplateDecl::Create(Context, Class, |
426 | Method->getLocation(), MethodName, |
427 | TemplateParams, |
428 | Method) : nullptr; |
429 | if (TemplateMethod) { |
430 | TemplateMethod->setLexicalDeclContext(CurContext); |
431 | TemplateMethod->setAccess(AS_public); |
432 | Method->setDescribedFunctionTemplate(TemplateMethod); |
433 | } |
434 | |
435 | |
436 | if (!Params.empty()) { |
437 | Method->setParams(Params); |
438 | CheckParmsForFunctionDef(Params, |
439 | ); |
440 | |
441 | for (auto P : Method->parameters()) |
442 | P->setOwningFunction(Method); |
443 | } |
444 | |
445 | Decl *ManglingContextDecl; |
446 | if (MangleNumberingContext *MCtx = |
447 | getCurrentMangleNumberContext(Class->getDeclContext(), |
448 | ManglingContextDecl)) { |
449 | unsigned ManglingNumber = MCtx->getManglingNumber(Method); |
450 | Class->setLambdaMangling(ManglingNumber, ManglingContextDecl); |
451 | } |
452 | |
453 | return Method; |
454 | } |
455 | |
456 | void Sema::buildLambdaScope(LambdaScopeInfo *LSI, |
457 | CXXMethodDecl *CallOperator, |
458 | SourceRange IntroducerRange, |
459 | LambdaCaptureDefault CaptureDefault, |
460 | SourceLocation CaptureDefaultLoc, |
461 | bool ExplicitParams, |
462 | bool ExplicitResultType, |
463 | bool Mutable) { |
464 | LSI->CallOperator = CallOperator; |
465 | CXXRecordDecl *LambdaClass = CallOperator->getParent(); |
466 | LSI->Lambda = LambdaClass; |
467 | if (CaptureDefault == LCD_ByCopy) |
468 | LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval; |
469 | else if (CaptureDefault == LCD_ByRef) |
470 | LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByref; |
471 | LSI->CaptureDefaultLoc = CaptureDefaultLoc; |
472 | LSI->IntroducerRange = IntroducerRange; |
473 | LSI->ExplicitParams = ExplicitParams; |
474 | LSI->Mutable = Mutable; |
475 | |
476 | if (ExplicitResultType) { |
477 | LSI->ReturnType = CallOperator->getReturnType(); |
478 | |
479 | if (!LSI->ReturnType->isDependentType() && |
480 | !LSI->ReturnType->isVoidType()) { |
481 | if (RequireCompleteType(CallOperator->getBeginLoc(), LSI->ReturnType, |
482 | diag::err_lambda_incomplete_result)) { |
483 | |
484 | } |
485 | } |
486 | } else { |
487 | LSI->HasImplicitReturnType = true; |
488 | } |
489 | } |
490 | |
491 | void Sema::finishLambdaExplicitCaptures(LambdaScopeInfo *LSI) { |
492 | LSI->finishedExplicitCaptures(); |
493 | } |
494 | |
495 | void Sema::addLambdaParameters( |
496 | ArrayRef<LambdaIntroducer::LambdaCapture> Captures, |
497 | CXXMethodDecl *CallOperator, Scope *CurScope) { |
498 | |
499 | for (unsigned p = 0, NumParams = CallOperator->getNumParams(); |
500 | p < NumParams; ++p) { |
501 | ParmVarDecl *Param = CallOperator->getParamDecl(p); |
502 | |
503 | |
504 | if (CurScope && Param->getIdentifier()) { |
505 | bool Error = false; |
506 | |
507 | |
508 | for (const auto &Capture : Captures) { |
509 | if (Capture.Id == Param->getIdentifier()) { |
510 | Error = true; |
511 | Diag(Param->getLocation(), diag::err_parameter_shadow_capture); |
512 | Diag(Capture.Loc, diag::note_var_explicitly_captured_here) |
513 | << Capture.Id << true; |
514 | } |
515 | } |
516 | if (!Error) |
517 | CheckShadow(CurScope, Param); |
518 | |
519 | PushOnScopeChains(Param, CurScope); |
520 | } |
521 | } |
522 | } |
523 | |
524 | |
525 | |
526 | |
527 | |
528 | |
529 | |
530 | |
531 | static EnumDecl *findEnumForBlockReturn(Expr *E) { |
532 | |
533 | |
534 | E = E->IgnoreParens(); |
535 | |
536 | |
537 | if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { |
538 | if (EnumConstantDecl *D |
539 | = dyn_cast<EnumConstantDecl>(DRE->getDecl())) { |
540 | return cast<EnumDecl>(D->getDeclContext()); |
541 | } |
542 | return nullptr; |
543 | } |
544 | |
545 | |
546 | |
547 | if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { |
548 | if (BO->getOpcode() == BO_Comma) |
549 | return findEnumForBlockReturn(BO->getRHS()); |
550 | return nullptr; |
551 | } |
552 | |
553 | |
554 | |
555 | if (StmtExpr *SE = dyn_cast<StmtExpr>(E)) { |
556 | if (Expr *last = dyn_cast_or_null<Expr>(SE->getSubStmt()->body_back())) |
557 | return findEnumForBlockReturn(last); |
558 | return nullptr; |
559 | } |
560 | |
561 | |
562 | |
563 | |
564 | if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { |
565 | if (EnumDecl *ED = findEnumForBlockReturn(CO->getTrueExpr())) |
566 | if (ED == findEnumForBlockReturn(CO->getFalseExpr())) |
567 | return ED; |
568 | return nullptr; |
569 | } |
570 | |
571 | |
572 | |
573 | |
574 | if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) { |
575 | |
576 | |
577 | if (ICE->getCastKind() == CK_IntegralCast) |
578 | return findEnumForBlockReturn(ICE->getSubExpr()); |
579 | |
580 | |
581 | } |
582 | |
583 | |
584 | if (const EnumType *ET = E->getType()->getAs<EnumType>()) { |
585 | return ET->getDecl(); |
586 | } |
587 | |
588 | |
589 | return nullptr; |
590 | } |
591 | |
592 | |
593 | |
594 | static EnumDecl *findEnumForBlockReturn(ReturnStmt *ret) { |
595 | if (Expr *retValue = ret->getRetValue()) |
596 | return findEnumForBlockReturn(retValue); |
597 | return nullptr; |
598 | } |
599 | |
600 | |
601 | |
602 | |
603 | static EnumDecl *findCommonEnumForBlockReturns(ArrayRef<ReturnStmt*> returns) { |
604 | ArrayRef<ReturnStmt*>::iterator i = returns.begin(), e = returns.end(); |
605 | |
606 | |
607 | EnumDecl *ED = findEnumForBlockReturn(*i); |
608 | if (!ED) return nullptr; |
609 | |
610 | |
611 | for (++i; i != e; ++i) { |
612 | if (findEnumForBlockReturn(*i) != ED) |
613 | return nullptr; |
614 | } |
615 | |
616 | |
617 | if (!ED->hasNameForLinkage()) return nullptr; |
618 | |
619 | return ED; |
620 | } |
621 | |
622 | |
623 | |
624 | static void adjustBlockReturnsToEnum(Sema &S, ArrayRef<ReturnStmt*> returns, |
625 | QualType returnType) { |
626 | for (ArrayRef<ReturnStmt*>::iterator |
627 | i = returns.begin(), e = returns.end(); i != e; ++i) { |
628 | ReturnStmt *ret = *i; |
629 | Expr *retValue = ret->getRetValue(); |
630 | if (S.Context.hasSameType(retValue->getType(), returnType)) |
631 | continue; |
632 | |
633 | |
634 | isIntegralOrUnscopedEnumerationType()", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 634, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(returnType->isIntegralOrUnscopedEnumerationType()); |
635 | getType()->isIntegralOrUnscopedEnumerationType()", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 635, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(retValue->getType()->isIntegralOrUnscopedEnumerationType()); |
636 | |
637 | ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(retValue); |
638 | |
639 | Expr *E = (cleanups ? cleanups->getSubExpr() : retValue); |
640 | E = ImplicitCastExpr::Create(S.Context, returnType, CK_IntegralCast, |
641 | E, nullptr, VK_RValue); |
642 | if (cleanups) { |
643 | cleanups->setSubExpr(E); |
644 | } else { |
645 | ret->setRetValue(E); |
646 | } |
647 | } |
648 | } |
649 | |
650 | void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) { |
651 | assert(CSI.HasImplicitReturnType); |
652 | |
653 | isUndeducedType()", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 653, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CSI.ReturnType.isNull() || !CSI.ReturnType->isUndeducedType()); |
654 | (0) . __assert_fail ("(!isa(CSI) || !getLangOpts().CPlusPlus14) && \"lambda expressions use auto deduction in C++14 onwards\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 655, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((!isa<LambdaScopeInfo>(CSI) || !getLangOpts().CPlusPlus14) && |
655 | (0) . __assert_fail ("(!isa(CSI) || !getLangOpts().CPlusPlus14) && \"lambda expressions use auto deduction in C++14 onwards\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 655, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "lambda expressions use auto deduction in C++14 onwards"); |
656 | |
657 | |
658 | |
659 | |
660 | |
661 | |
662 | |
663 | |
664 | |
665 | |
666 | |
667 | |
668 | |
669 | |
670 | |
671 | |
672 | |
673 | |
674 | |
675 | |
676 | |
677 | |
678 | |
679 | |
680 | |
681 | ASTContext &Ctx = getASTContext(); |
682 | if (CSI.Returns.empty()) { |
683 | |
684 | |
685 | if (CSI.ReturnType.isNull()) |
686 | CSI.ReturnType = Ctx.VoidTy; |
687 | return; |
688 | } |
689 | |
690 | |
691 | |
692 | (0) . __assert_fail ("!CSI.ReturnType.isNull() && \"We should have a tentative return type.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 692, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!CSI.ReturnType.isNull() && "We should have a tentative return type."); |
693 | if (CSI.ReturnType->isDependentType()) |
694 | return; |
695 | |
696 | |
697 | if (!getLangOpts().CPlusPlus) { |
698 | (CSI)", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 698, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<BlockScopeInfo>(CSI)); |
699 | const EnumDecl *ED = findCommonEnumForBlockReturns(CSI.Returns); |
700 | if (ED) { |
701 | CSI.ReturnType = Context.getTypeDeclType(ED); |
702 | adjustBlockReturnsToEnum(*this, CSI.Returns, CSI.ReturnType); |
703 | return; |
704 | } |
705 | } |
706 | |
707 | |
708 | if (CSI.Returns.size() == 1) |
709 | return; |
710 | |
711 | |
712 | |
713 | |
714 | |
715 | |
716 | |
717 | for (const ReturnStmt *RS : CSI.Returns) { |
718 | const Expr *RetE = RS->getRetValue(); |
719 | |
720 | QualType ReturnType = |
721 | (RetE ? RetE->getType() : Context.VoidTy).getUnqualifiedType(); |
722 | if (Context.getCanonicalFunctionResultType(ReturnType) == |
723 | Context.getCanonicalFunctionResultType(CSI.ReturnType)) { |
724 | |
725 | auto RetTyNullability = ReturnType->getNullability(Ctx); |
726 | auto BlockNullability = CSI.ReturnType->getNullability(Ctx); |
727 | if (BlockNullability && |
728 | (!RetTyNullability || |
729 | hasWeakerNullability(*RetTyNullability, *BlockNullability))) |
730 | CSI.ReturnType = ReturnType; |
731 | continue; |
732 | } |
733 | |
734 | |
735 | |
736 | Diag(RS->getBeginLoc(), |
737 | diag::err_typecheck_missing_return_type_incompatible) |
738 | << ReturnType << CSI.ReturnType << isa<LambdaScopeInfo>(CSI); |
739 | |
740 | } |
741 | } |
742 | |
743 | QualType Sema::buildLambdaInitCaptureInitialization(SourceLocation Loc, |
744 | bool ByRef, |
745 | IdentifierInfo *Id, |
746 | bool IsDirectInit, |
747 | Expr *&Init) { |
748 | |
749 | |
750 | QualType DeductType = Context.getAutoDeductType(); |
751 | TypeLocBuilder TLB; |
752 | TLB.pushTypeSpec(DeductType).setNameLoc(Loc); |
753 | if (ByRef) { |
754 | DeductType = BuildReferenceType(DeductType, true, Loc, Id); |
755 | (0) . __assert_fail ("!DeductType.isNull() && \"can't build reference to auto\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 755, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!DeductType.isNull() && "can't build reference to auto"); |
756 | TLB.push<ReferenceTypeLoc>(DeductType).setSigilLoc(Loc); |
757 | } |
758 | TypeSourceInfo *TSI = TLB.getTypeSourceInfo(Context, DeductType); |
759 | |
760 | |
761 | Expr *DeduceInit = Init; |
762 | QualType DeducedType = deduceVarTypeFromInitializer( |
763 | , DeclarationName(Id), DeductType, TSI, |
764 | SourceRange(Loc, Loc), IsDirectInit, DeduceInit); |
765 | if (DeducedType.isNull()) |
766 | return QualType(); |
767 | |
768 | |
769 | bool CXXDirectInit = isa<ParenListExpr>(Init); |
770 | |
771 | |
772 | |
773 | InitializedEntity Entity = |
774 | InitializedEntity::InitializeLambdaCapture(Id, DeducedType, Loc); |
775 | InitializationKind Kind = |
776 | IsDirectInit |
777 | ? (CXXDirectInit ? InitializationKind::CreateDirect( |
778 | Loc, Init->getBeginLoc(), Init->getEndLoc()) |
779 | : InitializationKind::CreateDirectList(Loc)) |
780 | : InitializationKind::CreateCopy(Loc, Init->getBeginLoc()); |
781 | |
782 | MultiExprArg Args = DeduceInit; |
783 | QualType DclT; |
784 | InitializationSequence InitSeq(*this, Entity, Kind, Args); |
785 | ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT); |
786 | |
787 | if (Result.isInvalid()) |
788 | return QualType(); |
789 | |
790 | Init = Result.getAs<Expr>(); |
791 | return DeducedType; |
792 | } |
793 | |
794 | VarDecl *Sema::createLambdaInitCaptureVarDecl(SourceLocation Loc, |
795 | QualType InitCaptureType, |
796 | IdentifierInfo *Id, |
797 | unsigned InitStyle, Expr *Init) { |
798 | TypeSourceInfo *TSI = Context.getTrivialTypeSourceInfo(InitCaptureType, |
799 | Loc); |
800 | |
801 | |
802 | |
803 | |
804 | VarDecl *NewVD = VarDecl::Create(Context, CurContext, Loc, |
805 | Loc, Id, InitCaptureType, TSI, SC_Auto); |
806 | NewVD->setInitCapture(true); |
807 | NewVD->setReferenced(true); |
808 | |
809 | NewVD->setInitStyle(static_cast<VarDecl::InitializationStyle>(InitStyle)); |
810 | NewVD->markUsed(Context); |
811 | NewVD->setInit(Init); |
812 | return NewVD; |
813 | } |
814 | |
815 | FieldDecl *Sema::buildInitCaptureField(LambdaScopeInfo *LSI, VarDecl *Var) { |
816 | FieldDecl *Field = FieldDecl::Create( |
817 | Context, LSI->Lambda, Var->getLocation(), Var->getLocation(), |
818 | nullptr, Var->getType(), Var->getTypeSourceInfo(), nullptr, false, |
819 | ICIS_NoInit); |
820 | Field->setImplicit(true); |
821 | Field->setAccess(AS_private); |
822 | LSI->Lambda->addDecl(Field); |
823 | |
824 | LSI->addCapture(Var, , Var->getType()->isReferenceType(), |
825 | , Var->getLocation(), SourceLocation(), |
826 | Var->getType(), Var->getInit()); |
827 | return Field; |
828 | } |
829 | |
830 | void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, |
831 | Declarator &ParamInfo, |
832 | Scope *CurScope) { |
833 | |
834 | |
835 | bool KnownDependent = false; |
836 | LambdaScopeInfo *const LSI = getCurLambda(); |
837 | (0) . __assert_fail ("LSI && \"LambdaScopeInfo should be on stack!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 837, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(LSI && "LambdaScopeInfo should be on stack!"); |
838 | |
839 | |
840 | |
841 | |
842 | if (CurScope->getTemplateParamParent()) |
843 | KnownDependent = true; |
844 | |
845 | |
846 | TypeSourceInfo *MethodTyInfo; |
847 | bool ExplicitParams = true; |
848 | bool ExplicitResultType = true; |
849 | bool ContainsUnexpandedParameterPack = false; |
850 | SourceLocation EndLoc; |
851 | SmallVector<ParmVarDecl *, 8> Params; |
852 | if (ParamInfo.getNumTypeObjects() == 0) { |
853 | |
854 | |
855 | |
856 | FunctionProtoType::ExtProtoInfo EPI(Context.getDefaultCallingConvention( |
857 | , )); |
858 | EPI.HasTrailingReturn = true; |
859 | EPI.TypeQuals.addConst(); |
860 | |
861 | |
862 | |
863 | |
864 | |
865 | |
866 | QualType DefaultTypeForNoTrailingReturn = |
867 | getLangOpts().CPlusPlus14 ? Context.getAutoDeductType() |
868 | : Context.DependentTy; |
869 | QualType MethodTy = |
870 | Context.getFunctionType(DefaultTypeForNoTrailingReturn, None, EPI); |
871 | MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy); |
872 | ExplicitParams = false; |
873 | ExplicitResultType = false; |
874 | EndLoc = Intro.Range.getEnd(); |
875 | } else { |
876 | (0) . __assert_fail ("ParamInfo.isFunctionDeclarator() && \"lambda-declarator is a function\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 877, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ParamInfo.isFunctionDeclarator() && |
877 | (0) . __assert_fail ("ParamInfo.isFunctionDeclarator() && \"lambda-declarator is a function\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 877, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "lambda-declarator is a function"); |
878 | DeclaratorChunk::FunctionTypeInfo &FTI = ParamInfo.getFunctionTypeInfo(); |
879 | |
880 | |
881 | |
882 | |
883 | |
884 | if (!FTI.hasMutableQualifier()) { |
885 | FTI.getOrCreateMethodQualifiers().SetTypeQual(DeclSpec::TQ_const, |
886 | SourceLocation()); |
887 | } |
888 | |
889 | MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope); |
890 | (0) . __assert_fail ("MethodTyInfo && \"no type from lambda-declarator\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 890, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(MethodTyInfo && "no type from lambda-declarator"); |
891 | EndLoc = ParamInfo.getSourceRange().getEnd(); |
892 | |
893 | ExplicitResultType = FTI.hasTrailingReturnType(); |
894 | |
895 | if (FTIHasNonVoidParameters(FTI)) { |
896 | Params.reserve(FTI.NumParams); |
897 | for (unsigned i = 0, e = FTI.NumParams; i != e; ++i) |
898 | Params.push_back(cast<ParmVarDecl>(FTI.Params[i].Param)); |
899 | } |
900 | |
901 | |
902 | if (MethodTyInfo->getType()->containsUnexpandedParameterPack()) |
903 | ContainsUnexpandedParameterPack = true; |
904 | } |
905 | |
906 | CXXRecordDecl *Class = createLambdaClosureType(Intro.Range, MethodTyInfo, |
907 | KnownDependent, Intro.Default); |
908 | |
909 | CXXMethodDecl *Method = |
910 | startLambdaDefinition(Class, Intro.Range, MethodTyInfo, EndLoc, Params, |
911 | ParamInfo.getDeclSpec().isConstexprSpecified()); |
912 | if (ExplicitParams) |
913 | CheckCXXDefaultArguments(Method); |
914 | |
915 | |
916 | |
917 | AddRangeBasedOptnone(Method); |
918 | |
919 | |
920 | if (Attr *A = getImplicitCodeSegOrSectionAttrForFunction(Method, )) |
921 | Method->addAttr(A); |
922 | |
923 | |
924 | ProcessDeclAttributes(CurScope, Method, ParamInfo); |
925 | |
926 | |
927 | |
928 | if (getLangOpts().CUDA) |
929 | CUDASetLambdaAttrs(Method); |
930 | |
931 | |
932 | PushDeclContext(CurScope, Method); |
933 | |
934 | |
935 | buildLambdaScope(LSI, Method, Intro.Range, Intro.Default, Intro.DefaultLoc, |
936 | ExplicitParams, ExplicitResultType, !Method->isConst()); |
937 | |
938 | |
939 | |
940 | |
941 | |
942 | |
943 | |
944 | |
945 | |
946 | |
947 | |
948 | |
949 | if (Intro.Default != LCD_None && !Class->getParent()->isFunctionOrMethod() && |
950 | (getCurrentThisType().isNull() || |
951 | CheckCXXThisCapture(SourceLocation(), , |
952 | ))) |
953 | Diag(Intro.DefaultLoc, diag::err_capture_default_non_local); |
954 | |
955 | |
956 | llvm::SmallSet<IdentifierInfo*, 8> CaptureNames; |
957 | |
958 | |
959 | SourceLocation PrevCaptureLoc |
960 | = Intro.Default == LCD_None? Intro.Range.getBegin() : Intro.DefaultLoc; |
961 | for (auto C = Intro.Captures.begin(), E = Intro.Captures.end(); C != E; |
962 | PrevCaptureLoc = C->Loc, ++C) { |
963 | if (C->Kind == LCK_This || C->Kind == LCK_StarThis) { |
964 | if (C->Kind == LCK_StarThis) |
965 | Diag(C->Loc, !getLangOpts().CPlusPlus17 |
966 | ? diag::ext_star_this_lambda_capture_cxx17 |
967 | : diag::warn_cxx14_compat_star_this_lambda_capture); |
968 | |
969 | |
970 | |
971 | |
972 | if (LSI->isCXXThisCaptured()) { |
973 | Diag(C->Loc, diag::err_capture_more_than_once) |
974 | << "'this'" << SourceRange(LSI->getCXXThisCapture().getLocation()) |
975 | << FixItHint::CreateRemoval( |
976 | SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); |
977 | continue; |
978 | } |
979 | |
980 | |
981 | |
982 | |
983 | |
984 | |
985 | if (Intro.Default == LCD_ByCopy && C->Kind != LCK_StarThis) |
986 | Diag(C->Loc, !getLangOpts().CPlusPlus2a |
987 | ? diag::ext_equals_this_lambda_capture_cxx2a |
988 | : diag::warn_cxx17_compat_equals_this_lambda_capture); |
989 | |
990 | |
991 | |
992 | |
993 | QualType ThisCaptureType = getCurrentThisType(); |
994 | if (ThisCaptureType.isNull()) { |
995 | Diag(C->Loc, diag::err_this_capture) << true; |
996 | continue; |
997 | } |
998 | |
999 | CheckCXXThisCapture(C->Loc, , true, |
1000 | nullptr, |
1001 | C->Kind == LCK_StarThis); |
1002 | if (!LSI->Captures.empty()) |
1003 | LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange; |
1004 | continue; |
1005 | } |
1006 | |
1007 | (0) . __assert_fail ("C->Id && \"missing identifier for capture\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 1007, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(C->Id && "missing identifier for capture"); |
1008 | |
1009 | if (C->Init.isInvalid()) |
1010 | continue; |
1011 | |
1012 | VarDecl *Var = nullptr; |
1013 | if (C->Init.isUsable()) { |
1014 | Diag(C->Loc, getLangOpts().CPlusPlus14 |
1015 | ? diag::warn_cxx11_compat_init_capture |
1016 | : diag::ext_init_capture); |
1017 | |
1018 | if (C->Init.get()->containsUnexpandedParameterPack()) |
1019 | ContainsUnexpandedParameterPack = true; |
1020 | |
1021 | |
1022 | |
1023 | |
1024 | |
1025 | if (C->InitCaptureType.get().isNull()) |
1026 | continue; |
1027 | |
1028 | unsigned InitStyle; |
1029 | switch (C->InitKind) { |
1030 | case LambdaCaptureInitKind::NoInit: |
1031 | llvm_unreachable("not an init-capture?"); |
1032 | case LambdaCaptureInitKind::CopyInit: |
1033 | InitStyle = VarDecl::CInit; |
1034 | break; |
1035 | case LambdaCaptureInitKind::DirectInit: |
1036 | InitStyle = VarDecl::CallInit; |
1037 | break; |
1038 | case LambdaCaptureInitKind::ListInit: |
1039 | InitStyle = VarDecl::ListInit; |
1040 | break; |
1041 | } |
1042 | Var = createLambdaInitCaptureVarDecl(C->Loc, C->InitCaptureType.get(), |
1043 | C->Id, InitStyle, C->Init.get()); |
1044 | |
1045 | |
1046 | |
1047 | |
1048 | if (Var) |
1049 | PushOnScopeChains(Var, CurScope, false); |
1050 | } else { |
1051 | (0) . __assert_fail ("C->InitKind == LambdaCaptureInitKind..NoInit && \"init capture has valid but null init?\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 1052, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(C->InitKind == LambdaCaptureInitKind::NoInit && |
1052 | (0) . __assert_fail ("C->InitKind == LambdaCaptureInitKind..NoInit && \"init capture has valid but null init?\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 1052, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "init capture has valid but null init?"); |
1053 | |
1054 | |
1055 | |
1056 | |
1057 | |
1058 | |
1059 | if (C->Kind == LCK_ByRef && Intro.Default == LCD_ByRef) { |
1060 | Diag(C->Loc, diag::err_reference_capture_with_reference_default) |
1061 | << FixItHint::CreateRemoval( |
1062 | SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); |
1063 | continue; |
1064 | } else if (C->Kind == LCK_ByCopy && Intro.Default == LCD_ByCopy) { |
1065 | Diag(C->Loc, diag::err_copy_capture_with_copy_default) |
1066 | << FixItHint::CreateRemoval( |
1067 | SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); |
1068 | continue; |
1069 | } |
1070 | |
1071 | |
1072 | |
1073 | |
1074 | DeclarationNameInfo Name(C->Id, C->Loc); |
1075 | LookupResult R(*this, Name, LookupOrdinaryName); |
1076 | LookupName(R, CurScope); |
1077 | if (R.isAmbiguous()) |
1078 | continue; |
1079 | if (R.empty()) { |
1080 | |
1081 | CXXScopeSpec ScopeSpec; |
1082 | DeclFilterCCC<VarDecl> Validator{}; |
1083 | if (DiagnoseEmptyLookup(CurScope, ScopeSpec, R, Validator)) |
1084 | continue; |
1085 | } |
1086 | |
1087 | Var = R.getAsSingle<VarDecl>(); |
1088 | if (Var && DiagnoseUseOfDecl(Var, C->Loc)) |
1089 | continue; |
1090 | } |
1091 | |
1092 | |
1093 | |
1094 | |
1095 | if (!CaptureNames.insert(C->Id).second) { |
1096 | if (Var && LSI->isCaptured(Var)) { |
1097 | Diag(C->Loc, diag::err_capture_more_than_once) |
1098 | << C->Id << SourceRange(LSI->getCapture(Var).getLocation()) |
1099 | << FixItHint::CreateRemoval( |
1100 | SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); |
1101 | } else |
1102 | |
1103 | |
1104 | Diag(C->Loc, diag::err_capture_more_than_once) << C->Id; |
1105 | continue; |
1106 | } |
1107 | |
1108 | |
1109 | |
1110 | |
1111 | |
1112 | if (!Var) { |
1113 | Diag(C->Loc, diag::err_capture_does_not_name_variable) << C->Id; |
1114 | continue; |
1115 | } |
1116 | |
1117 | |
1118 | if (Var->isInvalidDecl()) |
1119 | continue; |
1120 | |
1121 | if (!Var->hasLocalStorage()) { |
1122 | Diag(C->Loc, diag::err_capture_non_automatic_variable) << C->Id; |
1123 | Diag(Var->getLocation(), diag::note_previous_decl) << C->Id; |
1124 | continue; |
1125 | } |
1126 | |
1127 | |
1128 | |
1129 | SourceLocation EllipsisLoc; |
1130 | if (C->EllipsisLoc.isValid()) { |
1131 | if (Var->isParameterPack()) { |
1132 | EllipsisLoc = C->EllipsisLoc; |
1133 | } else { |
1134 | Diag(C->EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) |
1135 | << SourceRange(C->Loc); |
1136 | |
1137 | |
1138 | } |
1139 | } else if (Var->isParameterPack()) { |
1140 | ContainsUnexpandedParameterPack = true; |
1141 | } |
1142 | |
1143 | if (C->Init.isUsable()) { |
1144 | buildInitCaptureField(LSI, Var); |
1145 | } else { |
1146 | TryCaptureKind Kind = C->Kind == LCK_ByRef ? TryCapture_ExplicitByRef : |
1147 | TryCapture_ExplicitByVal; |
1148 | tryCaptureVariable(Var, C->Loc, Kind, EllipsisLoc); |
1149 | } |
1150 | if (!LSI->Captures.empty()) |
1151 | LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange; |
1152 | } |
1153 | finishLambdaExplicitCaptures(LSI); |
1154 | |
1155 | LSI->ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; |
1156 | |
1157 | |
1158 | addLambdaParameters(Intro.Captures, Method, CurScope); |
1159 | |
1160 | |
1161 | |
1162 | PushExpressionEvaluationContext( |
1163 | ExpressionEvaluationContext::PotentiallyEvaluated); |
1164 | } |
1165 | |
1166 | void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope, |
1167 | bool IsInstantiation) { |
1168 | LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(FunctionScopes.back()); |
1169 | |
1170 | |
1171 | DiscardCleanupsInEvaluationContext(); |
1172 | PopExpressionEvaluationContext(); |
1173 | |
1174 | |
1175 | if (!IsInstantiation) |
1176 | PopDeclContext(); |
1177 | |
1178 | |
1179 | CXXRecordDecl *Class = LSI->Lambda; |
1180 | Class->setInvalidDecl(); |
1181 | SmallVector<Decl*, 4> Fields(Class->fields()); |
1182 | ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(), |
1183 | SourceLocation(), ParsedAttributesView()); |
1184 | CheckCompletedCXXClass(Class); |
1185 | |
1186 | PopFunctionScopeInfo(); |
1187 | } |
1188 | |
1189 | QualType Sema::getLambdaConversionFunctionResultType( |
1190 | const FunctionProtoType *CallOpProto) { |
1191 | |
1192 | |
1193 | |
1194 | const FunctionProtoType::ExtProtoInfo CallOpExtInfo = |
1195 | CallOpProto->getExtProtoInfo(); |
1196 | FunctionProtoType::ExtProtoInfo InvokerExtInfo = CallOpExtInfo; |
1197 | CallingConv CC = Context.getDefaultCallingConvention( |
1198 | CallOpProto->isVariadic(), ); |
1199 | InvokerExtInfo.ExtInfo = InvokerExtInfo.ExtInfo.withCallingConv(CC); |
1200 | InvokerExtInfo.TypeQuals = Qualifiers(); |
1201 | (0) . __assert_fail ("InvokerExtInfo.RefQualifier == RQ_None && \"Lambda's call operator should not have a reference qualifier\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 1202, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(InvokerExtInfo.RefQualifier == RQ_None && |
1202 | (0) . __assert_fail ("InvokerExtInfo.RefQualifier == RQ_None && \"Lambda's call operator should not have a reference qualifier\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 1202, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Lambda's call operator should not have a reference qualifier"); |
1203 | return Context.getFunctionType(CallOpProto->getReturnType(), |
1204 | CallOpProto->getParamTypes(), InvokerExtInfo); |
1205 | } |
1206 | |
1207 | |
1208 | |
1209 | static void addFunctionPointerConversion(Sema &S, |
1210 | SourceRange IntroducerRange, |
1211 | CXXRecordDecl *Class, |
1212 | CXXMethodDecl *CallOperator) { |
1213 | |
1214 | |
1215 | auto HasPassObjectSizeAttr = [](const ParmVarDecl *P) { |
1216 | return P->hasAttr<PassObjectSizeAttr>(); |
1217 | }; |
1218 | if (llvm::any_of(CallOperator->parameters(), HasPassObjectSizeAttr)) |
1219 | return; |
1220 | |
1221 | |
1222 | QualType InvokerFunctionTy = S.getLambdaConversionFunctionResultType( |
1223 | CallOperator->getType()->castAs<FunctionProtoType>()); |
1224 | QualType PtrToFunctionTy = S.Context.getPointerType(InvokerFunctionTy); |
1225 | |
1226 | |
1227 | FunctionProtoType::ExtProtoInfo ConvExtInfo( |
1228 | S.Context.getDefaultCallingConvention( |
1229 | , )); |
1230 | |
1231 | ConvExtInfo.TypeQuals = Qualifiers(); |
1232 | ConvExtInfo.TypeQuals.addConst(); |
1233 | ConvExtInfo.ExceptionSpec.Type = EST_BasicNoexcept; |
1234 | QualType ConvTy = |
1235 | S.Context.getFunctionType(PtrToFunctionTy, None, ConvExtInfo); |
1236 | |
1237 | SourceLocation Loc = IntroducerRange.getBegin(); |
1238 | DeclarationName ConversionName |
1239 | = S.Context.DeclarationNames.getCXXConversionFunctionName( |
1240 | S.Context.getCanonicalType(PtrToFunctionTy)); |
1241 | DeclarationNameLoc ConvNameLoc; |
1242 | |
1243 | |
1244 | |
1245 | |
1246 | |
1247 | |
1248 | |
1249 | |
1250 | |
1251 | |
1252 | |
1253 | |
1254 | |
1255 | |
1256 | |
1257 | |
1258 | TypeSourceInfo *ConvNamePtrToFunctionTSI = |
1259 | S.Context.getTrivialTypeSourceInfo(PtrToFunctionTy, Loc); |
1260 | ConvNameLoc.NamedType.TInfo = ConvNamePtrToFunctionTSI; |
1261 | |
1262 | |
1263 | TypeSourceInfo *ConvTSI = S.Context.getTrivialTypeSourceInfo(ConvTy, Loc); |
1264 | FunctionProtoTypeLoc ConvTL = |
1265 | ConvTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>(); |
1266 | |
1267 | PointerTypeLoc PtrToFunctionTL = |
1268 | ConvTL.getReturnLoc().getAs<PointerTypeLoc>(); |
1269 | |
1270 | |
1271 | PointerTypeLoc ConvNamePtrToFunctionTL = |
1272 | ConvNamePtrToFunctionTSI->getTypeLoc().getAs<PointerTypeLoc>(); |
1273 | |
1274 | |
1275 | |
1276 | FunctionProtoTypeLoc CallOpConvTL = |
1277 | PtrToFunctionTL.getPointeeLoc().getAs<FunctionProtoTypeLoc>(); |
1278 | FunctionProtoTypeLoc CallOpConvNameTL = |
1279 | ConvNamePtrToFunctionTL.getPointeeLoc().getAs<FunctionProtoTypeLoc>(); |
1280 | |
1281 | |
1282 | |
1283 | |
1284 | |
1285 | |
1286 | |
1287 | |
1288 | |
1289 | SmallVector<ParmVarDecl *, 4> InvokerParams; |
1290 | for (unsigned I = 0, N = CallOperator->getNumParams(); I != N; ++I) { |
1291 | ParmVarDecl *From = CallOperator->getParamDecl(I); |
1292 | |
1293 | InvokerParams.push_back(ParmVarDecl::Create( |
1294 | S.Context, |
1295 | |
1296 | S.Context.getTranslationUnitDecl(), From->getBeginLoc(), |
1297 | From->getLocation(), From->getIdentifier(), From->getType(), |
1298 | From->getTypeSourceInfo(), From->getStorageClass(), |
1299 | )); |
1300 | CallOpConvTL.setParam(I, From); |
1301 | CallOpConvNameTL.setParam(I, From); |
1302 | } |
1303 | |
1304 | CXXConversionDecl *Conversion = CXXConversionDecl::Create( |
1305 | S.Context, Class, Loc, |
1306 | DeclarationNameInfo(ConversionName, Loc, ConvNameLoc), ConvTy, ConvTSI, |
1307 | , , |
1308 | .getLangOpts().CPlusPlus17, |
1309 | CallOperator->getBody()->getEndLoc()); |
1310 | Conversion->setAccess(AS_public); |
1311 | Conversion->setImplicit(true); |
1312 | |
1313 | if (Class->isGenericLambda()) { |
1314 | |
1315 | |
1316 | FunctionTemplateDecl *TemplateCallOperator = |
1317 | CallOperator->getDescribedFunctionTemplate(); |
1318 | FunctionTemplateDecl *ConversionTemplate = |
1319 | FunctionTemplateDecl::Create(S.Context, Class, |
1320 | Loc, ConversionName, |
1321 | TemplateCallOperator->getTemplateParameters(), |
1322 | Conversion); |
1323 | ConversionTemplate->setAccess(AS_public); |
1324 | ConversionTemplate->setImplicit(true); |
1325 | Conversion->setDescribedFunctionTemplate(ConversionTemplate); |
1326 | Class->addDecl(ConversionTemplate); |
1327 | } else |
1328 | Class->addDecl(Conversion); |
1329 | |
1330 | |
1331 | DeclarationName InvokerName = &S.Context.Idents.get( |
1332 | getLambdaStaticInvokerName()); |
1333 | |
1334 | |
1335 | |
1336 | |
1337 | |
1338 | |
1339 | |
1340 | |
1341 | |
1342 | |
1343 | |
1344 | CXXMethodDecl *Invoke = CXXMethodDecl::Create( |
1345 | S.Context, Class, Loc, DeclarationNameInfo(InvokerName, Loc), |
1346 | InvokerFunctionTy, CallOperator->getTypeSourceInfo(), SC_Static, |
1347 | , |
1348 | , CallOperator->getBody()->getEndLoc()); |
1349 | for (unsigned I = 0, N = CallOperator->getNumParams(); I != N; ++I) |
1350 | InvokerParams[I]->setOwningFunction(Invoke); |
1351 | Invoke->setParams(InvokerParams); |
1352 | Invoke->setAccess(AS_private); |
1353 | Invoke->setImplicit(true); |
1354 | if (Class->isGenericLambda()) { |
1355 | FunctionTemplateDecl *TemplateCallOperator = |
1356 | CallOperator->getDescribedFunctionTemplate(); |
1357 | FunctionTemplateDecl *StaticInvokerTemplate = FunctionTemplateDecl::Create( |
1358 | S.Context, Class, Loc, InvokerName, |
1359 | TemplateCallOperator->getTemplateParameters(), |
1360 | Invoke); |
1361 | StaticInvokerTemplate->setAccess(AS_private); |
1362 | StaticInvokerTemplate->setImplicit(true); |
1363 | Invoke->setDescribedFunctionTemplate(StaticInvokerTemplate); |
1364 | Class->addDecl(StaticInvokerTemplate); |
1365 | } else |
1366 | Class->addDecl(Invoke); |
1367 | } |
1368 | |
1369 | |
1370 | static void addBlockPointerConversion(Sema &S, |
1371 | SourceRange IntroducerRange, |
1372 | CXXRecordDecl *Class, |
1373 | CXXMethodDecl *CallOperator) { |
1374 | QualType FunctionTy = S.getLambdaConversionFunctionResultType( |
1375 | CallOperator->getType()->castAs<FunctionProtoType>()); |
1376 | QualType BlockPtrTy = S.Context.getBlockPointerType(FunctionTy); |
1377 | |
1378 | FunctionProtoType::ExtProtoInfo ConversionEPI( |
1379 | S.Context.getDefaultCallingConvention( |
1380 | , )); |
1381 | ConversionEPI.TypeQuals = Qualifiers(); |
1382 | ConversionEPI.TypeQuals.addConst(); |
1383 | QualType ConvTy = S.Context.getFunctionType(BlockPtrTy, None, ConversionEPI); |
1384 | |
1385 | SourceLocation Loc = IntroducerRange.getBegin(); |
1386 | DeclarationName Name |
1387 | = S.Context.DeclarationNames.getCXXConversionFunctionName( |
1388 | S.Context.getCanonicalType(BlockPtrTy)); |
1389 | DeclarationNameLoc NameLoc; |
1390 | NameLoc.NamedType.TInfo = S.Context.getTrivialTypeSourceInfo(BlockPtrTy, Loc); |
1391 | CXXConversionDecl *Conversion = CXXConversionDecl::Create( |
1392 | S.Context, Class, Loc, DeclarationNameInfo(Name, Loc, NameLoc), ConvTy, |
1393 | S.Context.getTrivialTypeSourceInfo(ConvTy, Loc), |
1394 | , , |
1395 | , CallOperator->getBody()->getEndLoc()); |
1396 | Conversion->setAccess(AS_public); |
1397 | Conversion->setImplicit(true); |
1398 | Class->addDecl(Conversion); |
1399 | } |
1400 | |
1401 | static ExprResult performLambdaVarCaptureInitialization( |
1402 | Sema &S, const Capture &Capture, FieldDecl *Field, |
1403 | SourceLocation ImplicitCaptureLoc, bool IsImplicitCapture) { |
1404 | (0) . __assert_fail ("Capture.isVariableCapture() && \"not a variable capture\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 1404, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Capture.isVariableCapture() && "not a variable capture"); |
1405 | |
1406 | auto *Var = Capture.getVariable(); |
1407 | SourceLocation Loc = |
1408 | IsImplicitCapture ? ImplicitCaptureLoc : Capture.getLocation(); |
1409 | |
1410 | |
1411 | |
1412 | |
1413 | |
1414 | |
1415 | |
1416 | |
1417 | |
1418 | |
1419 | |
1420 | |
1421 | |
1422 | ExprResult RefResult = S.BuildDeclarationNameExpr( |
1423 | CXXScopeSpec(), DeclarationNameInfo(Var->getDeclName(), Loc), Var); |
1424 | if (RefResult.isInvalid()) |
1425 | return ExprError(); |
1426 | Expr *Ref = RefResult.get(); |
1427 | |
1428 | auto Entity = InitializedEntity::InitializeLambdaCapture( |
1429 | Var->getIdentifier(), Field->getType(), Loc); |
1430 | InitializationKind InitKind = InitializationKind::CreateDirect(Loc, Loc, Loc); |
1431 | InitializationSequence Init(S, Entity, InitKind, Ref); |
1432 | return Init.Perform(S, Entity, InitKind, Ref); |
1433 | } |
1434 | |
1435 | ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, |
1436 | Scope *CurScope) { |
1437 | LambdaScopeInfo LSI = *cast<LambdaScopeInfo>(FunctionScopes.back()); |
1438 | ActOnFinishFunctionBody(LSI.CallOperator, Body); |
1439 | return BuildLambdaExpr(StartLoc, Body->getEndLoc(), &LSI); |
1440 | } |
1441 | |
1442 | static LambdaCaptureDefault |
1443 | mapImplicitCaptureStyle(CapturingScopeInfo::ImplicitCaptureStyle ICS) { |
1444 | switch (ICS) { |
1445 | case CapturingScopeInfo::ImpCap_None: |
1446 | return LCD_None; |
1447 | case CapturingScopeInfo::ImpCap_LambdaByval: |
1448 | return LCD_ByCopy; |
1449 | case CapturingScopeInfo::ImpCap_CapturedRegion: |
1450 | case CapturingScopeInfo::ImpCap_LambdaByref: |
1451 | return LCD_ByRef; |
1452 | case CapturingScopeInfo::ImpCap_Block: |
1453 | llvm_unreachable("block capture in lambda"); |
1454 | } |
1455 | llvm_unreachable("Unknown implicit capture style"); |
1456 | } |
1457 | |
1458 | bool Sema::CaptureHasSideEffects(const Capture &From) { |
1459 | if (!From.isVLATypeCapture()) { |
1460 | Expr *Init = From.getInitExpr(); |
1461 | if (Init && Init->HasSideEffects(Context)) |
1462 | return true; |
1463 | } |
1464 | |
1465 | if (!From.isCopyCapture()) |
1466 | return false; |
1467 | |
1468 | const QualType T = From.isThisCapture() |
1469 | ? getCurrentThisType()->getPointeeType() |
1470 | : From.getCaptureType(); |
1471 | |
1472 | if (T.isVolatileQualified()) |
1473 | return true; |
1474 | |
1475 | const Type *BaseT = T->getBaseElementTypeUnsafe(); |
1476 | if (const CXXRecordDecl *RD = BaseT->getAsCXXRecordDecl()) |
1477 | return !RD->isCompleteDefinition() || !RD->hasTrivialCopyConstructor() || |
1478 | !RD->hasTrivialDestructor(); |
1479 | |
1480 | return false; |
1481 | } |
1482 | |
1483 | bool Sema::DiagnoseUnusedLambdaCapture(SourceRange CaptureRange, |
1484 | const Capture &From) { |
1485 | if (CaptureHasSideEffects(From)) |
1486 | return false; |
1487 | |
1488 | if (From.isVLATypeCapture()) |
1489 | return false; |
1490 | |
1491 | auto diag = Diag(From.getLocation(), diag::warn_unused_lambda_capture); |
1492 | if (From.isThisCapture()) |
1493 | diag << "'this'"; |
1494 | else |
1495 | diag << From.getVariable(); |
1496 | diag << From.isNonODRUsed(); |
1497 | diag << FixItHint::CreateRemoval(CaptureRange); |
1498 | return true; |
1499 | } |
1500 | |
1501 | ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, |
1502 | LambdaScopeInfo *LSI) { |
1503 | |
1504 | SmallVector<LambdaCapture, 4> Captures; |
1505 | SmallVector<Expr *, 4> CaptureInits; |
1506 | SourceLocation CaptureDefaultLoc = LSI->CaptureDefaultLoc; |
1507 | LambdaCaptureDefault CaptureDefault = |
1508 | mapImplicitCaptureStyle(LSI->ImpCaptureStyle); |
1509 | CXXRecordDecl *Class; |
1510 | CXXMethodDecl *CallOperator; |
1511 | SourceRange IntroducerRange; |
1512 | bool ExplicitParams; |
1513 | bool ExplicitResultType; |
1514 | CleanupInfo LambdaCleanup; |
1515 | bool ContainsUnexpandedParameterPack; |
1516 | bool IsGenericLambda; |
1517 | { |
1518 | CallOperator = LSI->CallOperator; |
1519 | Class = LSI->Lambda; |
1520 | IntroducerRange = LSI->IntroducerRange; |
1521 | ExplicitParams = LSI->ExplicitParams; |
1522 | ExplicitResultType = !LSI->HasImplicitReturnType; |
1523 | LambdaCleanup = LSI->Cleanup; |
1524 | ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack; |
1525 | IsGenericLambda = Class->isGenericLambda(); |
1526 | |
1527 | CallOperator->setLexicalDeclContext(Class); |
1528 | Decl *TemplateOrNonTemplateCallOperatorDecl = |
1529 | CallOperator->getDescribedFunctionTemplate() |
1530 | ? CallOperator->getDescribedFunctionTemplate() |
1531 | : cast<Decl>(CallOperator); |
1532 | |
1533 | TemplateOrNonTemplateCallOperatorDecl->setLexicalDeclContext(Class); |
1534 | Class->addDecl(TemplateOrNonTemplateCallOperatorDecl); |
1535 | |
1536 | PopExpressionEvaluationContext(); |
1537 | |
1538 | |
1539 | auto CurField = Class->field_begin(); |
1540 | |
1541 | bool CurHasPreviousCapture = CaptureDefault != LCD_None; |
1542 | SourceLocation PrevCaptureLoc = CurHasPreviousCapture ? |
1543 | CaptureDefaultLoc : IntroducerRange.getBegin(); |
1544 | |
1545 | for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I, ++CurField) { |
1546 | const Capture &From = LSI->Captures[I]; |
1547 | |
1548 | (0) . __assert_fail ("!From.isBlockCapture() && \"Cannot capture __block variables\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaLambda.cpp", 1548, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!From.isBlockCapture() && "Cannot capture __block variables"); |
1549 | bool IsImplicit = I >= LSI->NumExplicitCaptures; |
1550 | |
1551 | |
1552 | SourceRange CaptureRange = LSI->ExplicitCaptureRanges[I]; |
1553 | |
1554 | |
1555 | bool IsCaptureUsed = true; |
1556 | if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) { |
1557 | |
1558 | bool NonODRUsedInitCapture = |
1559 | IsGenericLambda && From.isNonODRUsed() && From.getInitExpr(); |
1560 | if (!NonODRUsedInitCapture) { |
1561 | bool IsLast = (I + 1) == LSI->NumExplicitCaptures; |
1562 | SourceRange FixItRange; |
1563 | if (CaptureRange.isValid()) { |
1564 | if (!CurHasPreviousCapture && !IsLast) { |
1565 | |
1566 | |
1567 | FixItRange = SourceRange(CaptureRange.getBegin(), |
1568 | getLocForEndOfToken(CaptureRange.getEnd())); |
1569 | } else { |
1570 | |
1571 | FixItRange = SourceRange(getLocForEndOfToken(PrevCaptureLoc), |
1572 | CaptureRange.getEnd()); |
1573 | } |
1574 | } |
1575 | |
1576 | IsCaptureUsed = !DiagnoseUnusedLambdaCapture(FixItRange, From); |
1577 | } |
1578 | } |
1579 | |
1580 | if (CaptureRange.isValid()) { |
1581 | CurHasPreviousCapture |= IsCaptureUsed; |
1582 | PrevCaptureLoc = CaptureRange.getEnd(); |
1583 | } |
1584 | |
1585 | |
1586 | if (From.isThisCapture()) { |
1587 | |
1588 | |
1589 | |
1590 | if (getLangOpts().CPlusPlus2a && IsImplicit && |
1591 | CaptureDefault == LCD_ByCopy) { |
1592 | Diag(From.getLocation(), diag::warn_deprecated_this_capture); |
1593 | Diag(CaptureDefaultLoc, diag::note_deprecated_this_capture) |
1594 | << FixItHint::CreateInsertion( |
1595 | getLocForEndOfToken(CaptureDefaultLoc), ", this"); |
1596 | } |
1597 | |
1598 | Captures.push_back( |
1599 | LambdaCapture(From.getLocation(), IsImplicit, |
1600 | From.isCopyCapture() ? LCK_StarThis : LCK_This)); |
1601 | CaptureInits.push_back(From.getInitExpr()); |
1602 | continue; |
1603 | } |
1604 | if (From.isVLATypeCapture()) { |
1605 | Captures.push_back( |
1606 | LambdaCapture(From.getLocation(), IsImplicit, LCK_VLAType)); |
1607 | CaptureInits.push_back(nullptr); |
1608 | continue; |
1609 | } |
1610 | |
1611 | VarDecl *Var = From.getVariable(); |
1612 | LambdaCaptureKind Kind = From.isCopyCapture() ? LCK_ByCopy : LCK_ByRef; |
1613 | Captures.push_back(LambdaCapture(From.getLocation(), IsImplicit, Kind, |
1614 | Var, From.getEllipsisLoc())); |
1615 | Expr *Init = From.getInitExpr(); |
1616 | if (!Init) { |
1617 | auto InitResult = performLambdaVarCaptureInitialization( |
1618 | *this, From, *CurField, CaptureDefaultLoc, IsImplicit); |
1619 | if (InitResult.isInvalid()) |
1620 | return ExprError(); |
1621 | Init = InitResult.get(); |
1622 | } |
1623 | CaptureInits.push_back(Init); |
1624 | } |
1625 | |
1626 | |
1627 | |
1628 | |
1629 | |
1630 | |
1631 | if (Captures.empty() && CaptureDefault == LCD_None) |
1632 | addFunctionPointerConversion(*this, IntroducerRange, Class, |
1633 | CallOperator); |
1634 | |
1635 | |
1636 | |
1637 | |
1638 | |
1639 | |
1640 | |
1641 | if (getLangOpts().Blocks && getLangOpts().ObjC && !IsGenericLambda) |
1642 | addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator); |
1643 | |
1644 | |
1645 | SmallVector<Decl*, 4> Fields(Class->fields()); |
1646 | ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(), |
1647 | SourceLocation(), ParsedAttributesView()); |
1648 | CheckCompletedCXXClass(Class); |
1649 | } |
1650 | |
1651 | Cleanup.mergeFrom(LambdaCleanup); |
1652 | |
1653 | LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange, |
1654 | CaptureDefault, CaptureDefaultLoc, |
1655 | Captures, |
1656 | ExplicitParams, ExplicitResultType, |
1657 | CaptureInits, EndLoc, |
1658 | ContainsUnexpandedParameterPack); |
1659 | |
1660 | |
1661 | |
1662 | if (getLangOpts().CPlusPlus17 && !CallOperator->isInvalidDecl() && |
1663 | !CallOperator->isConstexpr() && |
1664 | !isa<CoroutineBodyStmt>(CallOperator->getBody()) && |
1665 | !Class->getDeclContext()->isDependentContext()) { |
1666 | TentativeAnalysisScope DiagnosticScopeGuard(*this); |
1667 | CallOperator->setConstexpr( |
1668 | CheckConstexprFunctionDecl(CallOperator) && |
1669 | CheckConstexprFunctionBody(CallOperator, CallOperator->getBody())); |
1670 | } |
1671 | |
1672 | |
1673 | DiagnoseShadowingLambdaDecls(LSI); |
1674 | |
1675 | if (!CurContext->isDependentContext()) { |
1676 | switch (ExprEvalContexts.back().Context) { |
1677 | |
1678 | |
1679 | |
1680 | case ExpressionEvaluationContext::Unevaluated: |
1681 | case ExpressionEvaluationContext::UnevaluatedList: |
1682 | case ExpressionEvaluationContext::UnevaluatedAbstract: |
1683 | |
1684 | |
1685 | |
1686 | |
1687 | |
1688 | |
1689 | |
1690 | |
1691 | |
1692 | case ExpressionEvaluationContext::ConstantEvaluated: |
1693 | |
1694 | |
1695 | |
1696 | ExprEvalContexts.back().Lambdas.push_back(Lambda); |
1697 | break; |
1698 | |
1699 | case ExpressionEvaluationContext::DiscardedStatement: |
1700 | case ExpressionEvaluationContext::PotentiallyEvaluated: |
1701 | case ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed: |
1702 | break; |
1703 | } |
1704 | } |
1705 | |
1706 | return MaybeBindToTemporary(Lambda); |
1707 | } |
1708 | |
1709 | ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation, |
1710 | SourceLocation ConvLocation, |
1711 | CXXConversionDecl *Conv, |
1712 | Expr *Src) { |
1713 | |
1714 | CXXRecordDecl *Lambda = Conv->getParent(); |
1715 | CXXMethodDecl *CallOperator |
1716 | = cast<CXXMethodDecl>( |
1717 | Lambda->lookup( |
1718 | Context.DeclarationNames.getCXXOperatorName(OO_Call)).front()); |
1719 | CallOperator->setReferenced(); |
1720 | CallOperator->markUsed(Context); |
1721 | |
1722 | ExprResult Init = PerformCopyInitialization( |
1723 | InitializedEntity::InitializeLambdaToBlock(ConvLocation, Src->getType(), |
1724 | ), |
1725 | CurrentLocation, Src); |
1726 | if (!Init.isInvalid()) |
1727 | Init = ActOnFinishFullExpr(Init.get(), false); |
1728 | |
1729 | if (Init.isInvalid()) |
1730 | return ExprError(); |
1731 | |
1732 | |
1733 | BlockDecl *Block = BlockDecl::Create(Context, CurContext, ConvLocation); |
1734 | |
1735 | |
1736 | Block->setSignatureAsWritten(CallOperator->getTypeSourceInfo()); |
1737 | Block->setIsVariadic(CallOperator->isVariadic()); |
1738 | Block->setBlockMissingReturnType(false); |
1739 | |
1740 | |
1741 | SmallVector<ParmVarDecl *, 4> BlockParams; |
1742 | for (unsigned I = 0, N = CallOperator->getNumParams(); I != N; ++I) { |
1743 | ParmVarDecl *From = CallOperator->getParamDecl(I); |
1744 | BlockParams.push_back(ParmVarDecl::Create( |
1745 | Context, Block, From->getBeginLoc(), From->getLocation(), |
1746 | From->getIdentifier(), From->getType(), From->getTypeSourceInfo(), |
1747 | From->getStorageClass(), |
1748 | )); |
1749 | } |
1750 | Block->setParams(BlockParams); |
1751 | |
1752 | Block->setIsConversionFromLambda(true); |
1753 | |
1754 | |
1755 | |
1756 | |
1757 | TypeSourceInfo *CapVarTSI = |
1758 | Context.getTrivialTypeSourceInfo(Src->getType()); |
1759 | VarDecl *CapVar = VarDecl::Create(Context, Block, ConvLocation, |
1760 | ConvLocation, nullptr, |
1761 | Src->getType(), CapVarTSI, |
1762 | SC_None); |
1763 | BlockDecl::Capture Capture(, , |
1764 | , .get()); |
1765 | Block->setCaptures(Context, Capture, ); |
1766 | |
1767 | |
1768 | |
1769 | Block->setBody(new (Context) CompoundStmt(ConvLocation)); |
1770 | |
1771 | |
1772 | Expr *BuildBlock = new (Context) BlockExpr(Block, Conv->getConversionType()); |
1773 | ExprCleanupObjects.push_back(Block); |
1774 | Cleanup.setExprNeedsCleanups(true); |
1775 | |
1776 | return BuildBlock; |
1777 | } |
1778 | |