forked from OSchip/llvm-project
Re-land r372863: [AST] Extract Decl::printNestedNameSpecifier helper from Decl::printQualifiedName
Reverted in r372880 due to the test failure. Also contains a fix that adjusts printQualifiedName to return the same results as before in case of anonymous function locals and parameters. llvm-svn: 372889
This commit is contained in:
parent
007e4fe901
commit
6648223faf
|
@ -310,6 +310,14 @@ public:
|
|||
void printQualifiedName(raw_ostream &OS) const;
|
||||
void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;
|
||||
|
||||
/// Print only the nested name specifier part of a fully-qualified name,
|
||||
/// including the '::' at the end. E.g.
|
||||
/// when `printQualifiedName(D)` prints "A::B::i",
|
||||
/// this function prints "A::B::".
|
||||
void printNestedNameSpecifier(raw_ostream &OS) const;
|
||||
void printNestedNameSpecifier(raw_ostream &OS,
|
||||
const PrintingPolicy &Policy) const;
|
||||
|
||||
// FIXME: Remove string version.
|
||||
std::string getQualifiedNameAsString() const;
|
||||
|
||||
|
|
|
@ -1558,6 +1558,24 @@ void NamedDecl::printQualifiedName(raw_ostream &OS) const {
|
|||
|
||||
void NamedDecl::printQualifiedName(raw_ostream &OS,
|
||||
const PrintingPolicy &P) const {
|
||||
if (getDeclContext()->isFunctionOrMethod()) {
|
||||
// We do not print '(anonymous)' for function parameters without name.
|
||||
printName(OS);
|
||||
return;
|
||||
}
|
||||
printNestedNameSpecifier(OS, P);
|
||||
if (getDeclName() || isa<DecompositionDecl>(this))
|
||||
OS << *this;
|
||||
else
|
||||
OS << "(anonymous)";
|
||||
}
|
||||
|
||||
void NamedDecl::printNestedNameSpecifier(raw_ostream &OS) const {
|
||||
printNestedNameSpecifier(OS, getASTContext().getPrintingPolicy());
|
||||
}
|
||||
|
||||
void NamedDecl::printNestedNameSpecifier(raw_ostream &OS,
|
||||
const PrintingPolicy &P) const {
|
||||
const DeclContext *Ctx = getDeclContext();
|
||||
|
||||
// For ObjC methods and properties, look through categories and use the
|
||||
|
@ -1571,10 +1589,8 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
|
|||
Ctx = ID;
|
||||
}
|
||||
|
||||
if (Ctx->isFunctionOrMethod()) {
|
||||
printName(OS);
|
||||
if (Ctx->isFunctionOrMethod())
|
||||
return;
|
||||
}
|
||||
|
||||
using ContextsTy = SmallVector<const DeclContext *, 8>;
|
||||
ContextsTy Contexts;
|
||||
|
@ -1644,11 +1660,6 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
|
|||
}
|
||||
OS << "::";
|
||||
}
|
||||
|
||||
if (getDeclName() || isa<DecompositionDecl>(this))
|
||||
OS << *this;
|
||||
else
|
||||
OS << "(anonymous)";
|
||||
}
|
||||
|
||||
void NamedDecl::getNameForDiagnostic(raw_ostream &OS,
|
||||
|
|
|
@ -16,9 +16,12 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/PrettyPrinter.h"
|
||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||
#include "clang/Tooling/Tooling.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace clang;
|
||||
|
@ -30,11 +33,12 @@ namespace {
|
|||
class PrintMatch : public MatchFinder::MatchCallback {
|
||||
SmallString<1024> Printed;
|
||||
unsigned NumFoundDecls;
|
||||
bool SuppressUnwrittenScope;
|
||||
std::function<void(llvm::raw_ostream &OS, const NamedDecl *)> Printer;
|
||||
|
||||
public:
|
||||
explicit PrintMatch(bool suppressUnwrittenScope)
|
||||
: NumFoundDecls(0), SuppressUnwrittenScope(suppressUnwrittenScope) {}
|
||||
explicit PrintMatch(
|
||||
std::function<void(llvm::raw_ostream &OS, const NamedDecl *)> Printer)
|
||||
: NumFoundDecls(0), Printer(std::move(Printer)) {}
|
||||
|
||||
void run(const MatchFinder::MatchResult &Result) override {
|
||||
const NamedDecl *ND = Result.Nodes.getNodeAs<NamedDecl>("id");
|
||||
|
@ -45,9 +49,7 @@ public:
|
|||
return;
|
||||
|
||||
llvm::raw_svector_ostream Out(Printed);
|
||||
PrintingPolicy Policy = Result.Context->getPrintingPolicy();
|
||||
Policy.SuppressUnwrittenScope = SuppressUnwrittenScope;
|
||||
ND->printQualifiedName(Out, Policy);
|
||||
Printer(Out, ND);
|
||||
}
|
||||
|
||||
StringRef getPrinted() const {
|
||||
|
@ -59,12 +61,12 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
::testing::AssertionResult
|
||||
PrintedNamedDeclMatches(StringRef Code, const std::vector<std::string> &Args,
|
||||
bool SuppressUnwrittenScope,
|
||||
const DeclarationMatcher &NodeMatch,
|
||||
StringRef ExpectedPrinted, StringRef FileName) {
|
||||
PrintMatch Printer(SuppressUnwrittenScope);
|
||||
::testing::AssertionResult PrintedDeclMatches(
|
||||
StringRef Code, const std::vector<std::string> &Args,
|
||||
const DeclarationMatcher &NodeMatch, StringRef ExpectedPrinted,
|
||||
StringRef FileName,
|
||||
std::function<void(llvm::raw_ostream &, const NamedDecl *)> Print) {
|
||||
PrintMatch Printer(std::move(Print));
|
||||
MatchFinder Finder;
|
||||
Finder.addMatcher(NodeMatch, &Printer);
|
||||
std::unique_ptr<FrontendActionFactory> Factory =
|
||||
|
@ -91,6 +93,21 @@ PrintedNamedDeclMatches(StringRef Code, const std::vector<std::string> &Args,
|
|||
return ::testing::AssertionSuccess();
|
||||
}
|
||||
|
||||
::testing::AssertionResult
|
||||
PrintedNamedDeclMatches(StringRef Code, const std::vector<std::string> &Args,
|
||||
bool SuppressUnwrittenScope,
|
||||
const DeclarationMatcher &NodeMatch,
|
||||
StringRef ExpectedPrinted, StringRef FileName) {
|
||||
return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, FileName,
|
||||
[=](llvm::raw_ostream &Out, const NamedDecl *ND) {
|
||||
auto Policy =
|
||||
ND->getASTContext().getPrintingPolicy();
|
||||
Policy.SuppressUnwrittenScope =
|
||||
SuppressUnwrittenScope;
|
||||
ND->printQualifiedName(Out, Policy);
|
||||
});
|
||||
}
|
||||
|
||||
::testing::AssertionResult
|
||||
PrintedNamedDeclCXX98Matches(StringRef Code, StringRef DeclName,
|
||||
StringRef ExpectedPrinted) {
|
||||
|
@ -127,6 +144,17 @@ PrintedWrittenPropertyDeclObjCMatches(StringRef Code, StringRef DeclName,
|
|||
"input.m");
|
||||
}
|
||||
|
||||
::testing::AssertionResult
|
||||
PrintedNestedNameSpecifierMatches(StringRef Code, StringRef DeclName,
|
||||
StringRef ExpectedPrinted) {
|
||||
std::vector<std::string> Args{"-std=c++11"};
|
||||
return PrintedDeclMatches(Code, Args, namedDecl(hasName(DeclName)).bind("id"),
|
||||
ExpectedPrinted, "input.cc",
|
||||
[](llvm::raw_ostream &Out, const NamedDecl *D) {
|
||||
D->printNestedNameSpecifier(Out);
|
||||
});
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
TEST(NamedDeclPrinter, TestNamespace1) {
|
||||
|
@ -223,3 +251,21 @@ R"(
|
|||
"property",
|
||||
"Obj::property"));
|
||||
}
|
||||
|
||||
TEST(NamedDeclPrinter, NestedNameSpecifierSimple) {
|
||||
const char *Code =
|
||||
R"(
|
||||
namespace foo { namespace bar { void func(); } }
|
||||
)";
|
||||
ASSERT_TRUE(PrintedNestedNameSpecifierMatches(Code, "func", "foo::bar::"));
|
||||
}
|
||||
|
||||
TEST(NamedDeclPrinter, NestedNameSpecifierTemplateArgs) {
|
||||
const char *Code =
|
||||
R"(
|
||||
template <class T> struct vector;
|
||||
template <> struct vector<int> { int method(); };
|
||||
)";
|
||||
ASSERT_TRUE(
|
||||
PrintedNestedNameSpecifierMatches(Code, "method", "vector<int>::"));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue