[cfe-commits] r150396 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/AST/ExprCXX.h include/clang/Sema/ScopeInfo.h lib/AST/DeclCXX.cpp lib/AST/ExprCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaLambda.cpp
Douglas Gregor
dgregor at apple.com
Mon Feb 13 08:35:30 PST 2012
Author: dgregor
Date: Mon Feb 13 10:35:30 2012
New Revision: 150396
URL: http://llvm.org/viewvc/llvm-project?rev=150396&view=rev
Log:
Keep track of the set of array index variables we use when we
synthesize a by-copy captured array in a lambda. This information will
be needed by IR generation.
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/include/clang/Sema/ScopeInfo.h
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/AST/ExprCXX.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaLambda.cpp
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=150396&r1=150395&r2=150396&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Feb 13 10:35:30 2012
@@ -561,7 +561,8 @@
typedef LambdaExpr::Capture Capture;
LambdaDefinitionData(CXXRecordDecl *D)
- : DefinitionData(D), NumCaptures(0), NumExplicitCaptures(0), Extra(0) {
+ : DefinitionData(D), NumCaptures(0), NumExplicitCaptures(0),
+ HasArrayIndexVars(false), Extra(0) {
IsLambda = true;
}
@@ -569,15 +570,22 @@
unsigned NumCaptures : 16;
/// \brief The number of explicit captures in this lambda.
- unsigned NumExplicitCaptures : 16;
+ 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, and the body of the lambda.
+ /// 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.
@@ -588,6 +596,18 @@
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);
+ }
};
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=150396&r1=150395&r2=150396&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Mon Feb 13 10:35:30 2012
@@ -1066,22 +1066,16 @@
/// module file just to determine the source range.
SourceLocation ClosingBrace;
- // Note: The Create method allocates storage after the LambdaExpr
- // object, which contains the captures, followed by the capture
- // initializers, and finally the body of the lambda. The capture
- // initializers and lambda body are placed next to each other so
- // that the children() function can visit all of them easily.
-
public:
/// \brief Describes the capture of either a variable or 'this'.
class Capture {
llvm::PointerIntPair<VarDecl *, 2> VarAndBits;
SourceLocation Loc;
SourceLocation EllipsisLoc;
-
+
friend class ASTStmtReader;
friend class ASTStmtWriter;
-
+
public:
/// \brief Create a new capture.
///
@@ -1155,6 +1149,8 @@
ArrayRef<Capture> Captures,
bool ExplicitParams,
ArrayRef<Expr *> CaptureInits,
+ ArrayRef<VarDecl *> ArrayIndexVars,
+ ArrayRef<unsigned> ArrayIndexStarts,
SourceLocation ClosingBrace);
public:
@@ -1166,6 +1162,8 @@
ArrayRef<Capture> Captures,
bool ExplicitParams,
ArrayRef<Expr *> CaptureInits,
+ ArrayRef<VarDecl *> ArrayIndexVars,
+ ArrayRef<unsigned> ArrayIndexStarts,
SourceLocation ClosingBrace);
/// \brief Determine the default capture kind for this lambda.
@@ -1212,6 +1210,13 @@
/// initialization argument for this lambda expression.
capture_init_iterator capture_init_end() const;
+ /// \brief Retrieve the set of index variables used in the capture
+ /// initializer of an array captured by copy.
+ ///
+ /// \param Iter The iterator that points at the capture initializer for
+ /// which we are extracting the corresponding index variables.
+ ArrayRef<VarDecl *> getCaptureInitIndexVars(capture_init_iterator Iter) const;
+
/// \brief Retrieve the source range covering the lambda introducer,
/// which contains the explicit capture list surrounded by square
/// brackets ([...]).
Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ScopeInfo.h?rev=150396&r1=150395&r2=150396&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ScopeInfo.h (original)
+++ cfe/trunk/include/clang/Sema/ScopeInfo.h Mon Feb 13 10:35:30 2012
@@ -301,6 +301,13 @@
/// \brief Whether any of the capture expressions requires cleanups.
bool ExprNeedsCleanups;
+ /// \brief Variables used to index into by-copy array captures.
+ llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
+
+ /// \brief Offsets into the ArrayIndexVars array at which each capture starts
+ /// its list of array index variables.
+ llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
+
LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
CXXMethodDecl *CallOperator)
: CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=150396&r1=150395&r2=150396&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Feb 13 10:35:30 2012
@@ -38,13 +38,23 @@
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));
+ sizeof(Stmt*) * (Captures.size() + 1) +
+ ArrayIndexSize);
// Copy captures.
Capture *ToCapture = getCaptures();
@@ -62,6 +72,15 @@
// 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();
+ }
}
Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=150396&r1=150395&r2=150396&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Mon Feb 13 10:35:30 2012
@@ -753,6 +753,8 @@
ArrayRef<Capture> Captures,
bool ExplicitParams,
ArrayRef<Expr *> CaptureInits,
+ ArrayRef<VarDecl *> ArrayElementVars,
+ ArrayRef<unsigned> ArrayElementStarts,
SourceLocation ClosingBrace)
: Expr(LambdaExprClass, T, VK_RValue, OK_Ordinary,
T->isDependentType(), T->isDependentType(), T->isDependentType(),
@@ -765,7 +767,8 @@
assert(CaptureInits.size() == Captures.size() && "Wrong number of arguments");
CXXRecordDecl *Class = getLambdaClass();
CXXRecordDecl::LambdaDefinitionData &Data = Class->getLambdaData();
- Data.allocateExtra(Captures, CaptureInits, getCallOperator()->getBody());
+ Data.allocateExtra(Captures, CaptureInits, ArrayElementVars,
+ ArrayElementStarts, getCallOperator()->getBody());
// FIXME: Propagate "has unexpanded parameter pack" bit.
}
@@ -777,6 +780,8 @@
ArrayRef<Capture> Captures,
bool ExplicitParams,
ArrayRef<Expr *> CaptureInits,
+ ArrayRef<VarDecl *> ArrayElementVars,
+ ArrayRef<unsigned> ArrayElementStarts,
SourceLocation ClosingBrace) {
// Determine the type of the expression (i.e., the type of the
// function object we're creating).
@@ -784,6 +789,7 @@
return new (Context) LambdaExpr(T, IntroducerRange, CaptureDefault,
Captures, ExplicitParams, CaptureInits,
+ ArrayElementVars, ArrayElementStarts,
ClosingBrace);
}
@@ -826,6 +832,19 @@
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?");
+
+ unsigned Index = Iter - capture_init_begin();
+ assert(Index < Data.NumCaptures && "Capture index out-of-range");
+ VarDecl **IndexVars = Data.getArrayIndexVars();
+ unsigned *IndexStarts = Data.getArrayIndexStarts();
+ return ArrayRef<VarDecl *>(IndexVars + IndexStarts[Index],
+ IndexVars + IndexStarts[Index + 1]);
+}
+
CXXRecordDecl *LambdaExpr::getLambdaClass() const {
return getType()->getAsCXXRecordDecl();
}
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=150396&r1=150395&r2=150396&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Feb 13 10:35:30 2012
@@ -9642,6 +9642,7 @@
bool InitializingArray = false;
QualType BaseType = FieldType;
QualType SizeType = S.Context.getSizeType();
+ LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
while (const ConstantArrayType *Array
= S.Context.getAsConstantArrayType(BaseType)) {
InitializingArray = true;
@@ -9660,7 +9661,8 @@
S.Context.getTrivialTypeSourceInfo(SizeType, Loc),
SC_None, SC_None);
IndexVariables.push_back(IterationVar);
-
+ LSI->ArrayIndexVars.push_back(IterationVar);
+
// Create a reference to the iteration variable.
ExprResult IterationVarRef
= S.BuildDeclRefExpr(IterationVar, SizeType, VK_LValue, Loc);
Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=150396&r1=150395&r2=150396&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Mon Feb 13 10:35:30 2012
@@ -306,6 +306,8 @@
SourceRange IntroducerRange;
bool ExplicitParams;
bool LambdaExprNeedsCleanups;
+ llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
+ llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
{
LambdaScopeInfo *LSI = getCurLambda();
CallOperator = LSI->CallOperator;
@@ -313,7 +315,9 @@
IntroducerRange = LSI->IntroducerRange;
ExplicitParams = LSI->ExplicitParams;
LambdaExprNeedsCleanups = LSI->ExprNeedsCleanups;
-
+ ArrayIndexVars.swap(LSI->ArrayIndexVars);
+ ArrayIndexStarts.swap(LSI->ArrayIndexStarts);
+
// Translate captures.
for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I) {
LambdaScopeInfo::Capture From = LSI->Captures[I];
@@ -467,6 +471,7 @@
LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,
CaptureDefault, Captures,
ExplicitParams, CaptureInits,
+ ArrayIndexVars, ArrayIndexStarts,
Body->getLocEnd());
// C++11 [expr.prim.lambda]p2:
More information about the cfe-commits
mailing list