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