summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ExprCXX.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-02-13 17:20:40 +0000
committerDouglas Gregor <dgregor@apple.com>2012-02-13 17:20:40 +0000
commite556163a66318847ea987bd0f82aa081f7cc2ac7 (patch)
treedf2885b1a7ce58e3b91ac1b2e24b6c6f2aec3931 /clang/lib/AST/ExprCXX.cpp
parent438447a7f3ea68bb2eed82a6ed4682907f902738 (diff)
downloadbcm5719-llvm-e556163a66318847ea987bd0f82aa081f7cc2ac7.tar.gz
bcm5719-llvm-e556163a66318847ea987bd0f82aa081f7cc2ac7.zip
Split the storage of lambda information between the LambdaExpr and the
CXXRecordDecl in a way that actually makes some sense: - LambdaExpr contains all of the information for initializing the lambda object, including the capture initializers and associated array index variables. - CXXRecordDecl's LambdaDefinitionData contains the captures, which are needed to understand the captured variable references in the body of the lambda. llvm-svn: 150401
Diffstat (limited to 'clang/lib/AST/ExprCXX.cpp')
-rw-r--r--clang/lib/AST/ExprCXX.cpp93
1 files changed, 52 insertions, 41 deletions
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 1e766ada239..4962bf4b92c 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -753,13 +753,14 @@ LambdaExpr::LambdaExpr(QualType T,
ArrayRef<Capture> Captures,
bool ExplicitParams,
ArrayRef<Expr *> CaptureInits,
- ArrayRef<VarDecl *> ArrayElementVars,
- ArrayRef<unsigned> ArrayElementStarts,
+ ArrayRef<VarDecl *> ArrayIndexVars,
+ ArrayRef<unsigned> ArrayIndexStarts,
SourceLocation ClosingBrace)
: Expr(LambdaExprClass, T, VK_RValue, OK_Ordinary,
T->isDependentType(), T->isDependentType(), T->isDependentType(),
/*ContainsUnexpandedParameterPack=*/false),
IntroducerRange(IntroducerRange),
+ NumCaptures(Captures.size()),
CaptureDefault(CaptureDefault),
ExplicitParams(ExplicitParams),
ClosingBrace(ClosingBrace)
@@ -767,10 +768,40 @@ LambdaExpr::LambdaExpr(QualType T,
assert(CaptureInits.size() == Captures.size() && "Wrong number of arguments");
CXXRecordDecl *Class = getLambdaClass();
CXXRecordDecl::LambdaDefinitionData &Data = Class->getLambdaData();
- Data.allocateExtra(Captures, CaptureInits, ArrayElementVars,
- ArrayElementStarts, getCallOperator()->getBody());
// FIXME: Propagate "has unexpanded parameter pack" bit.
+
+ // Copy captures.
+ ASTContext &Context = Class->getASTContext();
+ Data.NumCaptures = NumCaptures;
+ Data.NumExplicitCaptures = 0;
+ Data.Captures = (Capture *)Context.Allocate(sizeof(Capture) * NumCaptures);
+ Capture *ToCapture = Data.Captures;
+ for (unsigned I = 0, N = Captures.size(); I != N; ++I) {
+ if (Captures[I].isExplicit())
+ ++Data.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++ = getCallOperator()->getBody();
+
+ // Copy the array index variables, if any.
+ HasArrayIndexVars = !ArrayIndexVars.empty();
+ if (HasArrayIndexVars) {
+ assert(ArrayIndexStarts.size() == NumCaptures);
+ memcpy(getArrayIndexVars(), ArrayIndexVars.data(),
+ sizeof(VarDecl *) * ArrayIndexVars.size());
+ memcpy(getArrayIndexStarts(), ArrayIndexStarts.data(),
+ sizeof(unsigned) * Captures.size());
+ getArrayIndexStarts()[Captures.size()] = ArrayIndexVars.size();
+ }
}
LambdaExpr *LambdaExpr::Create(ASTContext &Context,
@@ -780,27 +811,30 @@ LambdaExpr *LambdaExpr::Create(ASTContext &Context,
ArrayRef<Capture> Captures,
bool ExplicitParams,
ArrayRef<Expr *> CaptureInits,
- ArrayRef<VarDecl *> ArrayElementVars,
- ArrayRef<unsigned> ArrayElementStarts,
+ ArrayRef<VarDecl *> ArrayIndexVars,
+ ArrayRef<unsigned> ArrayIndexStarts,
SourceLocation ClosingBrace) {
// Determine the type of the expression (i.e., the type of the
// function object we're creating).
QualType T = Context.getTypeDeclType(Class);
- return new (Context) LambdaExpr(T, IntroducerRange, CaptureDefault,
- Captures, ExplicitParams, CaptureInits,
- ArrayElementVars, ArrayElementStarts,
- ClosingBrace);
+ unsigned Size = sizeof(LambdaExpr) + sizeof(Stmt *) * (Captures.size() + 1);
+ if (!ArrayIndexVars.empty())
+ Size += sizeof(VarDecl *) * ArrayIndexVars.size()
+ + sizeof(unsigned) * (Captures.size() + 1);
+ void *Mem = Context.Allocate(Size);
+ return new (Mem) LambdaExpr(T, IntroducerRange, CaptureDefault,
+ Captures, ExplicitParams, CaptureInits,
+ ArrayIndexVars, ArrayIndexStarts,
+ ClosingBrace);
}
LambdaExpr::capture_iterator LambdaExpr::capture_begin() const {
- return getLambdaClass()->getLambdaData().getCaptures();
+ return getLambdaClass()->getLambdaData().Captures;
}
LambdaExpr::capture_iterator LambdaExpr::capture_end() const {
- struct CXXRecordDecl::LambdaDefinitionData &Data
- = getLambdaClass()->getLambdaData();
- return Data.getCaptures() + Data.NumCaptures;
+ return capture_begin() + NumCaptures;
}
LambdaExpr::capture_iterator LambdaExpr::explicit_capture_begin() const {
@@ -810,7 +844,7 @@ LambdaExpr::capture_iterator LambdaExpr::explicit_capture_begin() const {
LambdaExpr::capture_iterator LambdaExpr::explicit_capture_end() const {
struct CXXRecordDecl::LambdaDefinitionData &Data
= getLambdaClass()->getLambdaData();
- return Data.getCaptures() + Data.NumExplicitCaptures;
+ return Data.Captures + Data.NumExplicitCaptures;
}
LambdaExpr::capture_iterator LambdaExpr::implicit_capture_begin() const {
@@ -821,26 +855,15 @@ LambdaExpr::capture_iterator LambdaExpr::implicit_capture_end() const {
return capture_end();
}
-LambdaExpr::capture_init_iterator LambdaExpr::capture_init_begin() const {
- return reinterpret_cast<Expr **>(
- getLambdaClass()->getLambdaData().getStoredStmts());
-}
-
-LambdaExpr::capture_init_iterator LambdaExpr::capture_init_end() const {
- struct CXXRecordDecl::LambdaDefinitionData &Data
- = getLambdaClass()->getLambdaData();
- return reinterpret_cast<Expr **>(Data.getStoredStmts() + Data.NumCaptures);
-}
-
ArrayRef<VarDecl *>
LambdaExpr::getCaptureInitIndexVars(capture_init_iterator Iter) const {
CXXRecordDecl::LambdaDefinitionData &Data = getLambdaClass()->getLambdaData();
- assert(Data.HasArrayIndexVars && "No array index-var data?");
+ assert(HasArrayIndexVars && "No array index-var data?");
unsigned Index = Iter - capture_init_begin();
assert(Index < Data.NumCaptures && "Capture index out-of-range");
- VarDecl **IndexVars = Data.getArrayIndexVars();
- unsigned *IndexStarts = Data.getArrayIndexStarts();
+ VarDecl **IndexVars = getArrayIndexVars();
+ unsigned *IndexStarts = getArrayIndexStarts();
return ArrayRef<VarDecl *>(IndexVars + IndexStarts[Index],
IndexVars + IndexStarts[Index + 1]);
}
@@ -860,22 +883,10 @@ CXXMethodDecl *LambdaExpr::getCallOperator() const {
return Result;
}
-/// \brief Retrieve the body of the lambda.
-CompoundStmt *LambdaExpr::getBody() const {
- return cast<CompoundStmt>(*capture_init_end());
-}
-
bool LambdaExpr::isMutable() const {
return (getCallOperator()->getTypeQualifiers() & Qualifiers::Const) == 0;
}
-Stmt::child_range LambdaExpr::children() {
- struct CXXRecordDecl::LambdaDefinitionData &Data
- = getLambdaClass()->getLambdaData();
- return child_range(Data.getStoredStmts(),
- Data.getStoredStmts() + Data.NumCaptures + 1);
-}
-
ExprWithCleanups::ExprWithCleanups(Expr *subexpr,
ArrayRef<CleanupObject> objects)
: Expr(ExprWithCleanupsClass, subexpr->getType(),
OpenPOWER on IntegriCloud