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

    <tr>
        <th>Summary</th>
        <td>
            diagnostic improvement: missing-typename diagnostic
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang:diagnostics
      </td>
    </tr>

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

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

<pre>
    Given the following code: 

```
template<typename T1>
struct A1 {
 template<typename T2>
  struct A2 { T2 t; };
};

template <typename K>
void s(K k) {
   A1<K>::A2 a(2); // missing a `typename` at head!
}

void s() {
 s<double>(1.0);
}
```

Diagnostics emitted by clang are not quite useful, it would be nice to emit a "missing typename" diagnostic (both gcc and msvc do it for this case).

```
<source>:15:13: error: expected ';' after expression
   15 |    A1<K>::A2 a(2); // missing a typenamea at head!
      |             ^
      |             ;
<source>:15:14: error: use of undeclared identifier 'a'
   15 |    A1<K>::A2 a(2); // missing a typename at head!
      |              ^
<source>:15:11: error: use of class template 'A2' requires template arguments
   15 | A1<K>::A2 a(2); // missing a typename at head!
      | ^
<source>:19:3: note: in instantiation of function template specialization 's<double>' requested here
   19 |   s<double>(1.0);
 |   ^
<source>:10:10: note: template is declared here
    9 | template<typename T2>
      |   ~~~~~~~~~~~~~~~~~~~~~
   10 |   struct A2 { T2 t; };
      |          ^
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyslc2SmzgQx5-mfekaF7SMGQ4cGE-8h1zzAkI0RhuQHEk4O3vYZ98StsGedTKbqlAuGVvqj1_3n0Z6rw-GuYTsBbLXlRxDZ13Z2a-szaq2zVv5hz6xwdAxtrbv7XdtDqhswyAqhOQVkuqybpPLZ_oZeDj2MjCIXXg7spED45cUxKfztg9uVAGrFCF_Of-FD01oNkG8GlE0wi-EAcQLQv4K4uLj7v4uD7z1-nl2erK6QQ_0_Bm_AhU32SBWKYjddFRUIKqKUAI9E1AxhaU90B4H7X0siUTYJtcAsE1QBuxYNkDpktpNXnPg-6gexK6xY91zjEvP6To5x3vv5L7a5_VVy4OxPmjlkQcdAjdYv6HqZUzQMRob8NuoA-PouR17oB3qgN_t2DdYMxqtGIOdjCMR0RVvJiPCZg6DQM-1DR0elEJpGhz8SWFjo9PWOgyd9qikZ6Bi_ROxgNh5OzrF52KnWVxEVBg7Z91089eRVQQCymM5KEfZBnZxw7H32pq5cWmGkO_w11t4pZT_6R5O18XrfEH26afbc9se8W3u-EbPaFscTcOql44b1A2boFvNLjLLyP3bAP8n3wL4kCB9RKB66T0ujx3lFcVuOf42asc3W9IdxoFN8O-5fj_UDzkKENUkNGPDNNK0QW18kCZoGbQ1EakdjZru59T9kZWWvf77fAYof_fgnnnZR8V27HhBLC5V_uBJv5z6YeLJdZkzn5PTHmcR3cXGc-wP5-wihX8eXQtLcmX5cDA_0NeCdh0Gq6YUTSEKueIyzdMsKdLNllZdmSWSi6xps0YoTpVqxHOdUao2mdxSm2crXVJCmyRL8nST5pt0zSLf1htKCypY5VuGTcKD1P2670_D2rrDSns_clmkQuSrXtbc--klSDSNSxDVMuY8EMW3oyuj9VM9Hjxskl774Bd_QYeey5vZqIejsyeOCo_tuej1aS75cnQ1ur7sQjj6KPhJ3gcdurFeKzsA7WOMy9fT0dk_WQWg_QTggfYTw78BAAD__8zZNY4">