[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
Mon Oct 2 09:21:26 PDT 2017
MontyKutyi updated this revision to Diff 117367.
MontyKutyi added a comment.
Updated to the latest trunk version.
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,33 @@
}
};
-}
+
+// 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 PostOrderTraverse;
+
+public:
+ ASTSerializerVisitor(bool PostOrderTraverse,
+ std::vector<void *> &VisitedNodes)
+ : VisitedNodes(VisitedNodes), PostOrderTraverse(PostOrderTraverse) {}
+
+ bool shouldTraversePostOrder() const { return PostOrderTraverse; }
+
+ 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 +153,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
@@ -1835,11 +1835,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.117367.patch
Type: text/x-patch
Size: 3660 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171002/68a8eac7/attachment.bin>
More information about the cfe-commits
mailing list