diff options
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 8 | ||||
-rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 20 | ||||
-rw-r--r-- | clang/lib/AST/Stmt.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 7 | ||||
-rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 10 |
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 |