1
|
1 #include <iostream>
|
|
2
|
|
3 #include "llvm/Constants.h"
|
|
4 #include "llvm/Type.h"
|
|
5 #include "llvm/DerivedTypes.h"
|
|
6 #include "llvm/GlobalValue.h"
|
|
7 #include "llvm/Instructions.h"
|
|
8 #include "llvm/CallingConv.h"
|
|
9
|
|
10 #include "mtype.h"
|
|
11 #include "dsymbol.h"
|
|
12 #include "aggregate.h"
|
|
13 #include "declaration.h"
|
|
14 #include "init.h"
|
|
15
|
|
16 #include "tollvm.h"
|
|
17 #include "irstate.h"
|
|
18 #include "logger.h"
|
|
19 #include "runtime.h"
|
|
20 #include "elem.h"
|
|
21
|
|
22 const llvm::Type* LLVM_DtoType(Type* t)
|
|
23 {
|
|
24 assert(t);
|
|
25 switch (t->ty)
|
|
26 {
|
|
27 // integers
|
|
28 case Tint8:
|
|
29 case Tuns8:
|
|
30 case Tchar:
|
|
31 return (const llvm::Type*)llvm::Type::Int8Ty;
|
|
32 case Tint16:
|
|
33 case Tuns16:
|
|
34 case Twchar:
|
|
35 return (const llvm::Type*)llvm::Type::Int16Ty;
|
|
36 case Tint32:
|
|
37 case Tuns32:
|
|
38 case Tdchar:
|
|
39 return (const llvm::Type*)llvm::Type::Int32Ty;
|
|
40 case Tint64:
|
|
41 case Tuns64:
|
|
42 return (const llvm::Type*)llvm::Type::Int64Ty;
|
|
43
|
|
44 case Tbool:
|
|
45 return (const llvm::Type*)llvm::ConstantInt::getTrue()->getType();
|
|
46
|
|
47 // floats
|
|
48 case Tfloat32:
|
|
49 return llvm::Type::FloatTy;
|
|
50 case Tfloat64:
|
|
51 case Tfloat80:
|
|
52 return llvm::Type::DoubleTy;
|
|
53
|
|
54 // pointers
|
|
55 case Tpointer: {
|
|
56 assert(t->next);
|
|
57 if (t->next->ty == Tvoid)
|
|
58 return (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty);
|
|
59 else
|
|
60 return (const llvm::Type*)llvm::PointerType::get(LLVM_DtoType(t->next));
|
|
61 }
|
|
62
|
|
63 // arrays
|
|
64 case Tarray:
|
|
65 return LLVM_DtoArrayType(t);
|
|
66 case Tsarray:
|
|
67 return LLVM_DtoStaticArrayType(t);
|
|
68
|
|
69 // void
|
|
70 case Tvoid:
|
|
71 return llvm::Type::VoidTy;
|
|
72
|
|
73 // aggregates
|
|
74 case Tstruct: {
|
|
75 if (t->llvmType == 0)
|
|
76 {
|
|
77 // recursive or cyclic declaration
|
|
78 if (!gIR->structs.empty())
|
|
79 {
|
|
80 IRStruct* found = 0;
|
|
81 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
|
|
82 {
|
|
83 if (t == i->type)
|
|
84 {
|
|
85 return i->recty.get();
|
|
86 }
|
|
87 }
|
|
88 }
|
|
89
|
|
90 // forward declaration
|
|
91 TypeStruct* ts = (TypeStruct*)t;
|
|
92 assert(ts->sym);
|
|
93 ts->sym->toObjFile();
|
|
94 }
|
|
95 return t->llvmType;
|
|
96 }
|
|
97
|
|
98 case Tclass: {
|
|
99 if (t->llvmType == 0)
|
|
100 {
|
|
101 TypeClass* tc = (TypeClass*)t;
|
|
102 assert(tc->sym);
|
|
103 if (!tc->sym->llvmInProgress) {
|
|
104 tc->sym->toObjFile();
|
|
105 }
|
|
106 else {
|
|
107 //assert(0 && "circular class referencing");
|
|
108 return llvm::OpaqueType::get();
|
|
109 }
|
|
110 }
|
|
111 return llvm::PointerType::get(t->llvmType);
|
|
112 }
|
|
113
|
|
114 // functions
|
|
115 case Tfunction:
|
|
116 {
|
|
117 if (t->llvmType == 0) {
|
|
118 return LLVM_DtoFunctionType(t);
|
|
119 }
|
|
120 else {
|
|
121 return t->llvmType;
|
|
122 }
|
|
123 }
|
|
124
|
|
125 // delegates
|
|
126 case Tdelegate:
|
|
127 {
|
|
128 if (t->llvmType == 0) {
|
|
129 return LLVM_DtoDelegateType(t);
|
|
130 }
|
|
131 else {
|
|
132 return t->llvmType;
|
|
133 }
|
|
134 }
|
|
135
|
|
136 // typedefs
|
|
137 case Ttypedef:
|
|
138 {
|
|
139 Type* bt = t->toBasetype();
|
|
140 assert(bt);
|
|
141 return LLVM_DtoType(bt);
|
|
142 }
|
|
143
|
|
144 default:
|
|
145 printf("trying to convert unknown type with value %d\n", t->ty);
|
|
146 assert(0);
|
|
147 }
|
|
148 return 0;
|
|
149 }
|
|
150
|
|
151 //////////////////////////////////////////////////////////////////////////////////////////
|
|
152
|
|
153 llvm::FunctionType* LLVM_DtoFunctionType(Type* t, const llvm::Type* thisparam)
|
|
154 {
|
|
155 TypeFunction* f = (TypeFunction*)t;
|
|
156
|
|
157 // parameter types
|
|
158 const llvm::Type* rettype;
|
|
159 std::vector<const llvm::Type*> paramvec;
|
|
160
|
|
161 TY retty = f->next->ty;
|
|
162
|
|
163 if (retty == Tstruct || retty == Tdelegate || retty == Tarray) {
|
|
164 rettype = llvm::PointerType::get(LLVM_DtoType(f->next));
|
|
165 paramvec.push_back(rettype);
|
|
166 rettype = llvm::Type::VoidTy;
|
|
167 }
|
|
168 else {
|
|
169 Type* rt = f->next;
|
|
170 if (rt)
|
|
171 rettype = LLVM_DtoType(rt);
|
|
172 else
|
|
173 assert(0);
|
|
174 }
|
|
175
|
|
176 if (thisparam) {
|
|
177 paramvec.push_back(thisparam);
|
|
178 }
|
|
179
|
|
180 size_t n = Argument::dim(f->parameters);
|
|
181 for (int i=0; i < n; ++i) {
|
|
182 Argument* arg = Argument::getNth(f->parameters, i);
|
|
183 // ensure scalar
|
|
184 Type* argT = arg->type;
|
|
185 assert(argT);
|
|
186 paramvec.push_back(LLVM_DtoType(argT));
|
|
187 }
|
|
188
|
|
189 Logger::cout() << "Return type: " << *rettype << '\n';
|
|
190
|
|
191 llvm::FunctionType* functype = llvm::FunctionType::get(rettype, paramvec, f->varargs);
|
|
192 return functype;
|
|
193 }
|
|
194
|
|
195 //////////////////////////////////////////////////////////////////////////////////////////
|
|
196
|
|
197 llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl)
|
|
198 {
|
|
199 TypeFunction* f = (TypeFunction*)fdecl->type;
|
|
200 assert(f != 0);
|
|
201
|
|
202 // has already been pulled in by a reference to (
|
|
203 if (f->llvmType != 0) {
|
|
204 return llvm::cast<llvm::FunctionType>(f->llvmType);
|
|
205 }
|
|
206
|
|
207 // return value type
|
|
208 const llvm::Type* rettype;
|
|
209 const llvm::Type* actualRettype;
|
|
210 Type* rt = f->next;
|
|
211 bool retinptr = false;
|
|
212 bool usesthis = false;
|
|
213
|
|
214 if (fdecl->isMain()) {
|
|
215 rettype = llvm::Type::Int32Ty;
|
|
216 actualRettype = rettype;
|
|
217 }
|
|
218 else if (rt) {
|
|
219 if (rt->ty == Tstruct || rt->ty == Tdelegate || rt->ty == Tarray) {
|
|
220 rettype = llvm::PointerType::get(LLVM_DtoType(rt));
|
|
221 actualRettype = llvm::Type::VoidTy;
|
|
222 f->llvmRetInPtr = retinptr = true;
|
|
223 }
|
|
224 else {
|
|
225 rettype = LLVM_DtoType(rt);
|
|
226 actualRettype = rettype;
|
|
227 }
|
|
228 }
|
|
229 else {
|
|
230 assert(0);
|
|
231 }
|
|
232
|
|
233 // parameter types
|
|
234 std::vector<const llvm::Type*> paramvec;
|
|
235
|
|
236 if (retinptr) {
|
|
237 Logger::print("returning through pointer parameter\n");
|
|
238 paramvec.push_back(rettype);
|
|
239 }
|
|
240
|
|
241 if (fdecl->needThis() && fdecl->vthis) {
|
|
242 Logger::print("this is: %s\n", fdecl->vthis->type->toChars());
|
|
243 paramvec.push_back(LLVM_DtoType(fdecl->vthis->type));
|
|
244 usesthis = true;
|
|
245 }
|
|
246
|
|
247 size_t n = Argument::dim(f->parameters);
|
|
248 for (int i=0; i < n; ++i) {
|
|
249 Argument* arg = Argument::getNth(f->parameters, i);
|
|
250 // ensure scalar
|
|
251 Type* argT = arg->type;
|
|
252 assert(argT);
|
|
253
|
|
254 if ((arg->storageClass & STCref) || (arg->storageClass & STCout)) {
|
|
255 //assert(arg->vardecl);
|
|
256 //arg->vardecl->refparam = true;
|
|
257 }
|
|
258 else
|
|
259 arg->llvmCopy = true;
|
|
260
|
|
261 const llvm::Type* at = LLVM_DtoType(argT);
|
|
262 if (llvm::isa<llvm::StructType>(at)) {
|
|
263 Logger::println("struct param");
|
|
264 paramvec.push_back(llvm::PointerType::get(at));
|
|
265 }
|
|
266 else if (llvm::isa<llvm::ArrayType>(at)) {
|
|
267 Logger::println("sarray param");
|
|
268 assert(argT->ty == Tsarray);
|
|
269 //paramvec.push_back(llvm::PointerType::get(at->getContainedType(0)));
|
|
270 paramvec.push_back(llvm::PointerType::get(at));
|
|
271 }
|
|
272 else {
|
|
273 if (!arg->llvmCopy) {
|
|
274 Logger::println("ref param");
|
|
275 at = llvm::PointerType::get(at);
|
|
276 }
|
|
277 else {
|
|
278 Logger::println("in param");
|
|
279 }
|
|
280 paramvec.push_back(at);
|
|
281 }
|
|
282 }
|
|
283
|
|
284 // construct function type
|
|
285 bool isvararg = f->varargs;
|
|
286 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg);
|
|
287
|
|
288 f->llvmType = functype;
|
|
289 return functype;
|
|
290 }
|
|
291
|
|
292 //////////////////////////////////////////////////////////////////////////////////////////
|
|
293
|
|
294 llvm::StructType* LLVM_DtoDelegateType(Type* t)
|
|
295 {
|
|
296 const llvm::Type* i8ptr = llvm::PointerType::get(llvm::Type::Int8Ty);
|
|
297 const llvm::Type* func = LLVM_DtoFunctionType(t->next, i8ptr);
|
|
298 const llvm::Type* funcptr = llvm::PointerType::get(func);
|
|
299
|
|
300 std::vector<const llvm::Type*> types;
|
|
301 types.push_back(i8ptr);
|
|
302 types.push_back(funcptr);
|
|
303 return llvm::StructType::get(types);
|
|
304 }
|
|
305
|
|
306 //////////////////////////////////////////////////////////////////////////////////////////
|
|
307
|
|
308 llvm::Type* LLVM_DtoStructType(Type* t)
|
|
309 {
|
|
310 assert(0);
|
|
311 std::vector<const llvm::Type*> types;
|
|
312 return llvm::StructType::get(types);
|
|
313 }
|
|
314
|
|
315 //////////////////////////////////////////////////////////////////////////////////////////
|
|
316
|
|
317 llvm::StructType* LLVM_DtoArrayType(Type* t)
|
|
318 {
|
|
319 assert(t->next);
|
|
320 const llvm::Type* at = LLVM_DtoType(t->next);
|
|
321 const llvm::Type* arrty;
|
|
322
|
|
323 /*if (t->ty == Tsarray) {
|
|
324 TypeSArray* tsa = (TypeSArray*)t;
|
|
325 assert(tsa->dim->type->isintegral());
|
|
326 arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger());
|
|
327 }
|
|
328 else {
|
|
329 arrty = llvm::ArrayType::get(at,0);
|
|
330 }*/
|
|
331 if (at == llvm::Type::VoidTy) {
|
|
332 at = llvm::Type::Int8Ty;
|
|
333 }
|
|
334 arrty = llvm::PointerType::get(at);
|
|
335
|
|
336 std::vector<const llvm::Type*> members;
|
|
337 if (global.params.is64bit)
|
|
338 members.push_back(llvm::Type::Int64Ty);
|
|
339 else
|
|
340 members.push_back(llvm::Type::Int32Ty);
|
|
341
|
|
342 members.push_back(arrty);
|
|
343
|
|
344 return llvm::StructType::get(members);
|
|
345 }
|
|
346
|
|
347 //////////////////////////////////////////////////////////////////////////////////////////
|
|
348
|
|
349 llvm::ArrayType* LLVM_DtoStaticArrayType(Type* t)
|
|
350 {
|
|
351 if (t->llvmType)
|
|
352 return llvm::cast<llvm::ArrayType>(t->llvmType);
|
|
353
|
|
354 assert(t->ty == Tsarray);
|
|
355 assert(t->next);
|
|
356
|
|
357 const llvm::Type* at = LLVM_DtoType(t->next);
|
|
358
|
|
359 TypeSArray* tsa = (TypeSArray*)t;
|
|
360 assert(tsa->dim->type->isintegral());
|
|
361 llvm::ArrayType* arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger());
|
|
362
|
|
363 tsa->llvmType = arrty;
|
|
364 return arrty;
|
|
365 }
|
|
366
|
|
367 //////////////////////////////////////////////////////////////////////////////////////////
|
|
368
|
|
369 static llvm::Function* LLVM_DeclareMemIntrinsic(const char* name, int bits, bool set=false)
|
|
370 {
|
|
371 assert(bits == 32 || bits == 64);
|
|
372 const llvm::Type* int8ty = (const llvm::Type*)llvm::Type::Int8Ty;
|
|
373 const llvm::Type* int32ty = (const llvm::Type*)llvm::Type::Int32Ty;
|
|
374 const llvm::Type* int64ty = (const llvm::Type*)llvm::Type::Int64Ty;
|
|
375 const llvm::Type* int8ptrty = (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty);
|
|
376 const llvm::Type* voidty = (const llvm::Type*)llvm::Type::VoidTy;
|
|
377
|
|
378 assert(gIR);
|
|
379 assert(gIR->module);
|
|
380
|
|
381 // parameter types
|
|
382 std::vector<const llvm::Type*> pvec;
|
|
383 pvec.push_back(int8ptrty);
|
|
384 pvec.push_back(set?int8ty:int8ptrty);
|
|
385 pvec.push_back(bits==32?int32ty:int64ty);
|
|
386 pvec.push_back(int32ty);
|
|
387 llvm::FunctionType* functype = llvm::FunctionType::get(voidty, pvec, false);
|
|
388 return new llvm::Function(functype, llvm::GlobalValue::ExternalLinkage, name, gIR->module);
|
|
389 }
|
|
390
|
|
391 //////////////////////////////////////////////////////////////////////////////////////////
|
|
392
|
|
393 // llvm.memset.i32
|
|
394 static llvm::Function* LLVM_DeclareMemSet32()
|
|
395 {
|
|
396 static llvm::Function* _func = 0;
|
|
397 if (_func == 0) {
|
|
398 _func = LLVM_DeclareMemIntrinsic("llvm.memset.i32", 32, true);
|
|
399 }
|
|
400 return _func;
|
|
401 }
|
|
402
|
|
403 //////////////////////////////////////////////////////////////////////////////////////////
|
|
404
|
|
405 static llvm::Function* LLVM_DeclareMemSet64()
|
|
406 {
|
|
407 static llvm::Function* _func = 0;
|
|
408 if (_func == 0) {
|
|
409 _func = LLVM_DeclareMemIntrinsic("llvm.memset.i64", 64, true);
|
|
410 }
|
|
411 return _func;
|
|
412 }
|
|
413
|
|
414 //////////////////////////////////////////////////////////////////////////////////////////
|
|
415
|
|
416 // llvm.memcpy.i32
|
|
417 static llvm::Function* LLVM_DeclareMemCpy32()
|
|
418 {
|
|
419 static llvm::Function* _func = 0;
|
|
420 if (_func == 0) {
|
|
421 _func = LLVM_DeclareMemIntrinsic("llvm.memcpy.i32", 32);
|
|
422 }
|
|
423 return _func;
|
|
424 }
|
|
425
|
|
426 //////////////////////////////////////////////////////////////////////////////////////////
|
|
427
|
|
428 // llvm.memcpy.i64
|
|
429 static llvm::Function* LLVM_DeclareMemCpy64()
|
|
430 {
|
|
431 static llvm::Function* _func = 0;
|
|
432 if (_func == 0) {
|
|
433 _func = LLVM_DeclareMemIntrinsic("llvm.memcpy.i64", 64);
|
|
434 }
|
|
435 return _func;
|
|
436 }
|
|
437
|
|
438 //////////////////////////////////////////////////////////////////////////////////////////
|
|
439
|
|
440 llvm::Value* LLVM_DtoStructZeroInit(TypeStruct* t, llvm::Value* v)
|
|
441 {
|
|
442 assert(gIR);
|
|
443 uint64_t n = gTargetData->getTypeSize(t->llvmType);
|
|
444 //llvm::Type* sarrty = llvm::PointerType::get(llvm::ArrayType::get(llvm::Type::Int8Ty, n));
|
|
445 llvm::Type* sarrty = llvm::PointerType::get(llvm::Type::Int8Ty);
|
|
446
|
|
447 llvm::Value* sarr = new llvm::BitCastInst(v,sarrty,"tmp",gIR->scopebb());
|
|
448
|
|
449 llvm::Function* fn = LLVM_DeclareMemSet32();
|
|
450 std::vector<llvm::Value*> llargs;
|
|
451 llargs.resize(4);
|
|
452 llargs[0] = sarr;
|
|
453 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false);
|
|
454 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
|
|
455 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
|
456
|
|
457 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
|
458
|
|
459 return ret;
|
|
460 }
|
|
461
|
|
462 //////////////////////////////////////////////////////////////////////////////////////////
|
|
463
|
|
464 llvm::Value* LLVM_DtoStructCopy(TypeStruct* t, llvm::Value* dst, llvm::Value* src)
|
|
465 {
|
|
466 assert(dst->getType() == src->getType());
|
|
467 assert(gIR);
|
|
468
|
|
469 uint64_t n = gTargetData->getTypeSize(t->llvmType);
|
|
470 //llvm::Type* sarrty = llvm::PointerType::get(llvm::ArrayType::get(llvm::Type::Int8Ty, n));
|
|
471 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
|
|
472
|
|
473 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
|
|
474 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb());
|
|
475
|
|
476 llvm::Function* fn = LLVM_DeclareMemCpy32();
|
|
477 std::vector<llvm::Value*> llargs;
|
|
478 llargs.resize(4);
|
|
479 llargs[0] = dstarr;
|
|
480 llargs[1] = srcarr;
|
|
481 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
|
|
482 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
|
483
|
|
484 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
|
485 }
|
|
486
|
|
487 //////////////////////////////////////////////////////////////////////////////////////////
|
|
488 llvm::Constant* LLVM_DtoStructInitializer(StructInitializer* si)
|
|
489 {
|
|
490 llvm::StructType* structtype = llvm::cast<llvm::StructType>(si->ad->llvmType);
|
|
491 size_t n = structtype->getNumElements();
|
|
492
|
|
493 assert(si->value.dim == si->vars.dim);
|
|
494
|
|
495 std::vector<llvm::Constant*> inits;
|
|
496 inits.resize(n, NULL);
|
|
497 for (int i = 0; i < si->value.dim; ++i)
|
|
498 {
|
|
499 Initializer* ini = (Initializer*)si->value.data[i];
|
|
500 assert(ini);
|
|
501
|
|
502 VarDeclaration* vd = (VarDeclaration*)si->vars.data[i];
|
|
503 assert(vd);
|
|
504 Logger::println("vars[%d] = %s", i, vd->toChars());
|
|
505 unsigned idx = si->ad->offsetToIndex(vd->offset);
|
|
506
|
|
507 llvm::Constant* v = 0;
|
|
508
|
|
509 if (ExpInitializer* ex = ini->isExpInitializer())
|
|
510 {
|
|
511 elem* e = ex->exp->toElem(gIR);
|
|
512 v = llvm::cast<llvm::Constant>(e->val);
|
|
513 delete e;
|
|
514 }
|
|
515 else if (StructInitializer* si = ini->isStructInitializer())
|
|
516 {
|
|
517 v = LLVM_DtoStructInitializer(si);
|
|
518 }
|
|
519 else if (ArrayInitializer* ai = ini->isArrayInitializer())
|
|
520 {
|
|
521 v = LLVM_DtoArrayInitializer(ai);
|
|
522 }
|
|
523 else if (ini->isVoidInitializer())
|
|
524 {
|
|
525 v = llvm::UndefValue::get(structtype->getElementType(idx));
|
|
526 }
|
|
527 else
|
|
528 assert(v);
|
|
529
|
|
530 inits[idx] = v;
|
|
531 }
|
|
532
|
|
533 // fill out nulls
|
|
534 assert(si->ad->llvmInitZ);
|
|
535 if (si->ad->llvmInitZ->isNullValue())
|
|
536 {
|
|
537 for (int i = 0; i < n; ++i)
|
|
538 {
|
|
539 if (inits[i] == 0)
|
|
540 {
|
|
541 inits[i] = llvm::Constant::getNullValue(structtype->getElementType(i));
|
|
542 }
|
|
543 }
|
|
544 }
|
|
545 else
|
|
546 {
|
|
547 for (int i = 0; i < n; ++i)
|
|
548 {
|
|
549 if (inits[i] == 0)
|
|
550 {
|
|
551 inits[i] = si->ad->llvmInitZ->getOperand(i);
|
|
552 }
|
|
553 }
|
|
554 }
|
|
555
|
|
556 return llvm::ConstantStruct::get(structtype, inits);
|
|
557 }
|
|
558
|
|
559 //////////////////////////////////////////////////////////////////////////////////////////
|
|
560
|
|
561 llvm::Value* LLVM_DtoNullArray(llvm::Value* v)
|
|
562 {
|
|
563 assert(gIR);
|
|
564 d_uns64 n = (global.params.is64bit) ? 16 : 8;
|
|
565
|
|
566 llvm::Type* i8p_ty = llvm::PointerType::get(llvm::Type::Int8Ty);
|
|
567
|
|
568 llvm::Value* arr = new llvm::BitCastInst(v,i8p_ty,"tmp",gIR->scopebb());
|
|
569
|
|
570 llvm::Function* fn = LLVM_DeclareMemSet32();
|
|
571 std::vector<llvm::Value*> llargs;
|
|
572 llargs.resize(4);
|
|
573 llargs[0] = arr;
|
|
574 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false);
|
|
575 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
|
|
576 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
|
577
|
|
578 //Logger::cout() << *fn << '|' << *fn->getType() << '\n';
|
|
579 //Logger::cout() << "to null array call: " << *llargs[0] << '|' << *llargs[1] << '|' << *llargs[2] << '|' << *llargs[3] << '\n';
|
|
580
|
|
581 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
|
582
|
|
583 return ret;
|
|
584 }
|
|
585
|
|
586 //////////////////////////////////////////////////////////////////////////////////////////
|
|
587
|
|
588 llvm::Value* LLVM_DtoNullDelegate(llvm::Value* v)
|
|
589 {
|
|
590 assert(gIR);
|
|
591 d_uns64 n = (global.params.is64bit) ? 16 : 8;
|
|
592
|
|
593 llvm::Type* i8p_ty = llvm::PointerType::get(llvm::Type::Int8Ty);
|
|
594
|
|
595 llvm::Value* arr = new llvm::BitCastInst(v,i8p_ty,"tmp",gIR->scopebb());
|
|
596
|
|
597 llvm::Function* fn = LLVM_DeclareMemSet32();
|
|
598 std::vector<llvm::Value*> llargs;
|
|
599 llargs.resize(4);
|
|
600 llargs[0] = arr;
|
|
601 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false);
|
|
602 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
|
|
603 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
|
604
|
|
605 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
|
606
|
|
607 return ret;
|
|
608 }
|
|
609
|
|
610 //////////////////////////////////////////////////////////////////////////////////////////
|
|
611
|
|
612 llvm::Value* LLVM_DtoDelegateCopy(llvm::Value* dst, llvm::Value* src)
|
|
613 {
|
|
614 assert(dst->getType() == src->getType());
|
|
615 assert(gIR);
|
|
616
|
|
617 d_uns64 n = (global.params.is64bit) ? 16 : 8;
|
|
618
|
|
619 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
|
|
620
|
|
621 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
|
|
622 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb());
|
|
623
|
|
624 llvm::Function* fn = LLVM_DeclareMemCpy32();
|
|
625 std::vector<llvm::Value*> llargs;
|
|
626 llargs.resize(4);
|
|
627 llargs[0] = dstarr;
|
|
628 llargs[1] = srcarr;
|
|
629 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
|
|
630 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
|
631
|
|
632 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
|
633 }
|
|
634
|
|
635 //////////////////////////////////////////////////////////////////////////////////////////
|
|
636
|
|
637 llvm::Value* LLVM_DtoArrayAssign(llvm::Value* dst, llvm::Value* src)
|
|
638 {
|
|
639 assert(gIR);
|
|
640 if (dst->getType() == src->getType())
|
|
641 {
|
|
642 d_uns64 n = (global.params.is64bit) ? 16 : 8;
|
|
643
|
|
644 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
|
|
645
|
|
646 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
|
|
647 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb());
|
|
648
|
|
649 llvm::Function* fn = LLVM_DeclareMemCpy32();
|
|
650 std::vector<llvm::Value*> llargs;
|
|
651 llargs.resize(4);
|
|
652 llargs[0] = dstarr;
|
|
653 llargs[1] = srcarr;
|
|
654 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
|
|
655 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
|
656
|
|
657 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
|
658 }
|
|
659 else
|
|
660 {
|
|
661 if (!llvm::isa<llvm::ArrayType>(src->getType()->getContainedType(0)))
|
|
662 {
|
|
663 Logger::cout() << "invalid: " << *src << '\n';
|
|
664 assert(0);
|
|
665 }
|
|
666 const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(src->getType()->getContainedType(0));
|
|
667 llvm::Type* dstty = llvm::PointerType::get(arrty->getElementType());
|
|
668
|
|
669 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
|
670 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
|
|
671
|
|
672 llvm::Value* dstlen = new llvm::GetElementPtrInst(dst,zero,zero,"tmp",gIR->scopebb());
|
|
673 llvm::Value* srclen = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false);
|
|
674 new llvm::StoreInst(srclen, dstlen, gIR->scopebb());
|
|
675
|
|
676 llvm::Value* dstptr = new llvm::GetElementPtrInst(dst,zero,one,"tmp",gIR->scopebb());
|
|
677 llvm::Value* srcptr = new llvm::BitCastInst(src,dstty,"tmp",gIR->scopebb());
|
|
678 new llvm::StoreInst(srcptr, dstptr, gIR->scopebb());
|
|
679 }
|
|
680 }
|
|
681
|
|
682 //////////////////////////////////////////////////////////////////////////////////////////
|
|
683
|
|
684 void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r)
|
|
685 {
|
|
686 const llvm::PointerType* ptrty = llvm::cast<llvm::PointerType>(l->getType());
|
|
687 if (llvm::isa<llvm::ArrayType>(ptrty->getContainedType(0)))
|
|
688 {
|
|
689 const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(ptrty->getContainedType(0));
|
|
690 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
|
691
|
|
692 std::vector<llvm::Value*> args;
|
|
693 args.resize(3);
|
|
694 args[0] = new llvm::GetElementPtrInst(l,zero,zero,"tmp",gIR->scopebb());
|
|
695 args[1] = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false);
|
|
696 args[2] = r;
|
|
697
|
|
698 const char* funcname = NULL;
|
|
699
|
|
700 if (llvm::isa<llvm::PointerType>(arrty->getElementType())) {
|
|
701 funcname = "_d_array_init_pointer";
|
|
702
|
|
703 const llvm::Type* dstty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty));
|
|
704 if (args[0]->getType() != dstty)
|
|
705 args[0] = new llvm::BitCastInst(args[0],dstty,"tmp",gIR->scopebb());
|
|
706
|
|
707 const llvm::Type* valty = llvm::PointerType::get(llvm::Type::Int8Ty);
|
|
708 if (args[2]->getType() != valty)
|
|
709 args[2] = new llvm::BitCastInst(args[2],valty,"tmp",gIR->scopebb());
|
|
710 }
|
|
711 else if (r->getType() == llvm::Type::Int1Ty) {
|
|
712 funcname = "_d_array_init_i1";
|
|
713 }
|
|
714 else if (r->getType() == llvm::Type::Int8Ty) {
|
|
715 funcname = "_d_array_init_i8";
|
|
716 }
|
|
717 else if (r->getType() == llvm::Type::Int16Ty) {
|
|
718 funcname = "_d_array_init_i16";
|
|
719 }
|
|
720 else if (r->getType() == llvm::Type::Int32Ty) {
|
|
721 funcname = "_d_array_init_i32";
|
|
722 }
|
|
723 else if (r->getType() == llvm::Type::Int64Ty) {
|
|
724 funcname = "_d_array_init_i64";
|
|
725 }
|
|
726 else if (r->getType() == llvm::Type::FloatTy) {
|
|
727 funcname = "_d_array_init_float";
|
|
728 }
|
|
729 else if (r->getType() == llvm::Type::DoubleTy) {
|
|
730 funcname = "_d_array_init_double";
|
|
731 }
|
|
732 else {
|
|
733 assert(0);
|
|
734 }
|
|
735
|
|
736 Logger::cout() << *args[0] << '|' << *args[2] << '\n';
|
|
737
|
|
738 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname);
|
|
739 assert(fn);
|
|
740 llvm::CallInst* call = new llvm::CallInst(fn, args.begin(), args.end(), "", gIR->scopebb());
|
|
741 call->setCallingConv(llvm::CallingConv::C);
|
|
742
|
|
743 Logger::println("array init call ok");
|
|
744 }
|
|
745 else if (llvm::isa<llvm::StructType>(ptrty->getContainedType(0)))
|
|
746 {
|
|
747 assert(0 && "Only static arrays support initialisers atm");
|
|
748 }
|
|
749 else
|
|
750 assert(0);
|
|
751 }
|
|
752
|
|
753 //////////////////////////////////////////////////////////////////////////////////////////
|
|
754
|
|
755 void LLVM_DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr)
|
|
756 {
|
|
757 const llvm::StructType* st = llvm::cast<llvm::StructType>(arr->getType()->getContainedType(0));
|
|
758 //const llvm::PointerType* pt = llvm::cast<llvm::PointerType>(r->getType());
|
|
759
|
|
760 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
|
761 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
|
|
762
|
|
763 llvm::Value* arrdim = new llvm::GetElementPtrInst(arr,zero,zero,"tmp",gIR->scopebb());
|
|
764 new llvm::StoreInst(dim, arrdim, gIR->scopebb());
|
|
765
|
|
766 llvm::Value* arrptr = new llvm::GetElementPtrInst(arr,zero,one,"tmp",gIR->scopebb());
|
|
767 new llvm::StoreInst(ptr, arrptr, gIR->scopebb());
|
|
768 }
|
|
769
|
|
770 //////////////////////////////////////////////////////////////////////////////////////////
|
|
771 llvm::Constant* LLVM_DtoArrayInitializer(ArrayInitializer* arrinit)
|
|
772 {
|
|
773 Logger::println("arr init begin");
|
|
774 assert(arrinit->type->ty == Tsarray);
|
|
775 TypeSArray* t = (TypeSArray*)arrinit->type;
|
|
776 integer_t tdim = t->dim->toInteger();
|
|
777
|
|
778 std::vector<llvm::Constant*> inits(tdim, 0);
|
|
779
|
|
780 const llvm::Type* elemty = LLVM_DtoType(arrinit->type->next);
|
|
781
|
|
782 assert(arrinit->index.dim == arrinit->value.dim);
|
|
783 for (int i=0,j=0; i < tdim; ++i)
|
|
784 {
|
|
785 Initializer* init = 0;
|
|
786 Expression* idx = (Expression*)arrinit->index.data[j];
|
|
787
|
|
788 if (idx)
|
|
789 {
|
|
790 integer_t k = idx->toInteger();
|
|
791 if (i == k)
|
|
792 {
|
|
793 init = (Initializer*)arrinit->value.data[j];
|
|
794 assert(init);
|
|
795 ++j;
|
|
796 }
|
|
797 }
|
|
798 else
|
|
799 {
|
|
800 init = (Initializer*)arrinit->value.data[j];
|
|
801 ++j;
|
|
802 }
|
|
803
|
|
804 llvm::Constant* v = 0;
|
|
805
|
|
806 if (!init)
|
|
807 {
|
|
808 elem* e = t->next->defaultInit()->toElem(gIR);
|
|
809 v = llvm::cast<llvm::Constant>(e->val);
|
|
810 delete e;
|
|
811 }
|
|
812 else if (ExpInitializer* ex = init->isExpInitializer())
|
|
813 {
|
|
814 elem* e = ex->exp->toElem(gIR);
|
|
815 v = llvm::cast<llvm::Constant>(e->val);
|
|
816 delete e;
|
|
817 }
|
|
818 else if (StructInitializer* si = init->isStructInitializer())
|
|
819 {
|
|
820 v = LLVM_DtoStructInitializer(si);
|
|
821 }
|
|
822 else if (ArrayInitializer* ai = init->isArrayInitializer())
|
|
823 {
|
|
824 v = LLVM_DtoArrayInitializer(ai);
|
|
825 }
|
|
826 else if (init->isVoidInitializer())
|
|
827 {
|
|
828 v = llvm::UndefValue::get(elemty);
|
|
829 }
|
|
830 else
|
|
831 assert(v);
|
|
832
|
|
833 inits[i] = v;
|
|
834 }
|
|
835
|
|
836 llvm::ArrayType* arrty = LLVM_DtoStaticArrayType(t);
|
|
837 return llvm::ConstantArray::get(arrty, inits);
|
|
838 }
|
|
839
|
|
840 //////////////////////////////////////////////////////////////////////////////////////////
|
|
841 void LLVM_DtoArrayCopy(elem* dst, elem* src)
|
|
842 {
|
|
843 assert(0);
|
|
844 }
|
|
845
|
|
846 //////////////////////////////////////////////////////////////////////////////////////////
|
|
847
|
|
848 llvm::GlobalValue::LinkageTypes LLVM_DtoLinkage(PROT prot, uint stc)
|
|
849 {
|
|
850 switch(prot)
|
|
851 {
|
|
852 case PROTprivate:
|
|
853 return llvm::GlobalValue::InternalLinkage;
|
|
854
|
|
855 case PROTpublic:
|
|
856 case PROTpackage:
|
|
857 case PROTprotected:
|
|
858 case PROTexport:
|
|
859 return llvm::GlobalValue::ExternalLinkage;
|
|
860
|
|
861 case PROTundefined:
|
|
862 case PROTnone:
|
|
863 assert(0 && "Unsupported linkage type");
|
|
864 }
|
|
865 return llvm::GlobalValue::ExternalLinkage;
|
|
866
|
|
867 /* ExternalLinkage = 0, LinkOnceLinkage, WeakLinkage, AppendingLinkage,
|
|
868 InternalLinkage, DLLImportLinkage, DLLExportLinkage, ExternalWeakLinkage,
|
|
869 GhostLinkage */
|
|
870 }
|
|
871
|
|
872 //////////////////////////////////////////////////////////////////////////////////////////
|
|
873
|
|
874 unsigned LLVM_DtoCallingConv(LINK l)
|
|
875 {
|
|
876 if (l == LINKc)
|
|
877 return llvm::CallingConv::C;
|
|
878 else if (l == LINKd || l == LINKdefault)
|
|
879 return llvm::CallingConv::Fast;
|
|
880 else if (l == LINKwindows)
|
|
881 return llvm::CallingConv::X86_StdCall;
|
|
882 else
|
|
883 assert(0 && "Unsupported calling convention");
|
|
884 }
|
|
885
|
|
886 //////////////////////////////////////////////////////////////////////////////////////////
|
|
887
|
|
888 llvm::Value* LLVM_DtoPointedType(llvm::Value* ptr, llvm::Value* val)
|
|
889 {
|
|
890 const llvm::Type* ptrTy = ptr->getType()->getContainedType(0);
|
|
891 const llvm::Type* valTy = val->getType();
|
|
892 // ptr points to val's type
|
|
893 if (ptrTy == valTy)
|
|
894 {
|
|
895 return val;
|
|
896 }
|
|
897 // ptr is integer pointer
|
|
898 else if (ptrTy->isInteger())
|
|
899 {
|
|
900 // val is integer
|
|
901 assert(valTy->isInteger());
|
|
902 const llvm::IntegerType* pt = llvm::cast<const llvm::IntegerType>(ptrTy);
|
|
903 const llvm::IntegerType* vt = llvm::cast<const llvm::IntegerType>(valTy);
|
|
904 if (pt->getBitWidth() < vt->getBitWidth()) {
|
|
905 return new llvm::TruncInst(val, pt, "tmp", gIR->scopebb());
|
|
906 }
|
|
907 else
|
|
908 assert(0);
|
|
909 }
|
|
910 // something else unsupported
|
|
911 else
|
|
912 {
|
|
913 Logger::cout() << *ptrTy << '|' << *valTy << '\n';
|
|
914 assert(0);
|
|
915 }
|
|
916 return 0;
|
|
917 }
|
|
918
|
|
919 //////////////////////////////////////////////////////////////////////////////////////////
|
|
920
|
|
921 llvm::Value* LLVM_DtoBoolean(llvm::Value* val)
|
|
922 {
|
|
923 const llvm::Type* t = val->getType();
|
|
924 if (t->isInteger())
|
|
925 {
|
|
926 if (t == llvm::Type::Int1Ty)
|
|
927 return val;
|
|
928 else {
|
|
929 llvm::Value* zero = llvm::ConstantInt::get(t, 0, false);
|
|
930 return new llvm::ICmpInst(llvm::ICmpInst::ICMP_NE, val, zero, "tmp", gIR->scopebb());
|
|
931 }
|
|
932 }
|
|
933 else if (llvm::isa<llvm::PointerType>(t)) {
|
|
934 const llvm::Type* st = LLVM_DtoSize_t();
|
|
935 llvm::Value* ptrasint = new llvm::PtrToIntInst(val,st,"tmp",gIR->scopebb());
|
|
936 llvm::Value* zero = llvm::ConstantInt::get(st, 0, false);
|
|
937 return new llvm::ICmpInst(llvm::ICmpInst::ICMP_NE, ptrasint, zero, "tmp", gIR->scopebb());
|
|
938 }
|
|
939 else
|
|
940 {
|
|
941 Logger::cout() << *t << '\n';
|
|
942 }
|
|
943 assert(0);
|
|
944 return 0;
|
|
945 }
|
|
946
|
|
947 //////////////////////////////////////////////////////////////////////////////////////////
|
|
948
|
|
949 const llvm::Type* LLVM_DtoSize_t()
|
|
950 {
|
|
951 if (global.params.is64bit)
|
|
952 return llvm::Type::Int64Ty;
|
|
953 else
|
|
954 return llvm::Type::Int32Ty;
|
|
955 }
|
|
956
|
|
957 //////////////////////////////////////////////////////////////////////////////////////////
|
|
958
|
|
959 void LLVM_DtoMain()
|
|
960 {
|
|
961 // emit main function llvm style
|
|
962 // int main(int argc, char**argv, char**env);
|
|
963
|
|
964 assert(gIR != 0);
|
|
965 IRState& ir = *gIR;
|
|
966
|
|
967 assert(ir.emitMain && ir.mainFunc);
|
|
968
|
|
969 // parameter types
|
|
970 std::vector<const llvm::Type*> pvec;
|
|
971 pvec.push_back((const llvm::Type*)llvm::Type::Int32Ty);
|
|
972 const llvm::Type* chPtrType = (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty);
|
|
973 pvec.push_back((const llvm::Type*)llvm::PointerType::get(chPtrType));
|
|
974 pvec.push_back((const llvm::Type*)llvm::PointerType::get(chPtrType));
|
|
975 const llvm::Type* rettype = (const llvm::Type*)llvm::Type::Int32Ty;
|
|
976
|
|
977 llvm::FunctionType* functype = llvm::FunctionType::get(rettype, pvec, false);
|
|
978 llvm::Function* func = new llvm::Function(functype,llvm::GlobalValue::ExternalLinkage,"main",ir.module);
|
|
979
|
|
980 llvm::BasicBlock* bb = new llvm::BasicBlock("entry",func);
|
|
981
|
|
982 // call static ctors
|
|
983 llvm::Function* fn = LLVM_D_GetRuntimeFunction(ir.module,"_d_run_module_ctors");
|
|
984 new llvm::CallInst(fn,"",bb);
|
|
985
|
|
986 // call user main function
|
|
987 llvm::CallInst* call = new llvm::CallInst(ir.mainFunc,"ret",bb);
|
|
988 call->setCallingConv(ir.mainFunc->getCallingConv());
|
|
989
|
|
990 // call static dtors
|
|
991 fn = LLVM_D_GetRuntimeFunction(ir.module,"_d_run_module_dtors");
|
|
992 new llvm::CallInst(fn,"",bb);
|
|
993
|
|
994 // return
|
|
995 new llvm::ReturnInst(call,bb);
|
|
996
|
|
997 /*
|
|
998 // return value type
|
|
999 const llvm::Type* rettype;
|
|
1000 Type* rt = f->next;
|
|
1001 if (rt) {
|
|
1002 rettype = LLVM_DtoType(rt);
|
|
1003 }
|
|
1004 else {
|
|
1005 assert(0);
|
|
1006 }
|
|
1007
|
|
1008 llvm::FunctionType* functype = llvm::FunctionType::get(rettype, paramvec, false);
|
|
1009 */
|
|
1010 }
|
|
1011
|
|
1012 //////////////////////////////////////////////////////////////////////////////////////////
|
|
1013
|
|
1014 void LLVM_DtoCallClassDtors(TypeClass* tc, llvm::Value* instance)
|
|
1015 {
|
|
1016 Array* arr = &tc->sym->dtors;
|
|
1017 for (size_t i=0; i<arr->dim; i++)
|
|
1018 {
|
|
1019 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i];
|
|
1020 assert(fd->llvmValue);
|
|
1021 new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb());
|
|
1022 }
|
|
1023 }
|
|
1024
|
|
1025 //////////////////////////////////////////////////////////////////////////////////////////
|
|
1026
|
|
1027 void LLVM_DtoInitClass(TypeClass* tc, llvm::Value* dst)
|
|
1028 {
|
|
1029 assert(tc->llvmInit);
|
|
1030 assert(dst->getType() == tc->llvmInit->getType());
|
|
1031 assert(gIR);
|
|
1032
|
|
1033 assert(tc->llvmType);
|
|
1034 uint64_t n = gTargetData->getTypeSize(tc->llvmType);
|
|
1035 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
|
|
1036
|
|
1037 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
|
|
1038 llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb());
|
|
1039
|
|
1040 llvm::Function* fn = LLVM_DeclareMemCpy32();
|
|
1041 std::vector<llvm::Value*> llargs;
|
|
1042 llargs.resize(4);
|
|
1043 llargs[0] = dstarr;
|
|
1044 llargs[1] = srcarr;
|
|
1045 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
|
|
1046 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
|
1047
|
|
1048 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
|
1049 }
|
|
1050
|
|
1051 //////////////////////////////////////////////////////////////////////////////////////////
|
|
1052
|
|
1053 llvm::Constant* LLVM_DtoInitializer(Type* type, Initializer* init)
|
|
1054 {
|
|
1055 llvm::Constant* _init = 0;
|
|
1056 if (!init)
|
|
1057 {
|
|
1058 elem* e = type->defaultInit()->toElem(gIR);
|
|
1059 if (!e->inplace && !e->isNull()) {
|
|
1060 _init = llvm::cast<llvm::Constant>(e->getValue());
|
|
1061 }
|
|
1062 delete e;
|
|
1063 }
|
|
1064 else if (ExpInitializer* ex = init->isExpInitializer())
|
|
1065 {
|
|
1066 elem* e = ex->exp->toElem(gIR);
|
|
1067 if (!e->inplace && !e->isNull()) {
|
|
1068 _init = llvm::cast<llvm::Constant>(e->getValue());
|
|
1069 }
|
|
1070 delete e;
|
|
1071 }
|
|
1072 else if (StructInitializer* si = init->isStructInitializer())
|
|
1073 {
|
|
1074 _init = LLVM_DtoStructInitializer(si);
|
|
1075 }
|
|
1076 else if (ArrayInitializer* ai = init->isArrayInitializer())
|
|
1077 {
|
|
1078 _init = LLVM_DtoArrayInitializer(ai);
|
|
1079 }
|
|
1080 else if (init->isVoidInitializer())
|
|
1081 {
|
|
1082 const llvm::Type* ty = LLVM_DtoType(type);
|
|
1083 _init = llvm::Constant::getNullValue(ty);
|
|
1084 }
|
|
1085 else {
|
|
1086 Logger::println("unsupported initializer: %s", init->toChars());
|
|
1087 }
|
|
1088 return _init;
|
|
1089 }
|