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