Skip to content

[clang] ItaniumMangle: fix mangling for unresolved types #135312

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2511,7 +2511,6 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
case Type::PackIndexing:
case Type::TemplateTypeParm:
case Type::UnaryTransform:
case Type::SubstTemplateTypeParm:
unresolvedType:
// Some callers want a prefix before the mangled type.
Out << Prefix;
Expand All @@ -2524,6 +2523,16 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
// so we return directly.
return true;

case Type::SubstTemplateTypeParm: {
auto *ST = cast<SubstTemplateTypeParmType>(Ty);
// If this was replaced from a type alias, this is not substituted
// from an outer template parameter, so it's not an unresolved-type.
if (auto *TD = dyn_cast<TemplateDecl>(ST->getAssociatedDecl());
TD && TD->isTypeAlias())
return mangleUnresolvedTypeOrSimpleId(ST->getReplacementType(), Prefix);
goto unresolvedType;
}

case Type::Typedef:
mangleSourceNameWithAbiTags(cast<TypedefType>(Ty)->getDecl());
break;
Expand Down
27 changes: 27 additions & 0 deletions clang/test/CodeGenCXX/mangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1220,3 +1220,30 @@ namespace test61 {
// CHECK-LABEL: @_ZN6test611fINS_1XEEEvNT_1Y1aENS3_1bE
template void f<X>(int, int);
}

namespace test62 {
template <class> struct integral_constant {
static const int value = true;
};
template <int> struct _OrImpl {};
template <class _Args> using _Or = _OrImpl<_Args::value>;
template <class _Up>
void f(_Or<integral_constant<_Up>>) {}
// CHECK-LABEL: @_ZN6test621fIiEEvNS_7_OrImplIXsr17integral_constantIT_EE5valueEEE
template void f<int>(_OrImpl<1>);
} // namespace test62

namespace test63 {
namespace {
template <class, class> struct integral_constant {
static const int value = true;
};
template <class, class> struct _And {};
template <int> struct _OrImpl {};
template <class _First> using _Or = _OrImpl<_First::value>;
template <class _Up>
void f(_And<integral_constant<int, void>, _Or<integral_constant<_Up, int>>>);
} // namespace
// CHECK-LABEL: @_ZN6test6312_GLOBAL__N_11fIiEEvNS0_4_AndINS0_17integral_constantIivEENS0_7_OrImplIXsr17integral_constantIT_iEE5valueEEEEE
void g() { f<int>({}); }
} // namespace test63