summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp53
-rw-r--r--clang/lib/Sema/SemaLambda.cpp57
-rw-r--r--clang/lib/Sema/TreeTransform.h4
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.
OpenPOWER on IntegriCloud