-
Eric Müller authored
This introduces some LLVM patches to enable code generation via genpybind.
6cdef93b
llvm5-0005-Tooling-Fully-qualify-template-parameters-of-nested-.patch 3.79 KiB
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