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