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