Skip to content

Commit

Permalink
[clang][DeclPrinter] Implement visitors for {TemplateType,NonTypeTemp…
Browse files Browse the repository at this point in the history
…late}Parms

Reviewers: sammccall, hokein

Subscribers: kristof.beyls, jkorous, arphaman, usaxena95, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D73693
  • Loading branch information
kadircet committed Feb 14, 2020
1 parent a57ad00 commit c45fb35
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 36 deletions.
9 changes: 3 additions & 6 deletions clang-tools-extra/clangd/unittests/FindTargetTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,7 @@ TEST_F(TargetDeclTest, NestedNameSpecifier) {
template <typename T>
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; }
Expand Down Expand Up @@ -256,8 +255,7 @@ TEST_F(TargetDeclTest, Types) {
template<class T>
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
Expand Down Expand Up @@ -290,8 +288,7 @@ TEST_F(TargetDeclTest, Types) {
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 <typename T>
Expand Down
68 changes: 38 additions & 30 deletions clang/lib/AST/DeclPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ namespace {
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);
Expand Down Expand Up @@ -1051,37 +1053,10 @@ void DeclPrinter::printTemplateParameters(const TemplateParameterList *Params,
else
NeedComma = true;

if (auto TTP = dyn_cast<TemplateTypeParmDecl>(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<TemplateTypeParmDecl>(Param)) {
VisitTemplateTypeParmDecl(TTP);
} else if (auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(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<TemplateTemplateParmDecl>(Param)) {
VisitTemplateDecl(TTPD);
// FIXME: print the default argument, if present.
Expand Down Expand Up @@ -1705,3 +1680,36 @@ void DeclPrinter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
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);
}
}
10 changes: 10 additions & 0 deletions clang/unittests/AST/DeclPrinterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1273,6 +1274,15 @@ TEST(DeclPrinter, TestTemplateArgumentList15) {
// Should be: with semicolon
}

TEST(DeclPrinter, TestTemplateArgumentList16) {
llvm::StringLiteral Code = "template<typename T1, int NT1, typename T2 = "
"bool, int NT2 = 5> 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);",
Expand Down

0 comments on commit c45fb35

Please sign in to comment.