Skip to content

Commit

Permalink
[clang][ItaniumMangle] Mangle friend function templates with a constr…
Browse files Browse the repository at this point in the history
…aint that depends on a template parameter from an enclosing template as members of the enclosing class.

Such function templates should be considered member-like constrained friends per [temp.friend]p9 and itanium-cxx-abi/cxx-abi#24 (comment)).
  • Loading branch information
VitaNuo committed Sep 27, 2024
1 parent a059b29 commit f8d897f
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 6 deletions.
8 changes: 8 additions & 0 deletions clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2270,6 +2270,14 @@ void CXXNameMangler::mangleTemplatePrefix(GlobalDecl GD,
mangleTemplateParameter(TTP->getDepth(), TTP->getIndex());
} else {
const DeclContext *DC = Context.getEffectiveDeclContext(ND);
if (const auto *FD = dyn_cast<FunctionTemplateDecl>(GD.getDecl())) {
// Member-like constrained friends are mangled as if they were members of
// the enclosing class.
if (FD->getTemplatedDecl()->isMemberLikeConstrainedFriend() &&
getASTContext().getLangOpts().getClangABICompat() >
LangOptions::ClangABI::Ver17)
DC = GD.getDecl()->getLexicalDeclContext()->getRedeclContext();
}
manglePrefix(DC, NoFunction);
if (isa<BuiltinTemplateDecl>(ND) || isa<ConceptDecl>(ND))
mangleUnqualifiedName(GD, DC, nullptr);
Expand Down
6 changes: 3 additions & 3 deletions clang/test/CodeGenCXX/mangle-concept.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,19 @@ namespace test2 {
// CHECK: call {{.*}}@_ZN5test21AIiEF1fEzQ4TrueIT_E(
// CLANG17: call {{.*}}@_ZN5test21fEz(
f(ai);
// CHECK: call {{.*}}@_ZN5test2F1gIvEEvzQaa4TrueIT_E4TrueITL0__E(
// CHECK: call {{.*}}@_ZN5test21AIiEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E(
// CLANG17: call {{.*}}@_ZN5test21gIvEEvz(
g(ai);
// CHECK: call {{.*}}@_ZN5test21hIvEEvzQ4TrueITL0__E(
// CLANG17: call {{.*}}@_ZN5test21hIvEEvz(
h(ai);
// CHECK: call {{.*}}@_ZN5test2F1iIvQaa4TrueIT_E4TrueITL0__EEEvz(
// CHECK: call {{.*}}@_ZN5test21AIiEF1iIvQaa4TrueIT_E4TrueITL0__EEEvz(
// CLANG17: call {{.*}}@_ZN5test21iIvEEvz(
i(ai);
// CHECK: call {{.*}}@_ZN5test21jIvQ4TrueITL0__EEEvz(
// CLANG17: call {{.*}}@_ZN5test21jIvEEvz(
j(ai);
// CHECK: call {{.*}}@_ZN5test2F1kITk4TruevQ4TrueIT_EEEvz(
// CHECK: call {{.*}}@_ZN5test21AIiEF1kITk4TruevQ4TrueIT_EEEvz(
// CLANG17: call {{.*}}@_ZN5test21kIvEEvz(
k(ai);
// CHECK: call {{.*}}@_ZN5test21lITk4TruevEEvz(
Expand Down
6 changes: 3 additions & 3 deletions libcxxabi/test/test_demangle.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30128,11 +30128,11 @@ const char* cases[][2] =
// C++20 concepts, see https://github.com/itanium-cxx-abi/cxx-abi/issues/24.
{"_Z2f0IiE1SIX1CIT_EEEv", "S<C<int>> f0<int>()"},
{"_ZN5test21AIiEF1fEzQ4TrueIT_E", "test2::A<int>::friend f(...) requires True<T>"},
{"_ZN5test2F1gIvEEvzQaa4TrueIT_E4TrueITL0__E", "void test2::friend g<void>(...) requires True<T> && True<TL0_>"},
{"_ZN5test21AIiEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E", "void test2::A<int>::friend g<void>(...) requires True<T> && True<TL0_>"},
{"_ZN5test21hIvEEvzQ4TrueITL0__E", "void test2::h<void>(...) requires True<TL0_>"},
{"_ZN5test2F1iIvQaa4TrueIT_E4TrueITL0__EEEvz", "void test2::friend i<void>(...)"},
{"_ZN5test21AIiEF1iIvQaa4TrueIT_E4TrueITL0__EEEvz", "void test2::A<int>::friend i<void>(...)"},
{"_ZN5test21jIvQ4TrueITL0__EEEvz", "void test2::j<void>(...)"},
{"_ZN5test2F1kITk4TruevQ4TrueIT_EEEvz", "void test2::friend k<void>(...)"},
{"_ZN5test21AIiEF1kITk4TruevQ4TrueIT_EEEvz", "void test2::A<int>::friend k<void>(...)"},
{"_ZN5test21lITk4TruevEEvz", "void test2::l<void>(...)"},
{"_ZN5test31dITnDaLi0EEEvv", "void test3::d<0>()"},
{"_ZN5test31eITnDcLi0EEEvv", "void test3::e<0>()"},
Expand Down

0 comments on commit f8d897f

Please sign in to comment.