123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- //===- unittest/Tooling/QualTypeNameTest.cpp ------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "clang/AST/QualTypeNames.h"
- #include "TestVisitor.h"
- using namespace clang;
- namespace {
- struct TypeNameVisitor : TestVisitor<TypeNameVisitor> {
- llvm::StringMap<std::string> ExpectedQualTypeNames;
- bool WithGlobalNsPrefix = false;
- // ValueDecls are the least-derived decl with both a qualtype and a
- // name.
- bool traverseDecl(Decl *D) {
- return true; // Always continue
- }
- bool VisitValueDecl(const ValueDecl *VD) {
- std::string ExpectedName =
- ExpectedQualTypeNames.lookup(VD->getNameAsString());
- if (ExpectedName != "") {
- PrintingPolicy Policy(Context->getPrintingPolicy());
- Policy.SuppressScope = false;
- Policy.AnonymousTagLocations = true;
- Policy.PolishForDeclaration = true;
- Policy.SuppressUnwrittenScope = true;
- std::string ActualName = TypeName::getFullyQualifiedName(
- VD->getType(), *Context, Policy, WithGlobalNsPrefix);
- if (ExpectedName != ActualName) {
- // A custom message makes it much easier to see what declaration
- // failed compared to EXPECT_EQ.
- EXPECT_TRUE(false) << "Typename::getFullyQualifiedName failed for "
- << VD->getQualifiedNameAsString() << std::endl
- << " Actual: " << ActualName << std::endl
- << " Exepcted: " << ExpectedName;
- }
- }
- return true;
- }
- };
- // named namespaces inside anonymous namespaces
- TEST(QualTypeNameTest, getFullyQualifiedName) {
- TypeNameVisitor Visitor;
- // Simple case to test the test framework itself.
- Visitor.ExpectedQualTypeNames["CheckInt"] = "int";
- // Keeping the names of the variables whose types we check unique
- // within the entire test--regardless of their own scope--makes it
- // easier to diagnose test failures.
- // Simple namespace qualifier
- Visitor.ExpectedQualTypeNames["CheckA"] = "A::B::Class0";
- // Lookup up the enclosing scopes, then down another one. (These
- // appear as elaborated type in the AST. In that case--even if
- // policy.SuppressScope = 0--qual_type.getAsString(policy) only
- // gives the name as it appears in the source, not the full name.
- Visitor.ExpectedQualTypeNames["CheckB"] = "A::B::C::Class1";
- // Template parameter expansion.
- Visitor.ExpectedQualTypeNames["CheckC"] =
- "A::B::Template0<A::B::C::MyInt, A::B::AnotherClass>";
- // Recursive template parameter expansion.
- Visitor.ExpectedQualTypeNames["CheckD"] =
- "A::B::Template0<A::B::Template1<A::B::C::MyInt, A::B::AnotherClass>, "
- "A::B::Template0<int, long> >";
- // Variadic Template expansion.
- Visitor.ExpectedQualTypeNames["CheckE"] =
- "A::Variadic<int, A::B::Template0<int, char>, "
- "A::B::Template1<int, long>, A::B::C::MyInt>";
- // Using declarations should be fully expanded.
- Visitor.ExpectedQualTypeNames["CheckF"] = "A::B::Class0";
- // Elements found within "using namespace foo;" should be fully
- // expanded.
- Visitor.ExpectedQualTypeNames["CheckG"] = "A::B::C::MyInt";
- // Type inside function
- Visitor.ExpectedQualTypeNames["CheckH"] = "struct X";
- // Anonymous Namespaces
- Visitor.ExpectedQualTypeNames["CheckI"] = "aClass";
- // Keyword inclusion with namespaces
- Visitor.ExpectedQualTypeNames["CheckJ"] = "struct A::aStruct";
- // Anonymous Namespaces nested in named namespaces and vice-versa.
- Visitor.ExpectedQualTypeNames["CheckK"] = "D::aStruct";
- // Namespace alias
- Visitor.ExpectedQualTypeNames["CheckL"] = "A::B::C::MyInt";
- Visitor.ExpectedQualTypeNames["non_dependent_type_var"] =
- "Foo<X>::non_dependent_type";
- Visitor.ExpectedQualTypeNames["AnEnumVar"] = "EnumScopeClass::AnEnum";
- Visitor.ExpectedQualTypeNames["AliasTypeVal"] = "A::B::C::InnerAlias<int>";
- Visitor.ExpectedQualTypeNames["CheckM"] = "const A::B::Class0 *";
- Visitor.ExpectedQualTypeNames["CheckN"] = "const X *";
- Visitor.runOver(
- "int CheckInt;\n"
- "template <typename T>\n"
- "class OuterTemplateClass { };\n"
- "namespace A {\n"
- " namespace B {\n"
- " class Class0 { };\n"
- " namespace C {\n"
- " typedef int MyInt;"
- " template <typename T>\n"
- " using InnerAlias = OuterTemplateClass<T>;\n"
- " InnerAlias<int> AliasTypeVal;\n"
- " }\n"
- " template<class X, class Y> class Template0;"
- " template<class X, class Y> class Template1;"
- " typedef B::Class0 AnotherClass;\n"
- " void Function1(Template0<C::MyInt,\n"
- " AnotherClass> CheckC);\n"
- " void Function2(Template0<Template1<C::MyInt, AnotherClass>,\n"
- " Template0<int, long> > CheckD);\n"
- " void Function3(const B::Class0* CheckM);\n"
- " }\n"
- "template<typename... Values> class Variadic {};\n"
- "Variadic<int, B::Template0<int, char>, "
- " B::Template1<int, long>, "
- " B::C::MyInt > CheckE;\n"
- " namespace BC = B::C;\n"
- " BC::MyInt CheckL;\n"
- "}\n"
- "using A::B::Class0;\n"
- "void Function(Class0 CheckF);\n"
- "using namespace A::B::C;\n"
- "void Function(MyInt CheckG);\n"
- "void f() {\n"
- " struct X {} CheckH;\n"
- "}\n"
- "struct X;\n"
- "void f(const ::X* CheckN) {}\n"
- "namespace {\n"
- " class aClass {};\n"
- " aClass CheckI;\n"
- "}\n"
- "namespace A {\n"
- " struct aStruct {} CheckJ;\n"
- "}\n"
- "namespace {\n"
- " namespace D {\n"
- " namespace {\n"
- " class aStruct {};\n"
- " aStruct CheckK;\n"
- " }\n"
- " }\n"
- "}\n"
- "template<class T> struct Foo {\n"
- " typedef typename T::A dependent_type;\n"
- " typedef int non_dependent_type;\n"
- " dependent_type dependent_type_var;\n"
- " non_dependent_type non_dependent_type_var;\n"
- "};\n"
- "struct X { typedef int A; };"
- "Foo<X> var;"
- "void F() {\n"
- " var.dependent_type_var = 0;\n"
- "var.non_dependent_type_var = 0;\n"
- "}\n"
- "class EnumScopeClass {\n"
- "public:\n"
- " enum AnEnum { ZERO, ONE };\n"
- "};\n"
- "EnumScopeClass::AnEnum AnEnumVar;\n",
- TypeNameVisitor::Lang_CXX11
- );
- TypeNameVisitor Complex;
- Complex.ExpectedQualTypeNames["CheckTX"] = "B::TX";
- Complex.runOver(
- "namespace A {"
- " struct X {};"
- "}"
- "using A::X;"
- "namespace fake_std {"
- " template<class... Types > class tuple {};"
- "}"
- "namespace B {"
- " using fake_std::tuple;"
- " typedef tuple<X> TX;"
- " TX CheckTX;"
- " struct A { typedef int X; };"
- "}");
- TypeNameVisitor GlobalNsPrefix;
- GlobalNsPrefix.WithGlobalNsPrefix = true;
- GlobalNsPrefix.ExpectedQualTypeNames["IntVal"] = "int";
- GlobalNsPrefix.ExpectedQualTypeNames["BoolVal"] = "bool";
- GlobalNsPrefix.ExpectedQualTypeNames["XVal"] = "::A::B::X";
- GlobalNsPrefix.ExpectedQualTypeNames["IntAliasVal"] = "::A::B::Alias<int>";
- GlobalNsPrefix.ExpectedQualTypeNames["ZVal"] = "::A::B::Y::Z";
- GlobalNsPrefix.ExpectedQualTypeNames["GlobalZVal"] = "::Z";
- GlobalNsPrefix.ExpectedQualTypeNames["CheckK"] = "D::aStruct";
- GlobalNsPrefix.ExpectedQualTypeNames["YZMPtr"] = "::A::B::X ::A::B::Y::Z::*";
- GlobalNsPrefix.runOver(
- "namespace A {\n"
- " namespace B {\n"
- " int IntVal;\n"
- " bool BoolVal;\n"
- " struct X {};\n"
- " X XVal;\n"
- " template <typename T> class CCC { };\n"
- " template <typename T>\n"
- " using Alias = CCC<T>;\n"
- " Alias<int> IntAliasVal;\n"
- " struct Y { struct Z { X YZIPtr; }; };\n"
- " Y::Z ZVal;\n"
- " X Y::Z::*YZMPtr;\n"
- " }\n"
- "}\n"
- "struct Z {};\n"
- "Z GlobalZVal;\n"
- "namespace {\n"
- " namespace D {\n"
- " namespace {\n"
- " class aStruct {};\n"
- " aStruct CheckK;\n"
- " }\n"
- " }\n"
- "}\n"
- );
- TypeNameVisitor AnonStrucs;
- AnonStrucs.ExpectedQualTypeNames["a"] = "short";
- AnonStrucs.ExpectedQualTypeNames["un_in_st_1"] =
- "union (anonymous struct at input.cc:1:1)::(anonymous union at "
- "input.cc:2:27)";
- AnonStrucs.ExpectedQualTypeNames["b"] = "short";
- AnonStrucs.ExpectedQualTypeNames["un_in_st_2"] =
- "union (anonymous struct at input.cc:1:1)::(anonymous union at "
- "input.cc:5:27)";
- AnonStrucs.ExpectedQualTypeNames["anon_st"] =
- "struct (anonymous struct at input.cc:1:1)";
- AnonStrucs.runOver(R"(struct {
- union {
- short a;
- } un_in_st_1;
- union {
- short b;
- } un_in_st_2;
- } anon_st;)");
- }
- } // end anonymous namespace
|