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