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 template<> extern float va<float>; 71 extern template int va<int>; 72 73 template<typename T> T vb = T(10); 74 template<> extern float vb<float>; 75 76 template<typename T> T vc = T(10); 77 78 template<typename T> T vd = T(10); 79 template<typename T> extern T* vd<T*>; 80 } 81 82 #endif 83 84 85 // *** HEADER2: Second header file -- including HEADER1 86 #if defined(HEADER2) && !defined(HEADERUSE) 87 88 namespace join { 89 template<typename T> extern T va; 90 template<> constexpr float va<float> = 2.5; 91 92 template<typename T> T vb = T(100); 93 94 namespace diff_types { 95 #ifdef ERROR 96 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}} 97 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}} 98 #endif 99 template<typename T> extern T def; 100 } 101 } 102 103 namespace spec_join1 { 104 template<typename T> extern T va; 105 template<> float va<float> = 1.5; 106 extern template int va<int>; 107 108 template<> float vb<float> = 1.5; 109 template int vb<int>; 110 111 template<> float vc<float> = 1.5; 112 template int vc<int>; 113 114 template<typename T> extern T vd; 115 template<typename T> T* vd<T*> = new T(); 116 } 117 118 #endif 119 120 // *** HEADERUSE: File using both header files -- including HEADER2 121 #ifdef HEADERUSE 122 123 template int var0a<int>; 124 float fvara = var0a<float>; 125 126 template<typename T> extern T var0a; 127 128 template<typename T> T var0b = T(); 129 template int var0b<int>; 130 float fvarb = var0b<float>; 131 132 namespace join { 133 template const int va<const int>; 134 template<> const int va<int> = 50; 135 static_assert(va<float> == 2.5, ""); 136 static_assert(va<int> == 50, ""); 137 138 template<> constexpr float vb<float> = 2.5; 139 template const int vb<const int>; 140 static_assert(vb<float> == 2.5, ""); 141 static_assert(vb<const int> == 100, ""); 142 143 namespace diff_types { 144 template<typename T> T def = T(); 145 } 146 147 } 148 149 namespace spec { 150 static_assert(va<float> == 1.5, ""); 151 static_assert(va<int> == 10, ""); 152 153 template<typename T> T* vb<T*> = new T(); 154 int* intpb = vb<int*>; 155 static_assert(vb<float> == 1.5, ""); 156 157 template<typename T> T* vc<T*> = new T(); 158 template<> constexpr float vc<float> = 1.5; 159 int* intpc = vc<int*>; 160 static_assert(vc<float> == 1.5, ""); 161 162 char* intpd = vd<char*>; 163 } 164 165 namespace spec_join1 { 166 template int va<int>; 167 int a = va<int>; 168 169 template<typename T> extern T vb; 170 int b = vb<int>; 171 172 int* intpb = vd<int*>; 173 } 174 175 #endif 176