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.
This commit is contained in:
Richard Smith 2020-11-24 16:53:58 -08:00
parent 07f234be1c
commit 23dc04981b
2 changed files with 18 additions and 12 deletions

View File

@ -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) {

View File

@ -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>) {}