Home | History | Annotate | Download | only in IR
      1 //===- llvm/unittest/TypeBuilderTest.cpp - TypeBuilder tests --------------===//
      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 #include "llvm/IR/TypeBuilder.h"
     11 #include "llvm/ADT/ArrayRef.h"
     12 #include "llvm/IR/LLVMContext.h"
     13 #include "gtest/gtest.h"
     14 
     15 using namespace llvm;
     16 
     17 namespace {
     18 
     19 TEST(TypeBuilderTest, Void) {
     20   EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, true>::get(getGlobalContext())));
     21   EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, false>::get(getGlobalContext())));
     22   // Special cases for C compatibility:
     23   EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
     24             (TypeBuilder<void*, false>::get(getGlobalContext())));
     25   EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
     26             (TypeBuilder<const void*, false>::get(getGlobalContext())));
     27   EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
     28             (TypeBuilder<volatile void*, false>::get(getGlobalContext())));
     29   EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
     30             (TypeBuilder<const volatile void*, false>::get(
     31               getGlobalContext())));
     32 }
     33 
     34 TEST(TypeBuilderTest, HostIntegers) {
     35   EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<int8_t, false>::get(getGlobalContext())));
     36   EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<uint8_t, false>::get(getGlobalContext())));
     37   EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<int16_t, false>::get(getGlobalContext())));
     38   EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<uint16_t, false>::get(getGlobalContext())));
     39   EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<int32_t, false>::get(getGlobalContext())));
     40   EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<uint32_t, false>::get(getGlobalContext())));
     41   EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<int64_t, false>::get(getGlobalContext())));
     42   EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<uint64_t, false>::get(getGlobalContext())));
     43 
     44   EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(size_t) * CHAR_BIT),
     45             (TypeBuilder<size_t, false>::get(getGlobalContext())));
     46   EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(ptrdiff_t) * CHAR_BIT),
     47             (TypeBuilder<ptrdiff_t, false>::get(getGlobalContext())));
     48 }
     49 
     50 TEST(TypeBuilderTest, CrossCompilableIntegers) {
     51   EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, true>::get(getGlobalContext())));
     52   EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, false>::get(getGlobalContext())));
     53   EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, true>::get(getGlobalContext())));
     54   EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, false>::get(getGlobalContext())));
     55 }
     56 
     57 TEST(TypeBuilderTest, Float) {
     58   EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<float, false>::get(getGlobalContext())));
     59   EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<double, false>::get(getGlobalContext())));
     60   // long double isn't supported yet.
     61   EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, true>::get(getGlobalContext())));
     62   EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, false>::get(getGlobalContext())));
     63   EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, true>::get(getGlobalContext())));
     64   EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, false>::get(getGlobalContext())));
     65   EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, true>::get(getGlobalContext())));
     66   EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, false>::get(getGlobalContext())));
     67   EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, true>::get(getGlobalContext())));
     68   EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, false>::get(getGlobalContext())));
     69   EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, true>::get(getGlobalContext())));
     70   EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, false>::get(getGlobalContext())));
     71 }
     72 
     73 TEST(TypeBuilderTest, Derived) {
     74   EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())),
     75             (TypeBuilder<int8_t**, false>::get(getGlobalContext())));
     76   EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7),
     77             (TypeBuilder<int8_t[7], false>::get(getGlobalContext())));
     78   EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0),
     79             (TypeBuilder<int8_t[], false>::get(getGlobalContext())));
     80 
     81   EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())),
     82             (TypeBuilder<types::i<8>**, false>::get(getGlobalContext())));
     83   EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7),
     84             (TypeBuilder<types::i<8>[7], false>::get(getGlobalContext())));
     85   EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0),
     86             (TypeBuilder<types::i<8>[], false>::get(getGlobalContext())));
     87 
     88   EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())),
     89             (TypeBuilder<types::i<8>**, true>::get(getGlobalContext())));
     90   EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7),
     91             (TypeBuilder<types::i<8>[7], true>::get(getGlobalContext())));
     92   EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0),
     93             (TypeBuilder<types::i<8>[], true>::get(getGlobalContext())));
     94 
     95 
     96   EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
     97             (TypeBuilder<const int8_t, false>::get(getGlobalContext())));
     98   EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
     99             (TypeBuilder<volatile int8_t, false>::get(getGlobalContext())));
    100   EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
    101             (TypeBuilder<const volatile int8_t, false>::get(getGlobalContext())));
    102 
    103   EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
    104             (TypeBuilder<const types::i<8>, false>::get(getGlobalContext())));
    105   EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
    106             (TypeBuilder<volatile types::i<8>, false>::get(getGlobalContext())));
    107   EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
    108             (TypeBuilder<const volatile types::i<8>, false>::get(getGlobalContext())));
    109 
    110   EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
    111             (TypeBuilder<const types::i<8>, true>::get(getGlobalContext())));
    112   EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
    113             (TypeBuilder<volatile types::i<8>, true>::get(getGlobalContext())));
    114   EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
    115             (TypeBuilder<const volatile types::i<8>, true>::get(getGlobalContext())));
    116 
    117   EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
    118             (TypeBuilder<const volatile int8_t*const volatile, false>::get(getGlobalContext())));
    119 }
    120 
    121 TEST(TypeBuilderTest, Functions) {
    122   std::vector<Type*> params;
    123   EXPECT_EQ(FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false),
    124             (TypeBuilder<void(), true>::get(getGlobalContext())));
    125   EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
    126             (TypeBuilder<int8_t(...), false>::get(getGlobalContext())));
    127   params.push_back(TypeBuilder<int32_t*, false>::get(getGlobalContext()));
    128   EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
    129             (TypeBuilder<int8_t(const int32_t*), false>::get(getGlobalContext())));
    130   EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
    131             (TypeBuilder<int8_t(const int32_t*, ...), false>::get(getGlobalContext())));
    132   params.push_back(TypeBuilder<char*, false>::get(getGlobalContext()));
    133   EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
    134             (TypeBuilder<int8_t(int32_t*, void*), false>::get(getGlobalContext())));
    135   EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
    136             (TypeBuilder<int8_t(int32_t*, char*, ...), false>::get(getGlobalContext())));
    137   params.push_back(TypeBuilder<char, false>::get(getGlobalContext()));
    138   EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
    139             (TypeBuilder<int8_t(int32_t*, void*, char), false>::get(getGlobalContext())));
    140   EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
    141             (TypeBuilder<int8_t(int32_t*, char*, char, ...), false>::get(getGlobalContext())));
    142   params.push_back(TypeBuilder<char, false>::get(getGlobalContext()));
    143   EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
    144             (TypeBuilder<int8_t(int32_t*, void*, char, char), false>::get(getGlobalContext())));
    145   EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
    146             (TypeBuilder<int8_t(int32_t*, char*, char, char, ...),
    147                          false>::get(getGlobalContext())));
    148   params.push_back(TypeBuilder<char, false>::get(getGlobalContext()));
    149   EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
    150             (TypeBuilder<int8_t(int32_t*, void*, char, char, char),
    151                          false>::get(getGlobalContext())));
    152   EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
    153             (TypeBuilder<int8_t(int32_t*, char*, char, char, char, ...),
    154                          false>::get(getGlobalContext())));
    155 }
    156 
    157 TEST(TypeBuilderTest, Context) {
    158   // We used to cache TypeBuilder results in static local variables.  This
    159   // produced the same type for different contexts, which of course broke
    160   // things.
    161   LLVMContext context1;
    162   EXPECT_EQ(&context1,
    163             &(TypeBuilder<types::i<1>, true>::get(context1))->getContext());
    164   LLVMContext context2;
    165   EXPECT_EQ(&context2,
    166             &(TypeBuilder<types::i<1>, true>::get(context2))->getContext());
    167 }
    168 
    169 struct MyType {
    170   int a;
    171   int *b;
    172   void *array[1];
    173 };
    174 
    175 struct MyPortableType {
    176   int32_t a;
    177   int32_t *b;
    178   void *array[1];
    179 };
    180 
    181 }  // anonymous namespace
    182 
    183 namespace llvm {
    184 template<bool cross> class TypeBuilder<MyType, cross> {
    185 public:
    186   static StructType *get(LLVMContext &Context) {
    187     // Using the static result variable ensures that the type is
    188     // only looked up once.
    189     std::vector<Type*> st;
    190     st.push_back(TypeBuilder<int, cross>::get(Context));
    191     st.push_back(TypeBuilder<int*, cross>::get(Context));
    192     st.push_back(TypeBuilder<void*[], cross>::get(Context));
    193     static StructType *const result = StructType::get(Context, st);
    194     return result;
    195   }
    196 
    197   // You may find this a convenient place to put some constants
    198   // to help with getelementptr.  They don't have any effect on
    199   // the operation of TypeBuilder.
    200   enum Fields {
    201     FIELD_A,
    202     FIELD_B,
    203     FIELD_ARRAY
    204   };
    205 };
    206 
    207 template<bool cross> class TypeBuilder<MyPortableType, cross> {
    208 public:
    209   static StructType *get(LLVMContext &Context) {
    210     // Using the static result variable ensures that the type is
    211     // only looked up once.
    212     std::vector<Type*> st;
    213     st.push_back(TypeBuilder<types::i<32>, cross>::get(Context));
    214     st.push_back(TypeBuilder<types::i<32>*, cross>::get(Context));
    215     st.push_back(TypeBuilder<types::i<8>*[], cross>::get(Context));
    216     static StructType *const result = StructType::get(Context, st);
    217     return result;
    218   }
    219 
    220   // You may find this a convenient place to put some constants
    221   // to help with getelementptr.  They don't have any effect on
    222   // the operation of TypeBuilder.
    223   enum Fields {
    224     FIELD_A,
    225     FIELD_B,
    226     FIELD_ARRAY
    227   };
    228 };
    229 }  // namespace llvm
    230 namespace {
    231 
    232 TEST(TypeBuilderTest, Extensions) {
    233   EXPECT_EQ(PointerType::getUnqual(StructType::get(
    234                                      TypeBuilder<int, false>::get(getGlobalContext()),
    235                                      TypeBuilder<int*, false>::get(getGlobalContext()),
    236                                      TypeBuilder<void*[], false>::get(getGlobalContext()),
    237                                      (void*)nullptr)),
    238             (TypeBuilder<MyType*, false>::get(getGlobalContext())));
    239   EXPECT_EQ(PointerType::getUnqual(StructType::get(
    240                                      TypeBuilder<types::i<32>, false>::get(getGlobalContext()),
    241                                      TypeBuilder<types::i<32>*, false>::get(getGlobalContext()),
    242                                      TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()),
    243                                      (void*)nullptr)),
    244             (TypeBuilder<MyPortableType*, false>::get(getGlobalContext())));
    245   EXPECT_EQ(PointerType::getUnqual(StructType::get(
    246                                      TypeBuilder<types::i<32>, false>::get(getGlobalContext()),
    247                                      TypeBuilder<types::i<32>*, false>::get(getGlobalContext()),
    248                                      TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()),
    249                                      (void*)nullptr)),
    250             (TypeBuilder<MyPortableType*, true>::get(getGlobalContext())));
    251 }
    252 
    253 }  // anonymous namespace
    254