<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/64725>64725</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[AST] Question about ADL lookup & structural equivalence of produced templates
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
danix800
</td>
</tr>
</table>
<pre>
1. Without overloaded `operator+`:
```c
template <class T, T v>
struct integral_constant { static constexpr const T value = v; };
template <int N>
constexpr const int a = integral_constant<int, N>::value + 1;
```
produces plain `BinaryOperator +` for `a`:
```c
VarTemplateDecl 0x5622692efab0 <line:13:1, line:14:61> col:21 a
|-NonTypeTemplateParmDecl 0x5622692c1780 <line:13:11, col:15> col:15 referenced 'int' depth 0 index 0 N
`-VarDecl 0x5622692c1810 <line:14:1, col:61> col:21 a 'const int' constexpr cinit
`-BinaryOperator 0x5622692efd28 <col:25, col:61> '<dependent type>' '+'
|-DependentScopeDeclRefExpr 0x5622692efcd0 <col:25, col:53> '<dependent type>' lvalue
`-IntegerLiteral 0x5622692efd08 <col:61> 'int' 1
```
2. With overloaded `operator+`:
```c
template <class T> class A {};
template <class T> A<T> operator+(int N, const A<T> &X) { return A<T>(); }
template <class T, T v>
struct integral_constant { static constexpr const T value = v; };
template <int N>
constexpr const int a = integral_constant<int, N>::value + 1;
```
produces overloaded `CXXOperatorCallExpr +` for `a`:
```c
VarTemplateDecl 0x560e6a7e6ee8 <line:8:1, line:9:61> col:21 a
|-NonTypeTemplateParmDecl 0x560e6a7e6df0 <line:8:11, col:15> col:15 referenced 'int' depth 0 index 0 N
`-VarDecl 0x560e6a7e6e80 <line:9:1, col:61> col:21 a 'const int' constexpr cinit
`-CXXOperatorCallExpr 0x560e6a7e7190 <col:25, col:61> '<dependent type>' '+'
|-UnresolvedLookupExpr 0x560e6a7e7148 <col:59> '<overloaded function type>' lvalue (ADL) = 'operator+' 0x560e6a7b83c8
|-DependentScopeDeclRefExpr 0x560e6a7e70f0 <col:25, col:53> '<dependent type>' lvalue
`-IntegerLiteral 0x560e6a7e7128 <col:61> 'int' 1
```
Current ASTStructuralEquivalence.cpp implementation considers the two variable templates of `a` as inequivalent.
So I'm wondering which part could be the problem.
1. Is this overload resolution correct? If not then what's the correct one? Otherwise,
2. Should these two variable templates be considered as equivalent? If true, then then equivalence algorithm might
need improved in this case.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzklklv4zgWxz8NfXmIQZG2loMPsh0DAYKqmUmmpm4DSnqy2E2Taopykm_fICV5Sy3orqpTA4FCS-L7vfUviq6Te424Iss1WW5noneNsatKaPmaUjorTPW2iubwP-ka0zswR7TKiAorIDE1LVrhjCVsTWJKeE7oltDcr8NfOfx2eGiVcAiEb0olug6eCdvAMxwJvx9e6ZztSwdSO9xbof5fGt05oR2QZA2dE06WEO7ha2uHld8vVO-tbr2lNZBkS_h69OEdWWoHH07AW2P-qQim3vkw7PUeD_t5Tng-otkaojNzinv42VpT9SV20Cohtc_XWmph3z6OWYMhbVD7ZUzFt1II8EnY5zGaLZYK6OsyZizOGNaioD5AJTUSnkfcX7y7040F4XkcEX4PpVGE5ywCMZklyebug9HPby1O5v8l7OEaUUZJ-h4RGIPFaHm2Hi3BYo0Wdem7hCUheQlU2LoGKEhd4StQ-HByIaZ3n4S9RabRFXIxRTVQbuPxoFMlPe6iwFJLN8EG3E0hLnJZsTS06WB4eQskLCF8U2GLukLtwL216HuCJeERW_vrCTWkdzu9_VSaNhTvP1jfe88uuGVFv8xd8u9wVWjFK2hM7x58F6N9lA6tuOqWil5EeIpqzFr0xU5mgwD8vOn3pQvL3A_4t-f2Yk9O-CYsLtEsHSY7ZMw3wOktwuLPhGVBQyy63urTM8JSwrJJNL5D_idp1XWJN58_T0OyEUqFpv1h1aIYiwRjxPRivtMb0cp-QLNGQFXTW8CvkqwppCuVzH6KYnnUl8pwxiZR9hXt-Pua9V9tsTPqiNWjMb_37Tvk4kJEltkZc9E_da9LJ41-L1ZAWJpvH8Ns8q3feTXQyZlUpLxMp0x8V0tH52j9y7V0SgP7y1o6XDe9tZ6dPz0_BTnprVD3f_TyKJTvwnnZtiAPrcIDai8pRof-kBXaDlyD4F4MHIWVolAIk3Z0YOppKkF0IDVONt18ID8ZeCAsOcCL0RVaqffw0siygVZYB6XpVQUFBkRrTaHwMG6M5vDg0fIsEhCapB-9sxZLR_gOHmrQxnkTGl4a4ZMx-Dy-A8bPxw4-ugbti-yQsM3pQ_PUBBdcg91XgyzwlAysfJznKEe-s723OvgQLnhOLgi1N1a65gAHuW8uzgYasfJpt-boF3oItxQdzmfVilcZz8QMV1GcsShhC85nzapcUhpFgvJIpLUoijqKaBHVWRJndY1ZNJMrRhmnaRTTZMmXfB6VZYQYJzRjBY34giwoHoRUc6WOh7mx-5nsuh5X8SJhy5kSBaouHNAZ0_gC4SFhzJ_X7crvuSv6fUcWVMnOdWcrTjoVTvb50zNZbuHfPXahVqLwZ_l8-wgqTLf_UkJ36sOrXJkaxo9Dda7ArLdq1TjXdl772Y6w3V66pi_mpTkQtvMujP_uWmt-843BdsHxjrBdCOzPAAAA__86VbkR">