[cfe-commits] r150401 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/AST/ExprCXX.h lib/AST/DeclCXX.cpp lib/AST/ExprCXX.cpp
Douglas Gregor
dgregor at apple.com
Mon Feb 13 09:20:40 PST 2012
Author: dgregor
Date: Mon Feb 13 11:20:40 2012
New Revision: 150401
URL: http://llvm.org/viewvc/llvm-project?rev=150401&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/AST/ExprCXX.cpp
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=150401&r1=150400&r2=150401&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Feb 13 11:20:40 2012
@@ -561,8 +561,7 @@
typedef LambdaExpr::Capture Capture;
LambdaDefinitionData(CXXRecordDecl *D)
- : DefinitionData(D), NumCaptures(0), NumExplicitCaptures(0),
- HasArrayIndexVars(false), Extra(0) {
+ : DefinitionData(D), NumCaptures(0), NumExplicitCaptures(0), Captures(0) {
IsLambda = true;
}
@@ -572,42 +571,10 @@
/// \brief The number of explicit captures in this lambda.
unsigned NumExplicitCaptures : 15;
- /// \brief Whether This lambda has any by-copy array captures, and therefore
- /// has array index variables.
- unsigned HasArrayIndexVars : 1;
-
/// \brief The "extra" data associated with the lambda, including
/// captures, capture initializers, the body of the lambda, and the
/// array-index variables for array captures.
- void *Extra;
-
- /// \brief Allocate the "extra" data associated with a lambda definition.
- void allocateExtra(ArrayRef<Capture> Captures,
- ArrayRef<Expr *> CaptureInits,
- ArrayRef<VarDecl *> ArrayIndexVars,
- ArrayRef<unsigned> ArrayIndexStarts,
- Stmt *Body);
-
- /// \brief Retrieve the set of captures.
- Capture *getCaptures() const { return reinterpret_cast<Capture *>(Extra); }
-
- /// \brief Retrieve the set of stored statements, which contains the capture
- /// initializers followed by the body of the lambda.
- Stmt **getStoredStmts() const {
- return reinterpret_cast<Stmt **>(getCaptures() + NumCaptures);
- }
-
- /// \brief Retrieve the mapping from captures to the first array index
- /// variable.
- unsigned *getArrayIndexStarts() const {
- return reinterpret_cast<unsigned *>(getStoredStmts() + NumCaptures + 1);
- }
-
- /// \brief Retrieve the complete set of array-index variables.
- VarDecl **getArrayIndexVars() const {
- return reinterpret_cast<VarDecl **>(
- getArrayIndexStarts() + NumCaptures + 1);
- }
+ Capture *Captures;
};
struct DefinitionData &data() {
Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=150401&r1=150400&r2=150401&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Mon Feb 13 11:20:40 2012
@@ -1048,6 +1048,9 @@
/// \brief The source range that covers the lambda introducer ([...]).
SourceRange IntroducerRange;
+ /// \brief The number of captures.
+ unsigned NumCaptures : 16;
+
/// \brief The default capture kind, which is a value of type
/// LambdaCaptureDefault.
unsigned CaptureDefault : 2;
@@ -1056,6 +1059,8 @@
/// implicit (and empty) parameter list.
unsigned ExplicitParams : 1;
+ unsigned HasArrayIndexVars : 1;
+
/// \brief The location of the closing brace ('}') that completes
/// the lambda.
///
@@ -1066,6 +1071,10 @@
/// module file just to determine the source range.
SourceLocation ClosingBrace;
+ // Note: The capture initializers are stored directly after the lambda
+ // expression, along with the index variables used to initialize by-copy
+ // array captures.
+
public:
/// \brief Describes the capture of either a variable or 'this'.
class Capture {
@@ -1153,6 +1162,22 @@
ArrayRef<unsigned> ArrayIndexStarts,
SourceLocation ClosingBrace);
+ Stmt **getStoredStmts() const {
+ return reinterpret_cast<Stmt **>(const_cast<LambdaExpr *>(this) + 1);
+ }
+
+ /// \brief Retrieve the mapping from captures to the first array index
+ /// variable.
+ unsigned *getArrayIndexStarts() const {
+ return reinterpret_cast<unsigned *>(getStoredStmts() + NumCaptures + 1);
+ }
+
+ /// \brief Retrieve the complete set of array-index variables.
+ VarDecl **getArrayIndexVars() const {
+ return reinterpret_cast<VarDecl **>(
+ getArrayIndexStarts() + NumCaptures + 1);
+ }
+
public:
/// \brief Construct a new lambda expression.
static LambdaExpr *Create(ASTContext &C,
@@ -1182,6 +1207,9 @@
/// sequence of lambda captures.
capture_iterator capture_end() const;
+ /// \brief Determine the number of captures in this lambda.
+ unsigned capture_size() const { return NumCaptures; }
+
/// \brief Retrieve an iterator pointing to the first explicit
/// lambda capture.
capture_iterator explicit_capture_begin() const;
@@ -1204,11 +1232,15 @@
/// \brief Retrieve the first initialization argument for this
/// lambda expression (which initializes the first capture field).
- capture_init_iterator capture_init_begin() const;
+ capture_init_iterator capture_init_begin() const {
+ return reinterpret_cast<Expr **>(getStoredStmts());
+ }
/// \brief Retrieve the iterator pointing one past the last
/// initialization argument for this lambda expression.
- capture_init_iterator capture_init_end() const;
+ capture_init_iterator capture_init_end() const {
+ return capture_init_begin() + NumCaptures;
+ }
/// \brief Retrieve the set of index variables used in the capture
/// initializer of an array captured by copy.
@@ -1232,7 +1264,9 @@
CXXMethodDecl *getCallOperator() const;
/// \brief Retrieve the body of the lambda.
- CompoundStmt *getBody() const;
+ CompoundStmt *getBody() const {
+ return reinterpret_cast<CompoundStmt *>(getStoredStmts()[NumCaptures]);
+ }
/// \brief Determine whether the lambda is mutable, meaning that any
/// captures values can be modified.
@@ -1251,7 +1285,9 @@
return SourceRange(IntroducerRange.getBegin(), ClosingBrace);
}
- child_range children();
+ child_range children() {
+ return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1);
+ }
friend class ASTStmtReader;
friend class ASTStmtWriter;
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=150401&r1=150400&r2=150401&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Feb 13 11:20:40 2012
@@ -35,55 +35,6 @@
return new (Mem) AccessSpecDecl(EmptyShell());
}
-void CXXRecordDecl::LambdaDefinitionData::allocateExtra(
- ArrayRef<LambdaExpr::Capture> Captures,
- ArrayRef<Expr *> CaptureInits,
- ArrayRef<VarDecl *> ArrayIndexVars,
- ArrayRef<unsigned> ArrayIndexStarts,
- Stmt *Body) {
- NumCaptures = Captures.size();
- NumExplicitCaptures = 0;
-
- ASTContext &Context = Definition->getASTContext();
- unsigned ArrayIndexSize = 0;
- if (ArrayIndexVars.size() > 0) {
- HasArrayIndexVars = true;
- ArrayIndexSize = sizeof(unsigned) * (Captures.size() + 1)
- + sizeof(VarDecl *) * ArrayIndexVars.size();
- }
-
- this->Extra = Context.Allocate(sizeof(Capture) * Captures.size() +
- sizeof(Stmt*) * (Captures.size() + 1) +
- ArrayIndexSize);
-
- // 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;
-
- if (ArrayIndexVars.size() > 0) {
- assert(ArrayIndexStarts.size() == Captures.size());
- memcpy(getArrayIndexVars(), ArrayIndexVars.data(),
- sizeof(VarDecl *) * ArrayIndexVars.size());
- memcpy(getArrayIndexStarts(), ArrayIndexStarts.data(),
- sizeof(unsigned) * Captures.size());
- getArrayIndexStarts()[Captures.size()] = ArrayIndexVars.size();
- }
-}
-
-
CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
: UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false),
UserDeclaredMoveConstructor(false), UserDeclaredCopyAssignment(false),
@@ -1035,8 +986,7 @@
LambdaDefinitionData &Lambda = getLambdaData();
RecordDecl::field_iterator Field = field_begin();
- for (LambdaExpr::Capture *C = Lambda.getCaptures(),
- *CEnd = C + Lambda.NumCaptures;
+ for (LambdaExpr::Capture *C = Lambda.Captures, *CEnd = C + Lambda.NumCaptures;
C != CEnd; ++C, ++Field) {
if (C->capturesThis()) {
ThisCapture = *Field;
Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=150401&r1=150400&r2=150401&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Mon Feb 13 11:20:40 2012
@@ -753,13 +753,14 @@
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 @@
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 @@
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_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 @@
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 @@
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(),
More information about the cfe-commits
mailing list