1 //===- unittest/Tooling/QualTypeNameTest.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 "clang/Tooling/Core/QualTypeNames.h" 11 #include "TestVisitor.h" 12 using namespace clang; 13 14 namespace { 15 struct TypeNameVisitor : TestVisitor<TypeNameVisitor> { 16 llvm::StringMap<std::string> ExpectedQualTypeNames; 17 18 // ValueDecls are the least-derived decl with both a qualtype and a 19 // name. 20 bool traverseDecl(Decl *D) { 21 return true; // Always continue 22 } 23 24 bool VisitValueDecl(const ValueDecl *VD) { 25 std::string ExpectedName = 26 ExpectedQualTypeNames.lookup(VD->getNameAsString()); 27 if (ExpectedName != "") { 28 std::string ActualName = 29 TypeName::getFullyQualifiedName(VD->getType(), *Context); 30 if (ExpectedName != ActualName) { 31 // A custom message makes it much easier to see what declaration 32 // failed compared to EXPECT_EQ. 33 EXPECT_TRUE(false) << "Typename::getFullyQualifiedName failed for " 34 << VD->getQualifiedNameAsString() << std::endl 35 << " Actual: " << ActualName << std::endl 36 << " Exepcted: " << ExpectedName; 37 } 38 } 39 return true; 40 } 41 }; 42 43 // named namespaces inside anonymous namespaces 44 45 TEST(QualTypeNameTest, getFullyQualifiedName) { 46 TypeNameVisitor Visitor; 47 // Simple case to test the test framework itself. 48 Visitor.ExpectedQualTypeNames["CheckInt"] = "int"; 49 50 // Keeping the names of the variables whose types we check unique 51 // within the entire test--regardless of their own scope--makes it 52 // easier to diagnose test failures. 53 54 // Simple namespace qualifier 55 Visitor.ExpectedQualTypeNames["CheckA"] = "A::B::Class0"; 56 // Lookup up the enclosing scopes, then down another one. (These 57 // appear as elaborated type in the AST. In that case--even if 58 // policy.SuppressScope = 0--qual_type.getAsString(policy) only 59 // gives the name as it appears in the source, not the full name. 60 Visitor.ExpectedQualTypeNames["CheckB"] = "A::B::C::Class1"; 61 // Template parameter expansion. 62 Visitor.ExpectedQualTypeNames["CheckC"] = 63 "A::B::Template0<A::B::C::MyInt, A::B::AnotherClass>"; 64 // Recursive template parameter expansion. 65 Visitor.ExpectedQualTypeNames["CheckD"] = 66 "A::B::Template0<A::B::Template1<A::B::C::MyInt, A::B::AnotherClass>, " 67 "A::B::Template0<int, long> >"; 68 // Variadic Template expansion. 69 Visitor.ExpectedQualTypeNames["CheckE"] = 70 "A::Variadic<int, A::B::Template0<int, char>, " 71 "A::B::Template1<int, long>, A::B::C::MyInt>"; 72 // Using declarations should be fully expanded. 73 Visitor.ExpectedQualTypeNames["CheckF"] = "A::B::Class0"; 74 // Elements found within "using namespace foo;" should be fully 75 // expanded. 76 Visitor.ExpectedQualTypeNames["CheckG"] = "A::B::C::MyInt"; 77 // Type inside function 78 Visitor.ExpectedQualTypeNames["CheckH"] = "struct X"; 79 // Anonymous Namespaces 80 Visitor.ExpectedQualTypeNames["CheckI"] = "aClass"; 81 // Keyword inclusion with namespaces 82 Visitor.ExpectedQualTypeNames["CheckJ"] = "struct A::aStruct"; 83 // Anonymous Namespaces nested in named namespaces and vice-versa. 84 Visitor.ExpectedQualTypeNames["CheckK"] = "D::aStruct"; 85 // Namespace alias 86 Visitor.ExpectedQualTypeNames["CheckL"] = "A::B::C::MyInt"; 87 Visitor.ExpectedQualTypeNames["non_dependent_type_var"] = 88 "Foo<X>::non_dependent_type"; 89 Visitor.ExpectedQualTypeNames["AnEnumVar"] = "EnumScopeClass::AnEnum"; 90 Visitor.ExpectedQualTypeNames["AliasTypeVal"] = "A::B::C::InnerAlias<int>"; 91 Visitor.runOver( 92 "int CheckInt;\n" 93 "template <typename T>\n" 94 "class OuterTemplateClass { };\n" 95 "namespace A {\n" 96 " namespace B {\n" 97 " class Class0 { };\n" 98 " namespace C {\n" 99 " typedef int MyInt;" 100 " template <typename T>\n" 101 " using InnerAlias = OuterTemplateClass<T>;\n" 102 " InnerAlias<int> AliasTypeVal;\n" 103 " }\n" 104 " template<class X, class Y> class Template0;" 105 " template<class X, class Y> class Template1;" 106 " typedef B::Class0 AnotherClass;\n" 107 " void Function1(Template0<C::MyInt,\n" 108 " AnotherClass> CheckC);\n" 109 " void Function2(Template0<Template1<C::MyInt, AnotherClass>,\n" 110 " Template0<int, long> > CheckD);\n" 111 " }\n" 112 "template<typename... Values> class Variadic {};\n" 113 "Variadic<int, B::Template0<int, char>, " 114 " B::Template1<int, long>, " 115 " B::C::MyInt > CheckE;\n" 116 " namespace BC = B::C;\n" 117 " BC::MyInt CheckL;\n" 118 "}\n" 119 "using A::B::Class0;\n" 120 "void Function(Class0 CheckF);\n" 121 "using namespace A::B::C;\n" 122 "void Function(MyInt CheckG);\n" 123 "void f() {\n" 124 " struct X {} CheckH;\n" 125 "}\n" 126 "namespace {\n" 127 " class aClass {};\n" 128 " aClass CheckI;\n" 129 "}\n" 130 "namespace A {\n" 131 " struct aStruct {} CheckJ;\n" 132 "}\n" 133 "namespace {\n" 134 " namespace D {\n" 135 " namespace {\n" 136 " class aStruct {};\n" 137 " aStruct CheckK;\n" 138 " }\n" 139 " }\n" 140 "}\n" 141 "template<class T> struct Foo {\n" 142 " typedef typename T::A dependent_type;\n" 143 " typedef int non_dependent_type;\n" 144 " dependent_type dependent_type_var;\n" 145 " non_dependent_type non_dependent_type_var;\n" 146 "};\n" 147 "struct X { typedef int A; };" 148 "Foo<X> var;" 149 "void F() {\n" 150 " var.dependent_type_var = 0;\n" 151 "var.non_dependent_type_var = 0;\n" 152 "}\n" 153 "class EnumScopeClass {\n" 154 "public:\n" 155 " enum AnEnum { ZERO, ONE };\n" 156 "};\n" 157 "EnumScopeClass::AnEnum AnEnumVar;\n", 158 TypeNameVisitor::Lang_CXX11 159 ); 160 161 TypeNameVisitor Complex; 162 Complex.ExpectedQualTypeNames["CheckTX"] = "B::TX"; 163 Complex.runOver( 164 "namespace A {" 165 " struct X {};" 166 "}" 167 "using A::X;" 168 "namespace fake_std {" 169 " template<class... Types > class tuple {};" 170 "}" 171 "namespace B {" 172 " using fake_std::tuple;" 173 " typedef tuple<X> TX;" 174 " TX CheckTX;" 175 " struct A { typedef int X; };" 176 "}"); 177 } 178 179 } // end anonymous namespace 180