[clang] 79cb179 - PR47870: Properly mangle placeholders for deduced class template

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Sun Oct 18 13:57:50 PDT 2020


Author: Richard Smith
Date: 2020-10-18T13:57:41-07:00
New Revision: 79cb179b149b20e7e1bbfd45d1b5e5b055f3b067

URL: https://github.com/llvm/llvm-project/commit/79cb179b149b20e7e1bbfd45d1b5e5b055f3b067
DIFF: https://github.com/llvm/llvm-project/commit/79cb179b149b20e7e1bbfd45d1b5e5b055f3b067.diff

LOG: PR47870: Properly mangle placeholders for deduced class template
specializations that have no deduced type.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index ed8fc13050c2..26fc7f8ec816 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3668,13 +3668,18 @@ void CXXNameMangler::mangleType(const AutoType *T) {
 }
 
 void CXXNameMangler::mangleType(const DeducedTemplateSpecializationType *T) {
-  // FIXME: This is not the right mangling. We also need to include a scope
-  // here in some cases.
-  QualType D = T->getDeducedType();
-  if (D.isNull())
-    mangleUnscopedTemplateName(T->getTemplateName(), nullptr);
-  else
-    mangleType(D);
+  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';
+  }
 }
 
 void CXXNameMangler::mangleType(const AtomicType *T) {

diff  --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index fc3ff1412219..485cb85f517f 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -9761,7 +9761,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
 
   auto TemplateName = DeducedTST->getTemplateName();
   if (TemplateName.isDependent())
-    return Context.DependentTy;
+    return SubstAutoType(TSInfo->getType(), Context.DependentTy);
 
   // We can only perform deduction for class templates.
   auto *Template =
@@ -9780,7 +9780,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
     Diag(TSInfo->getTypeLoc().getBeginLoc(),
          diag::warn_cxx14_compat_class_template_argument_deduction)
         << TSInfo->getTypeLoc().getSourceRange() << 0;
-    return Context.DependentTy;
+    return SubstAutoType(TSInfo->getType(), Context.DependentTy);
   }
 
   // FIXME: Perform "exact type" matching first, per CWG discussion?

diff  --git a/clang/test/CodeGenCXX/cxx1z-class-deduction.cpp b/clang/test/CodeGenCXX/cxx1z-class-deduction.cpp
index 0761f2129b51..8edab748338e 100644
--- a/clang/test/CodeGenCXX/cxx1z-class-deduction.cpp
+++ b/clang/test/CodeGenCXX/cxx1z-class-deduction.cpp
@@ -19,3 +19,24 @@ void f(int *p) {
   // CHECK: @_ZN1AIxEC
   A c = 123LL;
 }
+
+namespace N {
+  template<typename T> struct B { B(T); };
+}
+using N::B;
+
+struct X {
+  template<typename T> struct C { C(T); };
+};
+
+// CHECK: @_Z1gIiEDaT_DTcv1AfL0p_E1AIS0_E(
+template<typename T> auto g(T x, decltype(A(x)), A<T>) {}
+// CHECK: @_Z1hIiEDaT_DTcvN1N1BEfL0p_ENS1_1BIS0_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>) {}
+void test() {
+  g(1, 2, A(3));
+  h(1, 2, B(3));
+  i<X>(1, 2, X::C(3));
+}


        


More information about the cfe-commits mailing list