[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