1 // No PCH: 2 // RUN: %clang_cc1 -pedantic -std=c++1y -include %s -include %s -verify %s -DNONPCH 3 // RUN: %clang_cc1 -pedantic -std=c++1y -include %s -include %s -verify %s -DNONPCH -DERROR 4 // 5 // With PCH: 6 // RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch %s -o %t.a -DHEADER1 7 // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.a -emit-pch %s -o %t.b -DHEADER2 8 // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.b -verify %s -DHEADERUSE 9 10 // RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch -fpch-instantiate-templates %s -o %t.a -DHEADER1 11 // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.a -emit-pch -fpch-instantiate-templates %s -o %t.b -DHEADER2 12 // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.b -verify %s -DHEADERUSE 13 14 #ifndef ERROR 15 // expected-no-diagnostics 16 #endif 17 18 #ifdef NONPCH 19 #if !defined(HEADER1) 20 #define HEADER1 21 #undef HEADER2 22 #undef HEADERUSE 23 #elif !defined(HEADER2) 24 #define HEADER2 25 #undef HEADERUSE 26 #else 27 #define HEADERUSE 28 #undef HEADER1 29 #undef HEADER2 30 #endif 31 #endif 32 33 34 // *** HEADER1: First header file 35 #if defined(HEADER1) && !defined(HEADER2) && !defined(HEADERUSE) 36 37 template<typename T> T var0a = T(); 38 template<typename T> extern T var0b; 39 40 namespace join { 41 template<typename T> T va = T(100); 42 template<typename T> extern T vb; 43 44 namespace diff_types { 45 #ifdef ERROR 46 template<typename T> extern float err0; 47 template<typename T> extern T err1; 48 #endif 49 template<typename T> extern T def; 50 } 51 52 } 53 54 namespace spec { 55 template<typename T> constexpr T va = T(10); 56 template<> constexpr float va<float> = 1.5; 57 template constexpr int va<int>; 58 59 template<typename T> T vb = T(); 60 template<> constexpr float vb<float> = 1.5; 61 62 template<typename T> T vc = T(); 63 64 template<typename T> constexpr T vd = T(10); 65 template<typename T> T* vd<T*> = new T(); 66 } 67 68 namespace spec_join1 { 69 template<typename T> T va = T(10); 70 #ifdef ERROR 71 template<> float va<float>; // expected-note {{previous definition is here}} 72 #endif 73 extern template int va<int>; 74 75 template<typename T> T vb = T(10); 76 #ifdef ERROR 77 template<> float vb<float>; // expected-note {{previous definition is here}} 78 #endif 79 80 template<typename T> T vc = T(10); 81 82 template<typename T> T vd = T(10); 83 template<typename T> extern T* vd<T*>; 84 } 85 86 #endif 87 88 89 // *** HEADER2: Second header file -- including HEADER1 90 #if defined(HEADER2) && !defined(HEADERUSE) 91 92 namespace join { 93 template<typename T> extern T va; 94 template<> constexpr float va<float> = 2.5; 95 96 template<typename T> T vb = T(100); 97 98 namespace diff_types { 99 #ifdef ERROR 100 template<typename T> extern T err0; // expected-error {{redeclaration of 'err0' with a different type: 'T' vs 'float'}} // expected-note@46 {{previous declaration is here}} 101 template<typename T> extern float err1; // expected-error {{redeclaration of 'err1' with a different type: 'float' vs 'T'}} // expected-note@47 {{previous declaration is here}} 102 #endif 103 template<typename T> extern T def; 104 } 105 } 106 107 namespace spec_join1 { 108 template<typename T> extern T va; 109 #ifdef ERROR 110 template<> float va<float> = 1.5; // expected-error {{redefinition of 'va<float>'}} 111 #endif 112 extern template int va<int>; 113 114 #ifdef ERROR 115 template<> float vb<float> = 1.5; // expected-error {{redefinition of 'vb<float>'}} 116 #endif 117 template int vb<int>; 118 119 template<> float vc<float> = 1.5; 120 template int vc<int>; 121 122 template<typename T> extern T vd; 123 template<typename T> T* vd<T*> = new T(); 124 } 125 126 #endif 127 128 // *** HEADERUSE: File using both header files -- including HEADER2 129 #ifdef HEADERUSE 130 131 template int var0a<int>; 132 float fvara = var0a<float>; 133 134 template<typename T> extern T var0a; 135 136 template<typename T> T var0b = T(); 137 template int var0b<int>; 138 float fvarb = var0b<float>; 139 140 namespace join { 141 template const int va<const int>; 142 template<> const int va<int> = 50; 143 static_assert(va<float> == 2.5, ""); 144 static_assert(va<int> == 50, ""); 145 146 template<> constexpr float vb<float> = 2.5; 147 template const int vb<const int>; 148 static_assert(vb<float> == 2.5, ""); 149 static_assert(vb<const int> == 100, ""); 150 151 namespace diff_types { 152 template<typename T> T def = T(); 153 } 154 155 } 156 157 namespace spec { 158 static_assert(va<float> == 1.5, ""); 159 static_assert(va<int> == 10, ""); 160 161 template<typename T> T* vb<T*> = new T(); 162 int* intpb = vb<int*>; 163 static_assert(vb<float> == 1.5, ""); 164 165 template<typename T> T* vc<T*> = new T(); 166 template<> constexpr float vc<float> = 1.5; 167 int* intpc = vc<int*>; 168 static_assert(vc<float> == 1.5, ""); 169 170 char* intpd = vd<char*>; 171 } 172 173 namespace spec_join1 { 174 template int va<int>; 175 int a = va<int>; 176 177 template<typename T> extern T vb; 178 int b = vb<int>; 179 180 int* intpb = vd<int*>; 181 } 182 183 #endif 184