summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Dennett <jdennett@google.com>2015-05-07 18:48:18 +0000
committerJames Dennett <jdennett@google.com>2015-05-07 18:48:18 +0000
commitdd2ffea28893a3bb59c3e46baddec631bdc68462 (patch)
treef66a6fa469f57da65e4af75b9d5e1fcd86eb7b4f
parent3d415cd2cd7949340c3cf181b8bd5780a9c32d91 (diff)
downloadbcm5719-llvm-dd2ffea28893a3bb59c3e46baddec631bdc68462.tar.gz
bcm5719-llvm-dd2ffea28893a3bb59c3e46baddec631bdc68462.zip
Replace the broken LambdaCapture::isInitCapture API.
A LambdaCapture does not have sufficient information to correctly determine whether it is an init-capture or not. Doing so requires knowledge held in the LambdaExpr itself. It the case of a nested capture of an init-capture it is not sufficient to check (as LambdaCapture::isInitCapture did) whether the associated VarDecl was from an init-capture. This patch moves isInitCapture to LambdaExpr and updates Capture->isInitCapture() to Lambda->isInitCapture(Capture). llvm-svn: 236760
-rw-r--r--clang/include/clang/AST/DataRecursiveASTVisitor.h2
-rw-r--r--clang/include/clang/AST/ExprCXX.h3
-rw-r--r--clang/include/clang/AST/LambdaCapture.h5
-rw-r--r--clang/include/clang/AST/RecursiveASTVisitor.h2
-rw-r--r--clang/lib/AST/ExprCXX.cpp5
-rw-r--r--clang/lib/AST/StmtPrinter.cpp4
-rw-r--r--clang/lib/Sema/TreeTransform.h4
-rw-r--r--clang/test/SemaCXX/cxx1y-init-captures.cpp25
8 files changed, 38 insertions, 12 deletions
diff --git a/clang/include/clang/AST/DataRecursiveASTVisitor.h b/clang/include/clang/AST/DataRecursiveASTVisitor.h
index d3dde6803fb..9b5b0233bb2 100644
--- a/clang/include/clang/AST/DataRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DataRecursiveASTVisitor.h
@@ -791,7 +791,7 @@ template <typename Derived>
bool
RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
const LambdaCapture *C) {
- if (C->isInitCapture())
+ if (LE->isInitCapture(C))
TRY_TO(TraverseDecl(C->getCapturedVar()));
return true;
}
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index d1a6063b6b9..1dbf5743c12 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -1452,6 +1452,9 @@ public:
return CaptureDefaultLoc;
}
+ /// \brief Determine whether one of this lambda's captures is an init-capture.
+ bool isInitCapture(const LambdaCapture *Capture) const;
+
/// \brief An iterator that walks over the captures of the lambda,
/// both implicit and explicit.
typedef const Capture *capture_iterator;
diff --git a/clang/include/clang/AST/LambdaCapture.h b/clang/include/clang/AST/LambdaCapture.h
index a7468a0fd53..ddefa88a6b6 100644
--- a/clang/include/clang/AST/LambdaCapture.h
+++ b/clang/include/clang/AST/LambdaCapture.h
@@ -85,11 +85,6 @@ public:
(DeclAndBits.getInt() & Capture_ByCopy);
}
- /// \brief Determine whether this is an init-capture.
- bool isInitCapture() const {
- return capturesVariable() && getCapturedVar()->isInitCapture();
- }
-
/// \brief Retrieve the declaration of the local variable being
/// captured.
///
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 235023d374e..129c2b5fe04 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -857,7 +857,7 @@ template <typename Derived>
bool
RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
const LambdaCapture *C) {
- if (C->isInitCapture())
+ if (LE->isInitCapture(C))
TRY_TO(TraverseDecl(C->getCapturedVar()));
return true;
}
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index f23b3eb79ce..d6f2ce63a0a 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1027,6 +1027,11 @@ LambdaExpr *LambdaExpr::CreateDeserialized(const ASTContext &C,
return new (Mem) LambdaExpr(EmptyShell(), NumCaptures, NumArrayIndexVars > 0);
}
+bool LambdaExpr::isInitCapture(const LambdaCapture *C) const {
+ return (C->capturesVariable() && C->getCapturedVar()->isInitCapture() &&
+ (getCallOperator() == C->getCapturedVar()->getDeclContext()));
+}
+
LambdaExpr::capture_iterator LambdaExpr::capture_begin() const {
return getLambdaClass()->getLambdaData().Captures;
}
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index b68f3a3a26e..dc4f9964c7a 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -1758,7 +1758,7 @@ void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
break;
case LCK_ByRef:
- if (Node->getCaptureDefault() != LCD_ByRef || C->isInitCapture())
+ if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
OS << '&';
OS << C->getCapturedVar()->getName();
break;
@@ -1770,7 +1770,7 @@ void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
llvm_unreachable("VLA type in explicit captures.");
}
- if (C->isInitCapture())
+ if (Node->isInitCapture(C))
PrintExpr(C->getCapturedVar()->getInit());
}
OS << ']';
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 704cef36d44..f5249fdeb01 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -9133,7 +9133,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
for (LambdaExpr::capture_iterator C = E->capture_begin(),
CEnd = E->capture_end();
C != CEnd; ++C) {
- if (!C->isInitCapture())
+ if (!E->isInitCapture(C))
continue;
EnterExpressionEvaluationContext EEEC(getSema(),
Sema::PotentiallyEvaluated);
@@ -9245,7 +9245,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
continue;
// Rebuild init-captures, including the implied field declaration.
- if (C->isInitCapture()) {
+ if (E->isInitCapture(C)) {
InitCaptureInfoTy InitExprTypePair =
InitCaptureExprsAndTypes[C - E->capture_begin()];
ExprResult Init = InitExprTypePair.first;
diff --git a/clang/test/SemaCXX/cxx1y-init-captures.cpp b/clang/test/SemaCXX/cxx1y-init-captures.cpp
index 64fe50a70e7..203e28d7c3f 100644
--- a/clang/test/SemaCXX/cxx1y-init-captures.cpp
+++ b/clang/test/SemaCXX/cxx1y-init-captures.cpp
@@ -166,4 +166,27 @@ int test(T t = T{}) {
int run = test(); //expected-note {{instantiation}}
-} \ No newline at end of file
+}
+
+namespace classification_of_captures_of_init_captures {
+
+template <typename T>
+void f() {
+ [a = 24] () mutable {
+ [&a] { a = 3; }();
+ }();
+}
+
+template <typename T>
+void h() {
+ [a = 24] (auto param) mutable {
+ [&a] { a = 3; }();
+ }(42);
+}
+
+int run() {
+ f<int>();
+ h<int>();
+}
+
+}
OpenPOWER on IntegriCloud