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<TypeLocVisitor> {
16 public:
VisitTypeLoc(TypeLoc TypeLocation)17 bool VisitTypeLoc(TypeLoc TypeLocation) {
18 Match(TypeLocation.getType().getAsString(), TypeLocation.getBeginLoc());
19 return true;
20 }
21 };
22
TEST(RecursiveASTVisitor,VisitsBaseClassDeclarations)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
TEST(RecursiveASTVisitor,VisitsCXXBaseSpecifiersOfForwardDeclaredClass)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
TEST(RecursiveASTVisitor,VisitsCXXBaseSpecifiersWithIncompleteInnerClass)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
TEST(RecursiveASTVisitor,VisitsCXXBaseSpecifiersOfSelfReferentialType)46 TEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersOfSelfReferentialType) {
47 TypeLocVisitor Visitor;
48 Visitor.ExpectMatch("X<class Y>", 2, 18);
49 EXPECT_TRUE(Visitor.runOver(
50 "template<typename T> class X {};\n"
51 "class Y : public X<Y> {};"));
52 }
53
TEST(RecursiveASTVisitor,VisitsClassTemplateTypeParmDefaultArgument)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
TEST(RecursiveASTVisitor,VisitsCompoundLiteralType)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
TEST(RecursiveASTVisitor,VisitsObjCPropertyType)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
TEST(RecursiveASTVisitor,VisitInvalidType)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 } // end anonymous namespace
92