diff --git a/clang-tools-extra/clangd/DumpAST.cpp b/clang-tools-extra/clangd/DumpAST.cpp index 36d61aca70fa..22bad6f91514 100644 --- a/clang-tools-extra/clangd/DumpAST.cpp +++ b/clang-tools-extra/clangd/DumpAST.cpp @@ -295,7 +295,7 @@ class DumpVisitor : public RecursiveASTVisitor { } std::string getDetail(const TemplateName &TN) { return toString([&](raw_ostream &OS) { - TN.print(OS, Ctx.getPrintingPolicy(), /*SuppressNNS=*/true); + TN.print(OS, Ctx.getPrintingPolicy(), TemplateName::Qualified::None); }); } std::string getDetail(const Attr *A) { diff --git a/clang/include/clang/AST/TemplateName.h b/clang/include/clang/AST/TemplateName.h index 010b813dc525..2befb5c1b45e 100644 --- a/clang/include/clang/AST/TemplateName.h +++ b/clang/include/clang/AST/TemplateName.h @@ -309,16 +309,17 @@ public: /// unexpanded parameter pack (for C++0x variadic templates). bool containsUnexpandedParameterPack() const; + enum class Qualified { None, AsWritten, Fully }; /// Print the template name. /// /// \param OS the output stream to which the template name will be /// printed. /// - /// \param SuppressNNS if true, don't print the - /// nested-name-specifier that precedes the template name (if it has - /// one). + /// \param Qual print the (Qualified::None) simple name, + /// (Qualified::AsWritten) any written (possibly partial) qualifier, or + /// (Qualified::Fully) the fully qualified name. void print(raw_ostream &OS, const PrintingPolicy &Policy, - bool SuppressNNS = false) const; + Qualified Qual = Qualified::AsWritten) const; /// Debugging aid that dumps the template name. void dump(raw_ostream &OS) const; diff --git a/clang/lib/AST/NestedNameSpecifier.cpp b/clang/lib/AST/NestedNameSpecifier.cpp index 21afdd1570f4..8f19d80cbdc5 100644 --- a/clang/lib/AST/NestedNameSpecifier.cpp +++ b/clang/lib/AST/NestedNameSpecifier.cpp @@ -311,7 +311,8 @@ void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy, = dyn_cast(T)) { // Print the template name without its corresponding // nested-name-specifier. - SpecType->getTemplateName().print(OS, InnerPolicy, true); + SpecType->getTemplateName().print(OS, InnerPolicy, + TemplateName::Qualified::None); // Print the template argument list. printTemplateArgumentList(OS, SpecType->template_arguments(), diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index f44230d1bd03..619ce42f9dd1 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -452,7 +452,7 @@ void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out, break; case Template: - getAsTemplate().print(Out, Policy); + getAsTemplate().print(Out, Policy, TemplateName::Qualified::Fully); break; case TemplateExpansion: diff --git a/clang/lib/AST/TemplateName.cpp b/clang/lib/AST/TemplateName.cpp index 22cfa9acbe1b..c8bd74f0b5bb 100644 --- a/clang/lib/AST/TemplateName.cpp +++ b/clang/lib/AST/TemplateName.cpp @@ -220,19 +220,28 @@ bool TemplateName::containsUnexpandedParameterPack() const { return getDependence() & TemplateNameDependence::UnexpandedPack; } -void -TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy, - bool SuppressNNS) const { +void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy, + Qualified Qual) const { if (TemplateDecl *Template = Storage.dyn_cast()) - OS << *Template; + if (Qual == Qualified::Fully && + getDependence() != TemplateNameDependenceScope::DependentInstantiation) + Template->printQualifiedName(OS, Policy); + else + OS << *Template; else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) { - if (!SuppressNNS) + if (Qual == Qualified::Fully && + getDependence() != + TemplateNameDependenceScope::DependentInstantiation) { + QTN->getTemplateDecl()->printQualifiedName(OS, Policy); + return; + } + if (Qual == Qualified::AsWritten) QTN->getQualifier()->print(OS, Policy); if (QTN->hasTemplateKeyword()) OS << "template "; OS << *QTN->getDecl(); } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) { - if (!SuppressNNS && DTN->getQualifier()) + if (Qual == Qualified::AsWritten && DTN->getQualifier()) DTN->getQualifier()->print(OS, Policy); OS << "template "; @@ -242,7 +251,7 @@ TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy, OS << "operator " << getOperatorSpelling(DTN->getOperator()); } else if (SubstTemplateTemplateParmStorage *subst = getAsSubstTemplateTemplateParm()) { - subst->getReplacement().print(OS, Policy, SuppressNNS); + subst->getReplacement().print(OS, Policy, Qual); } else if (SubstTemplateTemplateParmPackStorage *SubstPack = getAsSubstTemplateTemplateParmPack()) OS << *SubstPack->getParameterPack(); diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 0a20ce39135a..69d054583e63 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1226,7 +1226,8 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty, SmallString<128> NS; llvm::raw_svector_ostream OS(NS); - Ty->getTemplateName().print(OS, getPrintingPolicy(), /*qualified*/ false); + Ty->getTemplateName().print(OS, getPrintingPolicy(), + TemplateName::Qualified::None); printTemplateArgumentList(OS, Ty->template_arguments(), getPrintingPolicy()); SourceLocation Loc = AliasDecl->getLocation(); diff --git a/clang/test/CXX/drs/dr10xx.cpp b/clang/test/CXX/drs/dr10xx.cpp index 7f5fd8c7ec27..f629280c3d98 100644 --- a/clang/test/CXX/drs/dr10xx.cpp +++ b/clang/test/CXX/drs/dr10xx.cpp @@ -17,8 +17,8 @@ namespace dr1004 { // dr1004: 5 template struct B1 {}; template class> struct B2 {}; template void f(); // expected-note {{[with X = dr1004::A]}} - template class X> void f(); // expected-note {{[with X = A]}} - template class X> void g(); // expected-note {{[with X = A]}} + template class X> void f(); // expected-note {{[with X = dr1004::A]}} + template class X> void g(); // expected-note {{[with X = dr1004::A]}} template void g(); // expected-note {{[with X = dr1004::A]}} struct C : A { B1 b1a; diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp index fccac8f1e5a4..8f135b72546f 100644 --- a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp @@ -93,7 +93,7 @@ namespace DeduceNonTypeTemplateArgsInArray { } namespace DeduceWithDefaultArgs { - template class Container> void f(Container); // expected-note {{deduced type 'X<[...], (default) int>' of 1st parameter does not match adjusted type 'X<[...], double>' of argument [with Container = X]}} + template class Container> void f(Container); // expected-note {{deduced type 'X<[...], (default) int>' of 1st parameter does not match adjusted type 'X<[...], double>' of argument [with Container = DeduceWithDefaultArgs::X]}} template struct X {}; void g() { // OK, use default argument for the second template parameter. diff --git a/clang/test/Index/print-type.cpp b/clang/test/Index/print-type.cpp index 49e2c5f4c0fc..18259e80ebac 100644 --- a/clang/test/Index/print-type.cpp +++ b/clang/test/Index/print-type.cpp @@ -132,7 +132,7 @@ inline namespace InlineNS {} // CHECK: TypedefDecl=OtherType:26:18 (Definition) [type=outer::inner::Bar::OtherType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1] // CHECK: TypedefDecl=ArrayType:27:15 (Definition) [type=outer::inner::Bar::ArrayType] [typekind=Typedef] [canonicaltype=int [5]] [canonicaltypekind=ConstantArray] [isPOD=1] // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1] -// CHECK: FieldDecl=baz:28:20 (Definition) [type=Baz] [typekind=Unexposed] [templateargs/3= [type=int] [typekind=Int]] [canonicaltype=outer::Baz] [canonicaltypekind=Record] [canonicaltemplateargs/3= [type=int] [typekind=Int]] [isPOD=1] +// CHECK: FieldDecl=baz:28:20 (Definition) [type=Baz] [typekind=Unexposed] [templateargs/3= [type=int] [typekind=Int]] [canonicaltype=outer::Baz] [canonicaltypekind=Record] [canonicaltemplateargs/3= [type=int] [typekind=Int]] [isPOD=1] // CHECK: TemplateRef=Baz:9:8 [type=] [typekind=Invalid] [isPOD=0] // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1] // CHECK: TemplateRef=Foo:4:8 [type=] [typekind=Invalid] [isPOD=0] diff --git a/clang/test/Misc/diag-template.cpp b/clang/test/Misc/diag-template.cpp index e207344c2e9f..5299375f6565 100644 --- a/clang/test/Misc/diag-template.cpp +++ b/clang/test/Misc/diag-template.cpp @@ -34,8 +34,8 @@ namespace default_args { f(Q<>()).g(); // expected-error {{no member named 'g' in 'default_args::Q<>'}} f(Q()).g(); // expected-error {{no member named 'g' in 'default_args::Q<>'}} f(Q()).g(); // expected-error {{no member named 'g' in 'default_args::Q<>'}} - f(Q()).g(); // expected-error {{no member named 'g' in 'default_args::Q'}} - f(Q()).g(); // expected-error {{no member named 'g' in 'default_args::Q'}} - f(Q()).g(); // expected-error {{no member named 'g' in 'default_args::Q'}} + f(Q()).g(); // expected-error {{no member named 'g' in 'default_args::Q'}} + f(Q()).g(); // expected-error {{no member named 'g' in 'default_args::Q'}} + f(Q()).g(); // expected-error {{no member named 'g' in 'default_args::Q'}} } } diff --git a/clang/test/SemaTemplate/temp_arg_template.cpp b/clang/test/SemaTemplate/temp_arg_template.cpp index 59deae701801..37e1e5252126 100644 --- a/clang/test/SemaTemplate/temp_arg_template.cpp +++ b/clang/test/SemaTemplate/temp_arg_template.cpp @@ -59,7 +59,7 @@ namespace N { 0 << a.const_ref(); // expected-error{{invalid operands to binary expression ('int' and 'X')}} } - void f0( Y y){ 1 << y; } // expected-note{{in instantiation of function template specialization 'N::operator<<' requested here}} + void f0( Y y){ 1 << y; } // expected-note{{in instantiation of function template specialization 'N::operator<<' requested here}} } // PR12179