diff options
| author | Johannes Altmanninger <aclopte@gmail.com> | 2017-09-06 13:11:13 +0000 |
|---|---|---|
| committer | Johannes Altmanninger <aclopte@gmail.com> | 2017-09-06 13:11:13 +0000 |
| commit | 0a755162be957aa9f022dca7cbd7fcdcd30069bf (patch) | |
| tree | e531c67ca6924f7b5c86610d333ceebdbd326565 /clang/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp | |
| parent | bd84ce893126e337830a780ba9444a70f9a1c248 (diff) | |
| download | bcm5719-llvm-0a755162be957aa9f022dca7cbd7fcdcd30069bf.tar.gz bcm5719-llvm-0a755162be957aa9f022dca7cbd7fcdcd30069bf.zip | |
[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
llvm-svn: 312631
Diffstat (limited to 'clang/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp')
| -rw-r--r-- | clang/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/clang/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp b/clang/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp index 72aa6042af1..2f2c5d6ee18 100644 --- a/clang/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp +++ b/clang/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp @@ -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::VisitNamedDecl(const NamedDecl *D) { 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@1", 2, 11); + Visitor.ExpectMatch("/f/f/@2", 2, 20); + Visitor.ExpectMatch("/Class/U@4", 3, 11); + Visitor.ExpectMatch("/Class/@5", 3, 20); + Visitor.ExpectMatch("/Class/Class/@6", 3, 34); + EXPECT_TRUE(Visitor.runOver(Source)); +} + } // end anonymous namespace |

