...and replace the diffs that I lost because I don't know how to use `arc`.
http://llvm-reviews.chandlerc.com/D1192
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D1192?vs=2930&id=2931#toc
Files:
include/clang/Sema/ScopeInfo.h
include/clang/Sema/Sema.h
include/clang/AST/ExprCXX.h
lib/Sema/SemaLambda.cpp
lib/Sema/TreeTransform.h
lib/AST/ExprCXX.cpp
lib/Serialization/ASTReaderStmt.cpp
lib/Serialization/ASTWriterStmt.cpp
unittests/Tooling/RecursiveASTVisitorTest.cpp
Index: include/clang/Sema/ScopeInfo.h
===================================================================
--- include/clang/Sema/ScopeInfo.h
+++ include/clang/Sema/ScopeInfo.h
@@ -581,19 +581,23 @@
/// \brief The class that describes the lambda.
CXXRecordDecl *Lambda;
- /// \brief The class that describes the lambda.
+ /// \brief The lambda's compiler-generated \c operator().
CXXMethodDecl *CallOperator;
/// \brief Source range covering the lambda introducer [...].
SourceRange IntroducerRange;
- /// \brief The number of captures in the \c Captures list that are
+ /// \brief Source location of the '&' or '=' specifying the default capture
+ /// type, if any.
+ SourceLocation CaptureDefaultLoc;
+
+ /// \brief The number of captures in the \c Captures list that are
/// explicit captures.
unsigned NumExplicitCaptures;
/// \brief Whether this is a mutable lambda.
bool Mutable;
-
+
/// \brief Whether the (empty) parameter list is explicit.
bool ExplicitParams;
@@ -609,7 +613,7 @@
/// \brief Offsets into the ArrayIndexVars array at which each capture starts
/// its list of array index variables.
SmallVector<unsigned, 4> ArrayIndexStarts;
-
+
LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
CXXMethodDecl *CallOperator)
: CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
@@ -621,13 +625,13 @@
virtual ~LambdaScopeInfo();
- /// \brief Note when
+ /// \brief Note when all explicit captures have been added.
void finishedExplicitCaptures() {
NumExplicitCaptures = Captures.size();
}
static bool classof(const FunctionScopeInfo *FSI) {
- return FSI->Kind == SK_Lambda;
+ return FSI->Kind == SK_Lambda;
}
};
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -4380,6 +4380,7 @@
sema::LambdaScopeInfo *enterLambdaScope(CXXMethodDecl *CallOperator,
SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
+ SourceLocation CaptureDefaultLoc,
bool ExplicitParams,
bool ExplicitResultType,
bool Mutable);
Index: include/clang/AST/ExprCXX.h
===================================================================
--- include/clang/AST/ExprCXX.h
+++ include/clang/AST/ExprCXX.h
@@ -1323,6 +1323,9 @@
/// \brief The source range that covers the lambda introducer ([...]).
SourceRange IntroducerRange;
+ /// \brief The source location of this lambda's capture-default ('=' or '&').
+ SourceLocation CaptureDefaultLoc;
+
/// \brief The number of captures.
unsigned NumCaptures : 16;
@@ -1456,6 +1459,7 @@
/// \brief Construct a lambda expression.
LambdaExpr(QualType T, SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
+ SourceLocation CaptureDefaultLoc,
ArrayRef<Capture> Captures,
bool ExplicitParams,
bool ExplicitResultType,
@@ -1494,10 +1498,11 @@
public:
/// \brief Construct a new lambda expression.
- static LambdaExpr *Create(ASTContext &C,
+ static LambdaExpr *Create(ASTContext &C,
CXXRecordDecl *Class,
SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
+ SourceLocation CaptureDefaultLoc,
ArrayRef<Capture> Captures,
bool ExplicitParams,
bool ExplicitResultType,
@@ -1511,12 +1516,17 @@
/// an external source.
static LambdaExpr *CreateDeserialized(ASTContext &C, unsigned NumCaptures,
unsigned NumArrayIndexVars);
-
+
/// \brief Determine the default capture kind for this lambda.
LambdaCaptureDefault getCaptureDefault() const {
return static_cast<LambdaCaptureDefault>(CaptureDefault);
}
+ /// \brief Retrieve the location of this lambda's capture-default, if any.
+ SourceLocation getCaptureDefaultLoc() const {
+ return CaptureDefaultLoc;
+ }
+
/// \brief An iterator that walks over the captures of the lambda,
/// both implicit and explicit.
typedef const Capture *capture_iterator;
Index: lib/Sema/SemaLambda.cpp
===================================================================
--- lib/Sema/SemaLambda.cpp
+++ lib/Sema/SemaLambda.cpp
@@ -180,6 +180,7 @@
LambdaScopeInfo *Sema::enterLambdaScope(CXXMethodDecl *CallOperator,
SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
+ SourceLocation CaptureDefaultLoc,
bool ExplicitParams,
bool ExplicitResultType,
bool Mutable) {
@@ -189,6 +190,7 @@
LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval;
else if (CaptureDefault == LCD_ByRef)
LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByref;
+ LSI->CaptureDefaultLoc = CaptureDefaultLoc;
LSI->IntroducerRange = IntroducerRange;
LSI->ExplicitParams = ExplicitParams;
LSI->Mutable = Mutable;
@@ -598,7 +600,10 @@
// Introduce the lambda scope.
LambdaScopeInfo *LSI
- = enterLambdaScope(Method, Intro.Range, Intro.Default, ExplicitParams,
+ = enterLambdaScope(Method,
+ Intro.Range,
+ Intro.Default, Intro.DefaultLoc,
+ ExplicitParams,
ExplicitResultType,
!Method->isConst());
@@ -919,6 +924,7 @@
SmallVector<LambdaExpr::Capture, 4> Captures;
SmallVector<Expr *, 4> CaptureInits;
LambdaCaptureDefault CaptureDefault;
+ SourceLocation CaptureDefaultLoc;
CXXRecordDecl *Class;
CXXMethodDecl *CallOperator;
SourceRange IntroducerRange;
@@ -988,6 +994,7 @@
llvm_unreachable("block capture in lambda");
break;
}
+ CaptureDefaultLoc = LSI->CaptureDefaultLoc;
// C++11 [expr.prim.lambda]p4:
// If a lambda-expression does not include a
@@ -1052,7 +1059,8 @@
ExprNeedsCleanups = true;
LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,
- CaptureDefault, Captures,
+ CaptureDefault, CaptureDefaultLoc,
+ Captures,
ExplicitParams, ExplicitResultType,
CaptureInits, ArrayIndexVars,
ArrayIndexStarts, Body->getLocEnd(),
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -8254,6 +8254,7 @@
sema::LambdaScopeInfo *LSI
= getSema().enterLambdaScope(CallOperator, E->getIntroducerRange(),
E->getCaptureDefault(),
+ E->getCaptureDefaultLoc(),
E->hasExplicitParameters(),
E->hasExplicitResultType(),
E->isMutable());
Index: lib/AST/ExprCXX.cpp
===================================================================
--- lib/AST/ExprCXX.cpp
+++ lib/AST/ExprCXX.cpp
@@ -854,10 +854,11 @@
return (DeclAndBits.getInt() & Capture_ByCopy) ? LCK_ByCopy : LCK_ByRef;
}
-LambdaExpr::LambdaExpr(QualType T,
+LambdaExpr::LambdaExpr(QualType T,
SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
- ArrayRef<Capture> Captures,
+ SourceLocation CaptureDefaultLoc,
+ ArrayRef<Capture> Captures,
bool ExplicitParams,
bool ExplicitResultType,
ArrayRef<Expr *> CaptureInits,
@@ -869,6 +870,7 @@
T->isDependentType(), T->isDependentType(), T->isDependentType(),
ContainsUnexpandedParameterPack),
IntroducerRange(IntroducerRange),
+ CaptureDefaultLoc(CaptureDefaultLoc),
NumCaptures(Captures.size()),
CaptureDefault(CaptureDefault),
ExplicitParams(ExplicitParams),
@@ -914,11 +916,12 @@
}
}
-LambdaExpr *LambdaExpr::Create(ASTContext &Context,
+LambdaExpr *LambdaExpr::Create(ASTContext &Context,
CXXRecordDecl *Class,
SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
- ArrayRef<Capture> Captures,
+ SourceLocation CaptureDefaultLoc,
+ ArrayRef<Capture> Captures,
bool ExplicitParams,
bool ExplicitResultType,
ArrayRef<Expr *> CaptureInits,
@@ -938,8 +941,9 @@
Size += sizeof(VarDecl *) * ArrayIndexVars.size();
}
void *Mem = Context.Allocate(Size);
- return new (Mem) LambdaExpr(T, IntroducerRange, CaptureDefault,
- Captures, ExplicitParams, ExplicitResultType,
+ return new (Mem) LambdaExpr(T, IntroducerRange,
+ CaptureDefault, CaptureDefaultLoc, Captures,
+ ExplicitParams, ExplicitResultType,
CaptureInits, ArrayIndexVars, ArrayIndexStarts,
ClosingBrace, ContainsUnexpandedParameterPack);
}
Index: lib/Serialization/ASTReaderStmt.cpp
===================================================================
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -1207,6 +1207,7 @@
unsigned NumArrayIndexVars = Record[Idx++];
E->IntroducerRange = ReadSourceRange(Record, Idx);
E->CaptureDefault = static_cast<LambdaCaptureDefault>(Record[Idx++]);
+ E->CaptureDefaultLoc = ReadSourceLocation(Record, Idx);
E->ExplicitParams = Record[Idx++];
E->ExplicitResultType = Record[Idx++];
E->ClosingBrace = ReadSourceLocation(Record, Idx);
Index: lib/Serialization/ASTWriterStmt.cpp
===================================================================
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -6,9 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file implements serialization for Statements and Expressions.
-//
+///
+/// \file
+/// \brief Implements serialization for Statements and Expressions.
+///
//===----------------------------------------------------------------------===//
#include "clang/Serialization/ASTWriter.h"
@@ -1166,6 +1167,7 @@
Record.push_back(NumArrayIndexVars);
Writer.AddSourceRange(E->IntroducerRange, Record);
Record.push_back(E->CaptureDefault); // FIXME: stable encoding
+ Writer.AddSourceLocation(E->CaptureDefaultLoc, Record);
Record.push_back(E->ExplicitParams);
Record.push_back(E->ExplicitResultType);
Writer.AddSourceLocation(E->ClosingBrace, Record);
Index: unittests/Tooling/RecursiveASTVisitorTest.cpp
===================================================================
--- unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -102,7 +102,19 @@
return PendingBodies.empty();
}
private:
- std::stack<LambdaExpr *> PendingBodies;
+ std::stack<LambdaExpr *> PendingBodies;
+};
+
+// Matches the (optional) capture-default of a lambda-introducer.
+class LambdaDefaultCaptureVisitor
+ : public ExpectedLocationVisitor<LambdaDefaultCaptureVisitor> {
+public:
+ bool VisitLambdaExpr(LambdaExpr *Lambda) {
+ if (Lambda->getCaptureDefault() != LCD_None) {
+ Match("", Lambda->getCaptureDefaultLoc());
+ }
+ return true;
+ }
};
class TemplateArgumentLocTraverser
@@ -503,4 +515,11 @@
EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed());
}
+TEST(RecursiveASTVisitor, HasCaptureDefaultLoc) {
+ LambdaDefaultCaptureVisitor Visitor;
+ Visitor.ExpectMatch("", 1, 20);
+ EXPECT_TRUE(Visitor.runOver("void f() { int a; [=]{a;}; }",
+ LambdaDefaultCaptureVisitor::Lang_CXX11));
+}
+
} // end namespace clang
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits