diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 53 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 57 | ||||
| -rw-r--r-- | clang/lib/Sema/TreeTransform.h | 4 |
3 files changed, 66 insertions, 48 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 80f95e68690..bc7be6d4593 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9401,6 +9401,29 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD, Diag(Definition->getLocation(), diag::note_previous_definition); FD->setInvalidDecl(); } +static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator, + Sema &S) { + CXXRecordDecl *const LambdaClass = CallOperator->getParent(); + S.PushLambdaScope(); + LambdaScopeInfo *LSI = S.getCurLambda(); + LSI->CallOperator = CallOperator; + LSI->Lambda = LambdaClass; + LSI->ReturnType = CallOperator->getResultType(); + const LambdaCaptureDefault LCD = LambdaClass->getLambdaCaptureDefault(); + + if (LCD == LCD_None) + LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_None; + else if (LCD == LCD_ByCopy) + LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_LambdaByval; + else if (LCD == LCD_ByRef) + LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_LambdaByref; + DeclarationNameInfo DNI = CallOperator->getNameInfo(); + + LSI->IntroducerRange = DNI.getCXXOperatorNameRange(); + LSI->Mutable = !CallOperator->isConst(); + + // FIXME: Add the captures to the LSI. +} Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { // Clear the last template instantiation error context. @@ -9416,31 +9439,18 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { FD = cast<FunctionDecl>(D); // If we are instantiating a generic lambda call operator, push // a LambdaScopeInfo onto the function stack. But use the information - // that's already been calculated (ActOnLambdaExpr) when analyzing the - // template version, to prime the current LambdaScopeInfo. + // that's already been calculated (ActOnLambdaExpr) to prime the current + // LambdaScopeInfo. + // When the template operator is being specialized, the LambdaScopeInfo, + // has to be properly restored so that tryCaptureVariable doesn't try + // and capture any new variables. In addition when calculating potential + // captures during transformation of nested lambdas, it is necessary to + // have the LSI properly restored. if (isGenericLambdaCallOperatorSpecialization(FD)) { - CXXMethodDecl *CallOperator = cast<CXXMethodDecl>(D); - CXXRecordDecl *LambdaClass = CallOperator->getParent(); - LambdaExpr *LE = LambdaClass->getLambdaExpr(); - assert(LE && - "No LambdaExpr of closure class when instantiating a generic lambda!"); assert(ActiveTemplateInstantiations.size() && "There should be an active template instantiation on the stack " "when instantiating a generic lambda!"); - PushLambdaScope(); - LambdaScopeInfo *LSI = getCurLambda(); - LSI->CallOperator = CallOperator; - LSI->Lambda = LambdaClass; - LSI->ReturnType = CallOperator->getResultType(); - - if (LE->getCaptureDefault() == LCD_None) - LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_None; - else if (LE->getCaptureDefault() == LCD_ByCopy) - LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_LambdaByval; - else if (LE->getCaptureDefault() == LCD_ByRef) - LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_LambdaByref; - - LSI->IntroducerRange = LE->getIntroducerRange(); + RebuildLambdaScopeInfo(cast<CXXMethodDecl>(D), *this); } else // Enter a new function scope @@ -9804,7 +9814,6 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, PopDeclContext(); PopFunctionScopeInfo(ActivePolicy, dcl); - // If any errors have occurred, clear out any temporaries that may have // been leftover. This ensures that these temporaries won't be picked up for // deletion in some later function. diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 32a385caaa5..9b3afc99902 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -24,17 +24,43 @@ using namespace clang; using namespace sema; + +static inline TemplateParameterList * +getGenericLambdaTemplateParameterList(LambdaScopeInfo *LSI, Sema &SemaRef) { + if (LSI->GLTemplateParameterList) + return LSI->GLTemplateParameterList; + + if (LSI->AutoTemplateParams.size()) { + SourceRange IntroRange = LSI->IntroducerRange; + SourceLocation LAngleLoc = IntroRange.getBegin(); + SourceLocation RAngleLoc = IntroRange.getEnd(); + LSI->GLTemplateParameterList = TemplateParameterList::Create( + SemaRef.Context, + /*Template kw loc*/SourceLocation(), + LAngleLoc, + (NamedDecl**)LSI->AutoTemplateParams.data(), + LSI->AutoTemplateParams.size(), RAngleLoc); + } + return LSI->GLTemplateParameterList; +} + + + CXXRecordDecl *Sema::createLambdaClosureType(SourceRange IntroducerRange, TypeSourceInfo *Info, - bool KnownDependent) { + bool KnownDependent, + LambdaCaptureDefault CaptureDefault) { DeclContext *DC = CurContext; while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext())) DC = DC->getParent(); - + bool IsGenericLambda = getGenericLambdaTemplateParameterList(getCurLambda(), + *this); // Start constructing the lambda class. CXXRecordDecl *Class = CXXRecordDecl::CreateLambda(Context, DC, Info, IntroducerRange.getBegin(), - KnownDependent); + KnownDependent, + IsGenericLambda, + CaptureDefault); DC->addDecl(Class); return Class; @@ -131,25 +157,6 @@ Sema::ExpressionEvaluationContextRecord::getMangleNumberingContext( return *MangleNumbering; } -static inline TemplateParameterList * -getGenericLambdaTemplateParameterList(LambdaScopeInfo *LSI, Sema &SemaRef) { - if (LSI->GLTemplateParameterList) - return LSI->GLTemplateParameterList; - else if (LSI->AutoTemplateParams.size()) { - SourceRange IntroRange = LSI->IntroducerRange; - SourceLocation LAngleLoc = IntroRange.getBegin(); - SourceLocation RAngleLoc = IntroRange.getEnd(); - LSI->GLTemplateParameterList = - TemplateParameterList::Create(SemaRef.Context, - /* Template kw loc */ SourceLocation(), - LAngleLoc, - (NamedDecl**)LSI->AutoTemplateParams.data(), - LSI->AutoTemplateParams.size(), RAngleLoc); - } - return LSI->GLTemplateParameterList; -} - - CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class, SourceRange IntroducerRange, TypeSourceInfo *MethodTypeInfo, @@ -243,7 +250,8 @@ void Sema::buildLambdaScope(LambdaScopeInfo *LSI, bool ExplicitResultType, bool Mutable) { LSI->CallOperator = CallOperator; - LSI->Lambda = CallOperator->getParent(); + CXXRecordDecl *LambdaClass = CallOperator->getParent(); + LSI->Lambda = LambdaClass; if (CaptureDefault == LCD_ByCopy) LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval; else if (CaptureDefault == LCD_ByRef) @@ -628,7 +636,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, } CXXRecordDecl *Class = createLambdaClosureType(Intro.Range, MethodTyInfo, - KnownDependent); + KnownDependent, Intro.Default); CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range, MethodTyInfo, EndLoc, Params); @@ -1155,7 +1163,6 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, CaptureInits, ArrayIndexVars, ArrayIndexStarts, Body->getLocEnd(), ContainsUnexpandedParameterPack); - Class->setLambdaExpr(Lambda); // C++11 [expr.prim.lambda]p2: // A lambda-expression shall not appear in an unevaluated operand // (Clause 5). diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 3ac13bb08a6..2d22e4ca647 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -8352,7 +8352,9 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { CXXRecordDecl *Class = getSema().createLambdaClosureType(E->getIntroducerRange(), NewCallOpTSI, - /*KnownDependent=*/false); + /*KnownDependent=*/false, + E->getCaptureDefault()); + getDerived().transformedLocalDecl(E->getLambdaClass(), Class); // Build the call operator. |

