]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/PCH/cxx1y-variable-templates.cpp
Vendor import of clang release_34 branch r197841 (effectively, 3.4 RC3):
[FreeBSD/FreeBSD.git] / test / PCH / cxx1y-variable-templates.cpp
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 {{redefinition of 'err0' with a different type: 'T' vs 'float'}}  // expected-note@42 {{previous definition is here}}
93     template<typename T> extern float err1; // expected-error {{redefinition of 'err1' with a different type: 'float' vs 'T'}} // expected-note@43 {{previous definition 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