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

    <tr>
        <th>Summary</th>
        <td>
            Inconsistent AST for SubstNonTypeTemplateParmExpr for a templated function inside a templated class 
        </td>
    </tr>

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

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

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

<pre>
    Hi all,

I am currently applying some transformations to the clang AST and wrote me a consistency checker to better find and localize incorrect AST after my transformation.

Thereby, I think I have found an inconsistency within the clang AST. The following code

```
template <class> struct a {
  template <int c> static void b() { c; }
};
void test() {
    a<char>::b<1>(); 
}
```

produces the following AST ... see https://godbolt.org/z/bTz86ad8s for a full example.

```
TranslationUnitDecl 0x55ae8e335318 <<invalid sloc>> <invalid sloc>
|-ClassTemplateDecl 0x55ae8e37b700 <<source>:1:1, line:3:1> line:1:25 a
| |-TemplateTypeParmDecl 0x55ae8e37b5b0 <col:11> col:16 class depth 0 index 0
| |-CXXRecordDecl 0x55ae8e37b670 <col:18, line:3:1> line:1:25 struct a definition
| | |-...
| | `-FunctionTemplateDecl 0x55ae8e37bb78 <line:2:3, col:41> col:32 b
| |   |-NonTypeTemplateParmDecl 0x55ae8e37b9e8 <col:13, col:17> col:17 referenced 'int' depth 1 index 0 c
| |   `-CXXMethodDecl 0x55ae8e37bad8 <col:20, col:41> col:32 b 'void ()' static implicit-inline
| |     `-CompoundStmt 0x55ae8e37bc08 <col:36, col:41>
| |       `-DeclRefExpr 0x55ae8e37bbe8 <col:38> 'int' NonTypeTemplateParm 0x55ae8e37b9e8 'c' 'int'
| `-ClassTemplateSpecializationDecl 0x55ae8e37bd38 <line:1:1, line:3:1> line:1:25 struct a definition
|   |-...
|   `-FunctionTemplateDecl 0x55ae8e37c0b8 <line:2:3, col:41> col:32 b
|     |-NonTypeTemplateParmDecl 0x55ae8e37bfa8 <col:13, col:17> col:17 'int' depth 0 index 0 c
|     |-CXXMethodDecl 0x55ae8e37c018 <col:20, col:41> col:32 b 'void ()' static implicit-inline
|     `-CXXMethodDecl 0x55ae8e37c330 <col:20, col:41> col:32 used b 'void ()' static implicit-inline
|       |-TemplateArgument integral 1
|       `-CompoundStmt 0x55ae8e39bf30 <col:36, col:41>
|         `-SubstNonTypeTemplateParmExpr 0x55ae8e39bf10 <col:38> 'int'
|           |-NonTypeTemplateParmDecl 0x55ae8e37b9e8 <col:13, col:17> col:17 referenced 'int' depth 1 index 0 c
|           `-IntegerLiteral 0x55ae8e39bef0 <col:38> 'int' 1
```

During class template instantiation, the DeclRefExpr to the NonTypeTemplateParmDecl 0x55ae8e37b9e8 gets replaced by SubstNonTypeTemplateParmExpr . Thereby, also a copy of NonTypeTemplateParmDecl is introduced into the instantiated FunctionTemplateDecl. The inconsistency is that SubstNonTypeTemplateParmExpr references the original NonTypeTemplateParmDecl 0x55ae8e37b9e8 and not the copied NonTypeTemplateParmDecl 0x55ae8e37bfa8 .

The inconsistency is not harmful atm but might lead to follow-up errors in future...

I discovered that the SubstNonTypeTemplateParmExpr is copied in TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl and that the SubstNonTypeTemplateParmExpr is created in TemplateInstantiator::transformNonTypeTemplateParmRef . In transformNonTypeTemplateParmRef the NonTypeTemplateParmDecl object is given as parameter and passed without lookup/modification to the factory function.

