summaryrefslogtreecommitdiff
path: root/include/clang/AST
diff options
context:
space:
mode:
authorIlya Biryukov <ibiryukov@google.com>2019-07-22 09:58:53 +0000
committerIlya Biryukov <ibiryukov@google.com>2019-07-22 09:58:53 +0000
commitaebe7c421069cfbd51fded0d29ea3c9c50a4dc91 (patch)
tree36bdb575bfa5733ac2ee28d11a5b15324a709339 /include/clang/AST
parentd3067677be31c9c8aff122a797b0eca41a14a18f (diff)
downloadclang-aebe7c421069cfbd51fded0d29ea3c9c50a4dc91.tar.gz
[AST] Treat semantic form of InitListExpr as implicit code in traversals
Summary: In particular, do not traverse the semantic form if shouldVisitImplicitCode() returns false. This simplifies the common case of traversals, avoiding the need to worry about some expressions being traversed twice. No tests break after the change, the change would allow to simplify at least one of the usages, i.e. r366070 which had to handle this in clangd. Reviewers: gribozavr Reviewed By: gribozavr Subscribers: kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D64762 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@366672 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/AST')
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h23
1 files changed, 17 insertions, 6 deletions
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 698fba2f4e..dd2c1dad71 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -2308,19 +2308,30 @@ bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(
return true;
}
-// This method is called once for each pair of syntactic and semantic
-// InitListExpr, and it traverses the subtrees defined by the two forms. This
-// may cause some of the children to be visited twice, if they appear both in
-// the syntactic and the semantic form.
+// If shouldVisitImplicitCode() returns false, this method traverses only the
+// syntactic form of InitListExpr.
+// If shouldVisitImplicitCode() return true, this method is called once for
+// each pair of syntactic and semantic InitListExpr, and it traverses the
+// subtrees defined by the two forms. This may cause some of the children to be
+// visited twice, if they appear both in the syntactic and the semantic form.
//
// There is no guarantee about which form \p S takes when this method is called.
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(
InitListExpr *S, DataRecursionQueue *Queue) {
+ if (S->isSemanticForm() && S->isSyntacticForm()) {
+ // `S` does not have alternative forms, traverse only once.
+ TRY_TO(TraverseSynOrSemInitListExpr(S, Queue));
+ return true;
+ }
TRY_TO(TraverseSynOrSemInitListExpr(
S->isSemanticForm() ? S->getSyntacticForm() : S, Queue));
- TRY_TO(TraverseSynOrSemInitListExpr(
- S->isSemanticForm() ? S : S->getSemanticForm(), Queue));
+ if (getDerived().shouldVisitImplicitCode()) {
+ // Only visit the semantic form if the clients are interested in implicit
+ // compiler-generated.
+ TRY_TO(TraverseSynOrSemInitListExpr(
+ S->isSemanticForm() ? S : S->getSemanticForm(), Queue));
+ }
return true;
}