[clang-tools-extra] 5fb3f43 - Fully qualify template template parameters when printing
David Blaikie via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 2 15:05:11 PDT 2021
Author: David Blaikie
Date: 2021-09-02T15:04:34-07:00
New Revision: 5fb3f43778f85ebea48e880eef9493d188253890
URL: https://github.com/llvm/llvm-project/commit/5fb3f43778f85ebea48e880eef9493d188253890
DIFF: https://github.com/llvm/llvm-project/commit/5fb3f43778f85ebea48e880eef9493d188253890.diff
LOG: Fully qualify template template parameters when printing
I discovered this quirk when working on some DWARF - AST printing prints
type template parameters fully qualified, but printed template template
parameters the way they were written syntactically, or wholely
unqualified - instead, we should print them consistently with the way we
print type template parameters: fully qualified.
The one place this got weird was for partial specializations like in
ast-print-temp-class.cpp - hence the need for checking for
TemplateNameDependenceScope::DependentInstantiation template template
parameters. (not 100% sure that's the right solution to that, though -
open to ideas)
Differential Revision: https://reviews.llvm.org/D108794
Added:
Modified:
clang-tools-extra/clangd/DumpAST.cpp
clang/include/clang/AST/TemplateName.h
clang/lib/AST/NestedNameSpecifier.cpp
clang/lib/AST/TemplateBase.cpp
clang/lib/AST/TemplateName.cpp
clang/lib/CodeGen/CGDebugInfo.cpp
clang/test/CXX/drs/dr10xx.cpp
clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
clang/test/Index/print-type.cpp
clang/test/Misc/diag-template.cpp
clang/test/SemaTemplate/temp_arg_template.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/DumpAST.cpp b/clang-tools-extra/clangd/DumpAST.cpp
index 36d61aca70fa6..22bad6f915142 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -295,7 +295,7 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> {
}
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 010b813dc5253..2befb5c1b45e0 100644
--- a/clang/include/clang/AST/TemplateName.h
+++ b/clang/include/clang/AST/TemplateName.h
@@ -309,16 +309,17 @@ class TemplateName {
/// 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 21afdd1570f4b..8f19d80cbdc58 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<TemplateSpecializationType>(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 f44230d1bd03d..619ce42f9dd1d 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 22cfa9acbe1b2..c8bd74f0b5bb4 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<TemplateDecl *>())
- 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 0a20ce39135ac..69d054583e630 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 7f5fd8c7ec277..f629280c3d981 100644
--- a/clang/test/CXX/drs/dr10xx.cpp
+++ b/clang/test/CXX/drs/dr10xx.cpp
@@ -17,8 +17,8 @@ namespace dr1004 { // dr1004: 5
template<typename> struct B1 {};
template<template<typename> class> struct B2 {};
template<typename X> void f(); // expected-note {{[with X = dr1004::A<int>]}}
- template<template<typename> class X> void f(); // expected-note {{[with X = A]}}
- template<template<typename> class X> void g(); // expected-note {{[with X = A]}}
+ template<template<typename> class X> void f(); // expected-note {{[with X = dr1004::A]}}
+ template<template<typename> class X> void g(); // expected-note {{[with X = dr1004::A]}}
template<typename X> void g(); // expected-note {{[with X = dr1004::A<int>]}}
struct C : A<int> {
B1<A> 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 fccac8f1e5a4e..8f135b72546ff 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<template<typename...> class Container> void f(Container<int>); // expected-note {{deduced type 'X<[...], (default) int>' of 1st parameter does not match adjusted type 'X<[...], double>' of argument [with Container = X]}}
+ template<template<typename...> class Container> void f(Container<int>); // expected-note {{deduced type 'X<[...], (default) int>' of 1st parameter does not match adjusted type 'X<[...], double>' of argument [with Container = DeduceWithDefaultArgs::X]}}
template<typename, typename = int> 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 49e2c5f4c0fcd..18259e80ebac2 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<int, 1, Foo>] [typekind=Unexposed] [templateargs/3= [type=int] [typekind=Int]] [canonicaltype=outer::Baz<int, 1, Foo>] [canonicaltypekind=Record] [canonicaltemplateargs/3= [type=int] [typekind=Int]] [isPOD=1]
+// CHECK: FieldDecl=baz:28:20 (Definition) [type=Baz<int, 1, outer::Foo>] [typekind=Unexposed] [templateargs/3= [type=int] [typekind=Int]] [canonicaltype=outer::Baz<int, 1, outer::Foo>] [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 e207344c2e9fd..5299375f65650 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<allocator>()).g(); // expected-error {{no member named 'g' in 'default_args::Q<>'}}
f(Q<allocator, allocator>()).g(); // expected-error {{no member named 'g' in 'default_args::Q<>'}}
- f(Q<char_traits>()).g(); // expected-error {{no member named 'g' in 'default_args::Q<char_traits>'}}
- f(Q<char_traits, char_traits>()).g(); // expected-error {{no member named 'g' in 'default_args::Q<char_traits>'}}
- f(Q<char_traits, allocator>()).g(); // expected-error {{no member named 'g' in 'default_args::Q<char_traits, allocator>'}}
+ f(Q<char_traits>()).g(); // expected-error {{no member named 'g' in 'default_args::Q<default_args::char_traits>'}}
+ f(Q<char_traits, char_traits>()).g(); // expected-error {{no member named 'g' in 'default_args::Q<default_args::char_traits>'}}
+ f(Q<char_traits, allocator>()).g(); // expected-error {{no member named 'g' in 'default_args::Q<default_args::char_traits, default_args::allocator>'}}
}
}
diff --git a/clang/test/SemaTemplate/temp_arg_template.cpp b/clang/test/SemaTemplate/temp_arg_template.cpp
index 59deae701801e..37e1e52521263 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<int>')}}
}
- void f0( Y<int,1> y){ 1 << y; } // expected-note{{in instantiation of function template specialization 'N::operator<<<Y, int, 1>' requested here}}
+ void f0( Y<int,1> y){ 1 << y; } // expected-note{{in instantiation of function template specialization 'N::operator<<<N::Y, int, 1>' requested here}}
}
// PR12179
More information about the cfe-commits
mailing list