I tried to fix it but I don't know how to find the copied NonTypeTemplateParmDecl from the original NonTypeTemplateParmDecl within transformNonTypeTemplateParmRef.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzFV9uO4jgQ_ZrwUmoUkobAAw99Gy3S7mo1zazm1XEq4G0njmyHbvrrt-wECOHSaKTVShByqZxTdarKlFOVbee_CWBSBtFTED4H4UNzXAArgNdaY2nlFlhVya0oV2BUgWA1K02udMGsUKUBq8CuEbhkZPHwugRWZvCulUUgawacjISxWPIt8DXyN9TunRStpbNckLV7QyrOpPhEECVXxMxtA5Y7q2Lbox123V2uUWO6pSBgQb6I8o1-12yDkKvaw3vQgxvvwlkduz0EgqEXpFTvLlauMuySBJOw_fhLi0UlGcUYxE-EYUwQv4Cxuia_GQTJY2MG0DUUpQXeGFIUHDZKZJAG0TSIZu4d9_CRTp5bSjqJWyBvatHYg_WOAYA5J9ZME3QQP9AnpRsjd-WNPege8Vw0zbHSKqs5Gi_MQQmXhuFwCAYR1tZWxnFE3-izUlmqpB0qvaKrT_qmy8_phGVTQ-9rEiKvpQT8YKQBDq_IuXTZlT61P0phn5FLCD_GY4ZTjONxPJo6_byEGyqTDAzViw_3Bc7cbYN9untyqVm2KThGTdIkDFtUo2rNsZFv5L9US1KUdOshbu697K7d82hMmu9IwBHtOJbbCv9iuuhzjVPPxZV0EB6vPZ-Arx_IsLJrCKlUM_yA8Bj-6efP70h9kfVxJ0kXd_q13_sazZB6TzjFj6g8HaW7d3MS3n2rS-7ML8mZJj5JLV3kXSB3GtfuOyHHERX9ETx41j8Jm-Tb4Z-TcYbTTrgd_FHSkTQBjTmtCSXHDIIoob6jY6vwaKcwdVvfCYqSlP4D7VqdKE1VfaCOwsuhOUbfrm33EXPb74ICE1zYO1F6lXr0rQOqqNyy9WoL2-XnYYc_nvT4T7EaNBfFd8xfPip9lKuujvHUt9FepzN5OMlBlHBnun-pw-9i6Lbda4VcuLXdt3df1izuVs2NzXe1iOG0hOGWAuZh-ksFDLeXb85uK99-zYbnanbHe6lieTj67yoWvmgXHsfhTeS1oR79VQ_gaO190Ku6oJGFxLK40kzC6MT8YoPN0rzr8ZUGgw7Wa50aeybxx_1G2KPwYr-dIv_vyyEcBblwcqL-XdAoxmQ3LMwvh7UX_9yo8VxrP2T5f779iCRKSnpphV8oXDBuEOmuYO2seaMyK7SGQicbF3i6havZ8gPgbo5k0ig_u1ZbUPlFQmFcrTVjU-ZOG_8OcdDdc6tOM2weD6XCzV3MXndyn8hmSFNarERJOblRETdol8o2k6-qBLl346rVH7hPnXe4NIMWNPIBswWktYVCrNYWJLLMpa4ZKe_qClBrpZ12NCDaWuNhsW73H5kwXG0o1KwRxTl8VRhyoA2IQLtSL_a5ULoZjv8WRpzD8WE7hW5n1OhT3KE8pdtvXM4AUV1T3S1K-MroWtWr9B-3WyJ_VmKDJTADFdOsQLdzcvFU1GTkpdv1KEqKVOqtrmhYL1QmcsF9t-1aK2ecPN9SXpqq7eXFaiexy6X4AGF9kilbrlsTC2-leoc1fb2BV_LLOsu1Km6r5d2u7bpUwwHOR5PJfRRP7--TQTaPs1k8YwMrrMT54lC1zf7SbVOuprnZx-yWqGwvjGtykeHRs2Y5G9RaznsbJXK9TodcFXQh5Wb3c0dbLpc8uhTG1GjoZDwNw_FgPecTmrHyENOcJ8mMJxzHLI1HacJogzWbRQPJUpRmHowfgygq8R08BJ0H4-eBmEdhFIWziDY5URJNhuNpnoRpnoUzOnKMgvsQCybk0PnhdnADPfcupfXK0ENJIpnDQwpMrEpET0f4rKZi0nMaxESh4mQ68ORz7_y_hlAcAg">