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 15using namespace llvm; 16 17namespace { 18 19TEST(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 34TEST(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 50TEST(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 57TEST(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 73TEST(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 121TEST(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 157TEST(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 169struct MyType { 170 int a; 171 int *b; 172 void *array[1]; 173}; 174 175struct MyPortableType { 176 int32_t a; 177 int32_t *b; 178 void *array[1]; 179}; 180 181} // anonymous namespace 182 183namespace llvm { 184template<bool cross> class TypeBuilder<MyType, cross> { 185public: 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 207template<bool cross> class TypeBuilder<MyPortableType, cross> { 208public: 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 230namespace { 231 232TEST(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*)0)), 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*)0)), 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*)0)), 250 (TypeBuilder<MyPortableType*, true>::get(getGlobalContext()))); 251} 252 253} // anonymous namespace 254