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

    <tr>
        <th>Summary</th>
        <td>
            [Clang] `friend` declarations with a dependent NNS are not supported
        </td>
    </tr>

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

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

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

<pre>
    Consider (https://godbolt.org/z/brf4183r8):
```c++
template <typename T>
struct TS {
    struct Nested {};
};

struct S {
    template <typename T>
    friend struct TS<T>::Nested;
};
```
This valid, if horrible, `friend` declaration, roughly speaking, has the effect of making `TS<T>::Nested` a friend of `S` for each specialisation of `TS`—whether implicit or explicit—that contains a declaration of some `struct Nested`. [[temp.friend]p5](https://eel.is/c++draft/temp.friend#5)

We do not and seemingly have never supported this feature properly (there are FIXMEs about this from 2013). When we encounter such a declaration, we print
```
<source>:8:26: warning: dependent nested name specifier 'TS<T>::' for friend class declaration is not
supported; turning off access control for 'S' [-Wunsupported-friend]
    8 |     friend struct TS<T>::Nested;
      |                   ~~~~~~~^
```
and disable access checking entirely for `S` (yes, that means *anyone* can now access any private members of `S`). GCC and MSVC both seem to support this feature properly, though EDG doesn’t (see the godbolt link above).

There is an AST node in Clang, `FriendTemplateDecl`, that seems to have been intended for this exact use case, but it is currently unused: we can serialise it, traverse it, and print it, but we only create it in exactly one place and never use it again after that; instantiating would theoretically raise an error, but I don’t think it’s currently possible to get to that code path.

If someone wants to look into working on this: from what I can tell, a good starting point would be to search for references to `setUnsupportedFriend`. In at least one of these places, we seem to be creating a regular `FriendDecl` for this, which should probably be a `FriendTemplateDecl`, but I haven’t looked into this too much...
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVkuT4jgS_jXiklGEkXkeOFBQdNSh-1Ls9l7TchprW5YckgztOcxvn0jZUFRPzUwMQQTYlvLxPVLGEPTZEm3F4lksDhPsYu389k17j7qkSeHKfrt3NuiSPAi5rmNsg8h3Qh6FPJ5dWTgTp86fhTz-JuSx8NV8ts79WsgNL8sOItuJZTZ8lZDP_E13IzWtwUgg8n3sW7LYEJxE_jI8DtF3KsLpDcRq3AEAMN7-RiFSmR6tDiIfF3z4_xjllyD_kJqXVF6TLeFehcj3aUG-E_luyP552luvw-Wp1gEuaHQp5B50BbXzXheG-FIssyGNWGZQkjLoMWpn-Zl33bk2PYSW8Ie2Z75XY4BYE1BVkYrgKmjSMw70eYXLDPDWiqt43Rvfq5wHQlVzdKXR6JDyjktOvEa8SLHOxGZ-rSnW5EE3rdFKR-C9P4f_90WxxgjK2YjaBsDHZjhocA1x5A_kiWU2haS7Z-ZjOkKxOLQLsTj8SWtEZqqDkMdRRKXHKgp5fNwr8wXr7oH_7wSlA-siILNJ1Gh7Nj3UeCGwdCEPoWtb51lNkcmqCGPnCVrvWvKmZ9UzAAToCY6v__v6EgAL18VxvXcNyGyWC7mZwveaLFwJyCrX2ZjCq_ojIkzllRNoGz8Vjcj3wXVe0UDnWuQ7uRT5Dq7oLWsh30FJLdmSbAQ7WCFpOPFZ6eTV1S-SEHKViB_loAyG8IEoHRio0Tc3UET-DLFLacFVFaBSFELi2juTAgq5euPgYvH89L2z961Pd0bfbbUGsdrDvzVY2nDf-fHz-_ARi5dPsWTaSx2wMHSvvSaVbEM2ak-mH7oYvSHkuqfAHCVRN4Q2gJA7tL2zJOQOFFqw7noLh7ZnLi88TxpqCvLhwWtJFV_2-6S_r2__3UPhYp2UCNHdxPe59IYieBDAy-ELlI6CvVluE7nSQJQmwjiIwWj7g8V5Ic77aIRTkrDmcmH3dgLrSgJtYW9wGC5imR0TJadxOB5ImdTAiASXHLjm5J2CyIK2kUVYJgBTC_QTVYQuECgMacgVXQQdObPqvCcbTQ-d7QLTu2MfMJyBfBpDBDqmhB4v5O-XjF2yy3jNMa8EzpoelCdGnlPYIb3pwVmC1qCitHXweZfCAZ5RW8CKvcl9scC1DRFt1BhZFlfXGR4G5DxFrdCYHjxycWiBvHf-VsMrlO6RkVgz_u9zcfPYdOtC4MnPEJ4p8s84NkuCFmP9ga_XYWpyI1e0MQFvnPvBmDu4Op8U7GyCnZFMc-jKAV8TpJGMSdjB2Tn2GfrUXesYx6HHIhUTCL2qE4eeKvJkFaV8PLEp_ufd0cfbaTWFVwsYwRCGmNB2FSMWRtjDOONuMi9o4IkLQPB07gz6d8mNUrvLKO2uNR9QdSq09a7AwvQcCP9WqgMtLNFHYhg5Kgfskk6jc9B0qp5Op5Nym5ebfIMT2s5WMl8uFvNsOam3WMnlutoU81VeVFVR4HJGs3xOcklFscrWE72VmZxn69l8tppl2Xxarsr5Mt-sZvPVYlEUlZhn1KA2U2MuDb8lTXQIHW1n2TxbrCYGCzIhvXtJqZIR813lXXKVkJLfyPyW9z4V3TmIeWZ0iOE9WtTRpHe3wcWLw1--UgS46jicQ7dz49u3t3Sk8eF4Z3jSebP95SVPx7orpso1Qh459fjz1Hr3f1J8Bqeu-GweG7ts5R8BAAD__xMWUbA">