<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/110480>110480</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[abi][ItaniumMangle] Inconsistent mangling of friend function templates.
</td>
</tr>
<tr>
<th>Labels</th>
<td>
ABI
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
VitaNuo
</td>
</tr>
</table>
<pre>
a.cc:
```
template <class>
concept True = true;
namespace test2 {
template<typename T> struct A {
template<typename U>
friend void h(...) requires True<U> {}
template<typename S>
friend void g(...) requires True<S>;
};
template<typename S>
void g(...) requires True<S> {}
void call() {
A<int> ai;
h<void>(ai);
g<void>(ai);
}
}
```
In the above snippet:
- the call `h<void>(ai)` is mangled as `_ZN5test21hIvEEvzQ4TrueITL0__E`. Note that the constrained parameter `U` is mangled as `TL0_` (`4TrueITL0__E`), i.e., a second-level template parameter (presumably the next level after the template parameters of the enclosing class `A`). Note that the enclosing class template specialization `A<int>` is not part of the mangling.
- the call `g<void>(ai)` is mangled as `_ZN5test21gIvEEvzQ4TrueIT_E`. Note that the constrained parameter `U` is mangled as `T_` (`4TrueIT_E`), i.e., a first-level template parameter.
- the difference between `h` and `g` is that the definition of friend template function `h` is inside of `struct A`, and the definition of `g` is outside. Otherwise, their signatures are identical.
The mangling of `h<void>(ai)` makes it impossible to implement [demangling of template parameter substitutions](https://github.com/VitaNuo/llvm-project/blob/1557e3b9d672bb1f2fce745d664c039d578e5d0c/llvm/include/llvm/Demangle/ItaniumDemangle.h#L5795), since the substitution `TL0_` cannot be demangled.
Options:
- Include the enclosing class template specialization `A<int>` into the mangling of `h<void>(ai)`, i.e., in cases when the friend function definition is part of the enclosing class.
- Mangle the constraint `True<U>` in the definition of `h` as `TrueIT_E`, i.e., as a first-level template parameter (ignoring the enclosing class), since as per https://eel.is/c++draft/temp.friend#9 and https://github.com/itanium-cxx-abi/cxx-abi/issues/24#issuecomment-1491130332, `h` is not a member-like constrained friend.
The latter option seems to fit better into the proposal in https://github.com/itanium-cxx-abi/cxx-abi/issues/24#issuecomment-1491130332.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0Vltv4zYT_TX0CxGBInWxH_wQ2zEQYL9dfGi2D31ZUNTIYpciVZHyXn59MZKsyImTFmgLBI5FzuXMzDljSe_1yQJsSboj6WEl-1C7bvurDvJj71aFK39sZaQUEfeEHQi7Jxmb_obHAE1rZABKxF4Z6T0RD-ONclZBG-hT1-PtgYauByJ2U5jh08oGfCsV0AA-cEry6Zpe4hKxDz9aQEP6RMQD9aHrVaD3C1tKb5p_nqGgRdVpsCU9O13SmvB1FEWEb2gHf_S6Az_AJGKPTkPo_LAE-laOX97McXo7x-AkZvSY6rot72f6O-FvlDC4KWkM4Wt0u-rfPRF7bQN6Sv2MrSZij36Ym6-lJnyzAE7p6Z375_Tzl2vqjJ-PloYaqCzcGai3um0hzGS7G-4QNCUZu4UmY1R72kh7MlBS6dHuy28f04FPcf14fng4__x_gq15fPrAvnx5IBmL6EcXgIZahjGBsz50UlsoaSs72UCADiN9fh0fjzEQ3mAnM_YiOKLie6ojiPC_pB6Us-WdgTOYmUTLPHzdduD7Rhbmx4DHwvdAR3tZoQkevvb01FXDFVhlnNf2RAcJIsT7EcnLSl9azkF9C0pLo3_KoJ0dI1woMTXBuoC5wyXr0BRtT9GtWd1ixvuzOl3P6t8Z1Osx3Z5RpTsf3hxRRJcllrqqoAOrgBYQvgHYkZwZo9KWY_Ejmhl3CZW2euisqy5rYs5T9VZdul5Prtp6XQJak4xddt6AfD9keR11kdf1Ab0j-inU0H3THtAt1KA7iutehh73heyA6hJs0EqaaCnKp8V4p9hviK-RX8FTHahuWue9LgzQ4PDJQAM2UJLuSljGuqEA3xc-6NBjKZ6kB8LXdQitxz3Aj4QfTzrUfREp1xB-nH6bCD8ac27u2s79DioQfiyMKwg_xmmagyg2ZZbzoogrXinIk7TMskQxsSnTfA1pydQUgPCjtsr0JTwfHEbEePIYpNV9czmJasLFhzTfpBOHvEYi4DiWVSy3hJIWpVPgwCZ-XjX7UzvW_bz0Hkc8_1CxNrgrnb47yKUctKVKevD0Ww3jdp4YOxN1wTztr5bCC7jzbvjfUPi1iMPQpeff3RH1bWqP8vIXj1nHCxH7v9QxbgJ9sq5DfDfQXo1UetpCR6-JCGAi7Qk_KsJ3hO_KTlZIPcwVjV0iXGwGib5DYT2S6k59_34nC43x5m_a-x4wBU8IF8OTcg1q6S5ONnEsmBAcYS62BfJL0gaaAro7o79eb8oR1yuBGxmwJ26gH_UAjUfpVhq5OlzNFGo71zovDY7nvyxrwrgqt6LciI1cwTbOeZ5tWBrnq3qbqFSydS7yWKg8qbIyiSWTKY-B5Vkp1yu95YwnbCNYzFic5hEDKXIBSZmkOeQiIQmDRmoTodIj151WA5RtHLNkzVZGFmD88DLM-f3ukXCOb8Xddlg1RX_yJGFG--CfAwQdzPD-jIWmB5Lupp0xcp6kBxS0s177gBtxqceXwrpw1kervjPbd3o9baoXK3Du8lTPecv_DAAA__8aqrpV">