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