forked from OSchip/llvm-project
[DeclPrinter] Allow printing fully qualified name of function declaration
When requesting a tooltip for a function call in an IDE, the fully qualified name helps to remove ambiguity in the function signature. Patch by Nikolai Kosjar! Differential Revision: https://reviews.llvm.org/D40013 llvm-svn: 318896
This commit is contained in:
parent
c5b8e8b97f
commit
842022a0f1
|
@ -51,7 +51,8 @@ struct PrintingPolicy {
|
|||
TerseOutput(false), PolishForDeclaration(false),
|
||||
Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
|
||||
IncludeNewlines(true), MSVCFormatting(false),
|
||||
ConstantsAsWritten(false), SuppressImplicitBase(false) { }
|
||||
ConstantsAsWritten(false), SuppressImplicitBase(false),
|
||||
FullyQualifiedName(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
|
||||
|
@ -220,6 +221,10 @@ struct PrintingPolicy {
|
|||
|
||||
/// When true, don't print the implicit 'self' or 'this' expressions.
|
||||
bool SuppressImplicitBase : 1;
|
||||
|
||||
/// When true, print the fully qualified name of function declarations.
|
||||
/// This is the opposite of SuppressScope and thus overrules it.
|
||||
bool FullyQualifiedName : 1;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
|
|
@ -580,13 +580,19 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
|
|||
PrintingPolicy SubPolicy(Policy);
|
||||
SubPolicy.SuppressSpecifiers = false;
|
||||
std::string Proto;
|
||||
if (!Policy.SuppressScope) {
|
||||
if (const NestedNameSpecifier *NS = D->getQualifier()) {
|
||||
llvm::raw_string_ostream OS(Proto);
|
||||
NS->print(OS, Policy);
|
||||
|
||||
if (Policy.FullyQualifiedName) {
|
||||
Proto += D->getQualifiedNameAsString();
|
||||
} else {
|
||||
if (!Policy.SuppressScope) {
|
||||
if (const NestedNameSpecifier *NS = D->getQualifier()) {
|
||||
llvm::raw_string_ostream OS(Proto);
|
||||
NS->print(OS, Policy);
|
||||
}
|
||||
}
|
||||
Proto += D->getNameInfo().getAsString();
|
||||
}
|
||||
Proto += D->getNameInfo().getAsString();
|
||||
|
||||
if (GuideDecl)
|
||||
Proto = GuideDecl->getDeducedTemplate()->getDeclName().getAsString();
|
||||
if (const TemplateArgumentList *TArgs = D->getTemplateSpecializationArgs()) {
|
||||
|
|
|
@ -104,15 +104,17 @@ PrintedDeclMatches(StringRef Code, const std::vector<std::string> &Args,
|
|||
return ::testing::AssertionSuccess();
|
||||
}
|
||||
|
||||
::testing::AssertionResult PrintedDeclCXX98Matches(StringRef Code,
|
||||
StringRef DeclName,
|
||||
StringRef ExpectedPrinted) {
|
||||
::testing::AssertionResult
|
||||
PrintedDeclCXX98Matches(StringRef Code, StringRef DeclName,
|
||||
StringRef ExpectedPrinted,
|
||||
PrintingPolicyModifier PolicyModifier = nullptr) {
|
||||
std::vector<std::string> Args(1, "-std=c++98");
|
||||
return PrintedDeclMatches(Code,
|
||||
Args,
|
||||
namedDecl(hasName(DeclName)).bind("id"),
|
||||
ExpectedPrinted,
|
||||
"input.cc");
|
||||
"input.cc",
|
||||
PolicyModifier);
|
||||
}
|
||||
|
||||
::testing::AssertionResult
|
||||
|
@ -350,6 +352,47 @@ TEST(DeclPrinter, TestFunctionDecl1) {
|
|||
"void A()"));
|
||||
}
|
||||
|
||||
TEST(DeclPrinter, TestFreeFunctionDecl_FullyQualifiedName) {
|
||||
ASSERT_TRUE(PrintedDeclCXX98Matches(
|
||||
"void A();",
|
||||
"A",
|
||||
"void A()",
|
||||
[](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));
|
||||
}
|
||||
|
||||
TEST(DeclPrinter, TestFreeFunctionDeclInNamespace_FullyQualifiedName) {
|
||||
ASSERT_TRUE(PrintedDeclCXX98Matches(
|
||||
"namespace X { void A(); };",
|
||||
"A",
|
||||
"void X::A()",
|
||||
[](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));
|
||||
}
|
||||
|
||||
TEST(DeclPrinter, TestMemberFunction_FullyQualifiedName) {
|
||||
ASSERT_TRUE(PrintedDeclCXX98Matches(
|
||||
"struct X { void A(); };",
|
||||
"A",
|
||||
"void X::A()",
|
||||
[](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));
|
||||
}
|
||||
|
||||
TEST(DeclPrinter, TestMemberFunctionInNamespace_FullyQualifiedName) {
|
||||
ASSERT_TRUE(PrintedDeclCXX98Matches(
|
||||
"namespace Z { struct X { void A(); }; }",
|
||||
"A",
|
||||
"void Z::X::A()",
|
||||
[](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));
|
||||
}
|
||||
|
||||
TEST(DeclPrinter, TestMemberFunctionOutside_FullyQualifiedName) {
|
||||
ASSERT_TRUE(PrintedDeclCXX98Matches(
|
||||
"struct X { void A(); };"
|
||||
"void X::A() {}",
|
||||
functionDecl(hasName("A"), isDefinition()).bind("id"),
|
||||
"void X::A()",
|
||||
[](PrintingPolicy &Policy){ Policy.FullyQualifiedName = true; }));
|
||||
}
|
||||
|
||||
TEST(DeclPrinter, TestFunctionDecl2) {
|
||||
ASSERT_TRUE(PrintedDeclCXX98Matches(
|
||||
"void A() {}",
|
||||
|
|
Loading…
Reference in New Issue