Newer
Older
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
From 4427624b30117c6db67b9ea7c3f16e396edc3748 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Johann=20Kl=C3=A4hn?= <johann.klaehn@kip.uni-heidelberg.de>
Date: Wed, 26 Jul 2017 15:06:10 +0200
Subject: [PATCH 05/12] [Tooling] Fully qualify template parameters of nested
name specifier in getFullyQualifiedName
---
lib/Tooling/Core/QualTypeNames.cpp | 18 ++++++++++++++----
unittests/Tooling/QualTypeNamesTest.cpp | 8 +++++++-
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/tools/clang/lib/Tooling/Core/QualTypeNames.cpp b/tools/clang/lib/Tooling/Core/QualTypeNames.cpp
index 721c2c92fc..934624dd14 100644
--- a/tools/clang/lib/Tooling/Core/QualTypeNames.cpp
+++ b/tools/clang/lib/Tooling/Core/QualTypeNames.cpp
@@ -370,11 +370,21 @@ NestedNameSpecifier *createNestedNameSpecifier(const ASTContext &Ctx,
const TypeDecl *TD,
bool FullyQualify,
bool WithGlobalNsPrefix) {
+ const Type *TypePtr = TD->getTypeForDecl();
+ // In case of template specializations iterate over the arguments and
+ // fully qualify them as well.
+ if (isa<const TemplateSpecializationType>(TypePtr) ||
+ isa<const RecordType>(TypePtr)) {
+ // We are asked to fully qualify and we have a Record Type (which
+ // may point to a template specialization) or Template
+ // Specialization Type. We need to fully qualify their arguments.
+
+ TypePtr = getFullyQualifiedTemplateType(Ctx, TypePtr, WithGlobalNsPrefix);
+ }
+
return NestedNameSpecifier::Create(
- Ctx,
- createOuterNNS(Ctx, TD, FullyQualify, WithGlobalNsPrefix),
- false /*No TemplateKeyword*/,
- TD->getTypeForDecl());
+ Ctx, createOuterNNS(Ctx, TD, FullyQualify, WithGlobalNsPrefix),
+ false /*No TemplateKeyword*/, TypePtr);
}
/// \brief Return the fully qualified type, including fully-qualified
diff --git a/tools/clang/unittests/Tooling/QualTypeNamesTest.cpp b/tools/clang/unittests/Tooling/QualTypeNamesTest.cpp
index 532fae6f5a..e27089b986 100644
--- a/tools/clang/unittests/Tooling/QualTypeNamesTest.cpp
+++ b/tools/clang/unittests/Tooling/QualTypeNamesTest.cpp
@@ -63,6 +63,10 @@ TEST(QualTypeNameTest, getFullyQualifiedName) {
// Template parameter expansion.
Visitor.ExpectedQualTypeNames["CheckC"] =
"A::B::Template0<A::B::C::MyInt, A::B::AnotherClass>";
+ // Template parameters of nested name specifier should also be fully expanded.
+ Visitor.ExpectedQualTypeNames["CheckNested"] =
+ // "typename A::B::Template0<A::B::C::MyInt, A::B::AnotherClass>::nested";
+ "typename A::B::Template0<int, A::B::Class0>::nested";
// Recursive template parameter expansion.
Visitor.ExpectedQualTypeNames["CheckD"] =
"A::B::Template0<A::B::Template1<A::B::C::MyInt, A::B::AnotherClass>, "
@@ -105,7 +109,7 @@ TEST(QualTypeNameTest, getFullyQualifiedName) {
" using InnerAlias = OuterTemplateClass<T>;\n"
" InnerAlias<int> AliasTypeVal;\n"
" }\n"
- " template<class X, class Y> class Template0;"
+ " template<class X, class Y> struct Template0 { typedef int nested; };"
" template<class X, class Y> class Template1;"
" typedef B::Class0 AnotherClass;\n"
" void Function1(Template0<C::MyInt,\n"
@@ -113,6 +117,8 @@ TEST(QualTypeNameTest, getFullyQualifiedName) {
" void Function2(Template0<Template1<C::MyInt, AnotherClass>,\n"
" Template0<int, long> > CheckD);\n"
" void Function3(const B::Class0* CheckM);\n"
+ " void Function4(typename Template0<C::MyInt,\n"
+ " AnotherClass>::nested CheckNested);\n"
" }\n"
"template<typename... Values> class Variadic {};\n"
"Variadic<int, B::Template0<int, char>, "
--
2.13.0