From 90a3b19e645143e320b8ea4b5ca348bc6fb34e94 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Fri, 24 Oct 2014 20:22:57 +0000 Subject: [PATCH] Itanium ABI: Template template parameters are usable as substitutions Template template parameters weren't added to the list of substitutions. This would make the substitution map contain inaccurate mappings, leading to Clang violating the Itanium ABI and breaking compatibility with GCC. This fixes PR21351. Differential Revision: http://reviews.llvm.org/D5959 llvm-svn: 220588 --- clang/lib/AST/ItaniumMangle.cpp | 17 +++++++---------- clang/test/CodeGenCXX/mangle.cpp | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 5965ef051582..76664673d53c 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -637,13 +637,11 @@ void CXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *ND) { return; // ::= - if (const TemplateTemplateParmDecl *TTP - = dyn_cast(ND)) { + if (const auto *TTP = dyn_cast(ND)) mangleTemplateParameter(TTP->getIndex()); - return; - } + else + mangleUnscopedName(ND->getTemplatedDecl()); - mangleUnscopedName(ND->getTemplatedDecl()); addSubstitution(ND); } @@ -1563,14 +1561,13 @@ void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND, return; // ::= - if (const TemplateTemplateParmDecl *TTP - = dyn_cast(ND)) { + if (const auto *TTP = dyn_cast(ND)) { mangleTemplateParameter(TTP->getIndex()); - return; + } else { + manglePrefix(getEffectiveDeclContext(ND), NoFunction); + mangleUnqualifiedName(ND->getTemplatedDecl()); } - manglePrefix(getEffectiveDeclContext(ND), NoFunction); - mangleUnqualifiedName(ND->getTemplatedDecl()); addSubstitution(ND); } diff --git a/clang/test/CodeGenCXX/mangle.cpp b/clang/test/CodeGenCXX/mangle.cpp index 9bdac7f17289..9af0d9da9976 100644 --- a/clang/test/CodeGenCXX/mangle.cpp +++ b/clang/test/CodeGenCXX/mangle.cpp @@ -991,3 +991,25 @@ namespace test48 { template void f(S::u *); // CHECK-LABEL: define weak_odr void @_ZN6test481fINS_1SEEEvPTuNT_1uE(%"union.test48::S::u"*) } + +namespace test49 { + template + struct S {}; + + template