1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
From 363747b90f66f097fd45a6cd665adbaf7612188a Mon Sep 17 00:00:00 2001
From: Nikolai Kosjar <nikolai.kosjar@qt.io>
Date: Mon, 15 Jan 2018 12:51:18 +0100
Subject: [PATCH 2/3] Backport: [DeclPrinter] Allow printing fully qualified
name of function declaration
https://reviews.llvm.org/D40013
---
include/clang/AST/PrettyPrinter.h | 7 +++++-
lib/AST/DeclPrinter.cpp | 16 ++++++++----
unittests/AST/DeclPrinterTest.cpp | 51 ++++++++++++++++++++++++++++++++++++---
3 files changed, 64 insertions(+), 10 deletions(-)
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index 274df220e1..edcef0ae24 100644
--- a/tools/clang/include/clang/AST/PrettyPrinter.h
+++ b/tools/clang/include/clang/AST/PrettyPrinter.h
@@ -50,7 +50,8 @@ struct PrintingPolicy {
UseVoidForZeroParams(!LO.CPlusPlus),
TerseOutput(false), PolishForDeclaration(false),
Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
- IncludeNewlines(true), MSVCFormatting(false) { }
+ IncludeNewlines(true), MSVCFormatting(false),
+ FullyQualifiedName(false) { }
/// \brief Adjust this printing policy for cases where it's known that
/// we're printing C++ code (for instance, if AST dumping reaches a
@@ -200,6 +201,10 @@ struct PrintingPolicy {
/// prints anonymous namespaces as `anonymous namespace' and does not insert
/// spaces after template arguments.
bool MSVCFormatting : 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
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 37f08a4985..ea37abe8f6 100644
--- a/tools/clang/lib/AST/DeclPrinter.cpp
+++ b/tools/clang/lib/AST/DeclPrinter.cpp
@@ -510,13 +510,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()) {
diff --git a/unittests/AST/DeclPrinterTest.cpp b/unittests/AST/DeclPrinterTest.cpp
index dc1977d876..4cf8bce20e 100644
--- a/tools/clang/unittests/AST/DeclPrinterTest.cpp
+++ b/tools/clang/unittests/AST/DeclPrinterTest.cpp
@@ -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() {}",
--
2.15.1
|