r312631 - [AST] Traverse templates in LexicallyOrderedRecursiveASTVisitor
Johannes Altmanninger via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 6 06:11:13 PDT 2017
Author: krobelus
Date: Wed Sep 6 06:11:13 2017
New Revision: 312631
URL: http://llvm.org/viewvc/llvm-project?rev=312631&view=rev
Log:
[AST] Traverse templates in LexicallyOrderedRecursiveASTVisitor
Summary:
We need to specialize this because RecursiveASTVisitor visits template
template parameters after the templated declaration, unlike the order in
which they appear in the source code.
Reviewers: arphaman
Reviewed By: arphaman
Subscribers: klimek, cfe-commits
Differential Revision: https://reviews.llvm.org/D36998
Modified:
cfe/trunk/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
cfe/trunk/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp
Modified: cfe/trunk/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h?rev=312631&r1=312630&r2=312631&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h Wed Sep 6 06:11:13 2017
@@ -111,6 +111,8 @@ public:
return true;
}
+ bool shouldTraverseTemplateArgumentsBeforeDecl() const { return true; }
+
private:
bool TraverseAdditionalLexicallyNestedDeclarations() {
// FIXME: Ideally the gathered declarations and the declarations in the
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=312631&r1=312630&r2=312631&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Wed Sep 6 06:11:13 2017
@@ -535,6 +535,7 @@ private:
bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue);
bool PostVisitStmt(Stmt *S);
+ bool shouldTraverseTemplateArgumentsBeforeDecl() const { return false; }
};
template <typename Derived>
@@ -1688,8 +1689,13 @@ bool RecursiveASTVisitor<Derived>::Trave
// template declarations.
#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
- TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
+ if (getDerived().shouldTraverseTemplateArgumentsBeforeDecl()) { \
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
+ TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
+ } else { \
+ TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
+ } \
\
/* By default, we do not traverse the instantiations of \
class templates since they do not appear in the user code. The \
Modified: cfe/trunk/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp?rev=312631&r1=312630&r2=312631&view=diff
==============================================================================
--- cfe/trunk/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp Wed Sep 6 06:11:13 2017
@@ -21,8 +21,9 @@ class LexicallyOrderedDeclVisitor
: public LexicallyOrderedRecursiveASTVisitor<LexicallyOrderedDeclVisitor> {
public:
LexicallyOrderedDeclVisitor(DummyMatchVisitor &Matcher,
- const SourceManager &SM)
- : LexicallyOrderedRecursiveASTVisitor(SM), Matcher(Matcher) {}
+ const SourceManager &SM, bool EmitIndices)
+ : LexicallyOrderedRecursiveASTVisitor(SM), Matcher(Matcher),
+ EmitIndices(EmitIndices) {}
bool TraverseDecl(Decl *D) {
TraversalStack.push_back(D);
@@ -35,15 +36,20 @@ public:
private:
DummyMatchVisitor &Matcher;
+ bool EmitIndices;
+ unsigned Index = 0;
llvm::SmallVector<Decl *, 8> TraversalStack;
};
class DummyMatchVisitor : public ExpectedLocationVisitor<DummyMatchVisitor> {
+ bool EmitIndices;
+
public:
+ DummyMatchVisitor(bool EmitIndices = false) : EmitIndices(EmitIndices) {}
bool VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
const ASTContext &Context = TU->getASTContext();
const SourceManager &SM = Context.getSourceManager();
- LexicallyOrderedDeclVisitor SubVisitor(*this, SM);
+ LexicallyOrderedDeclVisitor SubVisitor(*this, SM, EmitIndices);
SubVisitor.TraverseDecl(TU);
return false;
}
@@ -64,9 +70,11 @@ bool LexicallyOrderedDeclVisitor::VisitN
OS << ND->getNameAsString();
else
OS << "???";
- if (isa<DeclContext>(D))
+ if (isa<DeclContext>(D) or isa<TemplateDecl>(D))
OS << "/";
}
+ if (EmitIndices)
+ OS << "@" << Index++;
Matcher.match(OS.str(), D);
return true;
}
@@ -138,4 +146,18 @@ MACRO_F(2)
EXPECT_TRUE(Visitor.runOver(Source, DummyMatchVisitor::Lang_OBJC));
}
+TEST(LexicallyOrderedRecursiveASTVisitor, VisitTemplateDecl) {
+ StringRef Source = R"(
+template <class T> T f();
+template <class U, class = void> class Class {};
+)";
+ DummyMatchVisitor Visitor(/*EmitIndices=*/true);
+ Visitor.ExpectMatch("/f/T at 1", 2, 11);
+ Visitor.ExpectMatch("/f/f/@2", 2, 20);
+ Visitor.ExpectMatch("/Class/U at 4", 3, 11);
+ Visitor.ExpectMatch("/Class/@5", 3, 20);
+ Visitor.ExpectMatch("/Class/Class/@6", 3, 34);
+ EXPECT_TRUE(Visitor.runOver(Source));
+}
+
} // end anonymous namespace
More information about the cfe-commits
mailing list