RecursiveASTVisitorTest.cpp revision 82b4550fb25ad578b6c8143b87a003fae7106cae
1e002631101d3bafbc90ed8589ffc615f04dc245bDavid Blaikie//===- unittest/Tooling/RecursiveASTVisitorTest.cpp -----------------------===//
2fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek//
3fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek//                     The LLVM Compiler Infrastructure
4fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek//
5fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek// This file is distributed under the University of Illinois Open Source
6fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek// License. See LICENSE.TXT for details.
7fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek//
8fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek//===----------------------------------------------------------------------===//
9fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek
10bc9e5582467e70ec38b9fc5d3605152e86e2a5f8Richard Smith#include "TestVisitor.h"
11fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek
12fad7f85553da052559077f28c6937a8dd704b28dManuel Klimeknamespace clang {
13fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek
14fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekclass TypeLocVisitor : public ExpectedLocationVisitor<TypeLocVisitor> {
15fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekpublic:
16fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  bool VisitTypeLoc(TypeLoc TypeLocation) {
17fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    Match(TypeLocation.getType().getAsString(), TypeLocation.getBeginLoc());
18fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    return true;
19fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  }
20fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek};
21fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek
22fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekclass DeclRefExprVisitor : public ExpectedLocationVisitor<DeclRefExprVisitor> {
23fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekpublic:
24fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  bool VisitDeclRefExpr(DeclRefExpr *Reference) {
25fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    Match(Reference->getNameInfo().getAsString(), Reference->getLocation());
26fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    return true;
27fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  }
28fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek};
29fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek
3052ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasperclass VarDeclVisitor : public ExpectedLocationVisitor<VarDeclVisitor> {
3152ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasperpublic:
3252ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper bool VisitVarDecl(VarDecl *Variable) {
3352ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper   Match(Variable->getNameAsString(), Variable->getLocStart());
3452ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper   return true;
3552ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper }
3652ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper};
3752ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper
38fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekclass CXXMemberCallVisitor
39fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  : public ExpectedLocationVisitor<CXXMemberCallVisitor> {
40fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekpublic:
41fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  bool VisitCXXMemberCallExpr(CXXMemberCallExpr *Call) {
42fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    Match(Call->getMethodDecl()->getQualifiedNameAsString(),
43fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek          Call->getLocStart());
44fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    return true;
45fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  }
46fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek};
47fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek
48a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smithclass NamedDeclVisitor
49a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  : public ExpectedLocationVisitor<NamedDeclVisitor> {
50a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smithpublic:
51a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  bool VisitNamedDecl(NamedDecl *Decl) {
52a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    std::string NameWithTemplateArgs;
53a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    Decl->getNameForDiagnostic(NameWithTemplateArgs,
54a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith                               Decl->getASTContext().getPrintingPolicy(),
55a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith                               true);
56a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    Match(NameWithTemplateArgs, Decl->getLocation());
57a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    return true;
58a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  }
59a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith};
60a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith
61c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smithclass CXXOperatorCallExprTraverser
62c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith  : public ExpectedLocationVisitor<CXXOperatorCallExprTraverser> {
63c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smithpublic:
64c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith  // Use Traverse, not Visit, to check that data recursion optimization isn't
65c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith  // bypassing the call of this function.
66c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith  bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
67c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith    Match(getOperatorSpelling(CE->getOperator()), CE->getExprLoc());
68c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith    return ExpectedLocationVisitor<CXXOperatorCallExprTraverser>::
69c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith        TraverseCXXOperatorCallExpr(CE);
70c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith  }
71c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith};
72c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith
73c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smithclass ParenExprVisitor : public ExpectedLocationVisitor<ParenExprVisitor> {
74c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smithpublic:
75c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith  bool VisitParenExpr(ParenExpr *Parens) {
76c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith    Match("", Parens->getExprLoc());
77c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith    return true;
78c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith  }
79c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith};
80c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith
816fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smithclass TemplateArgumentLocTraverser
826fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith  : public ExpectedLocationVisitor<TemplateArgumentLocTraverser> {
836fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smithpublic:
846fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
856fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    std::string ArgStr;
866fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    llvm::raw_string_ostream Stream(ArgStr);
876fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    const TemplateArgument &Arg = ArgLoc.getArgument();
886fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith
896fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    Arg.print(Context->getPrintingPolicy(), Stream);
906fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    Match(Stream.str(), ArgLoc.getLocation());
916fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    return ExpectedLocationVisitor<TemplateArgumentLocTraverser>::
926fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith      TraverseTemplateArgumentLoc(ArgLoc);
936fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith  }
946fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith};
956fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith
966fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smithclass CXXBoolLiteralExprVisitor
976fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith  : public ExpectedLocationVisitor<CXXBoolLiteralExprVisitor> {
986fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smithpublic:
996fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith  bool VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *BE) {
1006fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    if (BE->getValue())
1016fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith      Match("true", BE->getLocation());
1026fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    else
1036fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith      Match("false", BE->getLocation());
1046fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    return true;
1056fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith  }
1066fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith};
1076fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith
108fad7f85553da052559077f28c6937a8dd704b28dManuel KlimekTEST(RecursiveASTVisitor, VisitsBaseClassDeclarations) {
109fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  TypeLocVisitor Visitor;
110fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  Visitor.ExpectMatch("class X", 1, 30);
111fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  EXPECT_TRUE(Visitor.runOver("class X {}; class Y : public X {};"));
112fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek}
113fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek
1149f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel KlimekTEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersOfForwardDeclaredClass) {
1159f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek  TypeLocVisitor Visitor;
1169f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek  Visitor.ExpectMatch("class X", 3, 18);
1179f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek  EXPECT_TRUE(Visitor.runOver(
1189f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek    "class Y;\n"
1199f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek    "class X {};\n"
1209f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek    "class Y : public X {};"));
1219f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek}
1229f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek
1239f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel KlimekTEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersWithIncompleteInnerClass) {
1249f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek  TypeLocVisitor Visitor;
1259f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek  Visitor.ExpectMatch("class X", 2, 18);
1269f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek  EXPECT_TRUE(Visitor.runOver(
1279f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek    "class X {};\n"
1289f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek    "class Y : public X { class Z; };"));
1299f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek}
1309f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek
1319f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel KlimekTEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersOfSelfReferentialType) {
1329f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek  TypeLocVisitor Visitor;
1339f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek  Visitor.ExpectMatch("X<class Y>", 2, 18);
1349f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek  EXPECT_TRUE(Visitor.runOver(
1359f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek    "template<typename T> class X {};\n"
1369f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek    "class Y : public X<Y> {};"));
1379f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek}
1389f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek
139fad7f85553da052559077f28c6937a8dd704b28dManuel KlimekTEST(RecursiveASTVisitor, VisitsBaseClassTemplateArguments) {
140fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  DeclRefExprVisitor Visitor;
141fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  Visitor.ExpectMatch("x", 2, 3);
142fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  EXPECT_TRUE(Visitor.runOver(
143fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "void x(); template <void (*T)()> class X {};\nX<x> y;"));
144fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek}
145fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek
14652ec0c0357ce970ca52a27c1086626450f0967e7Daniel JasperTEST(RecursiveASTVisitor, VisitsCXXForRangeStmtRange) {
14752ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper  DeclRefExprVisitor Visitor;
14852ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper  Visitor.ExpectMatch("x", 2, 25);
1491071ba9c324d831b437870a1fe63bf2ecdc4e9e4Daniel Jasper  Visitor.ExpectMatch("x", 2, 30);
15052ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper  EXPECT_TRUE(Visitor.runOver(
15152ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper    "int x[5];\n"
1521071ba9c324d831b437870a1fe63bf2ecdc4e9e4Daniel Jasper    "void f() { for (int i : x) { x[0] = 1; } }"));
15352ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper}
15452ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper
15552ec0c0357ce970ca52a27c1086626450f0967e7Daniel JasperTEST(RecursiveASTVisitor, VisitsCXXForRangeStmtLoopVariable) {
15652ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper  VarDeclVisitor Visitor;
15752ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper  Visitor.ExpectMatch("i", 2, 17);
15852ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper  EXPECT_TRUE(Visitor.runOver(
15952ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper    "int x[5];\n"
16052ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper    "void f() { for (int i : x) {} }"));
16152ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper}
16252ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper
163fad7f85553da052559077f28c6937a8dd704b28dManuel KlimekTEST(RecursiveASTVisitor, VisitsCallExpr) {
164fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  DeclRefExprVisitor Visitor;
165fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  Visitor.ExpectMatch("x", 1, 22);
166fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  EXPECT_TRUE(Visitor.runOver(
167fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "void x(); void y() { x(); }"));
168fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek}
169fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek
170fad7f85553da052559077f28c6937a8dd704b28dManuel KlimekTEST(RecursiveASTVisitor, VisitsCallInTemplateInstantiation) {
171fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  CXXMemberCallVisitor Visitor;
172fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  Visitor.ExpectMatch("Y::x", 3, 3);
173fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  EXPECT_TRUE(Visitor.runOver(
174fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "struct Y { void x(); };\n"
175fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "template<typename T> void y(T t) {\n"
176fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "  t.x();\n"
177fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "}\n"
178fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "void foo() { y<Y>(Y()); }"));
179fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek}
180fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek
1815482dc3a88fce51307b5e1e19bdf72dea1562040Richard SmithTEST(RecursiveASTVisitor, VisitsCallInNestedFunctionTemplateInstantiation) {
182fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  CXXMemberCallVisitor Visitor;
183fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  Visitor.ExpectMatch("Y::x", 4, 5);
184fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  EXPECT_TRUE(Visitor.runOver(
185fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "struct Y { void x(); };\n"
186fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "template<typename T> struct Z {\n"
187fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "  template<typename U> static void f() {\n"
188fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "    T().x();\n"
189fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "  }\n"
190fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "};\n"
191fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "void foo() { Z<Y>::f<int>(); }"));
192fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek}
1935482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith
1945482dc3a88fce51307b5e1e19bdf72dea1562040Richard SmithTEST(RecursiveASTVisitor, VisitsCallInNestedClassTemplateInstantiation) {
1955482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith  CXXMemberCallVisitor Visitor;
1965482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith  Visitor.ExpectMatch("A::x", 5, 7);
1975482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith  EXPECT_TRUE(Visitor.runOver(
1985482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith    "template <typename T1> struct X {\n"
1995482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith    "  template <typename T2> struct Y {\n"
2005482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith    "    void f() {\n"
2015482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith    "      T2 y;\n"
2025482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith    "      y.x();\n"
2035482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith    "    }\n"
2045482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith    "  };\n"
2055482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith    "};\n"
2065482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith    "struct A { void x(); };\n"
2075482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith    "int main() {\n"
2085482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith    "  (new X<A>::Y<A>())->f();\n"
2095482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith    "}"));
2105482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith}
211fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek
212fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek/* FIXME: According to Richard Smith this is a bug in the AST.
213fad7f85553da052559077f28c6937a8dd704b28dManuel KlimekTEST(RecursiveASTVisitor, VisitsBaseClassTemplateArgumentsInInstantiation) {
214fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  DeclRefExprVisitor Visitor;
215fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  Visitor.ExpectMatch("x", 3, 43);
216fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek  EXPECT_TRUE(Visitor.runOver(
217fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "template <typename T> void x();\n"
218fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "template <void (*T)()> class X {};\n"
219fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "template <typename T> class Y : public X< x<T> > {};\n"
220fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek    "Y<int> y;"));
221fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek}
222fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek*/
223fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek
224a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsCallInPartialTemplateSpecialization) {
225a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  CXXMemberCallVisitor Visitor;
226a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  Visitor.ExpectMatch("A::x", 6, 20);
227a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  EXPECT_TRUE(Visitor.runOver(
228a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "template <typename T1> struct X {\n"
229a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "  template <typename T2, bool B> struct Y { void g(); };\n"
230a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "};\n"
231a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "template <typename T1> template <typename T2>\n"
232a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "struct X<T1>::Y<T2, true> {\n"
233a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "  void f() { T2 y; y.x(); }\n"
234a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "};\n"
235a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "struct A { void x(); };\n"
236a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "int main() {\n"
237a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "  (new X<A>::Y<A, true>())->f();\n"
238a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "}\n"));
239a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith}
240a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith
24106cd51a83577019ea26661b7d570ae9aef06f674Richard SmithTEST(RecursiveASTVisitor, VisitsExplicitTemplateSpecialization) {
24206cd51a83577019ea26661b7d570ae9aef06f674Richard Smith  CXXMemberCallVisitor Visitor;
24306cd51a83577019ea26661b7d570ae9aef06f674Richard Smith  Visitor.ExpectMatch("A::f", 4, 5);
24406cd51a83577019ea26661b7d570ae9aef06f674Richard Smith  EXPECT_TRUE(Visitor.runOver(
24506cd51a83577019ea26661b7d570ae9aef06f674Richard Smith    "struct A {\n"
24606cd51a83577019ea26661b7d570ae9aef06f674Richard Smith    "  void f() const {}\n"
24706cd51a83577019ea26661b7d570ae9aef06f674Richard Smith    "  template<class T> void g(const T& t) const {\n"
24806cd51a83577019ea26661b7d570ae9aef06f674Richard Smith    "    t.f();\n"
24906cd51a83577019ea26661b7d570ae9aef06f674Richard Smith    "  }\n"
25006cd51a83577019ea26661b7d570ae9aef06f674Richard Smith    "};\n"
25106cd51a83577019ea26661b7d570ae9aef06f674Richard Smith    "template void A::g(const A& a) const;\n"));
25206cd51a83577019ea26661b7d570ae9aef06f674Richard Smith}
25306cd51a83577019ea26661b7d570ae9aef06f674Richard Smith
254a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsPartialTemplateSpecialization) {
255a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  // From cfe-commits/Week-of-Mon-20100830/033998.html
256e966beaa6ef3eb7ced09203f748e6042f81b2a6cDaniel Jasper  // Contrary to the approach suggested in that email, we visit all
257a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  // specializations when we visit the primary template.  Visiting them when we
258a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  // visit the associated specialization is problematic for specializations of
259a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  // template members of class templates.
260a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  NamedDeclVisitor Visitor;
261a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  Visitor.ExpectMatch("A<bool>", 1, 26);
262a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  Visitor.ExpectMatch("A<char *>", 2, 26);
263a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  EXPECT_TRUE(Visitor.runOver(
264a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "template <class T> class A {};\n"
265a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "template <class T> class A<T*> {};\n"
266a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "A<bool> ab;\n"
267a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "A<char*> acp;\n"));
268a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith}
269a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith
270a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsUndefinedClassTemplateSpecialization) {
271a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  NamedDeclVisitor Visitor;
272a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  Visitor.ExpectMatch("A<int>", 1, 29);
273a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  EXPECT_TRUE(Visitor.runOver(
274a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "template<typename T> struct A;\n"
275a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "A<int> *p;\n"));
276a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith}
277a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith
278a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsNestedUndefinedClassTemplateSpecialization) {
279a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  NamedDeclVisitor Visitor;
280a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  Visitor.ExpectMatch("A<int>::B<char>", 2, 31);
281a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  EXPECT_TRUE(Visitor.runOver(
282a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "template<typename T> struct A {\n"
283a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "  template<typename U> struct B;\n"
284a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "};\n"
285a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "A<int>::B<char> *p;\n"));
286a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith}
287a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith
288a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsUndefinedFunctionTemplateSpecialization) {
289a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  NamedDeclVisitor Visitor;
290a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  Visitor.ExpectMatch("A<int>", 1, 26);
291a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  EXPECT_TRUE(Visitor.runOver(
292a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "template<typename T> int A();\n"
293a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "int k = A<int>();\n"));
294a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith}
295a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith
296a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsNestedUndefinedFunctionTemplateSpecialization) {
297a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  NamedDeclVisitor Visitor;
298a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  Visitor.ExpectMatch("A<int>::B<char>", 2, 35);
299a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  EXPECT_TRUE(Visitor.runOver(
300a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "template<typename T> struct A {\n"
301a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "  template<typename U> static int B();\n"
302a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "};\n"
303a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "int k = A<int>::B<char>();\n"));
304a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith}
305a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith
306a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, NoRecursionInSelfFriend) {
307a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  // From cfe-commits/Week-of-Mon-20100830/033977.html
308a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  NamedDeclVisitor Visitor;
309a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  Visitor.ExpectMatch("vector_iterator<int>", 2, 7);
310a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith  EXPECT_TRUE(Visitor.runOver(
311a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "template<typename Container>\n"
312a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "class vector_iterator {\n"
313a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "    template <typename C> friend class vector_iterator;\n"
314a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "};\n"
315a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith    "vector_iterator<int> it_int;\n"));
316a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith}
317a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith
318c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard SmithTEST(RecursiveASTVisitor, TraversesOverloadedOperator) {
319c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith  CXXOperatorCallExprTraverser Visitor;
320c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith  Visitor.ExpectMatch("()", 4, 9);
321c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith  EXPECT_TRUE(Visitor.runOver(
322c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith    "struct A {\n"
323c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith    "  int operator()();\n"
324c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith    "} a;\n"
325c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith    "int k = a();\n"));
326c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith}
327c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith
328c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard SmithTEST(RecursiveASTVisitor, VisitsParensDuringDataRecursion) {
329c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith  ParenExprVisitor Visitor;
330c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith  Visitor.ExpectMatch("", 1, 9);
331c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith  EXPECT_TRUE(Visitor.runOver("int k = (4) + 9;\n"));
332c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith}
333c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith
3346fada8e820f2fd1b4cd38e48c8986110e87c5915Richard SmithTEST(RecursiveASTVisitor, VisitsClassTemplateNonTypeParmDefaultArgument) {
3356fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith  CXXBoolLiteralExprVisitor Visitor;
3366fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith  Visitor.ExpectMatch("true", 2, 19);
3376fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith  EXPECT_TRUE(Visitor.runOver(
3386fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    "template<bool B> class X;\n"
3396fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    "template<bool B = true> class Y;\n"
3406fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    "template<bool B> class Y {};\n"));
3416fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith}
3426fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith
3436fada8e820f2fd1b4cd38e48c8986110e87c5915Richard SmithTEST(RecursiveASTVisitor, VisitsClassTemplateTypeParmDefaultArgument) {
3446fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith  TypeLocVisitor Visitor;
3456fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith  Visitor.ExpectMatch("class X", 2, 23);
3466fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith  EXPECT_TRUE(Visitor.runOver(
3476fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    "class X;\n"
3486fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    "template<typename T = X> class Y;\n"
3496fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    "template<typename T> class Y {};\n"));
3506fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith}
3516fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith
3526fada8e820f2fd1b4cd38e48c8986110e87c5915Richard SmithTEST(RecursiveASTVisitor, VisitsClassTemplateTemplateParmDefaultArgument) {
3536fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith  TemplateArgumentLocTraverser Visitor;
3546fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith  Visitor.ExpectMatch("X", 2, 40);
3556fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith  EXPECT_TRUE(Visitor.runOver(
3566fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    "template<typename T> class X;\n"
3576fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    "template<template <typename> class T = X> class Y;\n"
3586fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith    "template<template <typename> class T> class Y {};\n"));
3596fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith}
3606fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith
361c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith// A visitor that visits implicit declarations and matches constructors.
362c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smithclass ImplicitCtorVisitor
363c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith    : public ExpectedLocationVisitor<ImplicitCtorVisitor> {
364c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smithpublic:
36552ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper  bool shouldVisitImplicitCode() const { return true; }
366c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith
367c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith  bool VisitCXXConstructorDecl(CXXConstructorDecl* Ctor) {
368c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith    if (Ctor->isImplicit()) {  // Was not written in source code
369c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith      if (const CXXRecordDecl* Class = Ctor->getParent()) {
370c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith        Match(Class->getName(), Ctor->getLocation());
371c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith      }
372c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith    }
373c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith    return true;
374c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith  }
375c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith};
376c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith
377c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard SmithTEST(RecursiveASTVisitor, VisitsImplicitCopyConstructors) {
378c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith  ImplicitCtorVisitor Visitor;
379c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith  Visitor.ExpectMatch("Simple", 2, 8);
380c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith  // Note: Clang lazily instantiates implicit declarations, so we need
381c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith  // to use them in order to force them to appear in the AST.
382c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith  EXPECT_TRUE(Visitor.runOver(
383c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith      "struct WithCtor { WithCtor(); }; \n"
384c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith      "struct Simple { Simple(); WithCtor w; }; \n"
385c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith      "int main() { Simple s; Simple t(s); }\n"));
386c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith}
387c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith
3880652c35a303a6186142eea566c88714c59bdc664Richard SmithTEST(RecursiveASTVisitor, VisitsExtension) {
3890652c35a303a6186142eea566c88714c59bdc664Richard Smith  DeclRefExprVisitor Visitor;
3900652c35a303a6186142eea566c88714c59bdc664Richard Smith  Visitor.ExpectMatch("s", 1, 24);
3910652c35a303a6186142eea566c88714c59bdc664Richard Smith  EXPECT_TRUE(Visitor.runOver(
3920652c35a303a6186142eea566c88714c59bdc664Richard Smith    "int s = __extension__ (s);\n"));
3930652c35a303a6186142eea566c88714c59bdc664Richard Smith}
3940652c35a303a6186142eea566c88714c59bdc664Richard Smith
39582b4550fb25ad578b6c8143b87a003fae7106caeRichard SmithTEST(RecursiveASTVisitor, VisitsCompoundLiteralType) {
39682b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith  TypeLocVisitor Visitor;
39782b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith  Visitor.ExpectMatch("struct S", 1, 26);
39882b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith  EXPECT_TRUE(Visitor.runOver(
39982b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith      "int f() { return (struct S { int a; }){.a = 0}.a; }",
40082b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith      TypeLocVisitor::Lang_C));
40182b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith}
40282b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith
403fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek} // end namespace clang
404