[llvm-branch-commits] [clang] 23dc049 - Treat a placeholder type for class template argument deduction as

Richard Smith via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Nov 24 17:03:15 PST 2020


Author: Richard Smith
Date: 2020-11-24T16:59:06-08:00
New Revision: 23dc04981be29b8398b7a409540646b58af76983

URL: https://github.com/llvm/llvm-project/commit/23dc04981be29b8398b7a409540646b58af76983
DIFF: https://github.com/llvm/llvm-project/commit/23dc04981be29b8398b7a409540646b58af76983.diff

LOG: Treat a placeholder type for class template argument deduction as
substitutable for the deduced template.

As agreed in https://github.com/itanium-cxx-abi/cxx-abi/issues/109.

Added: 
    

Modified: 
    clang/lib/AST/ItaniumMangle.cpp
    clang/test/CodeGenCXX/cxx1z-class-deduction.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 172b94f26018..f5a4f6708c83 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -2507,6 +2507,12 @@ static bool isTypeSubstitutable(Qualifiers Quals, const Type *Ty,
   if (Ctx.getLangOpts().getClangABICompat() > LangOptions::ClangABI::Ver6 &&
       isa<AutoType>(Ty))
     return false;
+  // A placeholder type for class template deduction is substitutable with
+  // its corresponding template name; this is handled specially when mangling
+  // the type.
+  if (auto *DeducedTST = Ty->getAs<DeducedTemplateSpecializationType>())
+    if (DeducedTST->getDeducedType().isNull())
+      return false;
   return true;
 }
 
@@ -3696,16 +3702,16 @@ void CXXNameMangler::mangleType(const AutoType *T) {
 void CXXNameMangler::mangleType(const DeducedTemplateSpecializationType *T) {
   QualType Deduced = T->getDeducedType();
   if (!Deduced.isNull())
-    mangleType(Deduced);
-  else if (TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl())
-    mangleName(GlobalDecl(TD));
-  else {
-    // For an unresolved template-name, mangle it as if it were a template
-    // specialization but leave off the template arguments.
-    Out << 'N';
-    mangleTemplatePrefix(T->getTemplateName());
-    Out << 'E';
-  }
+    return mangleType(Deduced);
+
+  TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl();
+  assert(TD && "shouldn't form deduced TST unless we know we have a template");
+
+  if (mangleSubstitution(TD))
+    return;
+
+  mangleName(GlobalDecl(TD));
+  addSubstitution(TD);
 }
 
 void CXXNameMangler::mangleType(const AtomicType *T) {

diff  --git a/clang/test/CodeGenCXX/cxx1z-class-deduction.cpp b/clang/test/CodeGenCXX/cxx1z-class-deduction.cpp
index 8edab748338e..bf436e7ec980 100644
--- a/clang/test/CodeGenCXX/cxx1z-class-deduction.cpp
+++ b/clang/test/CodeGenCXX/cxx1z-class-deduction.cpp
@@ -29,9 +29,9 @@ struct X {
   template<typename T> struct C { C(T); };
 };
 
-// CHECK: @_Z1gIiEDaT_DTcv1AfL0p_E1AIS0_E(
+// CHECK: @_Z1gIiEDaT_DTcv1AfL0p_ES1_IS0_E
 template<typename T> auto g(T x, decltype(A(x)), A<T>) {}
-// CHECK: @_Z1hIiEDaT_DTcvN1N1BEfL0p_ENS1_1BIS0_EE(
+// CHECK: @_Z1hIiEDaT_DTcvN1N1BEfL0p_ENS2_IS0_EE
 template<typename T> auto h(T x, decltype(B(x)), B<T>) {}
 // CHECK: @_Z1iI1XiEDaT0_DTcvNT_1CEfL0p_ENS2_1CIS1_EE(
 template<typename U, typename T> auto i(T x, decltype(typename U::C(x)), typename U::template C<T>) {}


        


More information about the llvm-branch-commits mailing list