1 //===- unittest/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp ---------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "TestVisitor.h"
11 #include <stack>
12 
13 using namespace clang;
14 
15 namespace {
16 
17 class TypeLocVisitor : public ExpectedLocationVisitor<TypeLocVisitor> {
18 public:
VisitTypeLoc(TypeLoc TypeLocation)19   bool VisitTypeLoc(TypeLoc TypeLocation) {
20     Match(TypeLocation.getType().getAsString(), TypeLocation.getBeginLoc());
21     return true;
22   }
23 };
24 
TEST(RecursiveASTVisitor,VisitsBaseClassDeclarations)25 TEST(RecursiveASTVisitor, VisitsBaseClassDeclarations) {
26   TypeLocVisitor Visitor;
27   Visitor.ExpectMatch("class X", 1, 30);
28   EXPECT_TRUE(Visitor.runOver("class X {}; class Y : public X {};"));
29 }
30 
TEST(RecursiveASTVisitor,VisitsCXXBaseSpecifiersOfForwardDeclaredClass)31 TEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersOfForwardDeclaredClass) {
32   TypeLocVisitor Visitor;
33   Visitor.ExpectMatch("class X", 3, 18);
34   EXPECT_TRUE(Visitor.runOver(
35     "class Y;\n"
36     "class X {};\n"
37     "class Y : public X {};"));
38 }
39 
TEST(RecursiveASTVisitor,VisitsCXXBaseSpecifiersWithIncompleteInnerClass)40 TEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersWithIncompleteInnerClass) {
41   TypeLocVisitor Visitor;
42   Visitor.ExpectMatch("class X", 2, 18);
43   EXPECT_TRUE(Visitor.runOver(
44     "class X {};\n"
45     "class Y : public X { class Z; };"));
46 }
47 
TEST(RecursiveASTVisitor,VisitsCXXBaseSpecifiersOfSelfReferentialType)48 TEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersOfSelfReferentialType) {
49   TypeLocVisitor Visitor;
50   Visitor.ExpectMatch("X<class Y>", 2, 18);
51   EXPECT_TRUE(Visitor.runOver(
52     "template<typename T> class X {};\n"
53     "class Y : public X<Y> {};"));
54 }
55 
TEST(RecursiveASTVisitor,VisitsClassTemplateTypeParmDefaultArgument)56 TEST(RecursiveASTVisitor, VisitsClassTemplateTypeParmDefaultArgument) {
57   TypeLocVisitor Visitor;
58   Visitor.ExpectMatch("class X", 2, 23);
59   EXPECT_TRUE(Visitor.runOver(
60     "class X;\n"
61     "template<typename T = X> class Y;\n"
62     "template<typename T> class Y {};\n"));
63 }
64 
TEST(RecursiveASTVisitor,VisitsCompoundLiteralType)65 TEST(RecursiveASTVisitor, VisitsCompoundLiteralType) {
66   TypeLocVisitor Visitor;
67   Visitor.ExpectMatch("struct S", 1, 26);
68   EXPECT_TRUE(Visitor.runOver(
69       "int f() { return (struct S { int a; }){.a = 0}.a; }",
70       TypeLocVisitor::Lang_C));
71 }
72 
TEST(RecursiveASTVisitor,VisitsObjCPropertyType)73 TEST(RecursiveASTVisitor, VisitsObjCPropertyType) {
74   TypeLocVisitor Visitor;
75   Visitor.ExpectMatch("NSNumber", 2, 33);
76   EXPECT_TRUE(Visitor.runOver(
77       "@class NSNumber; \n"
78       "@interface A @property (retain) NSNumber *x; @end\n",
79       TypeLocVisitor::Lang_OBJC));
80 }
81 
TEST(RecursiveASTVisitor,VisitInvalidType)82 TEST(RecursiveASTVisitor, VisitInvalidType) {
83   TypeLocVisitor Visitor;
84   // FIXME: It would be nice to have information about subtypes of invalid type
85   //Visitor.ExpectMatch("typeof(struct F *) []", 1, 1);
86   // Even if the full type is invalid, it should still find sub types
87   //Visitor.ExpectMatch("struct F", 1, 19);
88   EXPECT_FALSE(Visitor.runOver(
89       "__typeof__(struct F*) var[invalid];\n",
90       TypeLocVisitor::Lang_C));
91 }
92 
93 } // end anonymous namespace
94