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

Added test for the fix.


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,47 @@
     }
   };
 
-}
+  // 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 PostVisitStmt(Stmt *s)
+    {
+      if (visitPostOrder)
+        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 +167,32 @@
     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)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to