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 33template<typename T> T var0a = T(); 34template<typename T> extern T var0b; 35 36namespace 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 50namespace 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 64namespace 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 84namespace 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 99namespace 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 119template int var0a<int>; 120float fvara = var0a<float>; 121 122template<typename T> extern T var0a; 123 124template<typename T> T var0b = T(); 125template int var0b<int>; 126float fvarb = var0b<float>; 127 128namespace 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 145namespace 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 161namespace 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