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