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