summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorFaisal Vali <faisalv@yahoo.com>2013-10-23 16:10:50 +0000
committerFaisal Vali <faisalv@yahoo.com>2013-10-23 16:10:50 +0000
commitc1a6dc4907f3fff257e5dca15d62dbb01d3f9111 (patch)
tree58126283d5860afb4e879b6cc02f3329b6459cfd /clang/lib/Sema/SemaDecl.cpp
parent857e3ece9bf9cf8a2f6341e9e0c1031c5ad2994d (diff)
downloadbcm5719-llvm-c1a6dc4907f3fff257e5dca15d62dbb01d3f9111.tar.gz
bcm5719-llvm-c1a6dc4907f3fff257e5dca15d62dbb01d3f9111.zip
Refactor out the circular reference to LambdaExpr in CXXRecordDecl.
A prior commit of this patch was reverted because it was within the blamelist's purview of a failing test. The failure of that test has been addressed here: http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20131021/091546.html. Therefore I am recommitting this patch (all tests pass on windows, except for the usual modules & index suspects that never pass on my box). Some background: Both Doug and Richard had asked me in Chicago to remove the circular reference in CXXRecordDecl to LambdaExpr by factoring out and storing the needed information from LambdaExpr directly into CXXRecordDecl. In addition, I have added an IsGenericLambda flag - this makes life a little easier when we implement capturing, and are Sema-analyzing the body of a lambda (and the calloperator hasn't been wired to the closure class yet). Any inner lambdas can have potential captures that could require walking up the scope chain and checking if any generic lambdas are capture-ready. This 'bit' makes some of that checking easier. No change in functionality. This patch was approved by Doug with minor modifications (comments were cleaned up, and all data members were converted from bool/enum to unsigned, as requested): http://llvm-reviews.chandlerc.com/D1856 Thanks! llvm-svn: 193246
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp53
1 files changed, 31 insertions, 22 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.
OpenPOWER on IntegriCloud