1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 -Wundefined-func-template %s
2*67e74705SXin Li
3*67e74705SXin Li template <class T> struct C1 {
4*67e74705SXin Li static char s_var_1; // expected-note{{forward declaration of template entity is here}}
5*67e74705SXin Li static char s_var_2; // expected-note{{forward declaration of template entity is here}}
6*67e74705SXin Li static void s_func_1(); // expected-note{{forward declaration of template entity is here}}
7*67e74705SXin Li static void s_func_2(); // expected-note{{forward declaration of template entity is here}}
8*67e74705SXin Li void meth_1(); // expected-note2{{forward declaration of template entity is here}}
9*67e74705SXin Li void meth_2();
10*67e74705SXin Li template <class T1> static char s_tvar_2; // expected-note{{forward declaration of template entity is here}}
11*67e74705SXin Li template <class T1> static void s_tfunc_2(); // expected-note{{forward declaration of template entity is here}}
12*67e74705SXin Li template<typename T1> struct C2 {
13*67e74705SXin Li static char s_var_2; // expected-note{{forward declaration of template entity is here}}
14*67e74705SXin Li static void s_func_2(); // expected-note{{forward declaration of template entity is here}}
15*67e74705SXin Li void meth_2(); // expected-note{{forward declaration of template entity is here}}
16*67e74705SXin Li template <class T2> static char s_tvar_2; // expected-note{{forward declaration of template entity is here}}
17*67e74705SXin Li template <class T2> void tmeth_2(); // expected-note{{forward declaration of template entity is here}}
18*67e74705SXin Li };
19*67e74705SXin Li };
20*67e74705SXin Li
21*67e74705SXin Li extern template char C1<int>::s_var_2;
22*67e74705SXin Li extern template void C1<int>::s_func_2();
23*67e74705SXin Li extern template void C1<int>::meth_2();
24*67e74705SXin Li extern template char C1<int>::s_tvar_2<char>;
25*67e74705SXin Li extern template void C1<int>::s_tfunc_2<char>();
26*67e74705SXin Li extern template void C1<int>::C2<long>::s_var_2;
27*67e74705SXin Li extern template void C1<int>::C2<long>::s_func_2();
28*67e74705SXin Li extern template void C1<int>::C2<long>::meth_2();
29*67e74705SXin Li extern template char C1<int>::C2<long>::s_tvar_2<char>;
30*67e74705SXin Li extern template void C1<int>::C2<long>::tmeth_2<char>();
31*67e74705SXin Li
func_01()32*67e74705SXin Li char func_01() {
33*67e74705SXin Li return C1<int>::s_var_2;
34*67e74705SXin Li }
35*67e74705SXin Li
func_02()36*67e74705SXin Li char func_02() {
37*67e74705SXin Li return C1<int>::s_var_1; // expected-warning{{instantiation of variable 'C1<int>::s_var_1' required here, but no definition is available}}
38*67e74705SXin Li // 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}}
39*67e74705SXin Li }
40*67e74705SXin Li
func_03()41*67e74705SXin Li char func_03() {
42*67e74705SXin Li return C1<char>::s_var_2; // expected-warning{{instantiation of variable 'C1<char>::s_var_2' required here, but no definition is available}}
43*67e74705SXin Li // 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}}
44*67e74705SXin Li }
45*67e74705SXin Li
func_04()46*67e74705SXin Li void func_04() {
47*67e74705SXin Li C1<int>::s_func_1(); // expected-warning{{instantiation of function 'C1<int>::s_func_1' required here, but no definition is available}}
48*67e74705SXin Li // 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}}
49*67e74705SXin Li }
50*67e74705SXin Li
func_05()51*67e74705SXin Li void func_05() {
52*67e74705SXin Li C1<int>::s_func_2();
53*67e74705SXin Li }
54*67e74705SXin Li
func_06()55*67e74705SXin Li void func_06() {
56*67e74705SXin Li C1<char>::s_func_2(); // expected-warning{{instantiation of function 'C1<char>::s_func_2' required here, but no definition is available}}
57*67e74705SXin Li // 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}}
58*67e74705SXin Li }
59*67e74705SXin Li
func_07(C1<int> * x)60*67e74705SXin Li void func_07(C1<int> *x) {
61*67e74705SXin Li x->meth_1(); // expected-warning{{instantiation of function 'C1<int>::meth_1' required here, but no definition is available}}
62*67e74705SXin Li // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<int>::meth_1' is explicitly instantiated in another translation unit}}
63*67e74705SXin Li }
64*67e74705SXin Li
func_08(C1<int> * x)65*67e74705SXin Li void func_08(C1<int> *x) {
66*67e74705SXin Li x->meth_2();
67*67e74705SXin Li }
68*67e74705SXin Li
func_09(C1<char> * x)69*67e74705SXin Li void func_09(C1<char> *x) {
70*67e74705SXin Li x->meth_1(); // expected-warning{{instantiation of function 'C1<char>::meth_1' required here, but no definition is available}}
71*67e74705SXin Li // expected-note@-1{{add an explicit instantiation declaration to suppress this warning if 'C1<char>::meth_1' is explicitly instantiated in another translation unit}}
72*67e74705SXin Li }
73*67e74705SXin Li
func_10()74*67e74705SXin Li char func_10() {
75*67e74705SXin Li return C1<int>::s_tvar_2<char>;
76*67e74705SXin Li }
77*67e74705SXin Li
func_11()78*67e74705SXin Li char func_11() {
79*67e74705SXin Li 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}}
80*67e74705SXin Li // 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}}
81*67e74705SXin Li }
82*67e74705SXin Li
func_12()83*67e74705SXin Li void func_12() {
84*67e74705SXin Li C1<int>::s_tfunc_2<char>();
85*67e74705SXin Li }
86*67e74705SXin Li
func_13()87*67e74705SXin Li void func_13() {
88*67e74705SXin Li C1<int>::s_tfunc_2<long>(); // expected-warning{{instantiation of function 'C1<int>::s_tfunc_2<long>' required here, but no definition is available}}
89*67e74705SXin Li // 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}}
90*67e74705SXin Li }
91*67e74705SXin Li
func_14()92*67e74705SXin Li char func_14() {
93*67e74705SXin Li return C1<int>::C2<long>::s_var_2;
94*67e74705SXin Li }
95*67e74705SXin Li
func_15()96*67e74705SXin Li char func_15() {
97*67e74705SXin Li 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}}
98*67e74705SXin Li // 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}}
99*67e74705SXin Li }
100*67e74705SXin Li
func_16()101*67e74705SXin Li void func_16() {
102*67e74705SXin Li C1<int>::C2<long>::s_func_2();
103*67e74705SXin Li }
104*67e74705SXin Li
func_17()105*67e74705SXin Li void func_17() {
106*67e74705SXin Li 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}}
107*67e74705SXin Li // 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}}
108*67e74705SXin Li }
109*67e74705SXin Li
func_18(C1<int>::C2<long> * x)110*67e74705SXin Li void func_18(C1<int>::C2<long> *x) {
111*67e74705SXin Li x->meth_2();
112*67e74705SXin Li }
113*67e74705SXin Li
func_19(C1<int>::C2<char> * x)114*67e74705SXin Li void func_19(C1<int>::C2<char> *x) {
115*67e74705SXin Li x->meth_2(); // expected-warning{{instantiation of function 'C1<int>::C2<char>::meth_2' required here, but no definition is available}}
116*67e74705SXin Li // 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}}
117*67e74705SXin Li }
118*67e74705SXin Li
func_20()119*67e74705SXin Li char func_20() {
120*67e74705SXin Li return C1<int>::C2<long>::s_tvar_2<char>;
121*67e74705SXin Li }
122*67e74705SXin Li
func_21()123*67e74705SXin Li char func_21() {
124*67e74705SXin Li 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}}
125*67e74705SXin Li // 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}}
126*67e74705SXin Li }
127*67e74705SXin Li
func_22(C1<int>::C2<long> * x)128*67e74705SXin Li void func_22(C1<int>::C2<long> *x) {
129*67e74705SXin Li x->tmeth_2<char>();
130*67e74705SXin Li }
131*67e74705SXin Li
func_23(C1<int>::C2<long> * x)132*67e74705SXin Li void func_23(C1<int>::C2<long> *x) {
133*67e74705SXin Li x->tmeth_2<int>(); // expected-warning{{instantiation of function 'C1<int>::C2<long>::tmeth_2<int>' required here, but no definition is available}}
134*67e74705SXin Li // 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}}
135*67e74705SXin Li }
136*67e74705SXin Li
main()137*67e74705SXin Li int main() {
138*67e74705SXin Li return 0;
139*67e74705SXin Li }
140