1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 -Wundefined-func-template %s
4 template <class T
> struct C1
{
5 static char s_var_1
; // expected-note{{forward declaration of template entity is here}}
6 static char s_var_2
; // expected-note{{forward declaration of template entity is here}}
7 static void s_func_1(); // expected-note{{forward declaration of template entity is here}}
8 static void s_func_2(); // expected-note{{forward declaration of template entity is here}}
9 void meth_1(); // expected-note2{{forward declaration of template entity is here}}
11 template <class T1
> static char s_tvar_2
; // expected-note{{forward declaration of template entity is here}}
12 template <class T1
> static void s_tfunc_2(); // expected-note{{forward declaration of template entity is here}}
13 template<typename T1
> struct C2
{
14 static char s_var_2
; // expected-note{{forward declaration of template entity is here}}
15 static void s_func_2(); // expected-note{{forward declaration of template entity is here}}
16 void meth_2(); // expected-note{{forward declaration of template entity is here}}
17 template <class T2
> static char s_tvar_2
; // expected-note{{forward declaration of template entity is here}}
18 template <class T2
> void tmeth_2(); // expected-note{{forward declaration of template entity is here}}
22 extern template char C1
<int>::s_var_2
;
23 extern template void C1
<int>::s_func_2();
24 extern template void C1
<int>::meth_2();
25 extern template char C1
<int>::s_tvar_2
<char>;
26 extern template void C1
<int>::s_tfunc_2
<char>();
27 extern template void C1
<int>::C2
<long>::s_var_2
;
28 extern template void C1
<int>::C2
<long>::s_func_2();
29 extern template void C1
<int>::C2
<long>::meth_2();
30 extern template char C1
<int>::C2
<long>::s_tvar_2
<char>;
31 extern template void C1
<int>::C2
<long>::tmeth_2
<char>();
34 return C1
<int>::s_var_2
;
38 return C1
<int>::s_var_1
; // expected-warning{{instantiation of variable 'C1<int>::s_var_1' required here, but no definition is available}}
39 // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<int>::s_var_1' is explicitly instantiated in another translation unit}}
43 return C1
<char>::s_var_2
; // expected-warning{{instantiation of variable 'C1<char>::s_var_2' required here, but no definition is available}}
44 // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<char>::s_var_2' is explicitly instantiated in another translation unit}}
48 C1
<int>::s_func_1(); // expected-warning{{instantiation of function 'C1<int>::s_func_1' required here, but no definition is available}}
49 // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<int>::s_func_1' is explicitly instantiated in another translation unit}}
57 C1
<char>::s_func_2(); // expected-warning{{instantiation of function 'C1<char>::s_func_2' required here, but no definition is available}}
58 // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<char>::s_func_2' is explicitly instantiated in another translation unit}}
61 void func_07(C1
<int> *x
) {
62 x
->meth_1(); // expected-warning{{instantiation of function 'C1<int>::meth_1' required here, but no definition is available}}
63 // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<int>::meth_1' is explicitly instantiated in another translation unit}}
66 void func_08(C1
<int> *x
) {
70 void func_09(C1
<char> *x
) {
71 x
->meth_1(); // expected-warning{{instantiation of function 'C1<char>::meth_1' required here, but no definition is available}}
72 // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<char>::meth_1' is explicitly instantiated in another translation unit}}
76 return C1
<int>::s_tvar_2
<char>;
80 return C1
<int>::s_tvar_2
<long>; // expected-warning{{instantiation of variable 'C1<int>::s_tvar_2<long>' required here, but no definition is available}}
81 // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<int>::s_tvar_2<long>' is explicitly instantiated in another translation unit}}
85 C1
<int>::s_tfunc_2
<char>();
89 C1
<int>::s_tfunc_2
<long>(); // expected-warning{{instantiation of function 'C1<int>::s_tfunc_2<long>' required here, but no definition is available}}
90 // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<int>::s_tfunc_2<long>' is explicitly instantiated in another translation unit}}
94 return C1
<int>::C2
<long>::s_var_2
;
98 return C1
<int>::C2
<char>::s_var_2
; //expected-warning {{instantiation of variable 'C1<int>::C2<char>::s_var_2' required here, but no definition is available}}
99 // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<int>::C2<char>::s_var_2' is explicitly instantiated in another translation unit}}
103 C1
<int>::C2
<long>::s_func_2();
107 C1
<int>::C2
<char>::s_func_2(); // expected-warning{{instantiation of function 'C1<int>::C2<char>::s_func_2' required here, but no definition is available}}
108 // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<int>::C2<char>::s_func_2' is explicitly instantiated in another translation unit}}
111 void func_18(C1
<int>::C2
<long> *x
) {
115 void func_19(C1
<int>::C2
<char> *x
) {
116 x
->meth_2(); // expected-warning{{instantiation of function 'C1<int>::C2<char>::meth_2' required here, but no definition is available}}
117 // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<int>::C2<char>::meth_2' is explicitly instantiated in another translation unit}}
121 return C1
<int>::C2
<long>::s_tvar_2
<char>;
125 return C1
<int>::C2
<long>::s_tvar_2
<long>; // expected-warning{{instantiation of variable 'C1<int>::C2<long>::s_tvar_2<long>' required here, but no definition is available}}
126 // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<int>::C2<long>::s_tvar_2<long>' is explicitly instantiated in another translation unit}}
129 void func_22(C1
<int>::C2
<long> *x
) {
133 void func_23(C1
<int>::C2
<long> *x
) {
134 x
->tmeth_2
<int>(); // expected-warning{{instantiation of function 'C1<int>::C2<long>::tmeth_2<int>' required here, but no definition is available}}
135 // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<int>::C2<long>::tmeth_2<int>' is explicitly instantiated in another translation unit}}
139 template <typename T
> struct X
{
141 operator int() { return 0; }
143 void h(X
<int> x
) { g(x
); } // no warning for use of 'g' despite the declaration having been instantiated from a template
147 #include "undefined-template.cpp"
148 void func_25(SystemHeader
<char> *x
) {
156 #pragma clang system_header
157 template <typename T
> struct SystemHeader
{ T
meth(); };