[PATCH] D34030: Fix the postorder visting of the ClassTemplateSpecializationDecl nodes in the RecursiveASTVisitor.

Peter Siket via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 28 04:50:45 PDT 2017


MontyKutyi updated this revision to Diff 108626.
MontyKutyi added a comment.

I run the clang-format with -style=llvm on the added code parts.


https://reviews.llvm.org/D34030

Files:
  include/clang/AST/RecursiveASTVisitor.h
  unittests/AST/PostOrderASTVisitor.cpp


Index: unittests/AST/PostOrderASTVisitor.cpp
===================================================================
--- unittests/AST/PostOrderASTVisitor.cpp
+++ unittests/AST/PostOrderASTVisitor.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Tooling/Tooling.h"
 #include "gtest/gtest.h"
+#include <algorithm>
 
 using namespace clang;
 
@@ -75,7 +76,32 @@
     }
   };
 
-}
+
+// Serializes the AST. It is not complete! It only serializes the Statement
+// and the Declaration nodes.
+class ASTSerializerVisitor : public RecursiveASTVisitor<ASTSerializerVisitor> {
+private:
+  std::vector<void *> &visitedNodes;
+  const bool visitPostOrder;
+
+public:
+  ASTSerializerVisitor(bool visitPostOrder, std::vector<void *> &visitedNodes)
+      : visitedNodes(visitedNodes), visitPostOrder(visitPostOrder) {}
+
+  bool shouldTraversePostOrder() const { return visitPostOrder; }
+
+  bool VisitStmt(Stmt *s) {
+    visitedNodes.push_back(s);
+    return true;
+  }
+
+  bool VisitDecl(Decl *d) {
+    visitedNodes.push_back(d);
+    return true;
+  }
+};
+
+} // anonymous namespace
 
 TEST(RecursiveASTVisitor, PostOrderTraversal) {
   auto ASTUnit = tooling::buildASTFromCode(
@@ -126,3 +152,30 @@
     ASSERT_EQ(expected[I], Visitor.VisitedNodes[I]);
   }
 }
+
+TEST(RecursiveASTVisitor, PrePostComparisonTest) {
+  auto ASTUnit = tooling::buildASTFromCode("template <typename> class X {};"
+                                           "template class X<int>;");
+
+  auto TU = ASTUnit->getASTContext().getTranslationUnitDecl();
+
+  std::vector<void *> preorderNodeList, postorderNodeList;
+
+  ASTSerializerVisitor PreVisitor(false, preorderNodeList);
+  PreVisitor.TraverseTranslationUnitDecl(TU);
+
+  ASTSerializerVisitor PostVisitor(true, postorderNodeList);
+  PostVisitor.TraverseTranslationUnitDecl(TU);
+
+  // The number of visited nodes must be independent of the ordering mode.
+  ASSERT_EQ(preorderNodeList.size(), postorderNodeList.size());
+
+  std::sort(preorderNodeList.begin(), preorderNodeList.end());
+  std::sort(postorderNodeList.begin(), postorderNodeList.end());
+
+  // Both traversal must visit the same nodes.
+  ASSERT_EQ(std::mismatch(preorderNodeList.begin(), preorderNodeList.end(),
+                          postorderNodeList.begin())
+                .first,
+            preorderNodeList.end());
+}
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -1802,11 +1802,10 @@
     TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));              \
     if (!getDerived().shouldVisitTemplateInstantiations() &&                   \
         D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)      \
-      /* Returning from here skips traversing the                              \
-         declaration context of the *TemplateSpecializationDecl                \
-         (embedded in the DEF_TRAVERSE_DECL() macro)                           \
-         which contains the instantiated members of the template. */           \
-      return true;                                                             \
+      /* Skip traversing the declaration context of the                        \
+         *TemplateSpecializationDecl (embedded in the DEF_TRAVERSE_DECL()      \
+         macro) which contains the instantiated members of the template. */    \
+      ShouldVisitChildren = false;                                             \
   })
 
 DEF_TRAVERSE_TMPL_SPEC_DECL(Class)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D34030.108626.patch
Type: text/x-patch
Size: 3621 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170728/27e6a7c6/attachment.bin>


More information about the cfe-commits mailing list