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