QualTypeNamesTest.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. //===- unittest/Tooling/QualTypeNameTest.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. #include "clang/AST/QualTypeNames.h"
  9. #include "TestVisitor.h"
  10. using namespace clang;
  11. namespace {
  12. struct TypeNameVisitor : TestVisitor<TypeNameVisitor> {
  13. llvm::StringMap<std::string> ExpectedQualTypeNames;
  14. bool WithGlobalNsPrefix = false;
  15. // ValueDecls are the least-derived decl with both a qualtype and a
  16. // name.
  17. bool traverseDecl(Decl *D) {
  18. return true; // Always continue
  19. }
  20. bool VisitValueDecl(const ValueDecl *VD) {
  21. std::string ExpectedName =
  22. ExpectedQualTypeNames.lookup(VD->getNameAsString());
  23. if (ExpectedName != "") {
  24. PrintingPolicy Policy(Context->getPrintingPolicy());
  25. Policy.SuppressScope = false;
  26. Policy.AnonymousTagLocations = true;
  27. Policy.PolishForDeclaration = true;
  28. Policy.SuppressUnwrittenScope = true;
  29. std::string ActualName = TypeName::getFullyQualifiedName(
  30. VD->getType(), *Context, Policy, WithGlobalNsPrefix);
  31. if (ExpectedName != ActualName) {
  32. // A custom message makes it much easier to see what declaration
  33. // failed compared to EXPECT_EQ.
  34. EXPECT_TRUE(false) << "Typename::getFullyQualifiedName failed for "
  35. << VD->getQualifiedNameAsString() << std::endl
  36. << " Actual: " << ActualName << std::endl
  37. << " Exepcted: " << ExpectedName;
  38. }
  39. }
  40. return true;
  41. }
  42. };
  43. // named namespaces inside anonymous namespaces
  44. TEST(QualTypeNameTest, getFullyQualifiedName) {
  45. TypeNameVisitor Visitor;
  46. // Simple case to test the test framework itself.
  47. Visitor.ExpectedQualTypeNames["CheckInt"] = "int";
  48. // Keeping the names of the variables whose types we check unique
  49. // within the entire test--regardless of their own scope--makes it
  50. // easier to diagnose test failures.
  51. // Simple namespace qualifier
  52. Visitor.ExpectedQualTypeNames["CheckA"] = "A::B::Class0";
  53. // Lookup up the enclosing scopes, then down another one. (These
  54. // appear as elaborated type in the AST. In that case--even if
  55. // policy.SuppressScope = 0--qual_type.getAsString(policy) only
  56. // gives the name as it appears in the source, not the full name.
  57. Visitor.ExpectedQualTypeNames["CheckB"] = "A::B::C::Class1";
  58. // Template parameter expansion.
  59. Visitor.ExpectedQualTypeNames["CheckC"] =
  60. "A::B::Template0<A::B::C::MyInt, A::B::AnotherClass>";
  61. // Recursive template parameter expansion.
  62. Visitor.ExpectedQualTypeNames["CheckD"] =
  63. "A::B::Template0<A::B::Template1<A::B::C::MyInt, A::B::AnotherClass>, "
  64. "A::B::Template0<int, long> >";
  65. // Variadic Template expansion.
  66. Visitor.ExpectedQualTypeNames["CheckE"] =
  67. "A::Variadic<int, A::B::Template0<int, char>, "
  68. "A::B::Template1<int, long>, A::B::C::MyInt>";
  69. // Using declarations should be fully expanded.
  70. Visitor.ExpectedQualTypeNames["CheckF"] = "A::B::Class0";
  71. // Elements found within "using namespace foo;" should be fully
  72. // expanded.
  73. Visitor.ExpectedQualTypeNames["CheckG"] = "A::B::C::MyInt";
  74. // Type inside function
  75. Visitor.ExpectedQualTypeNames["CheckH"] = "struct X";
  76. // Anonymous Namespaces
  77. Visitor.ExpectedQualTypeNames["CheckI"] = "aClass";
  78. // Keyword inclusion with namespaces
  79. Visitor.ExpectedQualTypeNames["CheckJ"] = "struct A::aStruct";
  80. // Anonymous Namespaces nested in named namespaces and vice-versa.
  81. Visitor.ExpectedQualTypeNames["CheckK"] = "D::aStruct";
  82. // Namespace alias
  83. Visitor.ExpectedQualTypeNames["CheckL"] = "A::B::C::MyInt";
  84. Visitor.ExpectedQualTypeNames["non_dependent_type_var"] =
  85. "Foo<X>::non_dependent_type";
  86. Visitor.ExpectedQualTypeNames["AnEnumVar"] = "EnumScopeClass::AnEnum";
  87. Visitor.ExpectedQualTypeNames["AliasTypeVal"] = "A::B::C::InnerAlias<int>";
  88. Visitor.ExpectedQualTypeNames["CheckM"] = "const A::B::Class0 *";
  89. Visitor.ExpectedQualTypeNames["CheckN"] = "const X *";
  90. Visitor.runOver(
  91. "int CheckInt;\n"
  92. "template <typename T>\n"
  93. "class OuterTemplateClass { };\n"
  94. "namespace A {\n"
  95. " namespace B {\n"
  96. " class Class0 { };\n"
  97. " namespace C {\n"
  98. " typedef int MyInt;"
  99. " template <typename T>\n"
  100. " using InnerAlias = OuterTemplateClass<T>;\n"
  101. " InnerAlias<int> AliasTypeVal;\n"
  102. " }\n"
  103. " template<class X, class Y> class Template0;"
  104. " template<class X, class Y> class Template1;"
  105. " typedef B::Class0 AnotherClass;\n"
  106. " void Function1(Template0<C::MyInt,\n"
  107. " AnotherClass> CheckC);\n"
  108. " void Function2(Template0<Template1<C::MyInt, AnotherClass>,\n"
  109. " Template0<int, long> > CheckD);\n"
  110. " void Function3(const B::Class0* CheckM);\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. "struct X;\n"
  127. "void f(const ::X* CheckN) {}\n"
  128. "namespace {\n"
  129. " class aClass {};\n"
  130. " aClass CheckI;\n"
  131. "}\n"
  132. "namespace A {\n"
  133. " struct aStruct {} CheckJ;\n"
  134. "}\n"
  135. "namespace {\n"
  136. " namespace D {\n"
  137. " namespace {\n"
  138. " class aStruct {};\n"
  139. " aStruct CheckK;\n"
  140. " }\n"
  141. " }\n"
  142. "}\n"
  143. "template<class T> struct Foo {\n"
  144. " typedef typename T::A dependent_type;\n"
  145. " typedef int non_dependent_type;\n"
  146. " dependent_type dependent_type_var;\n"
  147. " non_dependent_type non_dependent_type_var;\n"
  148. "};\n"
  149. "struct X { typedef int A; };"
  150. "Foo<X> var;"
  151. "void F() {\n"
  152. " var.dependent_type_var = 0;\n"
  153. "var.non_dependent_type_var = 0;\n"
  154. "}\n"
  155. "class EnumScopeClass {\n"
  156. "public:\n"
  157. " enum AnEnum { ZERO, ONE };\n"
  158. "};\n"
  159. "EnumScopeClass::AnEnum AnEnumVar;\n",
  160. TypeNameVisitor::Lang_CXX11
  161. );
  162. TypeNameVisitor Complex;
  163. Complex.ExpectedQualTypeNames["CheckTX"] = "B::TX";
  164. Complex.runOver(
  165. "namespace A {"
  166. " struct X {};"
  167. "}"
  168. "using A::X;"
  169. "namespace fake_std {"
  170. " template<class... Types > class tuple {};"
  171. "}"
  172. "namespace B {"
  173. " using fake_std::tuple;"
  174. " typedef tuple<X> TX;"
  175. " TX CheckTX;"
  176. " struct A { typedef int X; };"
  177. "}");
  178. TypeNameVisitor GlobalNsPrefix;
  179. GlobalNsPrefix.WithGlobalNsPrefix = true;
  180. GlobalNsPrefix.ExpectedQualTypeNames["IntVal"] = "int";
  181. GlobalNsPrefix.ExpectedQualTypeNames["BoolVal"] = "bool";
  182. GlobalNsPrefix.ExpectedQualTypeNames["XVal"] = "::A::B::X";
  183. GlobalNsPrefix.ExpectedQualTypeNames["IntAliasVal"] = "::A::B::Alias<int>";
  184. GlobalNsPrefix.ExpectedQualTypeNames["ZVal"] = "::A::B::Y::Z";
  185. GlobalNsPrefix.ExpectedQualTypeNames["GlobalZVal"] = "::Z";
  186. GlobalNsPrefix.ExpectedQualTypeNames["CheckK"] = "D::aStruct";
  187. GlobalNsPrefix.ExpectedQualTypeNames["YZMPtr"] = "::A::B::X ::A::B::Y::Z::*";
  188. GlobalNsPrefix.runOver(
  189. "namespace A {\n"
  190. " namespace B {\n"
  191. " int IntVal;\n"
  192. " bool BoolVal;\n"
  193. " struct X {};\n"
  194. " X XVal;\n"
  195. " template <typename T> class CCC { };\n"
  196. " template <typename T>\n"
  197. " using Alias = CCC<T>;\n"
  198. " Alias<int> IntAliasVal;\n"
  199. " struct Y { struct Z { X YZIPtr; }; };\n"
  200. " Y::Z ZVal;\n"
  201. " X Y::Z::*YZMPtr;\n"
  202. " }\n"
  203. "}\n"
  204. "struct Z {};\n"
  205. "Z GlobalZVal;\n"
  206. "namespace {\n"
  207. " namespace D {\n"
  208. " namespace {\n"
  209. " class aStruct {};\n"
  210. " aStruct CheckK;\n"
  211. " }\n"
  212. " }\n"
  213. "}\n"
  214. );
  215. TypeNameVisitor AnonStrucs;
  216. AnonStrucs.ExpectedQualTypeNames["a"] = "short";
  217. AnonStrucs.ExpectedQualTypeNames["un_in_st_1"] =
  218. "union (anonymous struct at input.cc:1:1)::(anonymous union at "
  219. "input.cc:2:27)";
  220. AnonStrucs.ExpectedQualTypeNames["b"] = "short";
  221. AnonStrucs.ExpectedQualTypeNames["un_in_st_2"] =
  222. "union (anonymous struct at input.cc:1:1)::(anonymous union at "
  223. "input.cc:5:27)";
  224. AnonStrucs.ExpectedQualTypeNames["anon_st"] =
  225. "struct (anonymous struct at input.cc:1:1)";
  226. AnonStrucs.runOver(R"(struct {
  227. union {
  228. short a;
  229. } un_in_st_1;
  230. union {
  231. short b;
  232. } un_in_st_2;
  233. } anon_st;)");
  234. }
  235. } // end anonymous namespace