summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/DeclCXX.cpp8
-rw-r--r--clang/lib/AST/ExprCXX.cpp20
-rw-r--r--clang/lib/AST/Stmt.cpp2
-rw-r--r--clang/lib/AST/StmtPrinter.cpp7
-rw-r--r--clang/lib/AST/StmtProfile.cpp10
5 files changed, 36 insertions, 11 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 064649904d3..df8a52675be 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -940,12 +940,10 @@ void CXXRecordDecl::getCaptureFields(
RecordDecl::field_iterator Field = field_begin();
for (LambdaExpr::Capture *C = Lambda.Captures, *CEnd = C + Lambda.NumCaptures;
C != CEnd; ++C, ++Field) {
- if (C->capturesThis()) {
+ if (C->capturesThis())
ThisCapture = *Field;
- continue;
- }
-
- Captures[C->getCapturedVar()] = *Field;
+ else if (C->capturesVariable())
+ Captures[C->getCapturedVar()] = *Field;
}
}
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 402d7b532b2..59e780ae0a1 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -811,7 +811,7 @@ CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
LambdaExpr::Capture::Capture(SourceLocation Loc, bool Implicit,
LambdaCaptureKind Kind, VarDecl *Var,
SourceLocation EllipsisLoc)
- : VarAndBits(Var, 0), Loc(Loc), EllipsisLoc(EllipsisLoc)
+ : DeclAndBits(Var, 0), Loc(Loc), EllipsisLoc(EllipsisLoc)
{
unsigned Bits = 0;
if (Implicit)
@@ -828,15 +828,27 @@ LambdaExpr::Capture::Capture(SourceLocation Loc, bool Implicit,
case LCK_ByRef:
assert(Var && "capture must have a variable!");
break;
+
+ case LCK_Init:
+ llvm_unreachable("don't use this constructor for an init-capture");
}
- VarAndBits.setInt(Bits);
+ DeclAndBits.setInt(Bits);
}
+LambdaExpr::Capture::Capture(FieldDecl *Field)
+ : DeclAndBits(Field,
+ Field->getType()->isReferenceType() ? 0 : Capture_ByCopy),
+ Loc(Field->getLocation()), EllipsisLoc() {}
+
LambdaCaptureKind LambdaExpr::Capture::getCaptureKind() const {
- if (capturesThis())
+ Decl *D = DeclAndBits.getPointer();
+ if (!D)
return LCK_This;
- return (VarAndBits.getInt() & Capture_ByCopy)? LCK_ByCopy : LCK_ByRef;
+ if (isa<FieldDecl>(D))
+ return LCK_Init;
+
+ return (DeclAndBits.getInt() & Capture_ByCopy) ? LCK_ByCopy : LCK_ByRef;
}
LambdaExpr::LambdaExpr(QualType T,
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index 5b29c073f92..7e85880b5fc 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -1128,7 +1128,7 @@ Stmt::child_range CapturedStmt::children() {
bool CapturedStmt::capturesVariable(const VarDecl *Var) const {
for (const_capture_iterator I = capture_begin(),
E = capture_end(); I != E; ++I) {
- if (I->capturesThis())
+ if (!I->capturesVariable())
continue;
// This does not handle variable redeclarations. This should be
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 9203dc1584b..2edb078442f 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -1387,6 +1387,13 @@ void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
OS << '=';
OS << C->getCapturedVar()->getName();
break;
+
+ case LCK_Init:
+ if (C->getInitCaptureField()->getType()->isReferenceType())
+ OS << '&';
+ OS << C->getInitCaptureField()->getName();
+ PrintExpr(Node->getInitCaptureInit(C));
+ break;
}
}
OS << ']';
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 8ade242d56d..4a3448c1e5f 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -822,9 +822,17 @@ StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) {
CEnd = S->explicit_capture_end();
C != CEnd; ++C) {
ID.AddInteger(C->getCaptureKind());
- if (C->capturesVariable()) {
+ switch (C->getCaptureKind()) {
+ case LCK_This:
+ break;
+ case LCK_ByRef:
+ case LCK_ByCopy:
VisitDecl(C->getCapturedVar());
ID.AddBoolean(C->isPackExpansion());
+ break;
+ case LCK_Init:
+ VisitDecl(C->getInitCaptureField());
+ break;
}
}
// Note: If we actually needed to be able to match lambda
OpenPOWER on IntegriCloud