<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/110088>110088</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [abi] Declaring class of a member-like friend method is not mangled.
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
            VitaNuo
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          VitaNuo
      </td>
    </tr>
</table>

<pre>
    The code sample

```
template <class>
concept True = true;

namespace test2 {
 template<typename T> struct A {
    template<typename U = void>
 friend void g(...) requires True<T> && True<U> {}
 };

 void call() {
    A<int> ai;
    A<bool> ab;
    g(ai);
    g(ab);
 }
}
```

does not compile with the following error 

```
Output of x86-64 clang (trunk) (Compiler #1)
<source>:10:17: error: definition with same mangled name '_ZN5test2F1gIvEEvzQaa4TrueIT_E4TrueITL0__E' as another definition
   10 | friend void g(...) requires True<T> && True<U> {}
      | ^
<source>:10:17: note: previous definition is here
1 error generated.
Compiler returned: 1
```

The reason appears to be that the enclosing class template specialization `A<int>` (or `A<bool>`, respectively) is not part of the mangled name `_ZN5test2F1gIvEEvzQaa4TrueIT_E4TrueITL0__E`, resulting in `g(ai)` and `g(ab)` mangled as the same string.

As per the discussion in https://github.com/itanium-cxx-abi/cxx-abi/issues/24#issuecomment-934493006, the code above is valid and the solution is to include the declaring class in the mangling. From @rjmccall on the aforementioned issue:

```
The only viable implementation path I can see, given that nothing in the standard prevents these friend declarations from otherwise matching perfectly in signatures and requires-clauses, is to mangle the declaring class for these friends.
```

Note 1: gcc can compile the above snippet by including the declaring class in the mangling, which results in the mangled string `_ZN5test21AIiEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E` for `g(ai)` (Note `AIiE` mangles the declaring class),  and `_ZN5test21AIbEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E`  for `g(ab)` (Note `AIbE` mangles the declaring class).

Note 2: this issue stands in the way of implementing the demangling of template parameters in constraints (https://github.com/llvm/llvm-project/blob/main/libcxxabi/src/demangle/ItaniumDemangle.h#L5795).
`T_` in `_ZN5test21AIiEF1gIvEEvzQaa4TrueIT_E4TrueITL0__E` is impossible to demangle, since it is a substitution for the template argument of class A that is not part of the mangling.

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysVl1v2zoS_TX0yyCGRNmW_eAH1x9AgKKLBdJ92JeAosYSW4rUkpQT99cvhpL80aa56cUtCkUeUsMzc84ZSXivKoO4ZvNPjPP_qCC-dJZxzua7iehCbd16CE4KW57XTzWCtCWCF02rkSU7lmyG6yIZ_sefAZtWi4DAsq3UwnuW7fsVaY3ENsCT62h1B8F1yLJPt8mMaNC3QiIE9IEDy4dlGPOybBvOLdJGeGLZHnxwnQywudkL8Ob2r_HUk1XlBRMcnUJTxiBUjC-n0ynjK3D4v0459BEsy7bxJMYXjC_G0NcYyj-xfDfkorv7cvq8UmjN-JLy3mHcsGyrTKA8Ql2eHFcKa3VcKu6WCKRQjK9-jRZ30Quu6809U_21tOjB2ADSNq3SCC8q1BBqhKPV2r4oUwE6Zx28Q_q_utB2AewRXpeLh8UMpBamAsaXwXXme6ycL7f9CQ4Yz1LC2qfKtt52TiKRkm3ShC45yzb9sXRT4lEZFZQ1PTpPbDbCVBpLiNQynj__98s8iuaQVo-n_f70499CzIisx6fn_XDzOXl-3jOeg_AgjA01upvsl36mCbB8-4-KI_6jpGy-_6vCjSXhbqB1eFK287cNUB5qdIMD04GaCg06EbCc9vFLpx2GzhksKVv6jgrI3w6FtwZE26JwHoKFAiHUIkQ1oJHaelJDdPXFYOBblEpo9UNEfGyRXHXNFgkRT-Lpw4Oo6XS-BYf0cFAn1GdqrOqV2AoXtUTH3rO8SP6A5csZnQ6EW0VwV_8sEhCmvMSKITaeKHwEELXmg1Ommt52bOOhRRe3lMrLzvvIjoE6hNazbMP4gfFDpULdFVNpG8YPKgijuuZBvr4-iEIxfrjeKe879Iwf-IzxLP6StmnQhIdVNputsiRZUD1hnMSisCeklp2EVmUsJeK1uhuFEiwoI3VXYo8TpRbuSqEy1xZTeXBwtgE2S9y3RtLQAtvvEEfrkKAoa7CECI4q_P1AID1Zo89wUqLQCIreGpShF0krQg2PIIUBj0hlVeqEplcb2XLgKxYUhCmFK6Mb0IRIi8fRnH1RMa2HIxUQXf2iPFUWZEzVojuiDPpMSenVJ0JHBqamjW5-kFp0nijYDr3rlfBm647W3cHw03fM9cUGhJQsWEkZix5nbWxu5NEb1bYYoDgPlNFZHyCN0L7UStaD0O83YDlI98466eZR7T_in1jmz55hfBkLIkc_qv3VMv4tvPQQ38LotFsMxccw3IEo3gJRfADE9BdCOBESauV7Pfc6u7TvRZxpBF10e6Vj7HycUOMQbIUTDQZ0MYG0xgcnFImV8eU7E0Hr0_jnoXX2G8rA-KHQtmD80AhlaFEV8vW1nxLeScYPAwhk_PDYj5TdEJnWjGef5_lqflPzInl6pg71A_BvyIB61LTWe0VeDhauALbglZEIKtAuAb4rfFChH0GDS65tEq7qqJvUu17Om97zv5v816k7KddZucpWYoLrNOd5lq2SeTKp13mRzUs8ilWZpllxzJalkHyxyvMZX_J0lk_Umid8lqz4IlnyWZpMj-VMzHmW4jzJZIo5myXYCKWnRMPUumoSFbFO0yRZLidaFKj98Kls8GWYf_3HsltH7oqu8myWaOWDv6YJKuj4jU3kzXew-8nL9ggCGmwKdA9afb_MtAZDbcuxKYOTp5PO6fUfa-nyXhmqOa35_wMAAP__XP_GfA">