summaryrefslogtreecommitdiffstats
path: root/include/clang/AST/RecursiveASTVisitor.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/RecursiveASTVisitor.h')
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h54
1 files changed, 22 insertions, 32 deletions
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index eb582c7a7a..44aba63557 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -298,14 +298,6 @@ public:
bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
Expr *Init);
- /// Recursively visit the body of a lambda expression.
- ///
- /// This provides a hook for visitors that need more context when visiting
- /// \c LE->getBody().
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseLambdaBody(LambdaExpr *LE, DataRecursionQueue *Queue = nullptr);
-
/// Recursively visit the syntactic or semantic form of an
/// initialization list.
///
@@ -936,13 +928,6 @@ RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
return true;
}
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(
- LambdaExpr *LE, DataRecursionQueue *Queue) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(LE->getBody());
- return true;
-}
-
// ----------------- Type traversal -----------------
// This macro makes available a variable T, the passed-in type.
@@ -1383,9 +1368,14 @@ DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
template <typename Derived>
bool RecursiveASTVisitor<Derived>::canIgnoreChildDeclWhileTraversingDeclContext(
const Decl *Child) {
- // BlockDecls and CapturedDecls are traversed through BlockExprs and
- // CapturedStmts respectively.
- return isa<BlockDecl>(Child) || isa<CapturedDecl>(Child);
+ // BlockDecls are traversed through BlockExprs,
+ // CapturedDecls are traversed through CapturedStmts.
+ if (isa<BlockDecl>(Child) || isa<CapturedDecl>(Child))
+ return true;
+ // Lambda classes are traversed through LambdaExprs.
+ if (const CXXRecordDecl* Cls = dyn_cast<CXXRecordDecl>(Child))
+ return Cls->isLambda();
+ return false;
}
template <typename Derived>
@@ -2404,6 +2394,7 @@ DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
// Walk only the visible parts of lambda expressions.
DEF_TRAVERSE_STMT(LambdaExpr, {
+ // Visit the capture list.
for (unsigned I = 0, N = S->capture_size(); I != N; ++I) {
const LambdaCapture *C = S->capture_begin() + I;
if (C->isExplicit() || getDerived().shouldVisitImplicitCode()) {
@@ -2411,32 +2402,31 @@ DEF_TRAVERSE_STMT(LambdaExpr, {
}
}
- TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
- FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
-
- if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
- // Visit the whole type.
- TRY_TO(TraverseTypeLoc(TL));
+ if (getDerived().shouldVisitImplicitCode()) {
+ // The implicit model is simple: everything else is in the lambda class.
+ TRY_TO(TraverseDecl(S->getLambdaClass()));
} else {
+ // We need to poke around to find the bits that might be explicitly written.
+ TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+ FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
+
if (S->hasExplicitParameters()) {
// Visit parameters.
- for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+ for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
TRY_TO(TraverseDecl(Proto.getParam(I)));
- }
- } else if (S->hasExplicitResultType()) {
- TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
}
+ if (S->hasExplicitResultType())
+ TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
auto *T = Proto.getTypePtr();
- for (const auto &E : T->exceptions()) {
+ for (const auto &E : T->exceptions())
TRY_TO(TraverseType(E));
- }
if (Expr *NE = T->getNoexceptExpr())
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(NE);
- }
- ReturnValue = TRAVERSE_STMT_BASE(LambdaBody, LambdaExpr, S, Queue);
+ TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
+ }
ShouldVisitChildren = false;
})