OLD | NEW |
1 //===---- llvm/Support/TypeBuilder.h - Builder for LLVM types ---*- C++ -*-===// | 1 //===---- llvm/Support/TypeBuilder.h - Builder for LLVM types ---*- C++ -*-===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file defines the TypeBuilder class, which is used as a convenient way to | 10 // This file defines the TypeBuilder class, which is used as a convenient way to |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 /// | 43 /// |
44 /// You'll want to use | 44 /// You'll want to use |
45 /// Function::Create(TypeBuilder<types::i<8>(MyType*), true>::get(), ...) | 45 /// Function::Create(TypeBuilder<types::i<8>(MyType*), true>::get(), ...) |
46 /// to declare the function, but when you first try this, your compiler will | 46 /// to declare the function, but when you first try this, your compiler will |
47 /// complain that TypeBuilder<MyType, true>::get() doesn't exist. To fix this, | 47 /// complain that TypeBuilder<MyType, true>::get() doesn't exist. To fix this, |
48 /// write: | 48 /// write: |
49 /// | 49 /// |
50 /// namespace llvm { | 50 /// namespace llvm { |
51 /// template<bool xcompile> class TypeBuilder<MyType, xcompile> { | 51 /// template<bool xcompile> class TypeBuilder<MyType, xcompile> { |
52 /// public: | 52 /// public: |
53 /// static const StructType *get() { | 53 /// static const StructType *get(LLVMContext &Context) { |
54 /// // Using the static result variable ensures that the type is | 54 /// // If you cache this result, be sure to cache it separately |
55 /// // only looked up once. | 55 /// // for each LLVMContext. |
56 /// static const StructType *const result = StructType::get( | 56 /// return StructType::get( |
57 /// TypeBuilder<types::i<32>, xcompile>::get(), | 57 /// TypeBuilder<types::i<32>, xcompile>::get(Context), |
58 /// TypeBuilder<types::i<32>*, xcompile>::get(), | 58 /// TypeBuilder<types::i<32>*, xcompile>::get(Context), |
59 /// TypeBuilder<types::i<8>*[], xcompile>::get(), | 59 /// TypeBuilder<types::i<8>*[], xcompile>::get(Context), |
60 /// NULL); | 60 /// NULL); |
61 /// return result; | |
62 /// } | 61 /// } |
63 /// | 62 /// |
64 /// // You may find this a convenient place to put some constants | 63 /// // You may find this a convenient place to put some constants |
65 /// // to help with getelementptr. They don't have any effect on | 64 /// // to help with getelementptr. They don't have any effect on |
66 /// // the operation of TypeBuilder. | 65 /// // the operation of TypeBuilder. |
67 /// enum Fields { | 66 /// enum Fields { |
68 /// FIELD_A, | 67 /// FIELD_A, |
69 /// FIELD_B, | 68 /// FIELD_B, |
70 /// FIELD_ARRAY | 69 /// FIELD_ARRAY |
71 /// }; | 70 /// }; |
72 /// } | 71 /// } |
73 /// } // namespace llvm | 72 /// } // namespace llvm |
74 /// | 73 /// |
75 /// Using the static result variable ensures that the type is only looked up | |
76 /// once. | |
77 /// | |
78 /// TypeBuilder cannot handle recursive types or types you only know at runtime. | 74 /// TypeBuilder cannot handle recursive types or types you only know at runtime. |
79 /// If you try to give it a recursive type, it will deadlock, infinitely | 75 /// If you try to give it a recursive type, it will deadlock, infinitely |
80 /// recurse, or throw a recursive_init exception. | 76 /// recurse, or throw a recursive_init exception. |
81 template<typename T, bool cross_compilable> class TypeBuilder {}; | 77 template<typename T, bool cross_compilable> class TypeBuilder {}; |
82 | 78 |
83 // Types for use with cross-compilable TypeBuilders. These correspond | 79 // Types for use with cross-compilable TypeBuilders. These correspond |
84 // exactly with an LLVM-native type. | 80 // exactly with an LLVM-native type. |
85 namespace types { | 81 namespace types { |
86 /// i<N> corresponds to the LLVM IntegerType with N bits. | 82 /// i<N> corresponds to the LLVM IntegerType with N bits. |
87 template<uint32_t num_bits> class i {}; | 83 template<uint32_t num_bits> class i {}; |
(...skipping 11 matching lines...) Expand all Loading... |
99 : public TypeBuilder<T, cross> {}; | 95 : public TypeBuilder<T, cross> {}; |
100 template<typename T, bool cross> class TypeBuilder<volatile T, cross> | 96 template<typename T, bool cross> class TypeBuilder<volatile T, cross> |
101 : public TypeBuilder<T, cross> {}; | 97 : public TypeBuilder<T, cross> {}; |
102 template<typename T, bool cross> class TypeBuilder<const volatile T, cross> | 98 template<typename T, bool cross> class TypeBuilder<const volatile T, cross> |
103 : public TypeBuilder<T, cross> {}; | 99 : public TypeBuilder<T, cross> {}; |
104 | 100 |
105 // Pointers | 101 // Pointers |
106 template<typename T, bool cross> class TypeBuilder<T*, cross> { | 102 template<typename T, bool cross> class TypeBuilder<T*, cross> { |
107 public: | 103 public: |
108 static const PointerType *get(LLVMContext &Context) { | 104 static const PointerType *get(LLVMContext &Context) { |
109 static const PointerType *const result = | 105 return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context)); |
110 PointerType::getUnqual(TypeBuilder<T,cross>::get(Context)); | |
111 return result; | |
112 } | 106 } |
113 }; | 107 }; |
114 | 108 |
115 /// There is no support for references | 109 /// There is no support for references |
116 template<typename T, bool cross> class TypeBuilder<T&, cross> {}; | 110 template<typename T, bool cross> class TypeBuilder<T&, cross> {}; |
117 | 111 |
118 // Arrays | 112 // Arrays |
119 template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> { | 113 template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> { |
120 public: | 114 public: |
121 static const ArrayType *get(LLVMContext &Context) { | 115 static const ArrayType *get(LLVMContext &Context) { |
122 static const ArrayType *const result = | 116 return ArrayType::get(TypeBuilder<T, cross>::get(Context), N); |
123 ArrayType::get(TypeBuilder<T, cross>::get(Context), N); | |
124 return result; | |
125 } | 117 } |
126 }; | 118 }; |
127 /// LLVM uses an array of length 0 to represent an unknown-length array. | 119 /// LLVM uses an array of length 0 to represent an unknown-length array. |
128 template<typename T, bool cross> class TypeBuilder<T[], cross> { | 120 template<typename T, bool cross> class TypeBuilder<T[], cross> { |
129 public: | 121 public: |
130 static const ArrayType *get(LLVMContext &Context) { | 122 static const ArrayType *get(LLVMContext &Context) { |
131 static const ArrayType *const result = | 123 return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0); |
132 ArrayType::get(TypeBuilder<T, cross>::get(Context), 0); | |
133 return result; | |
134 } | 124 } |
135 }; | 125 }; |
136 | 126 |
137 // Define the C integral types only for TypeBuilder<T, false>. | 127 // Define the C integral types only for TypeBuilder<T, false>. |
138 // | 128 // |
139 // C integral types do not have a defined size. It would be nice to use the | 129 // C integral types do not have a defined size. It would be nice to use the |
140 // stdint.h-defined typedefs that do have defined sizes, but we'd run into the | 130 // stdint.h-defined typedefs that do have defined sizes, but we'd run into the |
141 // following problem: | 131 // following problem: |
142 // | 132 // |
143 // On an ILP32 machine, stdint.h might define: | 133 // On an ILP32 machine, stdint.h might define: |
144 // | 134 // |
145 // typedef int int32_t; | 135 // typedef int int32_t; |
146 // typedef long long int64_t; | 136 // typedef long long int64_t; |
147 // typedef long size_t; | 137 // typedef long size_t; |
148 // | 138 // |
149 // If we defined TypeBuilder<int32_t> and TypeBuilder<int64_t>, then any use of | 139 // If we defined TypeBuilder<int32_t> and TypeBuilder<int64_t>, then any use of |
150 // TypeBuilder<size_t> would fail. We couldn't define TypeBuilder<size_t> in | 140 // TypeBuilder<size_t> would fail. We couldn't define TypeBuilder<size_t> in |
151 // addition to the defined-size types because we'd get duplicate definitions on | 141 // addition to the defined-size types because we'd get duplicate definitions on |
152 // platforms where stdint.h instead defines: | 142 // platforms where stdint.h instead defines: |
153 // | 143 // |
154 // typedef int int32_t; | 144 // typedef int int32_t; |
155 // typedef long long int64_t; | 145 // typedef long long int64_t; |
156 // typedef int size_t; | 146 // typedef int size_t; |
157 // | 147 // |
158 // So we define all the primitive C types and nothing else. | 148 // So we define all the primitive C types and nothing else. |
159 #define DEFINE_INTEGRAL_TYPEBUILDER(T) \ | 149 #define DEFINE_INTEGRAL_TYPEBUILDER(T) \ |
160 template<> class TypeBuilder<T, false> { \ | 150 template<> class TypeBuilder<T, false> { \ |
161 public: \ | 151 public: \ |
162 static const IntegerType *get(LLVMContext &Context) { \ | 152 static const IntegerType *get(LLVMContext &Context) { \ |
163 static const IntegerType *const result = \ | 153 return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \ |
164 IntegerType::get(Context, sizeof(T) * CHAR_BIT); \ | |
165 return result; \ | |
166 } \ | 154 } \ |
167 }; \ | 155 }; \ |
168 template<> class TypeBuilder<T, true> { \ | 156 template<> class TypeBuilder<T, true> { \ |
169 /* We provide a definition here so users don't accidentally */ \ | 157 /* We provide a definition here so users don't accidentally */ \ |
170 /* define these types to work. */ \ | 158 /* define these types to work. */ \ |
171 } | 159 } |
172 DEFINE_INTEGRAL_TYPEBUILDER(char); | 160 DEFINE_INTEGRAL_TYPEBUILDER(char); |
173 DEFINE_INTEGRAL_TYPEBUILDER(signed char); | 161 DEFINE_INTEGRAL_TYPEBUILDER(signed char); |
174 DEFINE_INTEGRAL_TYPEBUILDER(unsigned char); | 162 DEFINE_INTEGRAL_TYPEBUILDER(unsigned char); |
175 DEFINE_INTEGRAL_TYPEBUILDER(short); | 163 DEFINE_INTEGRAL_TYPEBUILDER(short); |
176 DEFINE_INTEGRAL_TYPEBUILDER(unsigned short); | 164 DEFINE_INTEGRAL_TYPEBUILDER(unsigned short); |
177 DEFINE_INTEGRAL_TYPEBUILDER(int); | 165 DEFINE_INTEGRAL_TYPEBUILDER(int); |
178 DEFINE_INTEGRAL_TYPEBUILDER(unsigned int); | 166 DEFINE_INTEGRAL_TYPEBUILDER(unsigned int); |
179 DEFINE_INTEGRAL_TYPEBUILDER(long); | 167 DEFINE_INTEGRAL_TYPEBUILDER(long); |
180 DEFINE_INTEGRAL_TYPEBUILDER(unsigned long); | 168 DEFINE_INTEGRAL_TYPEBUILDER(unsigned long); |
181 #ifdef _MSC_VER | 169 #ifdef _MSC_VER |
182 DEFINE_INTEGRAL_TYPEBUILDER(__int64); | 170 DEFINE_INTEGRAL_TYPEBUILDER(__int64); |
183 DEFINE_INTEGRAL_TYPEBUILDER(unsigned __int64); | 171 DEFINE_INTEGRAL_TYPEBUILDER(unsigned __int64); |
184 #else /* _MSC_VER */ | 172 #else /* _MSC_VER */ |
185 DEFINE_INTEGRAL_TYPEBUILDER(long long); | 173 DEFINE_INTEGRAL_TYPEBUILDER(long long); |
186 DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long); | 174 DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long); |
187 #endif /* _MSC_VER */ | 175 #endif /* _MSC_VER */ |
188 #undef DEFINE_INTEGRAL_TYPEBUILDER | 176 #undef DEFINE_INTEGRAL_TYPEBUILDER |
189 | 177 |
190 template<uint32_t num_bits, bool cross> | 178 template<uint32_t num_bits, bool cross> |
191 class TypeBuilder<types::i<num_bits>, cross> { | 179 class TypeBuilder<types::i<num_bits>, cross> { |
192 public: | 180 public: |
193 static const IntegerType *get(LLVMContext &C) { | 181 static const IntegerType *get(LLVMContext &C) { |
194 static const IntegerType *const result = IntegerType::get(C, num_bits); | 182 return IntegerType::get(C, num_bits); |
195 return result; | |
196 } | 183 } |
197 }; | 184 }; |
198 | 185 |
199 template<> class TypeBuilder<float, false> { | 186 template<> class TypeBuilder<float, false> { |
200 public: | 187 public: |
201 static const Type *get(LLVMContext& C) { | 188 static const Type *get(LLVMContext& C) { |
202 return Type::getFloatTy(C); | 189 return Type::getFloatTy(C); |
203 } | 190 } |
204 }; | 191 }; |
205 template<> class TypeBuilder<float, true> {}; | 192 template<> class TypeBuilder<float, true> {}; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 }; | 228 }; |
242 | 229 |
243 /// void* is disallowed in LLVM types, but it occurs often enough in C code that | 230 /// void* is disallowed in LLVM types, but it occurs often enough in C code that |
244 /// we special case it. | 231 /// we special case it. |
245 template<> class TypeBuilder<void*, false> | 232 template<> class TypeBuilder<void*, false> |
246 : public TypeBuilder<types::i<8>*, false> {}; | 233 : public TypeBuilder<types::i<8>*, false> {}; |
247 | 234 |
248 template<typename R, bool cross> class TypeBuilder<R(), cross> { | 235 template<typename R, bool cross> class TypeBuilder<R(), cross> { |
249 public: | 236 public: |
250 static const FunctionType *get(LLVMContext &Context) { | 237 static const FunctionType *get(LLVMContext &Context) { |
251 static const FunctionType *const result = create(Context); | |
252 return result; | |
253 } | |
254 | |
255 private: | |
256 static const FunctionType *create(LLVMContext &Context) { | |
257 return FunctionType::get(TypeBuilder<R, cross>::get(Context), false); | 238 return FunctionType::get(TypeBuilder<R, cross>::get(Context), false); |
258 } | 239 } |
259 }; | 240 }; |
260 template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> { | 241 template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> { |
261 public: | 242 public: |
262 static const FunctionType *get(LLVMContext &Context) { | 243 static const FunctionType *get(LLVMContext &Context) { |
263 static const FunctionType *const result = create(Context); | |
264 return result; | |
265 } | |
266 | |
267 private: | |
268 static const FunctionType *create(LLVMContext &Context) { | |
269 std::vector<const Type*> params; | 244 std::vector<const Type*> params; |
270 params.reserve(1); | 245 params.reserve(1); |
271 params.push_back(TypeBuilder<A1, cross>::get(Context)); | 246 params.push_back(TypeBuilder<A1, cross>::get(Context)); |
272 return FunctionType::get(TypeBuilder<R, cross>::get(Context), | 247 return FunctionType::get(TypeBuilder<R, cross>::get(Context), |
273 params, false); | 248 params, false); |
274 } | 249 } |
275 }; | 250 }; |
276 template<typename R, typename A1, typename A2, bool cross> | 251 template<typename R, typename A1, typename A2, bool cross> |
277 class TypeBuilder<R(A1, A2), cross> { | 252 class TypeBuilder<R(A1, A2), cross> { |
278 public: | 253 public: |
279 static const FunctionType *get(LLVMContext &Context) { | 254 static const FunctionType *get(LLVMContext &Context) { |
280 static const FunctionType *const result = create(Context); | |
281 return result; | |
282 } | |
283 | |
284 private: | |
285 static const FunctionType *create(LLVMContext &Context) { | |
286 std::vector<const Type*> params; | 255 std::vector<const Type*> params; |
287 params.reserve(2); | 256 params.reserve(2); |
288 params.push_back(TypeBuilder<A1, cross>::get(Context)); | 257 params.push_back(TypeBuilder<A1, cross>::get(Context)); |
289 params.push_back(TypeBuilder<A2, cross>::get(Context)); | 258 params.push_back(TypeBuilder<A2, cross>::get(Context)); |
290 return FunctionType::get(TypeBuilder<R, cross>::get(Context), | 259 return FunctionType::get(TypeBuilder<R, cross>::get(Context), |
291 params, false); | 260 params, false); |
292 } | 261 } |
293 }; | 262 }; |
294 template<typename R, typename A1, typename A2, typename A3, bool cross> | 263 template<typename R, typename A1, typename A2, typename A3, bool cross> |
295 class TypeBuilder<R(A1, A2, A3), cross> { | 264 class TypeBuilder<R(A1, A2, A3), cross> { |
296 public: | 265 public: |
297 static const FunctionType *get(LLVMContext &Context) { | 266 static const FunctionType *get(LLVMContext &Context) { |
298 static const FunctionType *const result = create(Context); | |
299 return result; | |
300 } | |
301 | |
302 private: | |
303 static const FunctionType *create(LLVMContext &Context) { | |
304 std::vector<const Type*> params; | 267 std::vector<const Type*> params; |
305 params.reserve(3); | 268 params.reserve(3); |
306 params.push_back(TypeBuilder<A1, cross>::get(Context)); | 269 params.push_back(TypeBuilder<A1, cross>::get(Context)); |
307 params.push_back(TypeBuilder<A2, cross>::get(Context)); | 270 params.push_back(TypeBuilder<A2, cross>::get(Context)); |
308 params.push_back(TypeBuilder<A3, cross>::get(Context)); | 271 params.push_back(TypeBuilder<A3, cross>::get(Context)); |
309 return FunctionType::get(TypeBuilder<R, cross>::get(Context), | 272 return FunctionType::get(TypeBuilder<R, cross>::get(Context), |
310 params, false); | 273 params, false); |
311 } | 274 } |
312 }; | 275 }; |
313 | 276 |
314 template<typename R, typename A1, typename A2, typename A3, typename A4, | 277 template<typename R, typename A1, typename A2, typename A3, typename A4, |
315 bool cross> | 278 bool cross> |
316 class TypeBuilder<R(A1, A2, A3, A4), cross> { | 279 class TypeBuilder<R(A1, A2, A3, A4), cross> { |
317 public: | 280 public: |
318 static const FunctionType *get(LLVMContext &Context) { | 281 static const FunctionType *get(LLVMContext &Context) { |
319 static const FunctionType *const result = create(Context); | |
320 return result; | |
321 } | |
322 | |
323 private: | |
324 static const FunctionType *create(LLVMContext &Context) { | |
325 std::vector<const Type*> params; | 282 std::vector<const Type*> params; |
326 params.reserve(4); | 283 params.reserve(4); |
327 params.push_back(TypeBuilder<A1, cross>::get(Context)); | 284 params.push_back(TypeBuilder<A1, cross>::get(Context)); |
328 params.push_back(TypeBuilder<A2, cross>::get(Context)); | 285 params.push_back(TypeBuilder<A2, cross>::get(Context)); |
329 params.push_back(TypeBuilder<A3, cross>::get(Context)); | 286 params.push_back(TypeBuilder<A3, cross>::get(Context)); |
330 params.push_back(TypeBuilder<A4, cross>::get(Context)); | 287 params.push_back(TypeBuilder<A4, cross>::get(Context)); |
331 return FunctionType::get(TypeBuilder<R, cross>::get(Context), | 288 return FunctionType::get(TypeBuilder<R, cross>::get(Context), |
332 params, false); | 289 params, false); |
333 } | 290 } |
334 }; | 291 }; |
335 | 292 |
336 template<typename R, typename A1, typename A2, typename A3, typename A4, | 293 template<typename R, typename A1, typename A2, typename A3, typename A4, |
337 typename A5, bool cross> | 294 typename A5, bool cross> |
338 class TypeBuilder<R(A1, A2, A3, A4, A5), cross> { | 295 class TypeBuilder<R(A1, A2, A3, A4, A5), cross> { |
339 public: | 296 public: |
340 static const FunctionType *get(LLVMContext &Context) { | 297 static const FunctionType *get(LLVMContext &Context) { |
341 static const FunctionType *const result = create(Context); | |
342 return result; | |
343 } | |
344 | |
345 private: | |
346 static const FunctionType *create(LLVMContext &Context) { | |
347 std::vector<const Type*> params; | 298 std::vector<const Type*> params; |
348 params.reserve(5); | 299 params.reserve(5); |
349 params.push_back(TypeBuilder<A1, cross>::get(Context)); | 300 params.push_back(TypeBuilder<A1, cross>::get(Context)); |
350 params.push_back(TypeBuilder<A2, cross>::get(Context)); | 301 params.push_back(TypeBuilder<A2, cross>::get(Context)); |
351 params.push_back(TypeBuilder<A3, cross>::get(Context)); | 302 params.push_back(TypeBuilder<A3, cross>::get(Context)); |
352 params.push_back(TypeBuilder<A4, cross>::get(Context)); | 303 params.push_back(TypeBuilder<A4, cross>::get(Context)); |
353 params.push_back(TypeBuilder<A5, cross>::get(Context)); | 304 params.push_back(TypeBuilder<A5, cross>::get(Context)); |
354 return FunctionType::get(TypeBuilder<R, cross>::get(Context), | 305 return FunctionType::get(TypeBuilder<R, cross>::get(Context), |
355 params, false); | 306 params, false); |
356 } | 307 } |
357 }; | 308 }; |
358 | 309 |
359 template<typename R, bool cross> class TypeBuilder<R(...), cross> { | 310 template<typename R, bool cross> class TypeBuilder<R(...), cross> { |
360 public: | 311 public: |
361 static const FunctionType *get(LLVMContext &Context) { | 312 static const FunctionType *get(LLVMContext &Context) { |
362 static const FunctionType *const result = create(Context); | |
363 return result; | |
364 } | |
365 | |
366 private: | |
367 static const FunctionType *create(LLVMContext &Context) { | |
368 return FunctionType::get(TypeBuilder<R, cross>::get(Context), true); | 313 return FunctionType::get(TypeBuilder<R, cross>::get(Context), true); |
369 } | 314 } |
370 }; | 315 }; |
371 template<typename R, typename A1, bool cross> | 316 template<typename R, typename A1, bool cross> |
372 class TypeBuilder<R(A1, ...), cross> { | 317 class TypeBuilder<R(A1, ...), cross> { |
373 public: | 318 public: |
374 static const FunctionType *get(LLVMContext &Context) { | 319 static const FunctionType *get(LLVMContext &Context) { |
375 static const FunctionType *const result = create(Context); | |
376 return result; | |
377 } | |
378 | |
379 private: | |
380 static const FunctionType *create(LLVMContext &Context) { | |
381 std::vector<const Type*> params; | 320 std::vector<const Type*> params; |
382 params.reserve(1); | 321 params.reserve(1); |
383 params.push_back(TypeBuilder<A1, cross>::get(Context)); | 322 params.push_back(TypeBuilder<A1, cross>::get(Context)); |
384 return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true); | 323 return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true); |
385 } | 324 } |
386 }; | 325 }; |
387 template<typename R, typename A1, typename A2, bool cross> | 326 template<typename R, typename A1, typename A2, bool cross> |
388 class TypeBuilder<R(A1, A2, ...), cross> { | 327 class TypeBuilder<R(A1, A2, ...), cross> { |
389 public: | 328 public: |
390 static const FunctionType *get(LLVMContext &Context) { | 329 static const FunctionType *get(LLVMContext &Context) { |
391 static const FunctionType *const result = create(Context); | |
392 return result; | |
393 } | |
394 | |
395 private: | |
396 static const FunctionType *create(LLVMContext &Context) { | |
397 std::vector<const Type*> params; | 330 std::vector<const Type*> params; |
398 params.reserve(2); | 331 params.reserve(2); |
399 params.push_back(TypeBuilder<A1, cross>::get(Context)); | 332 params.push_back(TypeBuilder<A1, cross>::get(Context)); |
400 params.push_back(TypeBuilder<A2, cross>::get(Context)); | 333 params.push_back(TypeBuilder<A2, cross>::get(Context)); |
401 return FunctionType::get(TypeBuilder<R, cross>::get(Context), | 334 return FunctionType::get(TypeBuilder<R, cross>::get(Context), |
402 params, true); | 335 params, true); |
403 } | 336 } |
404 }; | 337 }; |
405 template<typename R, typename A1, typename A2, typename A3, bool cross> | 338 template<typename R, typename A1, typename A2, typename A3, bool cross> |
406 class TypeBuilder<R(A1, A2, A3, ...), cross> { | 339 class TypeBuilder<R(A1, A2, A3, ...), cross> { |
407 public: | 340 public: |
408 static const FunctionType *get(LLVMContext &Context) { | 341 static const FunctionType *get(LLVMContext &Context) { |
409 static const FunctionType *const result = create(Context); | |
410 return result; | |
411 } | |
412 | |
413 private: | |
414 static const FunctionType *create(LLVMContext &Context) { | |
415 std::vector<const Type*> params; | 342 std::vector<const Type*> params; |
416 params.reserve(3); | 343 params.reserve(3); |
417 params.push_back(TypeBuilder<A1, cross>::get(Context)); | 344 params.push_back(TypeBuilder<A1, cross>::get(Context)); |
418 params.push_back(TypeBuilder<A2, cross>::get(Context)); | 345 params.push_back(TypeBuilder<A2, cross>::get(Context)); |
419 params.push_back(TypeBuilder<A3, cross>::get(Context)); | 346 params.push_back(TypeBuilder<A3, cross>::get(Context)); |
420 return FunctionType::get(TypeBuilder<R, cross>::get(Context), | 347 return FunctionType::get(TypeBuilder<R, cross>::get(Context), |
421 params, true); | 348 params, true); |
422 } | 349 } |
423 }; | 350 }; |
424 | 351 |
425 template<typename R, typename A1, typename A2, typename A3, typename A4, | 352 template<typename R, typename A1, typename A2, typename A3, typename A4, |
426 bool cross> | 353 bool cross> |
427 class TypeBuilder<R(A1, A2, A3, A4, ...), cross> { | 354 class TypeBuilder<R(A1, A2, A3, A4, ...), cross> { |
428 public: | 355 public: |
429 static const FunctionType *get(LLVMContext &Context) { | 356 static const FunctionType *get(LLVMContext &Context) { |
430 static const FunctionType *const result = create(Context); | |
431 return result; | |
432 } | |
433 | |
434 private: | |
435 static const FunctionType *create(LLVMContext &Context) { | |
436 std::vector<const Type*> params; | 357 std::vector<const Type*> params; |
437 params.reserve(4); | 358 params.reserve(4); |
438 params.push_back(TypeBuilder<A1, cross>::get(Context)); | 359 params.push_back(TypeBuilder<A1, cross>::get(Context)); |
439 params.push_back(TypeBuilder<A2, cross>::get(Context)); | 360 params.push_back(TypeBuilder<A2, cross>::get(Context)); |
440 params.push_back(TypeBuilder<A3, cross>::get(Context)); | 361 params.push_back(TypeBuilder<A3, cross>::get(Context)); |
441 params.push_back(TypeBuilder<A4, cross>::get(Context)); | 362 params.push_back(TypeBuilder<A4, cross>::get(Context)); |
442 return FunctionType::get(TypeBuilder<R, cross>::get(Context), | 363 return FunctionType::get(TypeBuilder<R, cross>::get(Context), |
443 params, true); | 364 params, true); |
444 } | 365 } |
445 }; | 366 }; |
446 | 367 |
447 template<typename R, typename A1, typename A2, typename A3, typename A4, | 368 template<typename R, typename A1, typename A2, typename A3, typename A4, |
448 typename A5, bool cross> | 369 typename A5, bool cross> |
449 class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> { | 370 class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> { |
450 public: | 371 public: |
451 static const FunctionType *get(LLVMContext &Context) { | 372 static const FunctionType *get(LLVMContext &Context) { |
452 static const FunctionType *const result = create(Context); | |
453 return result; | |
454 } | |
455 | |
456 private: | |
457 static const FunctionType *create(LLVMContext &Context) { | |
458 std::vector<const Type*> params; | 373 std::vector<const Type*> params; |
459 params.reserve(5); | 374 params.reserve(5); |
460 params.push_back(TypeBuilder<A1, cross>::get(Context)); | 375 params.push_back(TypeBuilder<A1, cross>::get(Context)); |
461 params.push_back(TypeBuilder<A2, cross>::get(Context)); | 376 params.push_back(TypeBuilder<A2, cross>::get(Context)); |
462 params.push_back(TypeBuilder<A3, cross>::get(Context)); | 377 params.push_back(TypeBuilder<A3, cross>::get(Context)); |
463 params.push_back(TypeBuilder<A4, cross>::get(Context)); | 378 params.push_back(TypeBuilder<A4, cross>::get(Context)); |
464 params.push_back(TypeBuilder<A5, cross>::get(Context)); | 379 params.push_back(TypeBuilder<A5, cross>::get(Context)); |
465 return FunctionType::get(TypeBuilder<R, cross>::get(Context), | 380 return FunctionType::get(TypeBuilder<R, cross>::get(Context), |
466 params, true); | 381 params, true); |
467 } | 382 } |
468 }; | 383 }; |
469 | 384 |
470 } // namespace llvm | 385 } // namespace llvm |
471 | 386 |
472 #endif | 387 #endif |
OLD | NEW |