LCOV - code coverage report
Current view: top level - include/llvm/IR - TypeBuilder.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 125 125 100.0 %
Date: 2018-10-20 13:21:21 Functions: 33 33 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===---- llvm/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_IR_TYPEBUILDER_H
      16             : #define LLVM_IR_TYPEBUILDER_H
      17             : 
      18             : #include "llvm/IR/DerivedTypes.h"
      19             : #include "llvm/IR/LLVMContext.h"
      20             : #include <climits>
      21             : 
      22             : namespace llvm {
      23             : 
      24             : /// TypeBuilder - This provides a uniform API for looking up types
      25             : /// known at compile time.  To support cross-compilation, we define a
      26             : /// series of tag types in the llvm::types namespace, like i<N>,
      27             : /// ieee_float, ppc_fp128, etc.  TypeBuilder<T, false> allows T to be
      28             : /// any of these, a native C type (whose size may depend on the host
      29             : /// compiler), or a pointer, function, or struct type built out of
      30             : /// these.  TypeBuilder<T, true> removes native C types from this set
      31             : /// to guarantee that its result is suitable for cross-compilation.
      32             : /// We define the primitive types, pointer types, and functions up to
      33             : /// 5 arguments here, but to use this class with your own types,
      34             : /// you'll need to specialize it.  For example, say you want to call a
      35             : /// function defined externally as:
      36             : ///
      37             : /// \code{.cpp}
      38             : ///
      39             : ///   struct MyType {
      40             : ///     int32 a;
      41             : ///     int32 *b;
      42             : ///     void *array[1];  // Intended as a flexible array.
      43             : ///   };
      44             : ///   int8 AFunction(struct MyType *value);
      45             : ///
      46             : /// \endcode
      47             : ///
      48             : /// You'll want to use
      49             : ///   Function::Create(TypeBuilder<types::i<8>(MyType*), true>::get(), ...)
      50             : /// to declare the function, but when you first try this, your compiler will
      51             : /// complain that TypeBuilder<MyType, true>::get() doesn't exist. To fix this,
      52             : /// write:
      53             : ///
      54             : /// \code{.cpp}
      55             : ///
      56             : ///   namespace llvm {
      57             : ///   template<bool xcompile> class TypeBuilder<MyType, xcompile> {
      58             : ///   public:
      59             : ///     static StructType *get(LLVMContext &Context) {
      60             : ///       // If you cache this result, be sure to cache it separately
      61             : ///       // for each LLVMContext.
      62             : ///       return StructType::get(
      63             : ///         TypeBuilder<types::i<32>, xcompile>::get(Context),
      64             : ///         TypeBuilder<types::i<32>*, xcompile>::get(Context),
      65             : ///         TypeBuilder<types::i<8>*[], xcompile>::get(Context),
      66             : ///         nullptr);
      67             : ///     }
      68             : ///
      69             : ///     // You may find this a convenient place to put some constants
      70             : ///     // to help with getelementptr.  They don't have any effect on
      71             : ///     // the operation of TypeBuilder.
      72             : ///     enum Fields {
      73             : ///       FIELD_A,
      74             : ///       FIELD_B,
      75             : ///       FIELD_ARRAY
      76             : ///     };
      77             : ///   }
      78             : ///   }  // namespace llvm
      79             : ///
      80             : /// \endcode
      81             : ///
      82             : /// TypeBuilder cannot handle recursive types or types you only know at runtime.
      83             : /// If you try to give it a recursive type, it will deadlock, infinitely
      84             : /// recurse, or do something similarly undesirable.
      85             : template<typename T, bool cross_compilable> class TypeBuilder {};
      86             : 
      87             : // Types for use with cross-compilable TypeBuilders.  These correspond
      88             : // exactly with an LLVM-native type.
      89             : namespace types {
      90             : /// i<N> corresponds to the LLVM IntegerType with N bits.
      91             : template<uint32_t num_bits> class i {};
      92             : 
      93             : // The following classes represent the LLVM floating types.
      94             : class ieee_float {};
      95             : class ieee_double {};
      96             : class x86_fp80 {};
      97             : class fp128 {};
      98             : class ppc_fp128 {};
      99             : // X86 MMX.
     100             : class x86_mmx {};
     101             : }  // namespace types
     102             : 
     103             : // LLVM doesn't have const or volatile types.
     104             : template<typename T, bool cross> class TypeBuilder<const T, cross>
     105             :   : public TypeBuilder<T, cross> {};
     106             : template<typename T, bool cross> class TypeBuilder<volatile T, cross>
     107             :   : public TypeBuilder<T, cross> {};
     108             : template<typename T, bool cross> class TypeBuilder<const volatile T, cross>
     109             :   : public TypeBuilder<T, cross> {};
     110             : 
     111             : // Pointers
     112             : template<typename T, bool cross> class TypeBuilder<T*, cross> {
     113             : public:
     114          52 :   static PointerType *get(LLVMContext &Context) {
     115          70 :     return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context));
     116             :   }
     117           1 : };
     118           1 : 
     119             : /// There is no support for references
     120           2 : template<typename T, bool cross> class TypeBuilder<T&, cross> {};
     121           2 : 
     122             : // Arrays
     123           2 : template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> {
     124           2 : public:
     125           2 :   static ArrayType *get(LLVMContext &Context) {
     126           3 :     return ArrayType::get(TypeBuilder<T, cross>::get(Context), N);
     127           1 :   }
     128             : };
     129           3 : /// LLVM uses an array of length 0 to represent an unknown-length array.
     130           3 : template<typename T, bool cross> class TypeBuilder<T[], cross> {
     131             : public:
     132           5 :   static ArrayType *get(LLVMContext &Context) {
     133           5 :     return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0);
     134             :   }
     135          11 : };
     136          11 : 
     137             : // Define the C integral types only for TypeBuilder<T, false>.
     138           1 : //
     139           1 : // 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
     141          14 : // following problem:
     142          14 : //
     143             : // On an ILP32 machine, stdint.h might define:
     144             : //
     145             : //   typedef int int32_t;
     146             : //   typedef long long int64_t;
     147             : //   typedef long size_t;
     148             : //
     149             : // 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
     151             : // addition to the defined-size types because we'd get duplicate definitions on
     152           3 : // platforms where stdint.h instead defines:
     153           3 : //
     154             : //   typedef int int32_t;
     155           1 : //   typedef long long int64_t;
     156           1 : //   typedef int size_t;
     157             : //
     158           1 : // So we define all the primitive C types and nothing else.
     159           1 : #define DEFINE_INTEGRAL_TYPEBUILDER(T) \
     160             : template<> class TypeBuilder<T, false> { \
     161           1 : public: \
     162           1 :   static IntegerType *get(LLVMContext &Context) { \
     163             :     return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \
     164             :   } \
     165             : }; \
     166             : template<> class TypeBuilder<T, true> { \
     167             :   /* We provide a definition here so users don't accidentally */ \
     168           3 :   /* define these types to work. */ \
     169           9 : }
     170          12 : DEFINE_INTEGRAL_TYPEBUILDER(char);
     171           1 : DEFINE_INTEGRAL_TYPEBUILDER(signed char);
     172           1 : DEFINE_INTEGRAL_TYPEBUILDER(unsigned char);
     173             : DEFINE_INTEGRAL_TYPEBUILDER(short);
     174           1 : DEFINE_INTEGRAL_TYPEBUILDER(unsigned short);
     175          60 : DEFINE_INTEGRAL_TYPEBUILDER(int);
     176             : DEFINE_INTEGRAL_TYPEBUILDER(unsigned int);
     177           1 : DEFINE_INTEGRAL_TYPEBUILDER(long);
     178           1 : 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 IntegerType *get(LLVMContext &C) {
     192           7 :     return IntegerType::get(C, num_bits);
     193             :   }
     194             : };
     195             : 
     196             : template<> class TypeBuilder<float, false> {
     197             : public:
     198             :   static Type *get(LLVMContext& C) {
     199             :     return Type::getFloatTy(C);
     200             :   }
     201             : };
     202             : template<> class TypeBuilder<float, true> {};
     203             : 
     204             : template<> class TypeBuilder<double, false> {
     205             : public:
     206             :   static Type *get(LLVMContext& C) {
     207             :     return Type::getDoubleTy(C);
     208             :   }
     209             : };
     210             : template<> class TypeBuilder<double, true> {};
     211             : 
     212             : template<bool cross> class TypeBuilder<types::ieee_float, cross> {
     213             : public:
     214             :   static Type *get(LLVMContext& C) { return Type::getFloatTy(C); }
     215           8 : };
     216          18 : template<bool cross> class TypeBuilder<types::ieee_double, cross> {
     217           1 : public:
     218           1 :   static Type *get(LLVMContext& C) { return Type::getDoubleTy(C); }
     219           1 : };
     220          16 : template<bool cross> class TypeBuilder<types::x86_fp80, cross> {
     221           1 : public:
     222           2 :   static Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); }
     223           2 : };
     224             : template<bool cross> class TypeBuilder<types::fp128, cross> {
     225             : public:
     226             :   static Type *get(LLVMContext& C) { return Type::getFP128Ty(C); }
     227             : };
     228             : template<bool cross> class TypeBuilder<types::ppc_fp128, cross> {
     229             : public:
     230             :   static Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); }
     231             : };
     232             : template<bool cross> class TypeBuilder<types::x86_mmx, cross> {
     233             : public:
     234             :   static Type *get(LLVMContext& C) { return Type::getX86_MMXTy(C); }
     235             : };
     236             : 
     237          40 : template<bool cross> class TypeBuilder<void, cross> {
     238             : public:
     239             :   static Type *get(LLVMContext &C) {
     240          70 :     return Type::getVoidTy(C);
     241             :   }
     242             : };
     243             : 
     244           1 : /// void* is disallowed in LLVM types, but it occurs often enough in C code that
     245             : /// we special case it.
     246             : template<> class TypeBuilder<void*, false>
     247             :   : public TypeBuilder<types::i<8>*, false> {};
     248             : template<> class TypeBuilder<const void*, false>
     249             :   : public TypeBuilder<types::i<8>*, false> {};
     250             : template<> class TypeBuilder<volatile void*, false>
     251             :   : public TypeBuilder<types::i<8>*, false> {};
     252           1 : template<> class TypeBuilder<const volatile void*, false>
     253             :   : public TypeBuilder<types::i<8>*, false> {};
     254             : 
     255             : template<typename R, bool cross> class TypeBuilder<R(), cross> {
     256             : public:
     257          48 :   static FunctionType *get(LLVMContext &Context) {
     258         109 :     return FunctionType::get(TypeBuilder<R, cross>::get(Context), false);
     259           2 :   }
     260             : };
     261             : template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> {
     262             : public:
     263          14 :   static FunctionType *get(LLVMContext &Context) {
     264          12 :     Type *params[] = {
     265             :       TypeBuilder<A1, cross>::get(Context),
     266             :     };
     267          14 :     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
     268          12 :                              params, false);
     269             :   }
     270             : };
     271           2 : template<typename R, typename A1, typename A2, bool cross>
     272             : class TypeBuilder<R(A1, A2), cross> {
     273             : public:
     274          37 :   static FunctionType *get(LLVMContext &Context) {
     275          52 :     Type *params[] = {
     276             :       TypeBuilder<A1, cross>::get(Context),
     277             :       TypeBuilder<A2, cross>::get(Context),
     278             :     };
     279          37 :     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
     280          37 :                              params, false);
     281             :   }
     282             : };
     283             : template<typename R, typename A1, typename A2, typename A3, bool cross>
     284             : class TypeBuilder<R(A1, A2, A3), cross> {
     285           3 : public:
     286             :   static FunctionType *get(LLVMContext &Context) {
     287             :     Type *params[] = {
     288             :       TypeBuilder<A1, cross>::get(Context),
     289             :       TypeBuilder<A2, cross>::get(Context),
     290             :       TypeBuilder<A3, cross>::get(Context),
     291             :     };
     292             :     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
     293             :                              params, false);
     294             :   }
     295             : };
     296             : 
     297             : template<typename R, typename A1, typename A2, typename A3, typename A4,
     298             :          bool cross>
     299             : class TypeBuilder<R(A1, A2, A3, A4), cross> {
     300             : public:
     301             :   static FunctionType *get(LLVMContext &Context) {
     302             :     Type *params[] = {
     303           1 :       TypeBuilder<A1, cross>::get(Context),
     304             :       TypeBuilder<A2, cross>::get(Context),
     305             :       TypeBuilder<A3, cross>::get(Context),
     306             :       TypeBuilder<A4, cross>::get(Context),
     307             :     };
     308           1 :     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
     309           1 :                              params, false);
     310           1 :   }
     311             : };
     312           1 : 
     313           1 : template<typename R, typename A1, typename A2, typename A3, typename A4,
     314             :          typename A5, bool cross>
     315             : class TypeBuilder<R(A1, A2, A3, A4, A5), cross> {
     316             : public:
     317             :   static FunctionType *get(LLVMContext &Context) {
     318             :     Type *params[] = {
     319           1 :       TypeBuilder<A1, cross>::get(Context),
     320           1 :       TypeBuilder<A2, cross>::get(Context),
     321           1 :       TypeBuilder<A3, cross>::get(Context),
     322           1 :       TypeBuilder<A4, cross>::get(Context),
     323             :       TypeBuilder<A5, cross>::get(Context),
     324           1 :     };
     325           1 :     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
     326             :                              params, false);
     327             :   }
     328             : };
     329             : 
     330             : template<typename R, bool cross> class TypeBuilder<R(...), cross> {
     331           1 : public:
     332           1 :   static FunctionType *get(LLVMContext &Context) {
     333           1 :     return FunctionType::get(TypeBuilder<R, cross>::get(Context), true);
     334           1 :   }
     335             : };
     336             : template<typename R, typename A1, bool cross>
     337           1 : class TypeBuilder<R(A1, ...), cross> {
     338           1 : public:
     339             :   static FunctionType *get(LLVMContext &Context) {
     340             :     Type *params[] = {
     341             :       TypeBuilder<A1, cross>::get(Context),
     342             :     };
     343             :     return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true);
     344             :   }
     345             : };
     346           1 : template<typename R, typename A1, typename A2, bool cross>
     347           1 : class TypeBuilder<R(A1, A2, ...), cross> {
     348           1 : public:
     349           1 :   static FunctionType *get(LLVMContext &Context) {
     350             :     Type *params[] = {
     351             :       TypeBuilder<A1, cross>::get(Context),
     352             :       TypeBuilder<A2, cross>::get(Context),
     353           1 :     };
     354           1 :     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
     355             :                                    params, true);
     356             :   }
     357             : };
     358             : template<typename R, typename A1, typename A2, typename A3, bool cross>
     359             : class TypeBuilder<R(A1, A2, A3, ...), cross> {
     360             : public:
     361             :   static FunctionType *get(LLVMContext &Context) {
     362           1 :     Type *params[] = {
     363           1 :       TypeBuilder<A1, cross>::get(Context),
     364           1 :       TypeBuilder<A2, cross>::get(Context),
     365           1 :       TypeBuilder<A3, cross>::get(Context),
     366             :     };
     367             :     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
     368             :                                    params, true);
     369             :   }
     370           1 : };
     371           1 : 
     372             : template<typename R, typename A1, typename A2, typename A3, typename A4,
     373             :          bool cross>
     374             : class TypeBuilder<R(A1, A2, A3, A4, ...), cross> {
     375             : public:
     376             :   static FunctionType *get(LLVMContext &Context) {
     377           1 :     Type *params[] = {
     378           1 :       TypeBuilder<A1, cross>::get(Context),
     379             :       TypeBuilder<A2, cross>::get(Context),
     380             :       TypeBuilder<A3, cross>::get(Context),
     381             :       TypeBuilder<A4, cross>::get(Context),
     382             :     };
     383             :     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
     384           1 :                              params, true);
     385           1 :   }
     386           1 : };
     387             : 
     388           1 : template<typename R, typename A1, typename A2, typename A3, typename A4,
     389             :          typename A5, bool cross>
     390             : class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> {
     391             : public:
     392             :   static FunctionType *get(LLVMContext &Context) {
     393             :     Type *params[] = {
     394           1 :       TypeBuilder<A1, cross>::get(Context),
     395           1 :       TypeBuilder<A2, cross>::get(Context),
     396           1 :       TypeBuilder<A3, cross>::get(Context),
     397           1 :       TypeBuilder<A4, cross>::get(Context),
     398             :       TypeBuilder<A5, cross>::get(Context),
     399           1 :     };
     400           1 :     return FunctionType::get(TypeBuilder<R, cross>::get(Context),
     401             :                                    params, true);
     402             :   }
     403             : };
     404             : 
     405             : }  // namespace llvm
     406           1 : 
     407           1 : #endif

Generated by: LCOV version 1.13