OSDN Git Service

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