diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-02-13 15:44:47 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-02-13 15:44:47 +0000 |
commit | da8962a6198bc4bf09a38209db99551b2b0a41a0 (patch) | |
tree | f9fb9bbc7de4c93b4deb623c4dd567dccadeaa24 /lib/AST/DeclCXX.cpp | |
parent | e88a71f00e9dce979dfb409459d54c92e5075a42 (diff) |
Move the storage of lambda captures and capture initializers from
LambdaExpr over to the CXXRecordDecl. This allows us to eliminate the
back-link from the closure type to the LambdaExpr, which will simplify
and lazify AST deserialization.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150393 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/DeclCXX.cpp')
-rw-r--r-- | lib/AST/DeclCXX.cpp | 53 |
1 files changed, 42 insertions, 11 deletions
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index f9d95b121a..257a507b23 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -35,6 +35,35 @@ AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) { return new (Mem) AccessSpecDecl(EmptyShell()); } +void CXXRecordDecl::LambdaDefinitionData::allocateExtra( + ArrayRef<LambdaExpr::Capture> Captures, + ArrayRef<Expr *> CaptureInits, + Stmt *Body) { + NumCaptures = Captures.size(); + NumExplicitCaptures = 0; + + ASTContext &Context = Definition->getASTContext(); + this->Extra = Context.Allocate(sizeof(Capture) * Captures.size() + + sizeof(Stmt*) * (Captures.size() + 1)); + + // Copy captures. + Capture *ToCapture = getCaptures(); + for (unsigned I = 0, N = Captures.size(); I != N; ++I) { + if (Captures[I].isExplicit()) + ++NumExplicitCaptures; + + *ToCapture++ = Captures[I]; + } + + // Copy initialization expressions for the non-static data members. + Stmt **Stored = getStoredStmts(); + for (unsigned I = 0, N = CaptureInits.size(); I != N; ++I) + *Stored++ = CaptureInits[I]; + + // Copy the body of the lambda. + *Stored++ = Body; +} + CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) : UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false), @@ -83,6 +112,16 @@ CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK, return R; } +CXXRecordDecl *CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC, + SourceLocation Loc) { + CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TTK_Class, DC, Loc, Loc, + 0, 0); + R->IsBeingDefined = true; + R->DefinitionData = new (C) struct LambdaDefinitionData(R); + C.getTypeDeclType(R, /*PrevDecl=*/0); + return R; +} + CXXRecordDecl * CXXRecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXRecordDecl)); @@ -969,24 +1008,16 @@ bool CXXRecordDecl::isCLike() const { return isPOD() && data().HasOnlyCMembers; } -void CXXRecordDecl::setLambda(LambdaExpr *Lambda) { - if (!Lambda) - return; - - data().IsLambda = true; - getASTContext().Lambdas[this] = Lambda; -} - void CXXRecordDecl::getCaptureFields( llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures, FieldDecl *&ThisCapture) const { Captures.clear(); ThisCapture = 0; - LambdaExpr *Lambda = getASTContext().Lambdas[this]; + LambdaDefinitionData &Lambda = getLambdaData(); RecordDecl::field_iterator Field = field_begin(); - for (LambdaExpr::capture_iterator C = Lambda->capture_begin(), - CEnd = Lambda->capture_end(); + for (LambdaExpr::Capture *C = Lambda.getCaptures(), + *CEnd = C + Lambda.NumCaptures; C != CEnd; ++C, ++Field) { if (C->capturesThis()) { ThisCapture = *Field; |