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
TEST(TypeBuilderTest,Void)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
TEST(TypeBuilderTest,HostIntegers)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
TEST(TypeBuilderTest,CrossCompilableIntegers)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
TEST(TypeBuilderTest,Float)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
TEST(TypeBuilderTest,Derived)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
TEST(TypeBuilderTest,Functions)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
TEST(TypeBuilderTest,Context)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:
get(LLVMContext & Context)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:
get(LLVMContext & Context)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
TEST(TypeBuilderTest,Extensions)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