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

    <tr>
        <th>Summary</th>
        <td>
            Unable to call method with forward-declared template variable: "implicit instantiation of undefined template"
        </td>
    </tr>

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

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

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

<pre>
    These code examples compile in GCC and MSVC in C++11 or newer modes. They fail in Clang in C++11 and newer modes.

# Template methods with forward-declared templated type

Here two methods are templated to avoid knowing the full type of ForwardDecl in their definitions. The template has a default value which is the forward declared type.

Simply constructing the template type works ok, as in `works()`. However calling from one method to the other does not, it tries to instantiate the ForwarDecl template and fails. This works in GCC and MSVC.

```
<source>:8:16: error: implicit instantiation of undefined template 'ForwardDecl<int>'
        return works();
               ^
<source>:2:7: note: template is declared here
class ForwardDecl;
      ^
1 error generated.
```

https://godbolt.org/z/53sf4Ed5T

```cpp
template <class T>
class ForwardDecl;

struct S {
    template <class Alias = ForwardDecl<int>>
    Alias doesntwork() {
        // This fails to compile in Clang. Calling `works<Alias>()` succeeds.
        return works();
    }

    template <class Alias = ForwardDecl<int>>
    Alias works() {
        return Alias();
    }
};

template <class T>
class ForwardDecl {};

int main() {
    S().doesntwork();
    S().works();
}
``` 

# Template methods with forward-declared non-templated type

While minimizing the above, I noticed that the compiler error is different if the forward-declared type is not itself templated. In this case, it says `works()` has an incomplete return type. Again, this works in GCC and MSVC.

```
<source>:7:16: error: calling 'works<ForwardDecl>' with incomplete return type 'ForwardDecl'
        return works();
               ^~~~~~~
<source>:11:11: note: 'works' declared here
    Alias works() {
          ^
<source>:1:7: note: forward declaration of 'ForwardDecl'
class ForwardDecl;
      ^
1 error generated.
```

https://godbolt.org/z/sdsE49Mo3

```cpp
class ForwardDecl;

struct S {
    template <class Alias = ForwardDecl>
    Alias doesntwork() {
        // This fails to compile in Clang. Calling `works<Alias>()` succeeds.
        return works();
    }

    template <class Alias = ForwardDecl>
    Alias works() {
        return Alias();
    }
};

class ForwardDecl {};

int main() {
    S().doesntwork();
    S().works();
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzlV0tzozgQ_jX40hUXCAP2gUPGSXbmMKdkd88yCKOJLLkkEW_m129LAmxsJzuzs6-qdWEZIdH9dX_9kDeqfi2fWmYYVKpmwH6ju71gBme7PRcMuISf1mugsobPj7-s3XwdkQ94JQkoDZIdmIYdvmvmgIJeoaFc-G2Cyu10v5Ny-kIU30XxbT-SFJ4YKqeWwY7ZVtUGDty20Ch9oLq-qVklqGY12H4b3r3u2amQj0wzsAc1CqBuftyugL4oXsOzVAeO6GzLoOmE8IJANfAQdN2hKgcd17mGmjVccsuVDDaOEqGlqMKt005YeKGiY3BoedUCN0F4kAdH7KhoYvcjR1mv6G9prO4qO8AadXhoB6WfDajniCAXxkGL8tg_jMgyIiuczeGjOrAXdG5FhXBiGq12oOTgTme-k6xwQKMUsiyVdRK5Bas5znEHRxxUWu5V4-7gEe-QEZLj0dHs3YGWBnRnoTJlN4_7K0zTtVGdrliU3kfp7RK_SY4DMK2VdjfOK7xCYEc86H9HUSc9HydxABEpTohD4VxaJ5kUQR30H81spyWc-i39MN3Sf6Ls_ipSgt_C4UPPMfc7YkA3jCSjf_uwxAfGwATcROGoJwmmw5ZJpl2wzq87zo-ttXuD2iPygNdW1Rsl7FzpLc6-4jdLTbO4r7OnqxRU-314cvRfug5An5yVfwA8jCFY4RGi4sSgS4m3gmO8RukdXGVoUOdeDltdXErrKAoMTRV4n3mrQ-T5KHRhe1KvfOGZw7rPgjFR0rXX4AOjzxkwXVUxVg-l6BsDJSruTn3xF1l-ou3S6B5RsOA9RHgzZeq7WPaKL0QgZNhRLq-BewwP5-e8TeANm6459Ah9CFD4k31BKnnzdm_4tXXxscNKvuNfhypLN-qFuRL4yWU0r9x7LbV-rQ8p3WemS3DeNJja6A3enJb3m0l5dztRGFZVw0RzbD9z-OQ6Cq5W1LC-7hr6ai5reWgsEqPZgRAMTe8DwPcPuN16NtZB3I-W3-Ky_A4tBEvokDyTKHa1NbBwHeJ5Sf6xSlxcXNfMSJJhGKvzCB_RXqnO35h7b7eD5LwdTPv92LPe8Ma_0x1Mbe4Xq88qfb87_M0d4H9X-P-pev_frOkzViZ5XhSrOCf5rC7TepWu6MxyK1j5s6QbpNCxidwNx9X3D_942tbcvRbynHzPgRG3zzotyrNMQX3dZo4BhRMhXoafm71WX1iFJ-UHbkzHjDthLZdpNmvLFVkykmyyzYY2CanyxaJZZOkyy6uqWKTLZCbohglTRhn-BSL43we8CLyPsrsZL0lMSJLERZwmMcnnyzpFacu4yUiekDyLFjFDksTc4XApPNOlh7TptgYXBTfWHBeReL6VjHl1KJ926Ehd1lTS5y8zr7n0yH8H4AAp-w">