]> granicus.if.org Git - clang/commitdiff
Divide TraverseInitListExpr to a different function for each form.
authorAngel Garcia Gomez <angelgarcia@google.com>
Fri, 2 Oct 2015 13:25:51 +0000 (13:25 +0000)
committerAngel Garcia Gomez <angelgarcia@google.com>
Fri, 2 Oct 2015 13:25:51 +0000 (13:25 +0000)
Summary: create TraverseSyntacticInitListExpr and TraverseSemanticInitListExpr.

Reviewers: rsmith, klimek

Subscribers: klimek, cfe-commits, alexfh

Differential Revision: http://reviews.llvm.org/D13249

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@249129 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/RecursiveASTVisitor.h

index e632536ee14b5e1dcbea7a3e4ace8db507760a39..3066b0d1bb2ef1276acdbb26185ff18eef21e409 100644 (file)
@@ -255,6 +255,12 @@ public:
   /// \returns false if the visitation was terminated early, true otherwise.
   bool TraverseLambdaBody(LambdaExpr *LE);
 
+  /// \brief Recursively visit the syntactic or semantic form of an
+  /// initialization list.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseSynOrSemInitListExpr(InitListExpr *S);
+
   // ---- Methods on Attrs ----
 
   // \brief Visit an attribute.
@@ -2056,31 +2062,33 @@ DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
   TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
 })
 
-// InitListExpr is a tricky one, because we want to do all our work on
-// the syntactic form of the listexpr, but this method takes the
-// semantic form by default.  We can't use the macro helper because it
-// calls WalkUp*() on the semantic form, before our code can convert
-// to the syntactic form.
 template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
-  InitListExpr *Syn = S->isSemanticForm() ? S->getSyntacticForm() : S;
-  if (Syn) {
-    TRY_TO(WalkUpFromInitListExpr(Syn));
+bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(InitListExpr *S) {
+  if (S) {
+    TRY_TO(WalkUpFromInitListExpr(S));
     // All we need are the default actions.  FIXME: use a helper function.
-    for (Stmt *SubStmt : Syn->children()) {
-      TRY_TO(TraverseStmt(SubStmt));
-    }
-  }
-  InitListExpr *Sem = S->isSemanticForm() ? S : S->getSemanticForm();
-  if (Sem) {
-    TRY_TO(WalkUpFromInitListExpr(Sem));
-    for (Stmt *SubStmt : Sem->children()) {
+    for (Stmt *SubStmt : S->children()) {
       TRY_TO(TraverseStmt(SubStmt));
     }
   }
   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) {
+  TRY_TO(TraverseSynOrSemInitListExpr(
+      S->isSemanticForm() ? S->getSyntacticForm() : S));
+  TRY_TO(TraverseSynOrSemInitListExpr(
+      S->isSemanticForm() ? S : S->getSemanticForm()));
+  return true;
+}
+
 // GenericSelectionExpr is a special case because the types and expressions
 // are interleaved.  We also need to watch out for null types (default
 // generic associations).