diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -215,8 +215,7 @@ template int x = [[T::]]y; )cpp"; - // FIXME: We don't do a good job printing TemplateTypeParmDecls, apparently! - EXPECT_DECLS("NestedNameSpecifierLoc", ""); + EXPECT_DECLS("NestedNameSpecifierLoc", "typename T"); Code = R"cpp( namespace a { int x; } @@ -256,8 +255,7 @@ template void foo() { [[T]] x; } )cpp"; - // FIXME: We don't do a good job printing TemplateTypeParmDecls, apparently! - EXPECT_DECLS("TemplateTypeParmTypeLoc", ""); + EXPECT_DECLS("TemplateTypeParmTypeLoc", "class T"); Flags.clear(); // FIXME: Auto-completion in a template requires disabling delayed template @@ -290,8 +288,7 @@ static const int size = sizeof...([[E]]); }; )cpp"; - // FIXME: We don't do a good job printing TemplateTypeParmDecls, apparently! - EXPECT_DECLS("SizeOfPackExpr", ""); + EXPECT_DECLS("SizeOfPackExpr", "typename ...E"); Code = R"cpp( template diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -105,6 +105,8 @@ void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D); void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D); void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D); + void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *TTP); + void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *NTTP); void printTemplateParameters(const TemplateParameterList *Params, bool OmitTemplateKW = false); @@ -1051,37 +1053,10 @@ else NeedComma = true; - if (auto TTP = dyn_cast(Param)) { - - if (const TypeConstraint *TC = TTP->getTypeConstraint()) - TC->print(Out, Policy); - else if (TTP->wasDeclaredWithTypename()) - Out << "typename"; - else - Out << "class"; - - if (TTP->isParameterPack()) - Out << " ..."; - else if (!TTP->getName().empty()) - Out << ' '; - - Out << *TTP; - - if (TTP->hasDefaultArgument()) { - Out << " = "; - Out << TTP->getDefaultArgument().getAsString(Policy); - }; + if (const auto *TTP = dyn_cast(Param)) { + VisitTemplateTypeParmDecl(TTP); } else if (auto NTTP = dyn_cast(Param)) { - StringRef Name; - if (IdentifierInfo *II = NTTP->getIdentifier()) - Name = II->getName(); - printDeclType(NTTP->getType(), Name, NTTP->isParameterPack()); - - if (NTTP->hasDefaultArgument()) { - Out << " = "; - NTTP->getDefaultArgument()->printPretty(Out, nullptr, Policy, - Indentation); - } + VisitNonTypeTemplateParmDecl(NTTP); } else if (auto TTPD = dyn_cast(Param)) { VisitTemplateDecl(TTPD); // FIXME: print the default argument, if present. @@ -1705,3 +1680,36 @@ D->getInit()->printPretty(Out, nullptr, Policy, Indentation); } +void DeclPrinter::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *TTP) { + if (const TypeConstraint *TC = TTP->getTypeConstraint()) + TC->print(Out, Policy); + else if (TTP->wasDeclaredWithTypename()) + Out << "typename"; + else + Out << "class"; + + if (TTP->isParameterPack()) + Out << " ..."; + else if (!TTP->getName().empty()) + Out << ' '; + + Out << *TTP; + + if (TTP->hasDefaultArgument()) { + Out << " = "; + Out << TTP->getDefaultArgument().getAsString(Policy); + } +} + +void DeclPrinter::VisitNonTypeTemplateParmDecl( + const NonTypeTemplateParmDecl *NTTP) { + StringRef Name; + if (IdentifierInfo *II = NTTP->getIdentifier()) + Name = II->getName(); + printDeclType(NTTP->getType(), Name, NTTP->isParameterPack()); + + if (NTTP->hasDefaultArgument()) { + Out << " = "; + NTTP->getDefaultArgument()->printPretty(Out, nullptr, Policy, Indentation); + } +} diff --git a/clang/unittests/AST/DeclPrinterTest.cpp b/clang/unittests/AST/DeclPrinterTest.cpp --- a/clang/unittests/AST/DeclPrinterTest.cpp +++ b/clang/unittests/AST/DeclPrinterTest.cpp @@ -22,6 +22,7 @@ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Tooling/Tooling.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" #include "gtest/gtest.h" using namespace clang; @@ -1273,6 +1274,15 @@ // Should be: with semicolon } +TEST(DeclPrinter, TestTemplateArgumentList16) { + llvm::StringLiteral Code = "template struct Z {};"; + ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "T1", "typename T1")); + ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "T2", "typename T2 = bool")); + ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "NT1", "int NT1")); + ASSERT_TRUE(PrintedDeclCXX11Matches(Code, "NT2", "int NT2 = 5")); +} + TEST(DeclPrinter, TestStaticAssert1) { ASSERT_TRUE(PrintedDeclCXX1ZMatches( "static_assert(true);",