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)); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits