LLVM API Documentation

TypeBuilder.h
Go to the documentation of this file.
00001 //===---- llvm/TypeBuilder.h - Builder for LLVM types -----------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the TypeBuilder class, which is used as a convenient way to
00011 // create LLVM types with a consistent and simplified interface.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_IR_TYPEBUILDER_H
00016 #define LLVM_IR_TYPEBUILDER_H
00017 
00018 #include "llvm/IR/DerivedTypes.h"
00019 #include "llvm/IR/LLVMContext.h"
00020 #include <climits>
00021 
00022 namespace llvm {
00023 
00024 /// TypeBuilder - This provides a uniform API for looking up types
00025 /// known at compile time.  To support cross-compilation, we define a
00026 /// series of tag types in the llvm::types namespace, like i<N>,
00027 /// ieee_float, ppc_fp128, etc.  TypeBuilder<T, false> allows T to be
00028 /// any of these, a native C type (whose size may depend on the host
00029 /// compiler), or a pointer, function, or struct type built out of
00030 /// these.  TypeBuilder<T, true> removes native C types from this set
00031 /// to guarantee that its result is suitable for cross-compilation.
00032 /// We define the primitive types, pointer types, and functions up to
00033 /// 5 arguments here, but to use this class with your own types,
00034 /// you'll need to specialize it.  For example, say you want to call a
00035 /// function defined externally as:
00036 ///
00037 ///   struct MyType {
00038 ///     int32 a;
00039 ///     int32 *b;
00040 ///     void *array[1];  // Intended as a flexible array.
00041 ///   };
00042 ///   int8 AFunction(struct MyType *value);
00043 ///
00044 /// You'll want to use
00045 ///   Function::Create(TypeBuilder<types::i<8>(MyType*), true>::get(), ...)
00046 /// to declare the function, but when you first try this, your compiler will
00047 /// complain that TypeBuilder<MyType, true>::get() doesn't exist. To fix this,
00048 /// write:
00049 ///
00050 ///   namespace llvm {
00051 ///   template<bool xcompile> class TypeBuilder<MyType, xcompile> {
00052 ///   public:
00053 ///     static StructType *get(LLVMContext &Context) {
00054 ///       // If you cache this result, be sure to cache it separately
00055 ///       // for each LLVMContext.
00056 ///       return StructType::get(
00057 ///         TypeBuilder<types::i<32>, xcompile>::get(Context),
00058 ///         TypeBuilder<types::i<32>*, xcompile>::get(Context),
00059 ///         TypeBuilder<types::i<8>*[], xcompile>::get(Context),
00060 ///         NULL);
00061 ///     }
00062 ///
00063 ///     // You may find this a convenient place to put some constants
00064 ///     // to help with getelementptr.  They don't have any effect on
00065 ///     // the operation of TypeBuilder.
00066 ///     enum Fields {
00067 ///       FIELD_A,
00068 ///       FIELD_B,
00069 ///       FIELD_ARRAY
00070 ///     };
00071 ///   }
00072 ///   }  // namespace llvm
00073 ///
00074 /// TypeBuilder cannot handle recursive types or types you only know at runtime.
00075 /// If you try to give it a recursive type, it will deadlock, infinitely
00076 /// recurse, or do something similarly undesirable.
00077 template<typename T, bool cross_compilable> class TypeBuilder {};
00078 
00079 // Types for use with cross-compilable TypeBuilders.  These correspond
00080 // exactly with an LLVM-native type.
00081 namespace types {
00082 /// i<N> corresponds to the LLVM IntegerType with N bits.
00083 template<uint32_t num_bits> class i {};
00084 
00085 // The following classes represent the LLVM floating types.
00086 class ieee_float {};
00087 class ieee_double {};
00088 class x86_fp80 {};
00089 class fp128 {};
00090 class ppc_fp128 {};
00091 // X86 MMX.
00092 class x86_mmx {};
00093 }  // namespace types
00094 
00095 // LLVM doesn't have const or volatile types.
00096 template<typename T, bool cross> class TypeBuilder<const T, cross>
00097   : public TypeBuilder<T, cross> {};
00098 template<typename T, bool cross> class TypeBuilder<volatile T, cross>
00099   : public TypeBuilder<T, cross> {};
00100 template<typename T, bool cross> class TypeBuilder<const volatile T, cross>
00101   : public TypeBuilder<T, cross> {};
00102 
00103 // Pointers
00104 template<typename T, bool cross> class TypeBuilder<T*, cross> {
00105 public:
00106   static PointerType *get(LLVMContext &Context) {
00107     return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context));
00108   }
00109 };
00110 
00111 /// There is no support for references
00112 template<typename T, bool cross> class TypeBuilder<T&, cross> {};
00113 
00114 // Arrays
00115 template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> {
00116 public:
00117   static ArrayType *get(LLVMContext &Context) {
00118     return ArrayType::get(TypeBuilder<T, cross>::get(Context), N);
00119   }
00120 };
00121 /// LLVM uses an array of length 0 to represent an unknown-length array.
00122 template<typename T, bool cross> class TypeBuilder<T[], cross> {
00123 public:
00124   static ArrayType *get(LLVMContext &Context) {
00125     return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0);
00126   }
00127 };
00128 
00129 // Define the C integral types only for TypeBuilder<T, false>.
00130 //
00131 // C integral types do not have a defined size. It would be nice to use the
00132 // stdint.h-defined typedefs that do have defined sizes, but we'd run into the
00133 // following problem:
00134 //
00135 // On an ILP32 machine, stdint.h might define:
00136 //
00137 //   typedef int int32_t;
00138 //   typedef long long int64_t;
00139 //   typedef long size_t;
00140 //
00141 // If we defined TypeBuilder<int32_t> and TypeBuilder<int64_t>, then any use of
00142 // TypeBuilder<size_t> would fail.  We couldn't define TypeBuilder<size_t> in
00143 // addition to the defined-size types because we'd get duplicate definitions on
00144 // platforms where stdint.h instead defines:
00145 //
00146 //   typedef int int32_t;
00147 //   typedef long long int64_t;
00148 //   typedef int size_t;
00149 //
00150 // So we define all the primitive C types and nothing else.
00151 #define DEFINE_INTEGRAL_TYPEBUILDER(T) \
00152 template<> class TypeBuilder<T, false> { \
00153 public: \
00154   static IntegerType *get(LLVMContext &Context) { \
00155     return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \
00156   } \
00157 }; \
00158 template<> class TypeBuilder<T, true> { \
00159   /* We provide a definition here so users don't accidentally */ \
00160   /* define these types to work. */ \
00161 }
00162 DEFINE_INTEGRAL_TYPEBUILDER(char);
00163 DEFINE_INTEGRAL_TYPEBUILDER(signed char);
00164 DEFINE_INTEGRAL_TYPEBUILDER(unsigned char);
00165 DEFINE_INTEGRAL_TYPEBUILDER(short);
00166 DEFINE_INTEGRAL_TYPEBUILDER(unsigned short);
00167 DEFINE_INTEGRAL_TYPEBUILDER(int);
00168 DEFINE_INTEGRAL_TYPEBUILDER(unsigned int);
00169 DEFINE_INTEGRAL_TYPEBUILDER(long);
00170 DEFINE_INTEGRAL_TYPEBUILDER(unsigned long);
00171 #ifdef _MSC_VER
00172 DEFINE_INTEGRAL_TYPEBUILDER(__int64);
00173 DEFINE_INTEGRAL_TYPEBUILDER(unsigned __int64);
00174 #else /* _MSC_VER */
00175 DEFINE_INTEGRAL_TYPEBUILDER(long long);
00176 DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long);
00177 #endif /* _MSC_VER */
00178 #undef DEFINE_INTEGRAL_TYPEBUILDER
00179 
00180 template<uint32_t num_bits, bool cross>
00181 class TypeBuilder<types::i<num_bits>, cross> {
00182 public:
00183   static IntegerType *get(LLVMContext &C) {
00184     return IntegerType::get(C, num_bits);
00185   }
00186 };
00187 
00188 template<> class TypeBuilder<float, false> {
00189 public:
00190   static Type *get(LLVMContext& C) {
00191     return Type::getFloatTy(C);
00192   }
00193 };
00194 template<> class TypeBuilder<float, true> {};
00195 
00196 template<> class TypeBuilder<double, false> {
00197 public:
00198   static Type *get(LLVMContext& C) {
00199     return Type::getDoubleTy(C);
00200   }
00201 };
00202 template<> class TypeBuilder<double, true> {};
00203 
00204 template<bool cross> class TypeBuilder<types::ieee_float, cross> {
00205 public:
00206   static Type *get(LLVMContext& C) { return Type::getFloatTy(C); }
00207 };
00208 template<bool cross> class TypeBuilder<types::ieee_double, cross> {
00209 public:
00210   static Type *get(LLVMContext& C) { return Type::getDoubleTy(C); }
00211 };
00212 template<bool cross> class TypeBuilder<types::x86_fp80, cross> {
00213 public:
00214   static Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); }
00215 };
00216 template<bool cross> class TypeBuilder<types::fp128, cross> {
00217 public:
00218   static Type *get(LLVMContext& C) { return Type::getFP128Ty(C); }
00219 };
00220 template<bool cross> class TypeBuilder<types::ppc_fp128, cross> {
00221 public:
00222   static Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); }
00223 };
00224 template<bool cross> class TypeBuilder<types::x86_mmx, cross> {
00225 public:
00226   static Type *get(LLVMContext& C) { return Type::getX86_MMXTy(C); }
00227 };
00228 
00229 template<bool cross> class TypeBuilder<void, cross> {
00230 public:
00231   static Type *get(LLVMContext &C) {
00232     return Type::getVoidTy(C);
00233   }
00234 };
00235 
00236 /// void* is disallowed in LLVM types, but it occurs often enough in C code that
00237 /// we special case it.
00238 template<> class TypeBuilder<void*, false>
00239   : public TypeBuilder<types::i<8>*, false> {};
00240 template<> class TypeBuilder<const void*, false>
00241   : public TypeBuilder<types::i<8>*, false> {};
00242 template<> class TypeBuilder<volatile void*, false>
00243   : public TypeBuilder<types::i<8>*, false> {};
00244 template<> class TypeBuilder<const volatile void*, false>
00245   : public TypeBuilder<types::i<8>*, false> {};
00246 
00247 template<typename R, bool cross> class TypeBuilder<R(), cross> {
00248 public:
00249   static FunctionType *get(LLVMContext &Context) {
00250     return FunctionType::get(TypeBuilder<R, cross>::get(Context), false);
00251   }
00252 };
00253 template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> {
00254 public:
00255   static FunctionType *get(LLVMContext &Context) {
00256     Type *params[] = {
00257       TypeBuilder<A1, cross>::get(Context),
00258     };
00259     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
00260                              params, false);
00261   }
00262 };
00263 template<typename R, typename A1, typename A2, bool cross>
00264 class TypeBuilder<R(A1, A2), cross> {
00265 public:
00266   static FunctionType *get(LLVMContext &Context) {
00267     Type *params[] = {
00268       TypeBuilder<A1, cross>::get(Context),
00269       TypeBuilder<A2, cross>::get(Context),
00270     };
00271     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
00272                              params, false);
00273   }
00274 };
00275 template<typename R, typename A1, typename A2, typename A3, bool cross>
00276 class TypeBuilder<R(A1, A2, A3), cross> {
00277 public:
00278   static FunctionType *get(LLVMContext &Context) {
00279     Type *params[] = {
00280       TypeBuilder<A1, cross>::get(Context),
00281       TypeBuilder<A2, cross>::get(Context),
00282       TypeBuilder<A3, cross>::get(Context),
00283     };
00284     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
00285                              params, false);
00286   }
00287 };
00288 
00289 template<typename R, typename A1, typename A2, typename A3, typename A4,
00290          bool cross>
00291 class TypeBuilder<R(A1, A2, A3, A4), cross> {
00292 public:
00293   static FunctionType *get(LLVMContext &Context) {
00294     Type *params[] = {
00295       TypeBuilder<A1, cross>::get(Context),
00296       TypeBuilder<A2, cross>::get(Context),
00297       TypeBuilder<A3, cross>::get(Context),
00298       TypeBuilder<A4, cross>::get(Context),
00299     };
00300     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
00301                              params, false);
00302   }
00303 };
00304 
00305 template<typename R, typename A1, typename A2, typename A3, typename A4,
00306          typename A5, bool cross>
00307 class TypeBuilder<R(A1, A2, A3, A4, A5), cross> {
00308 public:
00309   static FunctionType *get(LLVMContext &Context) {
00310     Type *params[] = {
00311       TypeBuilder<A1, cross>::get(Context),
00312       TypeBuilder<A2, cross>::get(Context),
00313       TypeBuilder<A3, cross>::get(Context),
00314       TypeBuilder<A4, cross>::get(Context),
00315       TypeBuilder<A5, cross>::get(Context),
00316     };
00317     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
00318                              params, false);
00319   }
00320 };
00321 
00322 template<typename R, bool cross> class TypeBuilder<R(...), cross> {
00323 public:
00324   static FunctionType *get(LLVMContext &Context) {
00325     return FunctionType::get(TypeBuilder<R, cross>::get(Context), true);
00326   }
00327 };
00328 template<typename R, typename A1, bool cross>
00329 class TypeBuilder<R(A1, ...), cross> {
00330 public:
00331   static FunctionType *get(LLVMContext &Context) {
00332     Type *params[] = {
00333       TypeBuilder<A1, cross>::get(Context),
00334     };
00335     return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true);
00336   }
00337 };
00338 template<typename R, typename A1, typename A2, bool cross>
00339 class TypeBuilder<R(A1, A2, ...), cross> {
00340 public:
00341   static FunctionType *get(LLVMContext &Context) {
00342     Type *params[] = {
00343       TypeBuilder<A1, cross>::get(Context),
00344       TypeBuilder<A2, cross>::get(Context),
00345     };
00346     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
00347                                    params, true);
00348   }
00349 };
00350 template<typename R, typename A1, typename A2, typename A3, bool cross>
00351 class TypeBuilder<R(A1, A2, A3, ...), cross> {
00352 public:
00353   static FunctionType *get(LLVMContext &Context) {
00354     Type *params[] = {
00355       TypeBuilder<A1, cross>::get(Context),
00356       TypeBuilder<A2, cross>::get(Context),
00357       TypeBuilder<A3, cross>::get(Context),
00358     };
00359     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
00360                                    params, true);
00361   }
00362 };
00363 
00364 template<typename R, typename A1, typename A2, typename A3, typename A4,
00365          bool cross>
00366 class TypeBuilder<R(A1, A2, A3, A4, ...), cross> {
00367 public:
00368   static FunctionType *get(LLVMContext &Context) {
00369     Type *params[] = {
00370       TypeBuilder<A1, cross>::get(Context),
00371       TypeBuilder<A2, cross>::get(Context),
00372       TypeBuilder<A3, cross>::get(Context),
00373       TypeBuilder<A4, cross>::get(Context),
00374     };
00375     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
00376                              params, true);
00377   }
00378 };
00379 
00380 template<typename R, typename A1, typename A2, typename A3, typename A4,
00381          typename A5, bool cross>
00382 class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> {
00383 public:
00384   static FunctionType *get(LLVMContext &Context) {
00385     Type *params[] = {
00386       TypeBuilder<A1, cross>::get(Context),
00387       TypeBuilder<A2, cross>::get(Context),
00388       TypeBuilder<A3, cross>::get(Context),
00389       TypeBuilder<A4, cross>::get(Context),
00390       TypeBuilder<A5, cross>::get(Context),
00391     };
00392     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
00393                                    params, true);
00394   }
00395 };
00396 
00397 }  // namespace llvm
00398 
00399 #endif