Index: include/clang/AST/PrettyPrinter.h =================================================================== --- include/clang/AST/PrettyPrinter.h +++ include/clang/AST/PrettyPrinter.h @@ -52,7 +52,7 @@ Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true), MSVCFormatting(false), ConstantsAsWritten(false), SuppressImplicitBase(false), - FullyQualifiedName(false) { } + FullyQualifiedName(false), SuppressTemplateArgs(false) { } /// Adjust this printing policy for cases where it's known that we're /// printing C++ code (for instance, if AST dumping reaches a C++-only @@ -225,6 +225,9 @@ /// When true, print the fully qualified name of function declarations. /// This is the opposite of SuppressScope and thus overrules it. bool FullyQualifiedName : 1; + + /// When true, suppresses printing template arguments + bool SuppressTemplateArgs : 1; }; } // end namespace clang Index: lib/AST/TypePrinter.cpp =================================================================== --- lib/AST/TypePrinter.cpp +++ lib/AST/TypePrinter.cpp @@ -1538,6 +1538,9 @@ template static void printTo(raw_ostream &OS, ArrayRef Args, const PrintingPolicy &Policy, bool SkipBrackets) { + if (Policy.SuppressTemplateArgs) + return; + const char *Comma = Policy.MSVCFormatting ? "," : ", "; if (!SkipBrackets) OS << '<'; Index: unittests/AST/NamedDeclPrinterTest.cpp =================================================================== --- unittests/AST/NamedDeclPrinterTest.cpp +++ unittests/AST/NamedDeclPrinterTest.cpp @@ -28,14 +28,19 @@ namespace { +using PrintingPolicyModifier = void (*)(PrintingPolicy &policy); + class PrintMatch : public MatchFinder::MatchCallback { SmallString<1024> Printed; unsigned NumFoundDecls; bool SuppressUnwrittenScope; + PrintingPolicyModifier PolicyModifier; public: - explicit PrintMatch(bool suppressUnwrittenScope) - : NumFoundDecls(0), SuppressUnwrittenScope(suppressUnwrittenScope) {} + explicit PrintMatch(bool suppressUnwrittenScope, + PrintingPolicyModifier PolicyModifier) + : NumFoundDecls(0), SuppressUnwrittenScope(suppressUnwrittenScope), + PolicyModifier(PolicyModifier) {} void run(const MatchFinder::MatchResult &Result) override { const NamedDecl *ND = Result.Nodes.getNodeAs("id"); @@ -48,6 +53,8 @@ llvm::raw_svector_ostream Out(Printed); PrintingPolicy Policy = Result.Context->getPrintingPolicy(); Policy.SuppressUnwrittenScope = SuppressUnwrittenScope; + if (PolicyModifier) + PolicyModifier(Policy); ND->printQualifiedName(Out, Policy); } @@ -64,8 +71,9 @@ PrintedNamedDeclMatches(StringRef Code, const std::vector &Args, bool SuppressUnwrittenScope, const DeclarationMatcher &NodeMatch, - StringRef ExpectedPrinted, StringRef FileName) { - PrintMatch Printer(SuppressUnwrittenScope); + StringRef ExpectedPrinted, StringRef FileName, + PrintingPolicyModifier PolicyModifier) { + PrintMatch Printer(SuppressUnwrittenScope, PolicyModifier); MatchFinder Finder; Finder.addMatcher(NodeMatch, &Printer); std::unique_ptr Factory = @@ -94,26 +102,30 @@ ::testing::AssertionResult PrintedNamedDeclCXX98Matches(StringRef Code, StringRef DeclName, - StringRef ExpectedPrinted) { + StringRef ExpectedPrinted, + PrintingPolicyModifier PolicyModifier = nullptr) { std::vector Args(1, "-std=c++98"); return PrintedNamedDeclMatches(Code, Args, /*SuppressUnwrittenScope*/ false, namedDecl(hasName(DeclName)).bind("id"), ExpectedPrinted, - "input.cc"); + "input.cc", + PolicyModifier); } ::testing::AssertionResult -PrintedWrittenNamedDeclCXX11Matches(StringRef Code, StringRef DeclName, - StringRef ExpectedPrinted) { +PrintedWrittenNamedDeclCXX11Matches( + StringRef Code, StringRef DeclName, StringRef ExpectedPrinted, + PrintingPolicyModifier PolicyModifier = nullptr) { std::vector Args(1, "-std=c++11"); return PrintedNamedDeclMatches(Code, Args, /*SuppressUnwrittenScope*/ true, namedDecl(hasName(DeclName)).bind("id"), ExpectedPrinted, - "input.cc"); + "input.cc", + PolicyModifier); } } // unnamed namespace @@ -180,3 +192,20 @@ "A", "X::A")); } + +TEST(NamedDeclPrinter, TestClassTemplateMemberFunction) { + ASSERT_TRUE(PrintedNamedDeclCXX98Matches( + "template struct X { void A(); };" + "void Y() { X x; x.A(); }", + "::X::A", + "X::A")); +} + +TEST(NamedDeclPrinter, TestClassTemplateMemberFunction_SuppressTemplateArgs) { + ASSERT_TRUE(PrintedNamedDeclCXX98Matches( + "template struct X { void A(); };" + "void Y() { X x; x.A(); }", + "::X::A", + "X::A", + [](PrintingPolicy &Policy){ Policy.SuppressTemplateArgs = true; })); +}