diff options
Diffstat (limited to 'include/clang/AST/RecursiveASTVisitor.h')
-rw-r--r-- | include/clang/AST/RecursiveASTVisitor.h | 54 |
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; }) |