llvm.org GIT mirror llvm / 28a460d
Remove TypeBuilder.h, and fix the few locations using it. This shortcut mechanism for creating types was added 10 years ago, but has seen almost no uptake since then, neither internally nor in external projects. The very small number of characters saved by using it does not seem worth the mental overhead of an additional type-creation API, so, delete it. Differential Revision: https://reviews.llvm.org/D56573 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351020 91177308-0d34-0410-b5e6-96231b3b80d8 James Y Knight 7 months ago
17 changed file(s) with 123 addition(s) and 831 deletion(s). Raw diff Collapse all Expand all
252252 add enum ``LLVMTypeKind`` and modify
253253 ``LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty)`` for the new type
254254
255 #. ``llvm/include/llvm/IR/TypeBuilder.h``:
256
257 add new class to represent new type in the hierarchy
258
259255 #. ``llvm/lib/AsmParser/LLLexer.cpp``:
260256
261257 add ability to parse in the type from text assembly
298294 add enum ``LLVMTypeKind`` and modify
299295 `LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty)` for the new type
300296
301 #. ``llvm/include/llvm/IR/TypeBuilder.h``:
302
303 add new class to represent new class in the hierarchy
304
305297 #. ``llvm/lib/AsmParser/LLLexer.cpp``:
306298
307299 modify ``lltok::Kind LLLexer::LexIdentifier()`` to add ability to
29042904 GV->eraseFromParent();
29052905
29062906
2907 .. _create_types:
2908
2909 How to Create Types
2910 -------------------
2911
2912 In generating IR, you may need some complex types. If you know these types
2913 statically, you can use ``TypeBuilder<...>::get()``, defined in
2914 ``llvm/Support/TypeBuilder.h``, to retrieve them. ``TypeBuilder`` has two forms
2915 depending on whether you're building types for cross-compilation or native
2916 library use. ``TypeBuilder`` requires that ``T`` be independent of the
2917 host environment, meaning that it's built out of types from the ``llvm::types``
2918 (`doxygen `__) namespace
2919 and pointers, functions, arrays, etc. built of those. ``TypeBuilder``
2920 additionally allows native C types whose size may depend on the host compiler.
2921 For example,
2922
2923 .. code-block:: c++
2924
2925 FunctionType *ft = TypeBuilder(types::i<32>*), true>::get();
2926
2927 is easier to read and write than the equivalent
2928
2929 .. code-block:: c++
2930
2931 std::vector params;
2932 params.push_back(PointerType::getUnqual(Type::Int32Ty));
2933 FunctionType *ft = FunctionType::get(Type::Int8Ty, params, false);
2934
2935 See the `class comment
2936 `_ for more details.
2937
29382907 .. _threading:
29392908
29402909 Threads and LLVM
+0
-407
include/llvm/IR/TypeBuilder.h less more
None //===---- llvm/TypeBuilder.h - Builder for LLVM types -----------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the TypeBuilder class, which is used as a convenient way to
10 // create LLVM types with a consistent and simplified interface.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_IR_TYPEBUILDER_H
15 #define LLVM_IR_TYPEBUILDER_H
16
17 #include "llvm/IR/DerivedTypes.h"
18 #include "llvm/IR/LLVMContext.h"
19 #include
20
21 namespace llvm {
22
23 /// TypeBuilder - This provides a uniform API for looking up types
24 /// known at compile time. To support cross-compilation, we define a
25 /// series of tag types in the llvm::types namespace, like i,
26 /// ieee_float, ppc_fp128, etc. TypeBuilder allows T to be
27 /// any of these, a native C type (whose size may depend on the host
28 /// compiler), or a pointer, function, or struct type built out of
29 /// these. TypeBuilder removes native C types from this set
30 /// to guarantee that its result is suitable for cross-compilation.
31 /// We define the primitive types, pointer types, and functions up to
32 /// 5 arguments here, but to use this class with your own types,
33 /// you'll need to specialize it. For example, say you want to call a
34 /// function defined externally as:
35 ///
36 /// \code{.cpp}
37 ///
38 /// struct MyType {
39 /// int32 a;
40 /// int32 *b;
41 /// void *array[1]; // Intended as a flexible array.
42 /// };
43 /// int8 AFunction(struct MyType *value);
44 ///
45 /// \endcode
46 ///
47 /// You'll want to use
48 /// Function::Create(TypeBuilder(MyType*), true>::get(), ...)
49 /// to declare the function, but when you first try this, your compiler will
50 /// complain that TypeBuilder::get() doesn't exist. To fix this,
51 /// write:
52 ///
53 /// \code{.cpp}
54 ///
55 /// namespace llvm {
56 /// template class TypeBuilder {
57 /// public:
58 /// static StructType *get(LLVMContext &Context) {
59 /// // If you cache this result, be sure to cache it separately
60 /// // for each LLVMContext.
61 /// return StructType::get(
62 /// TypeBuilder, xcompile>::get(Context),
63 /// TypeBuilder*, xcompile>::get(Context),
64 /// TypeBuilder*[], xcompile>::get(Context),
65 /// nullptr);
66 /// }
67 ///
68 /// // You may find this a convenient place to put some constants
69 /// // to help with getelementptr. They don't have any effect on
70 /// // the operation of TypeBuilder.
71 /// enum Fields {
72 /// FIELD_A,
73 /// FIELD_B,
74 /// FIELD_ARRAY
75 /// };
76 /// }
77 /// } // namespace llvm
78 ///
79 /// \endcode
80 ///
81 /// TypeBuilder cannot handle recursive types or types you only know at runtime.
82 /// If you try to give it a recursive type, it will deadlock, infinitely
83 /// recurse, or do something similarly undesirable.
84 template class TypeBuilder {};
85
86 // Types for use with cross-compilable TypeBuilders. These correspond
87 // exactly with an LLVM-native type.
88 namespace types {
89 /// i corresponds to the LLVM IntegerType with N bits.
90 template class i {};
91
92 // The following classes represent the LLVM floating types.
93 class ieee_float {};
94 class ieee_double {};
95 class x86_fp80 {};
96 class fp128 {};
97 class ppc_fp128 {};
98 // X86 MMX.
99 class x86_mmx {};
100 } // namespace types
101
102 // LLVM doesn't have const or volatile types.
103 template class TypeBuilder
104 : public TypeBuilder {};
105 template class TypeBuilder
106 : public TypeBuilder {};
107 template class TypeBuilder
108 : public TypeBuilder {};
109
110 // Pointers
111 template class TypeBuilder {
112 public:
113 static PointerType *get(LLVMContext &Context) {
114 return PointerType::getUnqual(TypeBuilder::get(Context));
115 }
116 };
117
118 /// There is no support for references
119 template class TypeBuilder {};
120
121 // Arrays
122 template class TypeBuilder {
123 public:
124 static ArrayType *get(LLVMContext &Context) {
125 return ArrayType::get(TypeBuilder::get(Context), N);
126 }
127 };
128 /// LLVM uses an array of length 0 to represent an unknown-length array.
129 template class TypeBuilder {
130 public:
131 static ArrayType *get(LLVMContext &Context) {
132 return ArrayType::get(TypeBuilder::get(Context), 0);
133 }
134 };
135
136 // Define the C integral types only for TypeBuilder.
137 //
138 // C integral types do not have a defined size. It would be nice to use the
139 // stdint.h-defined typedefs that do have defined sizes, but we'd run into the
140 // following problem:
141 //
142 // On an ILP32 machine, stdint.h might define:
143 //
144 // typedef int int32_t;
145 // typedef long long int64_t;
146 // typedef long size_t;
147 //
148 // If we defined TypeBuilder and TypeBuilder, then any use of
149 // TypeBuilder would fail. We couldn't define TypeBuilder in
150 // addition to the defined-size types because we'd get duplicate definitions on
151 // platforms where stdint.h instead defines:
152 //
153 // typedef int int32_t;
154 // typedef long long int64_t;
155 // typedef int size_t;
156 //
157 // So we define all the primitive C types and nothing else.
158 #define DEFINE_INTEGRAL_TYPEBUILDER(T) \
159 template<> class TypeBuilder { \
160 public: \
161 static IntegerType *get(LLVMContext &Context) { \
162 return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \
163 } \
164 }; \
165 template<> class TypeBuilder { \
166 /* We provide a definition here so users don't accidentally */ \
167 /* define these types to work. */ \
168 }
169 DEFINE_INTEGRAL_TYPEBUILDER(char);
170 DEFINE_INTEGRAL_TYPEBUILDER(signed char);
171 DEFINE_INTEGRAL_TYPEBUILDER(unsigned char);
172 DEFINE_INTEGRAL_TYPEBUILDER(short);
173 DEFINE_INTEGRAL_TYPEBUILDER(unsigned short);
174 DEFINE_INTEGRAL_TYPEBUILDER(int);
175 DEFINE_INTEGRAL_TYPEBUILDER(unsigned int);
176 DEFINE_INTEGRAL_TYPEBUILDER(long);
177 DEFINE_INTEGRAL_TYPEBUILDER(unsigned long);
178 #ifdef _MSC_VER
179 DEFINE_INTEGRAL_TYPEBUILDER(__int64);
180 DEFINE_INTEGRAL_TYPEBUILDER(unsigned __int64);
181 #else /* _MSC_VER */
182 DEFINE_INTEGRAL_TYPEBUILDER(long long);
183 DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long);
184 #endif /* _MSC_VER */
185 #undef DEFINE_INTEGRAL_TYPEBUILDER
186
187 template
188 class TypeBuilder, cross> {
189 public:
190 static IntegerType *get(LLVMContext &C) {
191 return IntegerType::get(C, num_bits);
192 }
193 };
194
195 template<> class TypeBuilder {
196 public:
197 static Type *get(LLVMContext& C) {
198 return Type::getFloatTy(C);
199 }
200 };
201 template<> class TypeBuilder {};
202
203 template<> class TypeBuilder {
204 public:
205 static Type *get(LLVMContext& C) {
206 return Type::getDoubleTy(C);
207 }
208 };
209 template<> class TypeBuilder {};
210
211 template class TypeBuilder {
212 public:
213 static Type *get(LLVMContext& C) { return Type::getFloatTy(C); }
214 };
215 template class TypeBuilder {
216 public:
217 static Type *get(LLVMContext& C) { return Type::getDoubleTy(C); }
218 };
219 template class TypeBuilder {
220 public:
221 static Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); }
222 };
223 template class TypeBuilder {
224 public:
225 static Type *get(LLVMContext& C) { return Type::getFP128Ty(C); }
226 };
227 template class TypeBuilder {
228 public:
229 static Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); }
230 };
231 template class TypeBuilder {
232 public:
233 static Type *get(LLVMContext& C) { return Type::getX86_MMXTy(C); }
234 };
235
236 template class TypeBuilder {
237 public:
238 static Type *get(LLVMContext &C) {
239 return Type::getVoidTy(C);
240 }
241 };
242
243 /// void* is disallowed in LLVM types, but it occurs often enough in C code that
244 /// we special case it.
245 template<> class TypeBuilder
246 : public TypeBuilder*, false> {};
247 template<> class TypeBuilder
248 : public TypeBuilder*, false> {};
249 template<> class TypeBuilder
250 : public TypeBuilder*, false> {};
251 template<> class TypeBuilder
252 : public TypeBuilder*, false> {};
253
254 template class TypeBuilder {
255 public:
256 static FunctionType *get(LLVMContext &Context) {
257 return FunctionType::get(TypeBuilder::get(Context), false);
258 }
259 };
260 template class TypeBuilder {
261 public:
262 static FunctionType *get(LLVMContext &Context) {
263 Type *params[] = {
264 TypeBuilder::get(Context),
265 };
266 return FunctionType::get(TypeBuilder::get(Context),
267 params, false);
268 }
269 };
270 template
271 class TypeBuilder {
272 public:
273 static FunctionType *get(LLVMContext &Context) {
274 Type *params[] = {
275 TypeBuilder::get(Context),
276 TypeBuilder::get(Context),
277 };
278 return FunctionType::get(TypeBuilder::get(Context),
279 params, false);
280 }
281 };
282 template
283 class TypeBuilder {
284 public:
285 static FunctionType *get(LLVMContext &Context) {
286 Type *params[] = {
287 TypeBuilder::get(Context),
288 TypeBuilder::get(Context),
289 TypeBuilder::get(Context),
290 };
291 return FunctionType::get(TypeBuilder::get(Context),
292 params, false);
293 }
294 };
295
296 template
297 bool cross>
298 class TypeBuilder {
299 public:
300 static FunctionType *get(LLVMContext &Context) {
301 Type *params[] = {
302 TypeBuilder::get(Context),
303 TypeBuilder::get(Context),
304 TypeBuilder::get(Context),
305 TypeBuilder::get(Context),
306 };
307 return FunctionType::get(TypeBuilder::get(Context),
308 params, false);
309 }
310 };
311
312 template
313 typename A5, bool cross>
314 class TypeBuilder {
315 public:
316 static FunctionType *get(LLVMContext &Context) {
317 Type *params[] = {
318 TypeBuilder::get(Context),
319 TypeBuilder::get(Context),
320 TypeBuilder::get(Context),
321 TypeBuilder::get(Context),
322 TypeBuilder::get(Context),
323 };
324 return FunctionType::get(TypeBuilder::get(Context),
325 params, false);
326 }
327 };
328
329 template class TypeBuilder {
330 public:
331 static FunctionType *get(LLVMContext &Context) {
332 return FunctionType::get(TypeBuilder::get(Context), true);
333 }
334 };
335 template
336 class TypeBuilder {
337 public:
338 static FunctionType *get(LLVMContext &Context) {
339 Type *params[] = {
340 TypeBuilder::get(Context),
341 };
342 return FunctionType::get(TypeBuilder::get(Context), params, true);
343 }
344 };
345 template
346 class TypeBuilder {
347 public:
348 static FunctionType *get(LLVMContext &Context) {
349 Type *params[] = {
350 TypeBuilder::get(Context),
351 TypeBuilder::get(Context),
352 };
353 return FunctionType::get(TypeBuilder::get(Context),
354 params, true);
355 }
356 };
357 template
358 class TypeBuilder {
359 public:
360 static FunctionType *get(LLVMContext &Context) {
361 Type *params[] = {
362 TypeBuilder::get(Context),
363 TypeBuilder::get(Context),
364 TypeBuilder::get(Context),
365 };
366 return FunctionType::get(TypeBuilder::get(Context),
367 params, true);
368 }
369 };
370
371 template
372 bool cross>
373 class TypeBuilder {
374 public:
375 static FunctionType *get(LLVMContext &Context) {
376 Type *params[] = {
377 TypeBuilder::get(Context),
378 TypeBuilder::get(Context),
379 TypeBuilder::get(Context),
380 TypeBuilder::get(Context),
381 };
382 return FunctionType::get(TypeBuilder::get(Context),
383 params, true);
384 }
385 };
386
387 template
388 typename A5, bool cross>
389 class TypeBuilder {
390 public:
391 static FunctionType *get(LLVMContext &Context) {
392 Type *params[] = {
393 TypeBuilder::get(Context),
394 TypeBuilder::get(Context),
395 TypeBuilder::get(Context),
396 TypeBuilder::get(Context),
397 TypeBuilder::get(Context),
398 };
399 return FunctionType::get(TypeBuilder::get(Context),
400 params, true);
401 }
402 };
403
404 } // namespace llvm
405
406 #endif
3434 #include "llvm/IR/LLVMContext.h"
3535 #include "llvm/IR/Module.h"
3636 #include "llvm/IR/Type.h"
37 #include "llvm/IR/TypeBuilder.h"
3837 #include "llvm/IR/Verifier.h"
3938 #include "llvm/IRReader/IRReader.h"
4039 #include "llvm/Object/Archive.h"
316315 M->setTargetTriple(TargetTripleStr);
317316
318317 // Create an empty function named "__main".
319 Function *Result;
320 if (TargetTriple.isArch64Bit()) {
321 Result = Function::Create(
322 TypeBuilder::get(Context),
323 GlobalValue::ExternalLinkage, "__main", M.get());
324 } else {
325 Result = Function::Create(
326 TypeBuilder::get(Context),
327 GlobalValue::ExternalLinkage, "__main", M.get());
328 }
318 Type *ReturnTy;
319 if (TargetTriple.isArch64Bit())
320 ReturnTy = Type::getInt64Ty(Context);
321 else
322 ReturnTy = Type::getInt32Ty(Context);
323 Function *Result =
324 Function::Create(FunctionType::get(ReturnTy, {}, false),
325 GlobalValue::ExternalLinkage, "__main", M.get());
326
329327 BasicBlock *BB = BasicBlock::Create(Context, "__main", Result);
330328 Builder.SetInsertPoint(BB);
331 Value *ReturnVal;
332 if (TargetTriple.isArch64Bit())
333 ReturnVal = ConstantInt::get(Context, APInt(64, 0));
334 else
335 ReturnVal = ConstantInt::get(Context, APInt(32, 0));
329 Value *ReturnVal = ConstantInt::get(ReturnTy, 0);
336330 Builder.CreateRet(ReturnVal);
337331
338332 // Add this new module to the ExecutionEngine.
174174 std::unique_ptr A, B;
175175 Function *FA1, *FA2, *FB;
176176 createTwoModuleExternCase(A, FA1, B, FB);
177 FA2 = insertSimpleCallFunction(A.get(), FA1);
177 FA2 = insertSimpleCallFunction(A.get(), FA1);
178178
179179 createJIT(std::move(A));
180180 TheJIT->addModule(std::move(B));
202202 std::unique_ptr A, B;
203203 Function *FA, *FB;
204204 GlobalVariable *GVA, *GVB, *GVC;
205
205206 A.reset(createEmptyModule("A"));
206207 B.reset(createEmptyModule("B"));
207208
208209 int32_t initialNum = 7;
209210 GVA = insertGlobalInt32(A.get(), "GVA", initialNum);
210211 GVB = insertGlobalInt32(B.get(), "GVB", initialNum);
211 FA = startFunction(A.get(), "FA");
212 FA = startFunction(A.get(),
213 FunctionType::get(Builder.getInt32Ty(), {}, false), "FA");
212214 endFunctionWithRet(FA, Builder.CreateLoad(GVA));
213 FB = startFunction(B.get(), "FB");
215 FB = startFunction(B.get(),
216 FunctionType::get(Builder.getInt32Ty(), {}, false), "FB");
214217 endFunctionWithRet(FB, Builder.CreateLoad(GVB));
215218
216219 GVC = insertGlobalInt32(B.get(), "GVC", initialNum);
9898 int32_t initialNum = 7;
9999 GlobalVariable *GV = insertGlobalInt32(M.get(), "myglob", initialNum);
100100
101 Function *ReturnGlobal = startFunction(M.get(),
102 "ReturnGlobal");
101 Function *ReturnGlobal =
102 startFunction(M.get(), FunctionType::get(Builder.getInt32Ty(), {}, false),
103 "ReturnGlobal");
103104 Value *ReadGlobal = Builder.CreateLoad(GV);
104105 endFunctionWithRet(ReturnGlobal, ReadGlobal);
105106
125126 SKIP_UNSUPPORTED_PLATFORM;
126127
127128 int32_t initialNum = 5;
128 Function *IncrementGlobal = startFunction(M.get(), "IncrementGlobal");
129 Function *IncrementGlobal = startFunction(
130 M.get(),
131 FunctionType::get(Builder.getInt32Ty(), {}, false),
132 "IncrementGlobal");
129133 GlobalVariable *GV = insertGlobalInt32(M.get(), "my_global", initialNum);
130134 Value *DerefGV = Builder.CreateLoad(GV);
131135 Value *AddResult = Builder.CreateAdd(DerefGV,
160164 unsigned int numLevels = 23;
161165 int32_t innerRetVal= 5;
162166
163 Function *Inner = startFunction(M.get(), "Inner");
167 Function *Inner = startFunction(
168 M.get(), FunctionType::get(Builder.getInt32Ty(), {}, false), "Inner");
164169 endFunctionWithRet(Inner, ConstantInt::get(Context, APInt(32, innerRetVal)));
165170
166171 Function *Outer;
167172 for (unsigned int i = 0; i < numLevels; ++i) {
168173 std::stringstream funcName;
169174 funcName << "level_" << i;
170 Outer = startFunction(M.get(), funcName.str());
175 Outer = startFunction(M.get(),
176 FunctionType::get(Builder.getInt32Ty(), {}, false),
177 funcName.str());
171178 Value *innerResult = Builder.CreateCall(Inner, {});
172179 endFunctionWithRet(Outer, innerResult);
173180
189196 TEST_F(MCJITTest, multiple_decl_lookups) {
190197 SKIP_UNSUPPORTED_PLATFORM;
191198
192 Function *Foo = insertExternalReferenceToFunction(M.get(), "_exit");
199 Function *Foo = insertExternalReferenceToFunction(
200 M.get(), FunctionType::get(Builder.getVoidTy(), {}, false), "_exit");
193201 createJIT(std::move(M));
194202 void *A = TheJIT->getPointerToFunction(Foo);
195203 void *B = TheJIT->getPointerToFunction(Foo);
202210
203211 TEST_F(MCJITTest, lazy_function_creator_pointer) {
204212 SKIP_UNSUPPORTED_PLATFORM;
205
206 Function *Foo = insertExternalReferenceToFunction(M.get(),
207 "\1Foo");
208 startFunction(M.get(), "Parent");
213
214 Function *Foo = insertExternalReferenceToFunction(
215 M.get(), FunctionType::get(Builder.getInt32Ty(), {}, false),
216 "\1Foo");
217 startFunction(M.get(), FunctionType::get(Builder.getInt32Ty(), {}, false),
218 "Parent");
209219 CallInst *Call = Builder.CreateCall(Foo, {});
210220 Builder.CreateRet(Call);
211221
239249
240250 TEST_F(MCJITTest, lazy_function_creator_lambda) {
241251 SKIP_UNSUPPORTED_PLATFORM;
242
243 Function *Foo1 = insertExternalReferenceToFunction(M.get(),
244 "\1Foo1");
245 Function *Foo2 = insertExternalReferenceToFunction(M.get(),
246 "\1Foo2");
247 startFunction(M.get(), "Parent");
252
253 FunctionType *Int32VoidFnTy =
254 FunctionType::get(Builder.getInt32Ty(), {}, false);
255 Function *Foo1 =
256 insertExternalReferenceToFunction(M.get(), Int32VoidFnTy, "\1Foo1");
257 Function *Foo2 =
258 insertExternalReferenceToFunction(M.get(), Int32VoidFnTy, "\1Foo2");
259 startFunction(M.get(), Int32VoidFnTy, "Parent");
248260 CallInst *Call1 = Builder.CreateCall(Foo1, {});
249261 CallInst *Call2 = Builder.CreateCall(Foo2, {});
250262 Value *Result = Builder.CreateAdd(Call1, Call2);
2323 #include "llvm/IR/IRBuilder.h"
2424 #include "llvm/IR/LLVMContext.h"
2525 #include "llvm/IR/Module.h"
26 #include "llvm/IR/TypeBuilder.h"
26 #include "llvm/IR/Type.h"
2727 #include "llvm/Support/CodeGen.h"
2828
2929 namespace llvm {
4444 return M;
4545 }
4646
47 template
48 Function *startFunction(Module *M, StringRef Name) {
49 Function *Result = Function::Create(
50 TypeBuilder::get(Context),
51 GlobalValue::ExternalLinkage, Name, M);
47 Function *startFunction(Module *M, FunctionType *FT, StringRef Name) {
48 Function *Result =
49 Function::Create(FT, GlobalValue::ExternalLinkage, Name, M);
5250
5351 BasicBlock *BB = BasicBlock::Create(Context, Name, Result);
5452 Builder.SetInsertPoint(BB);
6260
6361 // Inserts a simple function that invokes Callee and takes the same arguments:
6462 // int Caller(...) { return Callee(...); }
65 template
6663 Function *insertSimpleCallFunction(Module *M, Function *Callee) {
67 Function *Result = startFunction(M, "caller");
64 Function *Result = startFunction(M, Callee->getFunctionType(), "caller");
6865
6966 SmallVector CallArgs;
7067
8077 // int32_t main() { return X; }
8178 // where X is given by returnCode
8279 Function *insertMainFunction(Module *M, uint32_t returnCode) {
83 Function *Result = startFunction(M, "main");
80 Function *Result = startFunction(
81 M, FunctionType::get(Type::getInt32Ty(Context), {}, false), "main");
8482
8583 Value *ReturnVal = ConstantInt::get(Context, APInt(32, returnCode));
8684 endFunctionWithRet(Result, ReturnVal);
9290 // int32_t add(int32_t a, int32_t b) { return a + b; }
9391 // in the current module and returns a pointer to it.
9492 Function *insertAddFunction(Module *M, StringRef Name = "add") {
95 Function *Result = startFunction(M, Name);
93 Function *Result = startFunction(
94 M,
95 FunctionType::get(
96 Type::getInt32Ty(Context),
97 {Type::getInt32Ty(Context), Type::getInt32Ty(Context)}, false),
98 Name);
9699
97100 Function::arg_iterator args = Result->arg_begin();
98101 Value *Arg1 = &*args;
105108 }
106109
107110 // Inserts a declaration to a function defined elsewhere
108 template
109 Function *insertExternalReferenceToFunction(Module *M, StringRef Name) {
110 Function *Result = Function::Create(
111 TypeBuilder::get(Context),
112 GlobalValue::ExternalLinkage, Name, M);
113 return Result;
114 }
115
116 // Inserts an declaration to a function defined elsewhere
117 Function *insertExternalReferenceToFunction(Module *M, StringRef Name,
118 FunctionType *FuncTy) {
119 Function *Result = Function::Create(FuncTy,
120 GlobalValue::ExternalLinkage,
121 Name, M);
111 Function *insertExternalReferenceToFunction(Module *M, FunctionType *FTy,
112 StringRef Name) {
113 Function *Result =
114 Function::Create(FTy, GlobalValue::ExternalLinkage, Name, M);
122115 return Result;
123116 }
124117
135128 GlobalVariable *insertGlobalInt32(Module *M,
136129 StringRef name,
137130 int32_t InitialValue) {
138 Type *GlobalTy = TypeBuilder, true>::get(Context);
131 Type *GlobalTy = Type::getInt32Ty(Context);
139132 Constant *IV = ConstantInt::get(Context, APInt(32, InitialValue));
140133 GlobalVariable *Global = new GlobalVariable(*M,
141134 GlobalTy,
159152 Function *insertAccumulateFunction(Module *M,
160153 Function *Helper = nullptr,
161154 StringRef Name = "accumulate") {
162 Function *Result = startFunction(M, Name);
155 Function *Result =
156 startFunction(M,
157 FunctionType::get(Type::getInt32Ty(Context),
158 {Type::getInt32Ty(Context)}, false),
159 Name);
163160 if (!Helper)
164161 Helper = Result;
165162
224221
225222 B.reset(createEmptyModule("B"));
226223 Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA);
227 FB = insertSimpleCallFunction(B.get(), FAExtern_in_B);
224 FB = insertSimpleCallFunction(B.get(), FAExtern_in_B);
228225
229226 C.reset(createEmptyModule("C"));
230227 Function *FBExtern_in_C = insertExternalReferenceToFunction(C.get(), FB);
231 FC = insertSimpleCallFunction(C.get(), FBExtern_in_C);
228 FC = insertSimpleCallFunction(C.get(), FBExtern_in_C);
232229 }
233230
234231 // Module A { Function FA },
252249
253250 B.reset(createEmptyModule("B"));
254251 Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA);
255 FB = insertSimpleCallFunction(B.get(),
256 FAExtern_in_B);
252 FB = insertSimpleCallFunction(B.get(), FAExtern_in_B);
257253 }
258254
259255 // Module A { Function FA },
267263
268264 B.reset(createEmptyModule("B"));
269265 Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA);
270 FB = insertSimpleCallFunction(B.get(), FAExtern_in_B);
266 FB = insertSimpleCallFunction(B.get(), FAExtern_in_B);
271267
272268 C.reset(createEmptyModule("C"));
273269 Function *FAExtern_in_C = insertExternalReferenceToFunction(C.get(), FA);
274 FC = insertSimpleCallFunction(C.get(), FAExtern_in_C);
270 FC = insertSimpleCallFunction(C.get(), FAExtern_in_C);
275271 }
276272 };
277273
1818 TEST(IndirectionUtilsTest, MakeStub) {
1919 LLVMContext Context;
2020 ModuleBuilder MB(Context, "x86_64-apple-macosx10.10", "");
21 Function *F = MB.createFunctionDecl("");
21 FunctionType *FTy = FunctionType::get(
22 Type::getVoidTy(Context),
23 {getDummyStructTy(Context), getDummyStructTy(Context)}, false);
24 Function *F = MB.createFunctionDecl(FTy, "");
2225 AttributeSet FnAttrs = AttributeSet::get(
2326 Context, AttrBuilder().addAttribute(Attribute::NoUnwind));
2427 AttributeSet RetAttrs; // None
122122 if (!SupportsJIT)
123123 return;
124124
125 Type *Int32Ty = IntegerType::get(Context, 32);
126
125127 ExecutionSession ES;
126128
127129 auto MM = std::make_shared();
152154 ModuleBuilder MB1(Context, "", "dummy");
153155 {
154156 MB1.getModule()->setDataLayout(TM->createDataLayout());
155 Function *BarImpl = MB1.createFunctionDecl("bar");
157 Function *BarImpl =
158 MB1.createFunctionDecl(FunctionType::get(Int32Ty, {}, false), "bar");
156159 BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
157160 IRBuilder<> Builder(BarEntry);
158161 IntegerType *Int32Ty = IntegerType::get(Context, 32);
165168 ModuleBuilder MB2(Context, "", "dummy");
166169 {
167170 MB2.getModule()->setDataLayout(TM->createDataLayout());
168 Function *BarDecl = MB2.createFunctionDecl("bar");
169 Function *FooImpl = MB2.createFunctionDecl("foo");
171 Function *BarDecl =
172 MB2.createFunctionDecl(FunctionType::get(Int32Ty, {}, false), "bar");
173 Function *FooImpl =
174 MB2.createFunctionDecl(FunctionType::get(Int32Ty, {}, false), "foo");
170175 BasicBlock *FooEntry = BasicBlock::Create(Context, "entry", FooImpl);
171176 IRBuilder<> Builder(FooEntry);
172177 Builder.CreateRet(Builder.CreateCall(BarDecl));
205210 TEST_F(LegacyRTDyldObjectLinkingLayerExecutionTest, NoPrematureAllocation) {
206211 if (!SupportsJIT)
207212 return;
213
214 Type *Int32Ty = IntegerType::get(Context, 32);
208215
209216 ExecutionSession ES;
210217
232239 ModuleBuilder MB1(Context, "", "dummy");
233240 {
234241 MB1.getModule()->setDataLayout(TM->createDataLayout());
235 Function *BarImpl = MB1.createFunctionDecl("foo");
242 Function *BarImpl =
243 MB1.createFunctionDecl(FunctionType::get(Int32Ty, {}, false), "foo");
236244 BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
237245 IRBuilder<> Builder(BarEntry);
238246 IntegerType *Int32Ty = IntegerType::get(Context, 32);
245253 ModuleBuilder MB2(Context, "", "dummy");
246254 {
247255 MB2.getModule()->setDataLayout(TM->createDataLayout());
248 Function *BarImpl = MB2.createFunctionDecl("bar");
256 Function *BarImpl =
257 MB2.createFunctionDecl(FunctionType::get(Int32Ty, {}, false), "bar");
249258 BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
250259 IRBuilder<> Builder(BarEntry);
251260 IntegerType *Int32Ty = IntegerType::get(Context, 32);
2626 protected:
2727 std::unique_ptr createTestModule(const Triple &TT) {
2828 ModuleBuilder MB(Context, TT.str(), "");
29 Function *TestFunc = MB.createFunctionDecl("testFunc");
30 Function *Main = MB.createFunctionDecl("main");
29 Type *IntTy = Type::getScalarTy(Context);
30 Function *TestFunc =
31 MB.createFunctionDecl(FunctionType::get(IntTy, {}, false), "testFunc");
32 Function *Main = MB.createFunctionDecl(
33 FunctionType::get(
34 IntTy,
35 {IntTy, Type::getInt8PtrTy(Context)->getPointerTo()},
36 false),
37 "main");
3138
3239 Main->getBasicBlockList().push_back(BasicBlock::Create(Context));
3340 IRBuilder<> B(&Main->back());
2121 #include "llvm/IR/IRBuilder.h"
2222 #include "llvm/IR/LLVMContext.h"
2323 #include "llvm/IR/Module.h"
24 #include "llvm/IR/TypeBuilder.h"
2524 #include "llvm/Object/ObjectFile.h"
2625 #include "llvm/Support/TargetRegistry.h"
2726 #include "llvm/Support/TargetSelect.h"
168167 ModuleBuilder(LLVMContext &Context, StringRef Triple,
169168 StringRef Name);
170169
171 template
172 Function* createFunctionDecl(StringRef Name) {
173 return Function::Create(
174 TypeBuilder::get(M->getContext()),
175 GlobalValue::ExternalLinkage, Name, M.get());
170 Function *createFunctionDecl(FunctionType *FTy, StringRef Name) {
171 return Function::Create(FTy, GlobalValue::ExternalLinkage, Name, M.get());
176172 }
177173
178174 Module* getModule() { return M.get(); }
188184 int X[256];
189185 };
190186
191 // TypeBuilder specialization for DummyStruct.
192 template
193 class TypeBuilder {
194 public:
195 static StructType *get(LLVMContext &Context) {
196 return StructType::get(
197 TypeBuilder[256], XCompile>::get(Context));
198 }
199 };
187 inline StructType *getDummyStructTy(LLVMContext &Context) {
188 return StructType::get(ArrayType::get(Type::getInt32Ty(Context), 256));
189 }
200190
201191 template
202192 class MockBaseLayer {
130130 ModuleBuilder MB(*TSCtx.getContext(), TM->getTargetTriple().str(), "dummy");
131131 MB.getModule()->setDataLayout(TM->createDataLayout());
132132
133 Function *FooImpl = MB.createFunctionDecl("foo");
133 Function *FooImpl = MB.createFunctionDecl(
134 FunctionType::get(Type::getVoidTy(*TSCtx.getContext()), {}, false),
135 "foo");
134136 BasicBlock *FooEntry =
135137 BasicBlock::Create(*TSCtx.getContext(), "entry", FooImpl);
136138 IRBuilder<> B1(FooEntry);
137139 B1.CreateRetVoid();
138140
139 Function *BarImpl = MB.createFunctionDecl("bar");
141 Function *BarImpl = MB.createFunctionDecl(
142 FunctionType::get(Type::getVoidTy(*TSCtx.getContext()), {}, false),
143 "bar");
140144 BasicBlock *BarEntry =
141145 BasicBlock::Create(*TSCtx.getContext(), "entry", BarImpl);
142146 IRBuilder<> B2(BarEntry);
180184 FunkySimpleCompiler(TargetMachine &TM) : SimpleCompiler(TM) {}
181185
182186 CompileResult operator()(Module &M) {
183 Function *BarImpl =
184 Function::Create(TypeBuilder::get(M.getContext()),
185 GlobalValue::ExternalLinkage, "bar", &M);
187 Function *BarImpl = Function::Create(
188 FunctionType::get(Type::getVoidTy(M.getContext()), {}, false),
189 GlobalValue::ExternalLinkage, "bar", &M);
186190 BasicBlock *BarEntry =
187191 BasicBlock::Create(M.getContext(), "entry", BarImpl);
188192 IRBuilder<> B(BarEntry);
199203 ModuleBuilder MB(*TSCtx.getContext(), TM->getTargetTriple().str(), "dummy");
200204 MB.getModule()->setDataLayout(TM->createDataLayout());
201205
202 Function *FooImpl = MB.createFunctionDecl("foo");
206 Function *FooImpl = MB.createFunctionDecl(
207 FunctionType::get(Type::getVoidTy(*TSCtx.getContext()), {}, false),
208 "foo");
203209 BasicBlock *FooEntry =
204210 BasicBlock::Create(*TSCtx.getContext(), "entry", FooImpl);
205211 IRBuilder<> B(FooEntry);
9494 LLVMContext Ctx;
9595 ModuleBuilder MB(Ctx, TM->getTargetTriple().str(), "TestModule");
9696 MB.getModule()->setDataLayout(TM->createDataLayout());
97 auto *Main = MB.createFunctionDecl("main");
97 auto *Main = MB.createFunctionDecl(
98 FunctionType::get(Type::getInt32Ty(Ctx),
99 {Type::getInt32Ty(Ctx),
100 Type::getInt8PtrTy(Ctx)->getPointerTo()},
101 false),
102 "main");
98103 Main->getBasicBlockList().push_back(BasicBlock::Create(Ctx));
99104 IRBuilder<> B(&Main->back());
100105 B.CreateRet(ConstantInt::getSigned(Type::getInt32Ty(Ctx), 42));
1010
1111 #include "llvm/IR/IRBuilder.h"
1212 #include "llvm/IR/LLVMContext.h"
13 #include "llvm/IR/TypeBuilder.h"
1413 #include "llvm/Support/Debug.h"
1514 #include "llvm/Support/raw_ostream.h"
1615 #include "gtest/gtest.h"
2221 CFGHolder::CFGHolder(StringRef ModuleName, StringRef FunctionName)
2322 : Context(llvm::make_unique()),
2423 M(llvm::make_unique(ModuleName, *Context)) {
25 FunctionType *FTy = TypeBuilder::get(*Context);
24 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Context), {}, false);
2625 F = cast(M->getOrInsertFunction(FunctionName, FTy));
2726 }
2827 CFGHolder::~CFGHolder() = default;
2929 ModuleTest.cpp
3030 PassManagerTest.cpp
3131 PatternMatch.cpp
32 TypeBuilderTest.cpp
3332 TypesTest.cpp
3433 UseTest.cpp
3534 UserTest.cpp
+0
-284
unittests/IR/TypeBuilderTest.cpp less more
None //===- llvm/unittest/TypeBuilderTest.cpp - TypeBuilder tests --------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/IR/TypeBuilder.h"
10 #include "llvm/IR/LLVMContext.h"
11 #include "gtest/gtest.h"
12
13 using namespace llvm;
14
15 namespace {
16
17 TEST(TypeBuilderTest, Void) {
18 LLVMContext Context;
19 EXPECT_EQ(Type::getVoidTy(Context), (TypeBuilder::get(Context)));
20 EXPECT_EQ(Type::getVoidTy(Context), (TypeBuilder::get(Context)));
21 // Special cases for C compatibility:
22 EXPECT_EQ(Type::getInt8PtrTy(Context),
23 (TypeBuilder::get(Context)));
24 EXPECT_EQ(Type::getInt8PtrTy(Context),
25 (TypeBuilder::get(Context)));
26 EXPECT_EQ(Type::getInt8PtrTy(Context),
27 (TypeBuilder::get(Context)));
28 EXPECT_EQ(Type::getInt8PtrTy(Context),
29 (TypeBuilder::get(Context)));
30 }
31
32 TEST(TypeBuilderTest, HostIntegers) {
33 LLVMContext Context;
34 EXPECT_EQ(Type::getInt8Ty(Context),
35 (TypeBuilder::get(Context)));
36 EXPECT_EQ(Type::getInt8Ty(Context),
37 (TypeBuilder::get(Context)));
38 EXPECT_EQ(Type::getInt16Ty(Context),
39 (TypeBuilder::get(Context)));
40 EXPECT_EQ(Type::getInt16Ty(Context),
41 (TypeBuilder::get(Context)));
42 EXPECT_EQ(Type::getInt32Ty(Context),
43 (TypeBuilder::get(Context)));
44 EXPECT_EQ(Type::getInt32Ty(Context),
45 (TypeBuilder::get(Context)));
46 EXPECT_EQ(Type::getInt64Ty(Context),
47 (TypeBuilder::get(Context)));
48 EXPECT_EQ(Type::getInt64Ty(Context),
49 (TypeBuilder::get(Context)));
50
51 EXPECT_EQ(IntegerType::get(Context, sizeof(size_t) * CHAR_BIT),
52 (TypeBuilder::get(Context)));
53 EXPECT_EQ(IntegerType::get(Context, sizeof(ptrdiff_t) * CHAR_BIT),
54 (TypeBuilder::get(Context)));
55 }
56
57 TEST(TypeBuilderTest, CrossCompilableIntegers) {
58 LLVMContext Context;
59 EXPECT_EQ(IntegerType::get(Context, 1),
60 (TypeBuilder, true>::get(Context)));
61 EXPECT_EQ(IntegerType::get(Context, 1),
62 (TypeBuilder, false>::get(Context)));
63 EXPECT_EQ(IntegerType::get(Context, 72),
64 (TypeBuilder, true>::get(Context)));
65 EXPECT_EQ(IntegerType::get(Context, 72),
66 (TypeBuilder, false>::get(Context)));
67 }
68
69 TEST(TypeBuilderTest, Float) {
70 LLVMContext Context;
71 EXPECT_EQ(Type::getFloatTy(Context),
72 (TypeBuilder::get(Context)));
73 EXPECT_EQ(Type::getDoubleTy(Context),
74 (TypeBuilder::get(Context)));
75 // long double isn't supported yet.
76 EXPECT_EQ(Type::getFloatTy(Context),
77 (TypeBuilder::get(Context)));
78 EXPECT_EQ(Type::getFloatTy(Context),
79 (TypeBuilder::get(Context)));
80 EXPECT_EQ(Type::getDoubleTy(Context),
81 (TypeBuilder::get(Context)));
82 EXPECT_EQ(Type::getDoubleTy(Context),
83 (TypeBuilder::get(Context)));
84 EXPECT_EQ(Type::getX86_FP80Ty(Context),
85 (TypeBuilder::get(Context)));
86 EXPECT_EQ(Type::getX86_FP80Ty(Context),
87 (TypeBuilder::get(Context)));
88 EXPECT_EQ(Type::getFP128Ty(Context),
89 (TypeBuilder::get(Context)));
90 EXPECT_EQ(Type::getFP128Ty(Context),
91 (TypeBuilder::get(Context)));
92 EXPECT_EQ(Type::getPPC_FP128Ty(Context),
93 (TypeBuilder::get(Context)));
94 EXPECT_EQ(Type::getPPC_FP128Ty(Context),
95 (TypeBuilder::get(Context)));
96 }
97
98 TEST(TypeBuilderTest, Derived) {
99 LLVMContext Context;
100 EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(Context)),
101 (TypeBuilder::get(Context)));
102 EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 7),
103 (TypeBuilder::get(Context)));
104 EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 0),
105 (TypeBuilder::get(Context)));
106
107 EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(Context)),
108 (TypeBuilder **, false>::get(Context)));
109 EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 7),
110 (TypeBuilder[7], false>::get(Context)));
111 EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 0),
112 (TypeBuilder[], false>::get(Context)));
113
114 EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(Context)),
115 (TypeBuilder **, true>::get(Context)));
116 EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 7),
117 (TypeBuilder[7], true>::get(Context)));
118 EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 0),
119 (TypeBuilder[], true>::get(Context)));
120
121 EXPECT_EQ(Type::getInt8Ty(Context),
122 (TypeBuilder::get(Context)));
123 EXPECT_EQ(Type::getInt8Ty(Context),
124 (TypeBuilder::get(Context)));
125 EXPECT_EQ(Type::getInt8Ty(Context),
126 (TypeBuilder::get(Context)));
127
128 EXPECT_EQ(Type::getInt8Ty(Context),
129 (TypeBuilder, false>::get(Context)));
130 EXPECT_EQ(Type::getInt8Ty(Context),
131 (TypeBuilder, false>::get(Context)));
132 EXPECT_EQ(Type::getInt8Ty(Context),
133 (TypeBuilder, false>::get(Context)));
134
135 EXPECT_EQ(Type::getInt8Ty(Context),
136 (TypeBuilder, true>::get(Context)));
137 EXPECT_EQ(Type::getInt8Ty(Context),
138 (TypeBuilder, true>::get(Context)));
139 EXPECT_EQ(Type::getInt8Ty(Context),
140 (TypeBuilder, true>::get(Context)));
141
142 EXPECT_EQ(Type::getInt8PtrTy(Context),
143 (TypeBuilder::get(
144 Context)));
145 }
146
147 TEST(TypeBuilderTest, Functions) {
148 LLVMContext Context;
149 std::vector params;
150 EXPECT_EQ(FunctionType::get(Type::getVoidTy(Context), params, false),
151 (TypeBuilder::get(Context)));
152 EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true),
153 (TypeBuilder::get(Context)));
154 params.push_back(TypeBuilder::get(Context));
155 EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, false),
156 (TypeBuilder::get(Context)));
157 EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true),
158 (TypeBuilder::get(Context)));
159 params.push_back(TypeBuilder::get(Context));
160 EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, false),
161 (TypeBuilder::get(Context)));
162 EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true),
163 (TypeBuilder::get(Context)));
164 params.push_back(TypeBuilder::get(Context));
165 EXPECT_EQ(
166 FunctionType::get(Type::getInt8Ty(Context), params, false),
167 (TypeBuilder::get(Context)));
168 EXPECT_EQ(
169 FunctionType::get(Type::getInt8Ty(Context), params, true),
170 (TypeBuilder::get(Context)));
171 params.push_back(TypeBuilder::get(Context));
172 EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, false),
173 (TypeBuilder::get(
174 Context)));
175 EXPECT_EQ(
176 FunctionType::get(Type::getInt8Ty(Context), params, true),
177 (TypeBuilder::get(
178 Context)));
179 params.push_back(TypeBuilder::get(Context));
180 EXPECT_EQ(
181 FunctionType::get(Type::getInt8Ty(Context), params, false),
182 (TypeBuilder::get(
183 Context)));
184 EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true),
185 (TypeBuilder
186 false>::get(Context)));
187 }
188
189 TEST(TypeBuilderTest, Context) {
190 // We used to cache TypeBuilder results in static local variables. This
191 // produced the same type for different contexts, which of course broke
192 // things.
193 LLVMContext context1;
194 EXPECT_EQ(&context1,
195 &(TypeBuilder, true>::get(context1))->getContext());
196 LLVMContext context2;
197 EXPECT_EQ(&context2,
198 &(TypeBuilder, true>::get(context2))->getContext());
199 }
200
201 struct MyType {
202 int a;
203 int *b;
204 void *array[1];
205 };
206
207 struct MyPortableType {
208 int32_t a;
209 int32_t *b;
210 void *array[1];
211 };
212
213 } // anonymous namespace
214
215 namespace llvm {
216 template class TypeBuilder {
217 public:
218 static StructType *get(LLVMContext &Context) {
219 // Using the static result variable ensures that the type is
220 // only looked up once.
221 std::vector st;
222 st.push_back(TypeBuilder::get(Context));
223 st.push_back(TypeBuilder::get(Context));
224 st.push_back(TypeBuilder::get(Context));
225 static StructType *const result = StructType::get(Context, st);
226 return result;
227 }
228
229 // You may find this a convenient place to put some constants
230 // to help with getelementptr. They don't have any effect on
231 // the operation of TypeBuilder.
232 enum Fields {
233 FIELD_A,
234 FIELD_B,
235 FIELD_ARRAY
236 };
237 };
238
239 template class TypeBuilder {
240 public:
241 static StructType *get(LLVMContext &Context) {
242 // Using the static result variable ensures that the type is
243 // only looked up once.
244 std::vector st;
245 st.push_back(TypeBuilder, cross>::get(Context));
246 st.push_back(TypeBuilder*, cross>::get(Context));
247 st.push_back(TypeBuilder*[], cross>::get(Context));
248 static StructType *const result = StructType::get(Context, st);
249 return result;
250 }
251
252 // You may find this a convenient place to put some constants
253 // to help with getelementptr. They don't have any effect on
254 // the operation of TypeBuilder.
255 enum Fields {
256 FIELD_A,
257 FIELD_B,
258 FIELD_ARRAY
259 };
260 };
261 } // namespace llvm
262 namespace {
263
264 TEST(TypeBuilderTest, Extensions) {
265 LLVMContext Context;
266 EXPECT_EQ(PointerType::getUnqual(
267 StructType::get(TypeBuilder::get(Context),
268 TypeBuilder::get(Context),
269 TypeBuilder::get(Context))),
270 (TypeBuilder::get(Context)));
271 EXPECT_EQ(PointerType::getUnqual(StructType::get(
272 TypeBuilder, false>::get(Context),
273 TypeBuilder *, false>::get(Context),
274 TypeBuilder *[], false>::get(Context))),
275 (TypeBuilder::get(Context)));
276 EXPECT_EQ(PointerType::getUnqual(StructType::get(
277 TypeBuilder, false>::get(Context),
278 TypeBuilder *, false>::get(Context),
279 TypeBuilder *[], false>::get(Context))),
280 (TypeBuilder::get(Context)));
281 }
282
283 } // anonymous namespace
3232 "PassBuilderCallbacksTest.cpp",
3333 "PassManagerTest.cpp",
3434 "PatternMatch.cpp",
35 "TypeBuilderTest.cpp",
3635 "TypesTest.cpp",
3736 "UseTest.cpp",
3837 "UserTest.cpp",