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