sammccall created this revision.
sammccall added a reviewer: hokein.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous,
ilya-biryukov.
Herald added a project: clang.
This doesn't cover decls in diagnostics, which use
NamedDecl::getNameForDiagnostic().
(That should also be fixed later I think).
This covers some cases of https://github.com/clangd/clangd/issues/76
(hover, but not outline or sighelp)
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D70236
Files:
clang-tools-extra/clangd/unittests/FindTargetTests.cpp
clang-tools-extra/clangd/unittests/XRefsTests.cpp
clang/lib/AST/DeclPrinter.cpp
clang/test/Index/print-display-names.cpp
clang/unittests/AST/DeclPrinterTest.cpp
Index: clang/unittests/AST/DeclPrinterTest.cpp
===================================================================
--- clang/unittests/AST/DeclPrinterTest.cpp
+++ clang/unittests/AST/DeclPrinterTest.cpp
@@ -1067,8 +1067,7 @@
"template<typename T>"
"struct A<T *> { T a; };",
classTemplateSpecializationDecl().bind("id"),
- "template <typename T> struct A<type-parameter-0-0 *> {}"));
- // WRONG; Should be: "template<typename T> struct A<T *> { ... }"
+ "template <typename T> struct A<T *> {}"));
}
TEST(DeclPrinter, TestClassTemplateSpecializationDecl1) {
Index: clang/test/Index/print-display-names.cpp
===================================================================
--- clang/test/Index/print-display-names.cpp
+++ clang/test/Index/print-display-names.cpp
@@ -22,7 +22,7 @@
// RUN: env CINDEXTEST_PRINTINGPOLICY_TERSEOUTPUT=1 c-index-test -test-load-source all-pretty %s | FileCheck %s --check-prefix=PRETTY
// PRETTY: print-display-names.cpp:2:7: ClassTemplate=template <typename T, typename> class ClassTmpl {}:2:7 (Definition) Extent=[1:1 - 2:20]
// PRETTY: print-display-names.cpp:4:13: TypedefDecl=typedef int Integer:4:13 (Definition) Extent=[4:1 - 4:20]
-// PRETTY: print-display-names.cpp:6:16: ClassDecl=template<> class ClassTmpl<int, int> {}:6:16 (Definition) [Specialization of ClassTmpl:2:7] Extent=[6:1 - 6:43]
+// PRETTY: print-display-names.cpp:6:16: ClassDecl=template<> class ClassTmpl<Integer, Integer> {}:6:16 (Definition) [Specialization of ClassTmpl:2:7] Extent=[6:1 - 6:43]
// PRETTY: print-display-names.cpp:8:6: FunctionDecl=void f(ClassTmpl<float, Integer> p):8:6 Extent=[8:1 - 8:36]
// PRETTY: print-display-names.cpp:8:34: ParmDecl=ClassTmpl<float, Integer> p:8:34 (Definition) Extent=[8:8 - 8:35]
// PRETTY: print-display-names.cpp:11:6: FunctionTemplate=template <typename T> void g(ClassTmpl<T, T>):11:6 Extent=[10:1 - 11:24]
Index: clang/lib/AST/DeclPrinter.cpp
===================================================================
--- clang/lib/AST/DeclPrinter.cpp
+++ clang/lib/AST/DeclPrinter.cpp
@@ -108,8 +108,8 @@
void printTemplateParameters(const TemplateParameterList *Params,
bool OmitTemplateKW = false);
- void printTemplateArguments(const TemplateArgumentList &Args,
- const TemplateParameterList *Params = nullptr);
+ void printTemplateArguments(llvm::ArrayRef<TemplateArgument> Args);
+ void printTemplateArguments(llvm::ArrayRef<TemplateArgumentLoc> Args);
void prettyPrintAttributes(Decl *D);
void prettyPrintPragmas(Decl *D);
void printDeclType(QualType T, StringRef DeclName, bool Pack = false);
@@ -636,10 +636,14 @@
if (GuideDecl)
Proto = GuideDecl->getDeducedTemplate()->getDeclName().getAsString();
- if (const TemplateArgumentList *TArgs = D->getTemplateSpecializationArgs()) {
+ if (D->isFunctionTemplateSpecialization()) {
llvm::raw_string_ostream POut(Proto);
DeclPrinter TArgPrinter(POut, SubPolicy, Context, Indentation);
- TArgPrinter.printTemplateArguments(*TArgs);
+ if (const auto *TArgInfo = D->getTemplateSpecializationArgsAsWritten())
+ TArgPrinter.printTemplateArguments(TArgInfo->arguments());
+ else if (const TemplateArgumentList *TArgs =
+ D->getTemplateSpecializationArgs())
+ TArgPrinter.printTemplateArguments(TArgs->asArray());
}
QualType Ty = D->getType();
@@ -957,10 +961,15 @@
if (D->getIdentifier()) {
Out << ' ' << *D;
- if (auto S = dyn_cast<ClassTemplatePartialSpecializationDecl>(D))
- printTemplateArguments(S->getTemplateArgs(), S->getTemplateParameters());
- else if (auto S = dyn_cast<ClassTemplateSpecializationDecl>(D))
- printTemplateArguments(S->getTemplateArgs());
+ if (auto S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+ ArrayRef<TemplateArgument> Args = S->getTemplateArgs().asArray();
+ if (!Policy.PrintCanonicalTypes)
+ if (const auto* TSI = S->getTypeAsWritten())
+ if (const auto *TST =
+ dyn_cast<TemplateSpecializationType>(TSI->getType()))
+ Args = TST->template_arguments();
+ printTemplateArguments(Args);
+ }
}
if (D->isCompleteDefinition()) {
@@ -1083,44 +1092,28 @@
Out << ' ';
}
-void DeclPrinter::printTemplateArguments(const TemplateArgumentList &Args,
- const TemplateParameterList *Params) {
+void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgument> Args) {
Out << "<";
for (size_t I = 0, E = Args.size(); I < E; ++I) {
const TemplateArgument &A = Args[I];
if (I)
Out << ", ";
- if (Params) {
- if (A.getKind() == TemplateArgument::Type)
- if (auto T = A.getAsType()->getAs<TemplateTypeParmType>()) {
- auto P = cast<TemplateTypeParmDecl>(Params->getParam(T->getIndex()));
- Out << *P;
- continue;
- }
- if (A.getKind() == TemplateArgument::Template) {
- if (auto T = A.getAsTemplate().getAsTemplateDecl())
- if (auto TD = dyn_cast<TemplateTemplateParmDecl>(T)) {
- auto P = cast<TemplateTemplateParmDecl>(
- Params->getParam(TD->getIndex()));
- Out << *P;
- continue;
- }
- }
- if (A.getKind() == TemplateArgument::Expression) {
- if (auto E = dyn_cast<DeclRefExpr>(A.getAsExpr()))
- if (auto N = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) {
- auto P = cast<NonTypeTemplateParmDecl>(
- Params->getParam(N->getIndex()));
- Out << *P;
- continue;
- }
- }
- }
A.print(Policy, Out);
}
Out << ">";
}
+void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgumentLoc> Args) {
+ Out << "<";
+ for (size_t I = 0, E = Args.size(); I < E; ++I) {
+ const TemplateArgumentLoc &A = Args[I];
+ if (I)
+ Out << ", ";
+ A.getArgument().print(Policy, Out);
+ }
+ Out << ">";
+}
+
void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
printTemplateParameters(D->getTemplateParameters());
Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -897,6 +897,17 @@
HI.Definition = "int test";
HI.Type = "int";
}},
+ // Partially-specialized class decl. (formerly type-parameter-0-0)
+ {R"cpp(
+ template <typename T> class X;
+ template <typename T> class [[^X]]<T*> {};
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.Name = "X<T *>";
+ HI.NamespaceScope = "";
+ HI.Kind = SymbolKind::Class;
+ HI.Definition = "template <typename T> class X<T *> {}";
+ }},
// auto on lambda
{R"cpp(
Index: clang-tools-extra/clangd/unittests/FindTargetTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -288,8 +288,7 @@
)cpp";
EXPECT_DECLS("TemplateSpecializationTypeLoc",
{"template<> class Foo<int *>", Rel::TemplateInstantiation},
- {"template <typename T> class Foo<type-parameter-0-0 *>",
- Rel::TemplatePattern});
+ {"template <typename T> class Foo<T *>", Rel::TemplatePattern});
}
TEST_F(TargetDeclTest, FunctionTemplate) {
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits