1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===---- llvm/Support/TypeBuilder.h - Builder for LLVM types ---*- C++ -*-===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file defines the TypeBuilder class, which is used as a convenient way to 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// create LLVM types with a consistent and simplified interface. 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef LLVM_SUPPORT_TYPEBUILDER_H 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define LLVM_SUPPORT_TYPEBUILDER_H 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/DerivedTypes.h" 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/LLVMContext.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <limits.h> 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace llvm { 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// TypeBuilder - This provides a uniform API for looking up types 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// known at compile time. To support cross-compilation, we define a 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// series of tag types in the llvm::types namespace, like i<N>, 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ieee_float, ppc_fp128, etc. TypeBuilder<T, false> allows T to be 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// any of these, a native C type (whose size may depend on the host 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// compiler), or a pointer, function, or struct type built out of 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// these. TypeBuilder<T, true> removes native C types from this set 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// to guarantee that its result is suitable for cross-compilation. 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// We define the primitive types, pointer types, and functions up to 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 5 arguments here, but to use this class with your own types, 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// you'll need to specialize it. For example, say you want to call a 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// function defined externally as: 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// struct MyType { 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// int32 a; 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// int32 *b; 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// void *array[1]; // Intended as a flexible array. 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// }; 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// int8 AFunction(struct MyType *value); 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// You'll want to use 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Function::Create(TypeBuilder<types::i<8>(MyType*), true>::get(), ...) 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// to declare the function, but when you first try this, your compiler will 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// complain that TypeBuilder<MyType, true>::get() doesn't exist. To fix this, 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// write: 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// namespace llvm { 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// template<bool xcompile> class TypeBuilder<MyType, xcompile> { 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// public: 5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// static StructType *get(LLVMContext &Context) { 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// // If you cache this result, be sure to cache it separately 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// // for each LLVMContext. 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// return StructType::get( 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// TypeBuilder<types::i<32>, xcompile>::get(Context), 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// TypeBuilder<types::i<32>*, xcompile>::get(Context), 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// TypeBuilder<types::i<8>*[], xcompile>::get(Context), 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// NULL); 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// } 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// // You may find this a convenient place to put some constants 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// // to help with getelementptr. They don't have any effect on 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// // the operation of TypeBuilder. 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// enum Fields { 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// FIELD_A, 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// FIELD_B, 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// FIELD_ARRAY 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// }; 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// } 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// } // namespace llvm 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// TypeBuilder cannot handle recursive types or types you only know at runtime. 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// If you try to give it a recursive type, it will deadlock, infinitely 7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// recurse, or do something similarly undesirable. 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename T, bool cross_compilable> class TypeBuilder {}; 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Types for use with cross-compilable TypeBuilders. These correspond 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// exactly with an LLVM-native type. 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace types { 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// i<N> corresponds to the LLVM IntegerType with N bits. 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<uint32_t num_bits> class i {}; 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The following classes represent the LLVM floating types. 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass ieee_float {}; 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass ieee_double {}; 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass x86_fp80 {}; 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass fp128 {}; 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass ppc_fp128 {}; 9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// X86 MMX. 9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass x86_mmx {}; 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} // namespace types 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// LLVM doesn't have const or volatile types. 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename T, bool cross> class TypeBuilder<const T, cross> 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : public TypeBuilder<T, cross> {}; 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename T, bool cross> class TypeBuilder<volatile T, cross> 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : public TypeBuilder<T, cross> {}; 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename T, bool cross> class TypeBuilder<const volatile T, cross> 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : public TypeBuilder<T, cross> {}; 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Pointers 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename T, bool cross> class TypeBuilder<T*, cross> { 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static PointerType *get(LLVMContext &Context) { 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context)); 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// There is no support for references 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename T, bool cross> class TypeBuilder<T&, cross> {}; 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Arrays 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> { 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static ArrayType *get(LLVMContext &Context) { 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ArrayType::get(TypeBuilder<T, cross>::get(Context), N); 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// LLVM uses an array of length 0 to represent an unknown-length array. 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename T, bool cross> class TypeBuilder<T[], cross> { 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static ArrayType *get(LLVMContext &Context) { 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0); 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Define the C integral types only for TypeBuilder<T, false>. 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// C integral types do not have a defined size. It would be nice to use the 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// stdint.h-defined typedefs that do have defined sizes, but we'd run into the 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// following problem: 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// On an ILP32 machine, stdint.h might define: 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// typedef int int32_t; 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// typedef long long int64_t; 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// typedef long size_t; 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// If we defined TypeBuilder<int32_t> and TypeBuilder<int64_t>, then any use of 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// TypeBuilder<size_t> would fail. We couldn't define TypeBuilder<size_t> in 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// addition to the defined-size types because we'd get duplicate definitions on 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// platforms where stdint.h instead defines: 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// typedef int int32_t; 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// typedef long long int64_t; 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// typedef int size_t; 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// So we define all the primitive C types and nothing else. 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define DEFINE_INTEGRAL_TYPEBUILDER(T) \ 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<> class TypeBuilder<T, false> { \ 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: \ 15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static IntegerType *get(LLVMContext &Context) { \ 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \ 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } \ 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; \ 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<> class TypeBuilder<T, true> { \ 159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /* We provide a definition here so users don't accidentally */ \ 160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /* define these types to work. */ \ 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanDEFINE_INTEGRAL_TYPEBUILDER(char); 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanDEFINE_INTEGRAL_TYPEBUILDER(signed char); 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanDEFINE_INTEGRAL_TYPEBUILDER(unsigned char); 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanDEFINE_INTEGRAL_TYPEBUILDER(short); 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanDEFINE_INTEGRAL_TYPEBUILDER(unsigned short); 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanDEFINE_INTEGRAL_TYPEBUILDER(int); 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanDEFINE_INTEGRAL_TYPEBUILDER(unsigned int); 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanDEFINE_INTEGRAL_TYPEBUILDER(long); 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanDEFINE_INTEGRAL_TYPEBUILDER(unsigned long); 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifdef _MSC_VER 172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanDEFINE_INTEGRAL_TYPEBUILDER(__int64); 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanDEFINE_INTEGRAL_TYPEBUILDER(unsigned __int64); 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#else /* _MSC_VER */ 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanDEFINE_INTEGRAL_TYPEBUILDER(long long); 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanDEFINE_INTEGRAL_TYPEBUILDER(unsigned long long); 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif /* _MSC_VER */ 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#undef DEFINE_INTEGRAL_TYPEBUILDER 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<uint32_t num_bits, bool cross> 181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass TypeBuilder<types::i<num_bits>, cross> { 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static IntegerType *get(LLVMContext &C) { 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return IntegerType::get(C, num_bits); 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<> class TypeBuilder<float, false> { 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static Type *get(LLVMContext& C) { 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Type::getFloatTy(C); 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<> class TypeBuilder<float, true> {}; 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<> class TypeBuilder<double, false> { 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static Type *get(LLVMContext& C) { 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Type::getDoubleTy(C); 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<> class TypeBuilder<double, true> {}; 203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<bool cross> class TypeBuilder<types::ieee_float, cross> { 205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static Type *get(LLVMContext& C) { return Type::getFloatTy(C); } 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<bool cross> class TypeBuilder<types::ieee_double, cross> { 209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static Type *get(LLVMContext& C) { return Type::getDoubleTy(C); } 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<bool cross> class TypeBuilder<types::x86_fp80, cross> { 213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); } 215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<bool cross> class TypeBuilder<types::fp128, cross> { 217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static Type *get(LLVMContext& C) { return Type::getFP128Ty(C); } 219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<bool cross> class TypeBuilder<types::ppc_fp128, cross> { 221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); } 22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}; 22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumantemplate<bool cross> class TypeBuilder<types::x86_mmx, cross> { 22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanpublic: 22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static Type *get(LLVMContext& C) { return Type::getX86_MMXTy(C); } 227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<bool cross> class TypeBuilder<void, cross> { 230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static Type *get(LLVMContext &C) { 232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Type::getVoidTy(C); 233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// void* is disallowed in LLVM types, but it occurs often enough in C code that 237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// we special case it. 238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<> class TypeBuilder<void*, false> 239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : public TypeBuilder<types::i<8>*, false> {}; 240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<> class TypeBuilder<const void*, false> 241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : public TypeBuilder<types::i<8>*, false> {}; 242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<> class TypeBuilder<volatile void*, false> 243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : public TypeBuilder<types::i<8>*, false> {}; 244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<> class TypeBuilder<const volatile void*, false> 245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : public TypeBuilder<types::i<8>*, false> {}; 246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename R, bool cross> class TypeBuilder<R(), cross> { 248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static FunctionType *get(LLVMContext &Context) { 250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FunctionType::get(TypeBuilder<R, cross>::get(Context), false); 251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> { 254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static FunctionType *get(LLVMContext &Context) { 25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *params[] = { 25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A1, cross>::get(Context), 25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman }; 259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FunctionType::get(TypeBuilder<R, cross>::get(Context), 260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman params, false); 261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename R, typename A1, typename A2, bool cross> 264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass TypeBuilder<R(A1, A2), cross> { 265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static FunctionType *get(LLVMContext &Context) { 26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *params[] = { 26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A1, cross>::get(Context), 26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A2, cross>::get(Context), 27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman }; 271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FunctionType::get(TypeBuilder<R, cross>::get(Context), 272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman params, false); 273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename R, typename A1, typename A2, typename A3, bool cross> 276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass TypeBuilder<R(A1, A2, A3), cross> { 277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static FunctionType *get(LLVMContext &Context) { 27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *params[] = { 28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A1, cross>::get(Context), 28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A2, cross>::get(Context), 28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A3, cross>::get(Context), 28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman }; 284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FunctionType::get(TypeBuilder<R, cross>::get(Context), 285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman params, false); 286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename R, typename A1, typename A2, typename A3, typename A4, 290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool cross> 291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass TypeBuilder<R(A1, A2, A3, A4), cross> { 292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static FunctionType *get(LLVMContext &Context) { 29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *params[] = { 29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A1, cross>::get(Context), 29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A2, cross>::get(Context), 29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A3, cross>::get(Context), 29819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A4, cross>::get(Context), 29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman }; 300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FunctionType::get(TypeBuilder<R, cross>::get(Context), 301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman params, false); 302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename R, typename A1, typename A2, typename A3, typename A4, 306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman typename A5, bool cross> 307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass TypeBuilder<R(A1, A2, A3, A4, A5), cross> { 308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 30919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static FunctionType *get(LLVMContext &Context) { 31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *params[] = { 31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A1, cross>::get(Context), 31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A2, cross>::get(Context), 31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A3, cross>::get(Context), 31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A4, cross>::get(Context), 31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A5, cross>::get(Context), 31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman }; 317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FunctionType::get(TypeBuilder<R, cross>::get(Context), 318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman params, false); 319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename R, bool cross> class TypeBuilder<R(...), cross> { 323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static FunctionType *get(LLVMContext &Context) { 325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FunctionType::get(TypeBuilder<R, cross>::get(Context), true); 326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename R, typename A1, bool cross> 329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass TypeBuilder<R(A1, ...), cross> { 330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 33119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static FunctionType *get(LLVMContext &Context) { 33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *params[] = { 33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A1, cross>::get(Context), 33419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman }; 335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true); 336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename R, typename A1, typename A2, bool cross> 339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass TypeBuilder<R(A1, A2, ...), cross> { 340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static FunctionType *get(LLVMContext &Context) { 34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *params[] = { 34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A1, cross>::get(Context), 34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A2, cross>::get(Context), 34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman }; 346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FunctionType::get(TypeBuilder<R, cross>::get(Context), 347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman params, true); 348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename R, typename A1, typename A2, typename A3, bool cross> 351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass TypeBuilder<R(A1, A2, A3, ...), cross> { 352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static FunctionType *get(LLVMContext &Context) { 35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *params[] = { 35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A1, cross>::get(Context), 35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A2, cross>::get(Context), 35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A3, cross>::get(Context), 35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman }; 359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FunctionType::get(TypeBuilder<R, cross>::get(Context), 360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman params, true); 361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename R, typename A1, typename A2, typename A3, typename A4, 365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool cross> 366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass TypeBuilder<R(A1, A2, A3, A4, ...), cross> { 367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static FunctionType *get(LLVMContext &Context) { 36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *params[] = { 37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A1, cross>::get(Context), 37119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A2, cross>::get(Context), 37219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A3, cross>::get(Context), 37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A4, cross>::get(Context), 37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman }; 375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FunctionType::get(TypeBuilder<R, cross>::get(Context), 376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman params, true); 377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<typename R, typename A1, typename A2, typename A3, typename A4, 381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman typename A5, bool cross> 382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> { 383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static FunctionType *get(LLVMContext &Context) { 38519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *params[] = { 38619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A1, cross>::get(Context), 38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A2, cross>::get(Context), 38819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A3, cross>::get(Context), 38919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A4, cross>::get(Context), 39019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeBuilder<A5, cross>::get(Context), 39119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman }; 392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return FunctionType::get(TypeBuilder<R, cross>::get(Context), 393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman params, true); 394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} // namespace llvm 398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 400