xref: /aosp_15_r20/external/clang/test/SemaTemplate/extern-templates.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -triple i686-pc-win32 -fsyntax-only -verify %s -DMS
2*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu-pc-win32 -fsyntax-only -verify %s
3*67e74705SXin Li 
4*67e74705SXin Li template<typename T>
5*67e74705SXin Li class X0 {
6*67e74705SXin Li public:
7*67e74705SXin Li   void f(T t);
8*67e74705SXin Li 
9*67e74705SXin Li   struct Inner {
10*67e74705SXin Li     void g(T t);
11*67e74705SXin Li   };
12*67e74705SXin Li };
13*67e74705SXin Li 
14*67e74705SXin Li template<typename T>
f(T t)15*67e74705SXin Li void X0<T>::f(T t) {
16*67e74705SXin Li   t = 17; // expected-error{{incompatible}}
17*67e74705SXin Li }
18*67e74705SXin Li 
19*67e74705SXin Li extern template class X0<int>;
20*67e74705SXin Li 
21*67e74705SXin Li extern template class X0<int*>;
22*67e74705SXin Li 
23*67e74705SXin Li template<typename T>
g(T t)24*67e74705SXin Li void X0<T>::Inner::g(T t) {
25*67e74705SXin Li #ifdef MS
26*67e74705SXin Li   t = 17; // expected-error{{assigning to 'long *' from incompatible}} expected-error{{assigning to 'int *' from incompatible}}
27*67e74705SXin Li #else
28*67e74705SXin Li   t = 17; // expected-error{{assigning to 'long *' from incompatible}}
29*67e74705SXin Li #endif
30*67e74705SXin Li }
31*67e74705SXin Li 
test_intptr(X0<int * > xi,X0<int * >::Inner xii)32*67e74705SXin Li void test_intptr(X0<int*> xi, X0<int*>::Inner xii) {
33*67e74705SXin Li   xi.f(0);
34*67e74705SXin Li #ifdef MS
35*67e74705SXin Li   xii.g(0); // expected-note {{instantiation}}
36*67e74705SXin Li #else
37*67e74705SXin Li   xii.g(0);
38*67e74705SXin Li #endif
39*67e74705SXin Li }
40*67e74705SXin Li 
41*67e74705SXin Li extern template class X0<long*>;
42*67e74705SXin Li 
test_longptr(X0<long * > xl,X0<long * >::Inner xli)43*67e74705SXin Li void test_longptr(X0<long*> xl, X0<long*>::Inner xli) {
44*67e74705SXin Li   xl.f(0);
45*67e74705SXin Li   xli.g(0);
46*67e74705SXin Li }
47*67e74705SXin Li 
48*67e74705SXin Li template class X0<long*>; // expected-note 2{{instantiation}}
49*67e74705SXin Li 
50*67e74705SXin Li template<typename T>
51*67e74705SXin Li class X1 {
52*67e74705SXin Li public:
f(T t)53*67e74705SXin Li   void f(T t) { t += 2; }
54*67e74705SXin Li 
55*67e74705SXin Li   void g(T t);
56*67e74705SXin Li };
57*67e74705SXin Li 
58*67e74705SXin Li template<typename T>
g(T t)59*67e74705SXin Li void X1<T>::g(T t) {
60*67e74705SXin Li   t += 2;
61*67e74705SXin Li }
62*67e74705SXin Li 
63*67e74705SXin Li extern template class X1<void*>;
64*67e74705SXin Li 
g_X1(X1<void * > x1,void * ptr)65*67e74705SXin Li void g_X1(X1<void*> x1, void *ptr) {
66*67e74705SXin Li   x1.g(ptr);
67*67e74705SXin Li }
68*67e74705SXin Li 
69*67e74705SXin Li extern template void X1<const void*>::g(const void*);
70*67e74705SXin Li 
g_X1_2(X1<const void * > x1,const void * ptr)71*67e74705SXin Li void g_X1_2(X1<const void *> x1, const void *ptr) {
72*67e74705SXin Li   x1.g(ptr);
73*67e74705SXin Li }
74