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

    <tr>
        <th>Summary</th>
        <td>
            Can't obtain full type of the non-template type parameter in clang frontend
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

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

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

<pre>
    Consider [this example](https://godbolt.org/z/hcb1q8das):

```c++
template< typename T, auto ... dims >
struct NDArray;

struct Dimension
{
    using value_type = unsigned short;

    value_type size{ value_type( 0 ) };
};

template < typename ConcreteDim >
struct DimensionImpl : Dimension {}; 

struct Width : DimensionImpl< Width  > {};
struct Height: DimensionImpl< Height > {};

inline constexpr Width  W;
inline constexpr Height H;

NDArray< float, W > bla;
```

Clang reports the error as

```
error: implicit instantiation of undefined template 'NDArray<float, {{{0}}}>
```

while GCC provides full type information:

```
error: aggregate 'NDArray<float, Width{DimensionImpl<Width>{Dimension{0}}}> bla' has incomplete type and cannot be defined
```

In my code, I'm using libTooling to obtain full type names of some C++ code, and I've noticed that in cases such as the above, Clang simply writes `{{{0}}}` instead of `Width{DimensionImpl<Width>{Dimension{0}}}`. This is problematic for me as my tool should behave differently if this `{{{0}}}` is actually `Width` than if it's actually `Height`.

I'm obtaining type information in libTooling using this snippet:

```c++
        bool VisitVarDecl( clang::VarDecl * varDecl )
        {
                 auto canonicalType{ varDecl->getType().getCanonicalType().getAsString() };
                 // make some decisions based on canonicalType
            }
            return true;
        }
```

However, clang appears to correctly resolve overloads taking `NDArray< float, W >` vs `NDArray< float, H >`, so this means that clang actually does have a distinction between those two types.

However, how to obtain the full name of the type?

Also, would you consider putting the full name of the type in the clang's error as well (the way GCC does)?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJydVk1z2zgM_TXyhROPIkX-OPjg2M0ml1420x53KAmyuKVFL0nZdX_9PlDyt93ZWQ3jSCQAPgAPIHNT7mcL0zhVkhVR9upr5QT9lOuNpihbRsmk9n7jonQeJW8YK1PmRvuhsSt8_cJfXeTP_0xK6aJkymLxMooPv6O4G0WUvPIIs55gXHqK0oXw-w01ck3iM0oWQrbeiOFwKEq1diJKv3QKztu28OLrcm6t3Efp6_ke_eJSrQlemKZfG_dCAk_rVLMSW6lb-os3hOWlaCG9aqgUrjbWXxllrTN5p34RLJ5NIS4iFvBYROPlSfn8_cJXceEsAl5Y8gTQN14eHfmAJlbnpxnBXoUtxJ0IfFelry8V2ARv3C3xVicTF7rvpFa1v6vbLd3T7X5Vo1VDogCHPP3c2MNm349yNxK9yfcrS8f8LkSljfTMiO9h41zLk-yBU-eqCy2RYUsbpNIJX5Mga40VIOU9OnafQYR9VnBVFcoLBYSy8Up6jrapQJKSKsUsOSUyGZ-AHnGG0PCIOULdOCT2LuJdrTSJPxYLsbFmi-pzomq1DhwBjsrYdUDxqKKuXJCrlaXVY3whKYB3nd5uHkjPlq69COFPxqKWDsgKw60BGwWksilFIZvGeJGT6IP1G7c_GrHegwolMaoPmF335alV_mmM5lc0AZN7qZqzkHDdOE6JM1xAXT85GmIYbGwLQeNVwQmrJScU6BwUXVvUYEOghszNNmh1rHGc_r3YWeUhyHjv5HIUB3KQLBkDPv9_QEfxUHxyl8VA7nNNnOlCIOUCrgEkIuQRCu5MrS4R2FrCsVJVFVlqPMCqSoRG_Ru0TsjCt1JD-ggX8whLw-oKtBhfyvRNAPguMhZy1OUjJOeKoBzjs9x1yQzgXKM2G_L_6UwQ_ZOz39-UU_6btEsqNDfagvPEZtJ5PwuWz9GND-_TSyMXzf_iCQcM-GoaVUj9yY08tPVg6AlpW5H_7No7rA7xtbgQPk7P3Z_ewtNu5uIQuNm0OzjFWv6gjr0lFYp54UQOcoJRzRWmGzts_2YSJ0hrG4EOTjebHxXuVuG72dGWLNdAiK2QSJS0jiuvMNZSwSSz5IwG8VAtFn2kxLL8wdmFtYe9mjm2dY9E3nsRfnemo8maZOO6cu3BHDhZGhRk4L4E-51H8wmMy8nviOB5bRz60M4EUrrhAxdrsztrKdwBQlsJJ7GpwkQ40tO3cwNz7Qxr70IN7k0bDrBwTdq03ncsf2BK9Pt0xOU6OxxHYkeaGTvh5Z3chxOA_QyXp7cBzZ5HoyQdT7M4G5SztJymUznwymuagYqw5W97Y78zGPR0PKbCwkZaIPOAzI0wBLeypvHUlIPW6tnV1U75us2HaPD40Hp7-PeELvU3KIFP5VzLWN-ycTZKBjUAviTlJMliWUyyshqNXtIsz0ZyPEpenimpBlrmpN0MN0vcJgdqlsRJEk_j7DmJszgdVpN8UtB0MpGT-CVOq-glRjtUesgb8yVzYGcBQ96uHBY1aOBOi9KFSxwd7KO-cZubLc3SfPn6OQhwZwHrv7JbVQw">