comparison gen/tollvm.cpp @ 86:fd32135dca3e trunk

[svn r90] Major updates to the gen directory. Redesigned the 'elem' struct. Much more... !!! Lots of bugfixes. Added support for special foreach on strings. Added std.array, std.utf, std.ctype and std.uni to phobos. Changed all the .c files in the gen dir to .cpp (it *is* C++ after all)
author lindquist
date Sat, 03 Nov 2007 14:44:58 +0100
parents gen/tollvm.c@f869c636a113
children 058d3925950e
comparison
equal deleted inserted replaced
85:f869c636a113 86:fd32135dca3e
1 #include <iostream>
2
3 #include "gen/llvm.h"
4
5 #include "mtype.h"
6 #include "dsymbol.h"
7 #include "aggregate.h"
8 #include "declaration.h"
9 #include "init.h"
10
11 #include "gen/tollvm.h"
12 #include "gen/irstate.h"
13 #include "gen/logger.h"
14 #include "gen/runtime.h"
15 #include "gen/arrays.h"
16 #include "gen/dvalue.h"
17
18 bool DtoIsPassedByRef(Type* type)
19 {
20 TY t = DtoDType(type)->ty;
21 return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray);
22 }
23
24 Type* DtoDType(Type* t)
25 {
26 if (t->ty == Ttypedef) {
27 Type* bt = t->toBasetype();
28 assert(bt);
29 return DtoDType(bt);
30 }
31 return t;
32 }
33
34 const llvm::Type* DtoType(Type* t)
35 {
36 assert(t);
37 switch (t->ty)
38 {
39 // integers
40 case Tint8:
41 case Tuns8:
42 case Tchar:
43 return (const llvm::Type*)llvm::Type::Int8Ty;
44 case Tint16:
45 case Tuns16:
46 case Twchar:
47 return (const llvm::Type*)llvm::Type::Int16Ty;
48 case Tint32:
49 case Tuns32:
50 case Tdchar:
51 return (const llvm::Type*)llvm::Type::Int32Ty;
52 case Tint64:
53 case Tuns64:
54 return (const llvm::Type*)llvm::Type::Int64Ty;
55
56 case Tbool:
57 return (const llvm::Type*)llvm::ConstantInt::getTrue()->getType();
58
59 // floats
60 case Tfloat32:
61 case Timaginary32:
62 return llvm::Type::FloatTy;
63 case Tfloat64:
64 case Timaginary64:
65 case Tfloat80:
66 case Timaginary80:
67 return llvm::Type::DoubleTy;
68
69 // complex
70 case Tcomplex32:
71 case Tcomplex64:
72 case Tcomplex80:
73 assert(0 && "complex number types not yet implemented");
74
75 // pointers
76 case Tpointer: {
77 assert(t->next);
78 if (t->next->ty == Tvoid)
79 return (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty);
80 else
81 return (const llvm::Type*)llvm::PointerType::get(DtoType(t->next));
82 }
83
84 // arrays
85 case Tarray:
86 return DtoArrayType(t);
87 case Tsarray:
88 return DtoStaticArrayType(t);
89
90 // void
91 case Tvoid:
92 return llvm::Type::VoidTy;
93
94 // aggregates
95 case Tstruct: {
96 if (t->llvmType == 0)
97 {
98 // recursive or cyclic declaration
99 if (!gIR->structs.empty())
100 {
101 IRStruct* found = 0;
102 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
103 {
104 if (t == i->type)
105 {
106 return i->recty.get();
107 }
108 }
109 }
110
111 // forward declaration
112 TypeStruct* ts = (TypeStruct*)t;
113 assert(ts->sym);
114 ts->sym->toObjFile();
115 }
116 return t->llvmType;
117 }
118
119 case Tclass: {
120 if (t->llvmType == 0)
121 {
122 // recursive or cyclic declaration
123 if (!gIR->structs.empty())
124 {
125 IRStruct* found = 0;
126 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
127 {
128 if (t == i->type)
129 {
130 return llvm::PointerType::get(i->recty.get());
131 }
132 }
133 }
134
135 // forward declaration
136 TypeClass* tc = (TypeClass*)t;
137 assert(tc->sym);
138 tc->sym->toObjFile();
139 }
140 return llvm::PointerType::get(t->llvmType);
141 }
142
143 // functions
144 case Tfunction:
145 {
146 if (t->llvmType == 0) {
147 return DtoFunctionType(t,NULL);
148 }
149 else {
150 return t->llvmType;
151 }
152 }
153
154 // delegates
155 case Tdelegate:
156 {
157 if (t->llvmType == 0) {
158 return DtoDelegateType(t);
159 }
160 else {
161 return t->llvmType;
162 }
163 }
164
165 // typedefs
166 // enum
167 case Ttypedef:
168 case Tenum:
169 {
170 Type* bt = t->toBasetype();
171 assert(bt);
172 return DtoType(bt);
173 }
174
175 default:
176 printf("trying to convert unknown type with value %d\n", t->ty);
177 assert(0);
178 }
179 return 0;
180 }
181
182 //////////////////////////////////////////////////////////////////////////////////////////
183
184 const llvm::FunctionType* DtoFunctionType(Type* type, const llvm::Type* thistype, bool ismain)
185 {
186 TypeFunction* f = (TypeFunction*)type;
187 assert(f != 0);
188
189 bool typesafeVararg = false;
190 if (f->linkage == LINKd && f->varargs == 1) {
191 typesafeVararg = true;
192 }
193
194 // return value type
195 const llvm::Type* rettype;
196 const llvm::Type* actualRettype;
197 Type* rt = f->next;
198 bool retinptr = false;
199 bool usesthis = false;
200
201 if (ismain) {
202 rettype = llvm::Type::Int32Ty;
203 actualRettype = rettype;
204 }
205 else {
206 assert(rt);
207 if (DtoIsPassedByRef(rt)) {
208 rettype = llvm::PointerType::get(DtoType(rt));
209 actualRettype = llvm::Type::VoidTy;
210 f->llvmRetInPtr = retinptr = true;
211 }
212 else {
213 rettype = DtoType(rt);
214 actualRettype = rettype;
215 }
216 }
217
218 // parameter types
219 std::vector<const llvm::Type*> paramvec;
220
221 if (retinptr) {
222 Logger::cout() << "returning through pointer parameter: " << *rettype << '\n';
223 paramvec.push_back(rettype);
224 }
225
226 if (thistype) {
227 paramvec.push_back(thistype);
228 usesthis = true;
229 }
230
231 if (typesafeVararg) {
232 ClassDeclaration* ti = Type::typeinfo;
233 if (!ti->llvmInitZ)
234 ti->toObjFile();
235 assert(ti->llvmInitZ);
236 std::vector<const llvm::Type*> types;
237 types.push_back(DtoSize_t());
238 types.push_back(llvm::PointerType::get(llvm::PointerType::get(ti->llvmInitZ->getType())));
239 const llvm::Type* t1 = llvm::StructType::get(types);
240 paramvec.push_back(llvm::PointerType::get(t1));
241 paramvec.push_back(llvm::PointerType::get(llvm::Type::Int8Ty));
242 }
243
244 size_t n = Argument::dim(f->parameters);
245
246 for (int i=0; i < n; ++i) {
247 Argument* arg = Argument::getNth(f->parameters, i);
248 // ensure scalar
249 Type* argT = DtoDType(arg->type);
250 assert(argT);
251
252 if ((arg->storageClass & STCref) || (arg->storageClass & STCout)) {
253 //assert(arg->vardecl);
254 //arg->vardecl->refparam = true;
255 }
256 else
257 arg->llvmCopy = true;
258
259 const llvm::Type* at = DtoType(argT);
260 if (llvm::isa<llvm::StructType>(at)) {
261 Logger::println("struct param");
262 paramvec.push_back(llvm::PointerType::get(at));
263 }
264 else if (llvm::isa<llvm::ArrayType>(at)) {
265 Logger::println("sarray param");
266 assert(argT->ty == Tsarray);
267 //paramvec.push_back(llvm::PointerType::get(at->getContainedType(0)));
268 paramvec.push_back(llvm::PointerType::get(at));
269 }
270 else if (llvm::isa<llvm::OpaqueType>(at)) {
271 Logger::println("opaque param");
272 if (argT->ty == Tstruct || argT->ty == Tclass)
273 paramvec.push_back(llvm::PointerType::get(at));
274 else
275 assert(0);
276 }
277 /*if (llvm::isa<llvm::StructType>(at) || argT->ty == Tstruct || argT->ty == Tsarray) {
278 paramvec.push_back(llvm::PointerType::get(at));
279 }*/
280 else {
281 if (!arg->llvmCopy) {
282 Logger::println("ref param");
283 at = llvm::PointerType::get(at);
284 }
285 else {
286 Logger::println("in param");
287 }
288 paramvec.push_back(at);
289 }
290 }
291
292 // construct function type
293 bool isvararg = !typesafeVararg && f->varargs;
294 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg);
295
296 f->llvmRetInPtr = retinptr;
297 f->llvmUsesThis = usesthis;
298 return functype;
299 }
300
301 //////////////////////////////////////////////////////////////////////////////////////////
302
303 static const llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl)
304 {
305 TypeFunction* f = (TypeFunction*)fdecl->type;
306 assert(f != 0);
307
308 const llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty);
309 std::vector<const llvm::Type*> args;
310
311 if (fdecl->llvmInternal == LLVMva_start) {
312 args.push_back(i8pty);
313 }
314 else if (fdecl->llvmInternal == LLVMva_intrinsic) {
315 size_t n = Argument::dim(f->parameters);
316 for (size_t i=0; i<n; ++i) {
317 args.push_back(i8pty);
318 }
319 }
320 else
321 assert(0);
322
323 const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::VoidTy, args, false);
324 f->llvmType = fty;
325 return fty;
326 }
327
328 //////////////////////////////////////////////////////////////////////////////////////////
329
330 const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
331 {
332 if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) {
333 return DtoVaFunctionType(fdecl);
334 }
335
336 // type has already been resolved
337 if (fdecl->type->llvmType != 0) {
338 return llvm::cast<llvm::FunctionType>(fdecl->type->llvmType);
339 }
340
341 const llvm::Type* thisty = NULL;
342 if (fdecl->needThis()) {
343 if (AggregateDeclaration* ad = fdecl->isMember()) {
344 Logger::print("isMember = this is: %s\n", ad->type->toChars());
345 thisty = DtoType(ad->type);
346 Logger::cout() << "this llvm type: " << *thisty << '\n';
347 if (llvm::isa<llvm::StructType>(thisty) || thisty == gIR->topstruct().recty.get())
348 thisty = llvm::PointerType::get(thisty);
349 }
350 else
351 assert(0);
352 }
353 else if (fdecl->isNested()) {
354 thisty = llvm::PointerType::get(llvm::Type::Int8Ty);
355 }
356
357 const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, thisty, fdecl->isMain());
358 fdecl->type->llvmType = functype;
359 return functype;
360 }
361
362 //////////////////////////////////////////////////////////////////////////////////////////
363
364 const llvm::StructType* DtoDelegateType(Type* t)
365 {
366 const llvm::Type* i8ptr = llvm::PointerType::get(llvm::Type::Int8Ty);
367 const llvm::Type* func = DtoFunctionType(t->next, i8ptr);
368 const llvm::Type* funcptr = llvm::PointerType::get(func);
369
370 std::vector<const llvm::Type*> types;
371 types.push_back(i8ptr);
372 types.push_back(funcptr);
373 return llvm::StructType::get(types);
374 }
375
376 //////////////////////////////////////////////////////////////////////////////////////////
377
378 const llvm::Type* DtoStructType(Type* t)
379 {
380 assert(0);
381 std::vector<const llvm::Type*> types;
382 return llvm::StructType::get(types);
383 }
384
385
386 //////////////////////////////////////////////////////////////////////////////////////////
387
388 static llvm::Function* LLVM_DeclareMemIntrinsic(const char* name, int bits, bool set=false)
389 {
390 assert(bits == 32 || bits == 64);
391 const llvm::Type* int8ty = (const llvm::Type*)llvm::Type::Int8Ty;
392 const llvm::Type* int32ty = (const llvm::Type*)llvm::Type::Int32Ty;
393 const llvm::Type* int64ty = (const llvm::Type*)llvm::Type::Int64Ty;
394 const llvm::Type* int8ptrty = (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty);
395 const llvm::Type* voidty = (const llvm::Type*)llvm::Type::VoidTy;
396
397 assert(gIR);
398 assert(gIR->module);
399
400 // parameter types
401 std::vector<const llvm::Type*> pvec;
402 pvec.push_back(int8ptrty);
403 pvec.push_back(set?int8ty:int8ptrty);
404 pvec.push_back(bits==32?int32ty:int64ty);
405 pvec.push_back(int32ty);
406 llvm::FunctionType* functype = llvm::FunctionType::get(voidty, pvec, false);
407 return new llvm::Function(functype, llvm::GlobalValue::ExternalLinkage, name, gIR->module);
408 }
409
410 //////////////////////////////////////////////////////////////////////////////////////////
411
412 // llvm.memset.i32
413 llvm::Function* LLVM_DeclareMemSet32()
414 {
415 static llvm::Function* _func = 0;
416 if (_func == 0) {
417 _func = LLVM_DeclareMemIntrinsic("llvm.memset.i32", 32, true);
418 }
419 return _func;
420 }
421
422 //////////////////////////////////////////////////////////////////////////////////////////
423
424 llvm::Function* LLVM_DeclareMemSet64()
425 {
426 static llvm::Function* _func = 0;
427 if (_func == 0) {
428 _func = LLVM_DeclareMemIntrinsic("llvm.memset.i64", 64, true);
429 }
430 return _func;
431 }
432
433 //////////////////////////////////////////////////////////////////////////////////////////
434
435 // llvm.memcpy.i32
436 llvm::Function* LLVM_DeclareMemCpy32()
437 {
438 static llvm::Function* _func = 0;
439 if (_func == 0) {
440 _func = LLVM_DeclareMemIntrinsic("llvm.memcpy.i32", 32);
441 }
442 return _func;
443 }
444
445 //////////////////////////////////////////////////////////////////////////////////////////
446
447 // llvm.memcpy.i64
448 llvm::Function* LLVM_DeclareMemCpy64()
449 {
450 static llvm::Function* _func = 0;
451 if (_func == 0) {
452 _func = LLVM_DeclareMemIntrinsic("llvm.memcpy.i64", 64);
453 }
454 return _func;
455 }
456
457 //////////////////////////////////////////////////////////////////////////////////////////
458
459 llvm::Value* DtoStructZeroInit(llvm::Value* v)
460 {
461 assert(gIR);
462 uint64_t n = gTargetData->getTypeSize(v->getType()->getContainedType(0));
463 //llvm::Type* sarrty = llvm::PointerType::get(llvm::ArrayType::get(llvm::Type::Int8Ty, n));
464 llvm::Type* sarrty = llvm::PointerType::get(llvm::Type::Int8Ty);
465
466 llvm::Value* sarr = new llvm::BitCastInst(v,sarrty,"tmp",gIR->scopebb());
467
468 llvm::Function* fn = LLVM_DeclareMemSet32();
469 std::vector<llvm::Value*> llargs;
470 llargs.resize(4);
471 llargs[0] = sarr;
472 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false);
473 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
474 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
475
476 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
477
478 return ret;
479 }
480
481 //////////////////////////////////////////////////////////////////////////////////////////
482
483 llvm::Value* DtoStructCopy(llvm::Value* dst, llvm::Value* src)
484 {
485 Logger::cout() << "dst = " << *dst << " src = " << *src << '\n';
486 assert(dst->getType() == src->getType());
487 assert(gIR);
488
489 uint64_t n = gTargetData->getTypeSize(dst->getType()->getContainedType(0));
490 //llvm::Type* sarrty = llvm::PointerType::get(llvm::ArrayType::get(llvm::Type::Int8Ty, n));
491 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
492
493 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
494 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb());
495
496 llvm::Function* fn = LLVM_DeclareMemCpy32();
497 std::vector<llvm::Value*> llargs;
498 llargs.resize(4);
499 llargs[0] = dstarr;
500 llargs[1] = srcarr;
501 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
502 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
503
504 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
505 }
506
507 //////////////////////////////////////////////////////////////////////////////////////////
508 llvm::Constant* DtoConstStructInitializer(StructInitializer* si)
509 {
510 llvm::StructType* structtype = llvm::cast<llvm::StructType>(si->ad->llvmType);
511 size_t n = structtype->getNumElements();
512
513 assert(si->value.dim == si->vars.dim);
514
515 std::vector<llvm::Constant*> inits;
516 inits.resize(n, NULL);
517 for (int i = 0; i < si->value.dim; ++i)
518 {
519 Initializer* ini = (Initializer*)si->value.data[i];
520 assert(ini);
521
522 VarDeclaration* vd = (VarDeclaration*)si->vars.data[i];
523 Type* vdtype = DtoDType(vd->type);
524 assert(vd);
525 Logger::println("vars[%d] = %s", i, vd->toChars());
526
527 llvm::Constant* v = 0;
528
529 assert(vd->llvmFieldIndex >= 0);
530 unsigned idx = vd->llvmFieldIndex;
531
532 if (ExpInitializer* ex = ini->isExpInitializer())
533 {
534 v = ex->exp->toConstElem(gIR);
535 }
536 else if (StructInitializer* si = ini->isStructInitializer())
537 {
538 v = DtoConstStructInitializer(si);
539 }
540 else if (ArrayInitializer* ai = ini->isArrayInitializer())
541 {
542 v = DtoConstArrayInitializer(ai);
543 }
544 else if (ini->isVoidInitializer())
545 {
546 v = llvm::UndefValue::get(structtype->getElementType(idx));
547 }
548 else
549 assert(v);
550
551 inits[idx] = v;
552 Logger::cout() << "init[" << idx << "] = " << *v << '\n';
553 }
554
555 // fill out nulls
556 assert(si->ad->llvmInitZ);
557 if (si->ad->llvmInitZ->isNullValue())
558 {
559 for (int i = 0; i < n; ++i)
560 {
561 if (inits[i] == 0)
562 {
563 inits[i] = llvm::Constant::getNullValue(structtype->getElementType(i));
564 }
565 }
566 }
567 else
568 {
569 for (int i = 0; i < n; ++i)
570 {
571 if (inits[i] == 0)
572 {
573 inits[i] = si->ad->llvmInitZ->getOperand(i);
574 }
575 }
576 }
577
578 return llvm::ConstantStruct::get(structtype, inits);
579 }
580
581
582
583 //////////////////////////////////////////////////////////////////////////////////////////
584
585 llvm::Value* DtoNullDelegate(llvm::Value* v)
586 {
587 assert(gIR);
588 d_uns64 n = (global.params.is64bit) ? 16 : 8;
589
590 llvm::Type* i8p_ty = llvm::PointerType::get(llvm::Type::Int8Ty);
591
592 llvm::Value* arr = new llvm::BitCastInst(v,i8p_ty,"tmp",gIR->scopebb());
593
594 llvm::Function* fn = LLVM_DeclareMemSet32();
595 std::vector<llvm::Value*> llargs;
596 llargs.resize(4);
597 llargs[0] = arr;
598 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false);
599 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
600 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
601
602 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
603
604 return ret;
605 }
606
607 //////////////////////////////////////////////////////////////////////////////////////////
608
609 llvm::Value* DtoDelegateCopy(llvm::Value* dst, llvm::Value* src)
610 {
611 assert(dst->getType() == src->getType());
612 assert(gIR);
613
614 d_uns64 n = (global.params.is64bit) ? 16 : 8;
615
616 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
617
618 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
619 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb());
620
621 llvm::Function* fn = LLVM_DeclareMemCpy32();
622 std::vector<llvm::Value*> llargs;
623 llargs.resize(4);
624 llargs[0] = dstarr;
625 llargs[1] = srcarr;
626 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
627 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
628
629 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
630 }
631
632 //////////////////////////////////////////////////////////////////////////////////////////
633
634 llvm::Value* DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs)
635 {
636 llvm::ICmpInst::Predicate pred = (op == TOKequal) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
637 llvm::Value* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp");
638 llvm::Value* r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,0,"tmp"),"tmp");
639 llvm::Value* b1 = gIR->ir->CreateICmp(pred,l,r,"tmp");
640 l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp");
641 r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,1,"tmp"),"tmp");
642 llvm::Value* b2 = gIR->ir->CreateICmp(pred,l,r,"tmp");
643 llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp");
644 if (op == TOKnotequal)
645 return gIR->ir->CreateNot(b,"tmp");
646 return b;
647 }
648
649 //////////////////////////////////////////////////////////////////////////////////////////
650
651 llvm::GlobalValue::LinkageTypes DtoLinkage(PROT prot, uint stc)
652 {
653 switch(prot)
654 {
655 case PROTprivate:
656 return llvm::GlobalValue::InternalLinkage;
657
658 case PROTpublic:
659 case PROTpackage:
660 case PROTprotected:
661 case PROTexport:
662 return llvm::GlobalValue::ExternalLinkage;
663
664 case PROTundefined:
665 case PROTnone:
666 assert(0 && "Unsupported linkage type");
667 }
668 return llvm::GlobalValue::ExternalLinkage;
669
670 /* ExternalLinkage = 0, LinkOnceLinkage, WeakLinkage, AppendingLinkage,
671 InternalLinkage, DLLImportLinkage, DLLExportLinkage, ExternalWeakLinkage,
672 GhostLinkage */
673 }
674
675 //////////////////////////////////////////////////////////////////////////////////////////
676
677 unsigned DtoCallingConv(LINK l)
678 {
679 if (l == LINKc)
680 return llvm::CallingConv::C;
681 else if (l == LINKd || l == LINKdefault)
682 return llvm::CallingConv::Fast;
683 else if (l == LINKwindows)
684 return llvm::CallingConv::X86_StdCall;
685 else
686 assert(0 && "Unsupported calling convention");
687 }
688
689 //////////////////////////////////////////////////////////////////////////////////////////
690
691 llvm::Value* DtoPointedType(llvm::Value* ptr, llvm::Value* val)
692 {
693 const llvm::Type* ptrTy = ptr->getType()->getContainedType(0);
694 const llvm::Type* valTy = val->getType();
695 // ptr points to val's type
696 if (ptrTy == valTy)
697 {
698 return val;
699 }
700 // ptr is integer pointer
701 else if (ptrTy->isInteger())
702 {
703 // val is integer
704 assert(valTy->isInteger());
705 const llvm::IntegerType* pt = llvm::cast<const llvm::IntegerType>(ptrTy);
706 const llvm::IntegerType* vt = llvm::cast<const llvm::IntegerType>(valTy);
707 if (pt->getBitWidth() < vt->getBitWidth()) {
708 return new llvm::TruncInst(val, pt, "tmp", gIR->scopebb());
709 }
710 else
711 assert(0);
712 }
713 // something else unsupported
714 else
715 {
716 Logger::cout() << *ptrTy << '|' << *valTy << '\n';
717 assert(0);
718 }
719 return 0;
720 }
721
722 //////////////////////////////////////////////////////////////////////////////////////////
723
724 llvm::Value* DtoBoolean(llvm::Value* val)
725 {
726 const llvm::Type* t = val->getType();
727 if (t->isInteger())
728 {
729 if (t == llvm::Type::Int1Ty)
730 return val;
731 else {
732 llvm::Value* zero = llvm::ConstantInt::get(t, 0, false);
733 return new llvm::ICmpInst(llvm::ICmpInst::ICMP_NE, val, zero, "tmp", gIR->scopebb());
734 }
735 }
736 else if (llvm::isa<llvm::PointerType>(t)) {
737 const llvm::Type* st = DtoSize_t();
738 llvm::Value* ptrasint = new llvm::PtrToIntInst(val,st,"tmp",gIR->scopebb());
739 llvm::Value* zero = llvm::ConstantInt::get(st, 0, false);
740 return new llvm::ICmpInst(llvm::ICmpInst::ICMP_NE, ptrasint, zero, "tmp", gIR->scopebb());
741 }
742 else
743 {
744 Logger::cout() << *t << '\n';
745 }
746 assert(0);
747 return 0;
748 }
749
750 //////////////////////////////////////////////////////////////////////////////////////////
751
752 const llvm::Type* DtoSize_t()
753 {
754 if (global.params.is64bit)
755 return llvm::Type::Int64Ty;
756 else
757 return llvm::Type::Int32Ty;
758 }
759
760 //////////////////////////////////////////////////////////////////////////////////////////
761
762 void DtoMain()
763 {
764 // emit main function llvm style
765 // int main(int argc, char**argv, char**env);
766
767 assert(gIR != 0);
768 IRState& ir = *gIR;
769
770 assert(ir.emitMain && ir.mainFunc);
771
772 // parameter types
773 std::vector<const llvm::Type*> pvec;
774 pvec.push_back((const llvm::Type*)llvm::Type::Int32Ty);
775 const llvm::Type* chPtrType = (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty);
776 pvec.push_back((const llvm::Type*)llvm::PointerType::get(chPtrType));
777 pvec.push_back((const llvm::Type*)llvm::PointerType::get(chPtrType));
778 const llvm::Type* rettype = (const llvm::Type*)llvm::Type::Int32Ty;
779
780 llvm::FunctionType* functype = llvm::FunctionType::get(rettype, pvec, false);
781 llvm::Function* func = new llvm::Function(functype,llvm::GlobalValue::ExternalLinkage,"main",ir.module);
782
783 llvm::BasicBlock* bb = new llvm::BasicBlock("entry",func);
784
785 // call static ctors
786 llvm::Function* fn = LLVM_D_GetRuntimeFunction(ir.module,"_d_run_module_ctors");
787 new llvm::CallInst(fn,"",bb);
788
789 // call user main function
790 llvm::CallInst* call = new llvm::CallInst(ir.mainFunc,"ret",bb);
791 call->setCallingConv(ir.mainFunc->getCallingConv());
792
793 // call static dtors
794 fn = LLVM_D_GetRuntimeFunction(ir.module,"_d_run_module_dtors");
795 new llvm::CallInst(fn,"",bb);
796
797 // return
798 new llvm::ReturnInst(call,bb);
799 }
800
801 //////////////////////////////////////////////////////////////////////////////////////////
802
803 void DtoCallClassDtors(TypeClass* tc, llvm::Value* instance)
804 {
805 Array* arr = &tc->sym->dtors;
806 for (size_t i=0; i<arr->dim; i++)
807 {
808 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i];
809 assert(fd->llvmValue);
810 new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb());
811 }
812 }
813
814 //////////////////////////////////////////////////////////////////////////////////////////
815
816 void DtoInitClass(TypeClass* tc, llvm::Value* dst)
817 {
818 assert(gIR);
819
820 assert(tc->llvmType);
821 uint64_t size_t_size = gTargetData->getTypeSize(DtoSize_t());
822 uint64_t n = gTargetData->getTypeSize(tc->llvmType) - size_t_size;
823
824 // set vtable field
825 llvm::Value* vtblvar = DtoGEPi(dst,0,0,"tmp",gIR->scopebb());
826 assert(tc->sym->llvmVtbl);
827 new llvm::StoreInst(tc->sym->llvmVtbl, vtblvar, gIR->scopebb());
828
829 // copy the static initializer
830 if (n > 0) {
831 assert(tc->llvmInit);
832 assert(dst->getType() == tc->llvmInit->getType());
833
834 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
835
836 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
837 dstarr = DtoGEPi(dstarr,size_t_size,"tmp",gIR->scopebb());
838
839 llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb());
840 srcarr = DtoGEPi(srcarr,size_t_size,"tmp",gIR->scopebb());
841
842 llvm::Function* fn = LLVM_DeclareMemCpy32();
843 std::vector<llvm::Value*> llargs;
844 llargs.resize(4);
845 llargs[0] = dstarr;
846 llargs[1] = srcarr;
847 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
848 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
849
850 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
851 }
852 }
853
854 //////////////////////////////////////////////////////////////////////////////////////////
855
856 llvm::Constant* DtoConstInitializer(Type* type, Initializer* init)
857 {
858 llvm::Constant* _init = 0; // may return zero
859 if (!init)
860 {
861 Logger::println("const default initializer for %s", type->toChars());
862 _init = type->defaultInit()->toConstElem(gIR);
863 }
864 else if (ExpInitializer* ex = init->isExpInitializer())
865 {
866 Logger::println("const expression initializer");
867 _init = ex->exp->toConstElem(gIR);
868 }
869 else if (StructInitializer* si = init->isStructInitializer())
870 {
871 Logger::println("const struct initializer");
872 _init = DtoConstStructInitializer(si);
873 }
874 else if (ArrayInitializer* ai = init->isArrayInitializer())
875 {
876 Logger::println("const array initializer");
877 _init = DtoConstArrayInitializer(ai);
878 }
879 else if (init->isVoidInitializer())
880 {
881 Logger::println("const void initializer");
882 const llvm::Type* ty = DtoType(type);
883 _init = llvm::Constant::getNullValue(ty);
884 }
885 else {
886 Logger::println("unsupported const initializer: %s", init->toChars());
887 }
888 return _init;
889 }
890
891 //////////////////////////////////////////////////////////////////////////////////////////
892
893 DValue* DtoInitializer(Initializer* init)
894 {
895 if (ExpInitializer* ex = init->isExpInitializer())
896 {
897 Logger::println("expression initializer");
898 return ex->exp->toElem(gIR);
899 }
900 else if (init->isVoidInitializer())
901 {
902 // do nothing
903 }
904 else {
905 Logger::println("unsupported initializer: %s", init->toChars());
906 assert(0);
907 }
908 return 0;
909 }
910
911 //////////////////////////////////////////////////////////////////////////////////////////
912
913 llvm::Value* DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb)
914 {
915 std::vector<llvm::Value*> v(2);
916 v[0] = i0;
917 v[1] = i1;
918 Logger::cout() << "DtoGEP: " << *ptr << '\n';
919 return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb());
920 }
921
922 //////////////////////////////////////////////////////////////////////////////////////////
923
924 llvm::Value* DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb)
925 {
926 size_t n = src.size();
927 std::vector<llvm::Value*> dst(n);
928 std::ostream& ostr = Logger::cout();
929 ostr << "indices for '" << *ptr << "':";
930 for (size_t i=0; i<n; ++i)
931 {
932 ostr << ' ' << i;
933 dst[i] = llvm::ConstantInt::get(llvm::Type::Int32Ty, src[i], false);
934 }
935 ostr << '\n';
936 return new llvm::GetElementPtrInst(ptr, dst.begin(), dst.end(), var, bb?bb:gIR->scopebb());
937 }
938
939 //////////////////////////////////////////////////////////////////////////////////////////
940
941 llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i, const std::string& var, llvm::BasicBlock* bb)
942 {
943 return new llvm::GetElementPtrInst(ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false), var, bb?bb:gIR->scopebb());
944 }
945
946 //////////////////////////////////////////////////////////////////////////////////////////
947
948 llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb)
949 {
950 std::vector<llvm::Value*> v(2);
951 v[0] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i0, false);
952 v[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i1, false);
953 return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb());
954 }
955
956 //////////////////////////////////////////////////////////////////////////////////////////
957
958 static llvm::Function* DtoDeclareVaFunction(FuncDeclaration* fdecl)
959 {
960 TypeFunction* f = (TypeFunction*)DtoDType(fdecl->type);
961 const llvm::FunctionType* fty = DtoVaFunctionType(fdecl);
962 llvm::Constant* fn = 0;
963
964 if (fdecl->llvmInternal == LLVMva_start) {
965 fn = gIR->module->getOrInsertFunction("llvm.va_start", fty);
966 assert(fn);
967 }
968 else if (fdecl->llvmInternal == LLVMva_intrinsic) {
969 fn = gIR->module->getOrInsertFunction(fdecl->llvmInternal1, fty);
970 assert(fn);
971 }
972 else
973 assert(0);
974
975 llvm::Function* func = llvm::cast_or_null<llvm::Function>(fn);
976 assert(func);
977 assert(func->isIntrinsic());
978 fdecl->llvmValue = func;
979 return func;
980 }
981
982 //////////////////////////////////////////////////////////////////////////////////////////
983
984 llvm::Function* DtoDeclareFunction(FuncDeclaration* fdecl)
985 {
986 if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) {
987 return DtoDeclareVaFunction(fdecl);
988 }
989
990 // mangled name
991 char* mangled_name;
992 if (fdecl->llvmInternal == LLVMintrinsic)
993 mangled_name = fdecl->llvmInternal1;
994 else
995 mangled_name = fdecl->mangle();
996
997 // unit test special handling
998 if (fdecl->isUnitTestDeclaration())
999 {
1000 assert(0 && "no unittests yet");
1001 /*const llvm::FunctionType* fnty = llvm::FunctionType::get(llvm::Type::VoidTy, std::vector<const llvm::Type*>(), false);
1002 // make the function
1003 llvm::Function* func = gIR->module->getFunction(mangled_name);
1004 if (func == 0)
1005 func = new llvm::Function(fnty,llvm::GlobalValue::InternalLinkage,mangled_name,gIR->module);
1006 func->setCallingConv(llvm::CallingConv::Fast);
1007 fdecl->llvmValue = func;
1008 return func;
1009 */
1010 }
1011
1012 // regular function
1013 TypeFunction* f = (TypeFunction*)DtoDType(fdecl->type);
1014 assert(f != 0);
1015
1016 if (fdecl->llvmValue != 0) {
1017 if (!llvm::isa<llvm::Function>(fdecl->llvmValue))
1018 {
1019 Logger::cout() << *fdecl->llvmValue << '\n';
1020 assert(0);
1021 }
1022 return llvm::cast<llvm::Function>(fdecl->llvmValue);
1023 }
1024
1025 Logger::print("FuncDeclaration::toObjFile(%s): %s\n", fdecl->needThis()?"this":"static",fdecl->toChars());
1026 LOG_SCOPE;
1027
1028 if (fdecl->llvmInternal == LLVMintrinsic && fdecl->fbody) {
1029 error("intrinsics cannot have function bodies");
1030 fatal();
1031 }
1032
1033 // construct function
1034 const llvm::FunctionType* functype = (f->llvmType == 0) ? DtoFunctionType(fdecl) : llvm::cast<llvm::FunctionType>(f->llvmType);
1035
1036 // make the function
1037 llvm::Function* func = gIR->module->getFunction(mangled_name);
1038 if (func == 0) {
1039 func = new llvm::Function(functype,DtoLinkage(fdecl->protection, fdecl->storage_class),mangled_name,gIR->module);
1040 }
1041
1042 if (fdecl->llvmInternal != LLVMintrinsic)
1043 func->setCallingConv(DtoCallingConv(f->linkage));
1044
1045 fdecl->llvmValue = func;
1046 f->llvmType = functype;
1047 assert(llvm::isa<llvm::FunctionType>(f->llvmType));
1048
1049 if (fdecl->isMain()) {
1050 gIR->mainFunc = func;
1051 }
1052
1053 // name parameters
1054 llvm::Function::arg_iterator iarg = func->arg_begin();
1055 int k = 0;
1056 if (f->llvmRetInPtr) {
1057 iarg->setName("retval");
1058 f->llvmRetArg = iarg;
1059 ++iarg;
1060 }
1061 if (f->llvmUsesThis) {
1062 iarg->setName("this");
1063 ++iarg;
1064 }
1065 int varargs = -1;
1066 if (f->linkage == LINKd && f->varargs == 1)
1067 varargs = 0;
1068 for (; iarg != func->arg_end(); ++iarg)
1069 {
1070 Argument* arg = Argument::getNth(f->parameters, k++);
1071 //arg->llvmValue = iarg;
1072 //Logger::println("identifier: '%s' %p\n", arg->ident->toChars(), arg->ident);
1073 if (arg && arg->ident != 0) {
1074 if (arg->vardecl) {
1075 arg->vardecl->llvmValue = iarg;
1076 }
1077 iarg->setName(arg->ident->toChars());
1078 }
1079 else if (!arg && varargs >= 0) {
1080 if (varargs == 0) {
1081 iarg->setName("_arguments");
1082 fdecl->llvmArguments = iarg;
1083 }
1084 else if (varargs == 1) {
1085 iarg->setName("_argptr");
1086 fdecl->llvmArgPtr = iarg;
1087 }
1088 else
1089 assert(0);
1090 varargs++;
1091 }
1092 else {
1093 iarg->setName("unnamed");
1094 }
1095 }
1096
1097 Logger::cout() << "func decl: " << *func << '\n';
1098
1099 return func;
1100 }
1101
1102 //////////////////////////////////////////////////////////////////////////////////////////
1103
1104 llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty)
1105 {
1106 /*size_t sz = gTargetData->getTypeSize(ty);
1107 llvm::ConstantInt* n = llvm::ConstantInt::get(DtoSize_t(), sz, false);
1108 if (ptr == 0) {
1109 llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty);
1110 ptr = llvm::ConstantPointerNull::get(i8pty);
1111 }
1112 return DtoRealloc(ptr, n);*/
1113 return NULL;
1114 }
1115
1116 //////////////////////////////////////////////////////////////////////////////////////////
1117
1118 llvm::Value* DtoRealloc(llvm::Value* ptr, llvm::Value* n)
1119 {
1120 assert(ptr);
1121 assert(n);
1122
1123 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_realloc");
1124 assert(fn);
1125
1126 llvm::Value* newptr = ptr;
1127
1128 llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty);
1129 if (ptr->getType() != i8pty) {
1130 newptr = new llvm::BitCastInst(ptr,i8pty,"tmp",gIR->scopebb());
1131 }
1132
1133 std::vector<llvm::Value*> args;
1134 args.push_back(newptr);
1135 args.push_back(n);
1136 llvm::Value* ret = new llvm::CallInst(fn, args.begin(), args.end(), "tmprealloc", gIR->scopebb());
1137
1138 return ret->getType() == ptr->getType() ? ret : new llvm::BitCastInst(ret,ptr->getType(),"tmp",gIR->scopebb());
1139 }
1140
1141 //////////////////////////////////////////////////////////////////////////////////////////
1142
1143 void DtoAssert(llvm::Value* cond, llvm::Value* loc, llvm::Value* msg)
1144 {
1145 assert(loc);
1146 std::vector<llvm::Value*> llargs;
1147 llargs.resize(3);
1148 llargs[0] = cond ? DtoBoolean(cond) : llvm::ConstantInt::getFalse();
1149 llargs[1] = loc;
1150 llargs[2] = msg ? msg : llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty));
1151
1152 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_assert");
1153 assert(fn);
1154 llvm::CallInst* call = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
1155 call->setCallingConv(llvm::CallingConv::C);
1156 }
1157
1158 //////////////////////////////////////////////////////////////////////////////////////////
1159
1160 llvm::Value* DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expression* argexp)
1161 {
1162 llvm::Value* retval = 0;
1163
1164 bool haslvals = !gIR->exps.empty();
1165 if (haslvals)
1166 gIR->exps.push_back(IRExp(NULL,NULL,NULL));
1167
1168 DValue* arg = argexp->toElem(gIR);
1169
1170 if (haslvals)
1171 gIR->exps.pop_back();
1172
1173 if (arg->inPlace()) {
1174 retval = arg->getRVal();
1175 return retval;
1176 }
1177
1178 Type* realtype = DtoDType(argexp->type);
1179 TY argty = realtype->ty;
1180 if (DtoIsPassedByRef(realtype)) {
1181 if (!fnarg || !fnarg->llvmCopy) {
1182 if (DSliceValue* sv = arg->isSlice()) {
1183 retval = new llvm::AllocaInst(DtoType(realtype), "tmpparam", gIR->topallocapoint());
1184 DtoSetArray(retval, DtoArrayLen(sv), DtoArrayPtr(sv));
1185 }
1186 else {
1187 retval = arg->getRVal();
1188 }
1189 }
1190 else {
1191 llvm::Value* allocaInst = 0;
1192 llvm::BasicBlock* entryblock = &gIR->topfunc()->front();
1193 //const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(arg->mem->getType());
1194 const llvm::Type* realtypell = DtoType(realtype);
1195 const llvm::PointerType* pty = llvm::PointerType::get(realtypell);
1196 if (argty == Tstruct) {
1197 allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", gIR->topallocapoint());
1198 DValue* dst = new DVarValue(realtype, allocaInst, true);
1199 DtoAssign(dst,arg);
1200 delete dst;
1201 }
1202 else if (argty == Tdelegate) {
1203 allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", gIR->topallocapoint());
1204 DValue* dst = new DVarValue(realtype, allocaInst, true);
1205 DtoAssign(dst,arg);
1206 delete dst;
1207 }
1208 else if (argty == Tarray) {
1209 if (arg->isSlice()) {
1210 allocaInst = new llvm::AllocaInst(realtypell, "tmpparam", gIR->topallocapoint());
1211 }
1212 else {
1213 allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", gIR->topallocapoint());
1214 }
1215 }
1216 else
1217 assert(0);
1218
1219 DValue* dst = new DVarValue(realtype, allocaInst, true);
1220 DtoAssign(dst,arg);
1221 delete dst;
1222
1223 retval = allocaInst;
1224 }
1225 }
1226 else if (!fnarg || fnarg->llvmCopy) {
1227 Logger::println("regular arg");
1228 if (DSliceValue* sl = arg->isSlice()) {
1229 if (sl->ptr) Logger::cout() << "ptr = " << *sl->ptr << '\n';
1230 if (sl->len) Logger::cout() << "len = " << *sl->len << '\n';
1231 assert(0);
1232 }
1233 else {
1234 retval = arg->getRVal();
1235 }
1236 }
1237 else {
1238 Logger::println("as ptr arg");
1239 retval = arg->getLVal();
1240 if (paramtype && retval->getType() != paramtype)
1241 {
1242 assert(0);
1243 /*assert(retval->getType() == paramtype->getContainedType(0));
1244 new llvm::StoreInst(retval, arg->getLVal(), gIR->scopebb());
1245 retval = arg->getLVal();*/
1246 }
1247 }
1248
1249 if (fnarg && paramtype && retval->getType() != paramtype) {
1250 // this is unfortunately needed with the way SymOffExp is overused
1251 // and static arrays can end up being a pointer to their element type
1252 if (arg->isField()) {
1253 retval = gIR->ir->CreateBitCast(retval, paramtype, "tmp");
1254 }
1255 else {
1256 Logger::cout() << "got '" << *retval->getType() << "' expected '" << *paramtype << "'\n";
1257 assert(0 && "parameter type that was actually passed is invalid");
1258 }
1259 }
1260
1261 delete arg;
1262
1263 return retval;
1264 }
1265
1266 //////////////////////////////////////////////////////////////////////////////////////////
1267
1268 llvm::Value* DtoNestedVariable(VarDeclaration* vd)
1269 {
1270 FuncDeclaration* fd = vd->toParent()->isFuncDeclaration();
1271 assert(fd != NULL);
1272
1273 IRFunction* fcur = &gIR->func();
1274 FuncDeclaration* f = fcur->decl;
1275
1276 // on this stack
1277 if (fd == f) {
1278 llvm::Value* v = DtoGEPi(vd->llvmValue,0,unsigned(vd->llvmNestedIndex),"tmp");
1279 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) {
1280 Logger::cout() << "1267 loading: " << *v << '\n';
1281 v = gIR->ir->CreateLoad(v,"tmp");
1282 }
1283 return v;
1284 }
1285
1286 // on a caller stack
1287 llvm::Value* ptr = f->llvmThisVar;
1288 assert(ptr);
1289
1290 f = f->toParent()->isFuncDeclaration();
1291 assert(f);
1292 assert(f->llvmNested);
1293 const llvm::Type* nesttype = f->llvmNested->getType();
1294 assert(nesttype);
1295
1296 ptr = gIR->ir->CreateBitCast(ptr, nesttype, "tmp");
1297
1298 Logger::cout() << "nested var reference:" << '\n' << *ptr << *nesttype << '\n';
1299
1300 while (f) {
1301 if (fd == f) {
1302 llvm::Value* v = DtoGEPi(ptr,0,vd->llvmNestedIndex,"tmp");
1303 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) {
1304 Logger::cout() << "1291 loading: " << *v << '\n';
1305 v = gIR->ir->CreateLoad(v,"tmp");
1306 }
1307 return v;
1308 }
1309 else {
1310 ptr = DtoGEPi(ptr,0,0,"tmp");
1311 ptr = gIR->ir->CreateLoad(ptr,"tmp");
1312 }
1313 f = f->toParent()->isFuncDeclaration();
1314 }
1315
1316 assert(0 && "nested var not found");
1317 return NULL;
1318 }
1319
1320 //////////////////////////////////////////////////////////////////////////////////////////
1321
1322 void DtoAssign(DValue* lhs, DValue* rhs)
1323 {
1324 Type* t = DtoDType(lhs->getType());
1325 Type* t2 = DtoDType(rhs->getType());
1326
1327 if (t->ty == Tstruct) {
1328 if (t2 != t) {
1329 // TODO: fix this, use 'rhs' for something
1330 DtoStructZeroInit(lhs->getLVal());
1331 }
1332 else if (!rhs->inPlace()) {
1333 DtoStructCopy(lhs->getLVal(),rhs->getRVal());
1334 }
1335 }
1336 else if (t->ty == Tarray) {
1337 // lhs is slice
1338 if (DSliceValue* s = lhs->isSlice()) {
1339 if (DSliceValue* s2 = rhs->isSlice()) {
1340 DtoArrayCopy(s, s2);
1341 }
1342 else if (t->next == t2) {
1343 if (s->len)
1344 DtoArrayInit(s->ptr, s->len, rhs->getRVal());
1345 else
1346 DtoArrayInit(s->ptr, rhs->getRVal());
1347 }
1348 else
1349 assert(rhs->inPlace());
1350 }
1351 // rhs is slice
1352 else if (DSliceValue* s = rhs->isSlice()) {
1353 DtoSetArray(lhs->getLVal(),s->len,s->ptr);
1354 }
1355 // null
1356 else if (rhs->isNull()) {
1357 DtoNullArray(lhs->getLVal());
1358 }
1359 // reference assignment
1360 else {
1361 DtoArrayAssign(lhs->getLVal(), rhs->getRVal());
1362 }
1363 }
1364 else if (t->ty == Tsarray) {
1365 DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal());
1366 }
1367 else if (t->ty == Tdelegate) {
1368 if (rhs->isNull())
1369 DtoNullDelegate(lhs->getLVal());
1370 else if (!rhs->inPlace())
1371 DtoDelegateCopy(lhs->getLVal(), rhs->getRVal());
1372 }
1373 else if (t->ty == Tclass) {
1374 assert(t2->ty == Tclass);
1375 // assignment to this in constructor special case
1376 if (lhs->isThis()) {
1377 llvm::Value* tmp = rhs->getRVal();
1378 FuncDeclaration* fdecl = gIR->func().decl;
1379 // respecify the this param
1380 if (!llvm::isa<llvm::AllocaInst>(fdecl->llvmThisVar))
1381 fdecl->llvmThisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint());
1382 DtoStore(tmp, fdecl->llvmThisVar);
1383 }
1384 // regular class ref -> class ref assignment
1385 else {
1386 DtoStore(rhs->getRVal(), lhs->getLVal());
1387 }
1388 }
1389 else {
1390 llvm::Value* r = rhs->getRVal();
1391 llvm::Value* l = lhs->getLVal();
1392 Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n';
1393 gIR->ir->CreateStore(r, l);
1394 }
1395 }
1396
1397 //////////////////////////////////////////////////////////////////////////////////////////
1398
1399 llvm::ConstantInt* DtoConstSize_t(size_t i)
1400 {
1401 return llvm::ConstantInt::get(DtoSize_t(), i, false);
1402 }
1403 llvm::ConstantInt* DtoConstUint(unsigned i)
1404 {
1405 return llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false);
1406 }
1407 llvm::ConstantInt* DtoConstInt(int i)
1408 {
1409 return llvm::ConstantInt::get(llvm::Type::Int32Ty, i, true);
1410 }
1411 llvm::Constant* DtoConstBool(bool b)
1412 {
1413 return llvm::ConstantInt::get(llvm::Type::Int1Ty, b, false);
1414 }
1415
1416 //////////////////////////////////////////////////////////////////////////////////////////
1417
1418 llvm::Constant* DtoConstString(const char* str)
1419 {
1420 std::string s(str);
1421 llvm::Constant* init = llvm::ConstantArray::get(s, true);
1422 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(
1423 init->getType(), true,llvm::GlobalValue::InternalLinkage, init, "stringliteral", gIR->module);
1424 llvm::Constant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) };
1425 return DtoConstSlice(
1426 DtoConstSize_t(s.length()),
1427 llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2)
1428 );
1429 }
1430 llvm::Constant* DtoConstStringPtr(const char* str, const char* section)
1431 {
1432 std::string s(str);
1433 llvm::Constant* init = llvm::ConstantArray::get(s, true);
1434 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(
1435 init->getType(), true,llvm::GlobalValue::InternalLinkage, init, "stringliteral", gIR->module);
1436 if (section) gvar->setSection(section);
1437 llvm::Constant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) };
1438 return llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
1439 }
1440
1441 //////////////////////////////////////////////////////////////////////////////////////////
1442
1443 void DtoMemCpy(llvm::Value* dst, llvm::Value* src, llvm::Value* nbytes)
1444 {
1445 assert(dst->getType() == src->getType());
1446
1447 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
1448 llvm::Value *dstarr, *srcarr;
1449 if (dst->getType() == arrty)
1450 {
1451 dstarr = dst;
1452 srcarr = src;
1453 }
1454 else
1455 {
1456 dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
1457 srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb());
1458 }
1459
1460 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32();
1461 std::vector<llvm::Value*> llargs;
1462 llargs.resize(4);
1463 llargs[0] = dstarr;
1464 llargs[1] = srcarr;
1465 llargs[2] = nbytes;
1466 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
1467
1468 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
1469 }
1470
1471 //////////////////////////////////////////////////////////////////////////////////////////
1472
1473 llvm::Value* DtoLoad(llvm::Value* src)
1474 {
1475 return gIR->ir->CreateLoad(src,"tmp");
1476 }
1477
1478 void DtoStore(llvm::Value* src, llvm::Value* dst)
1479 {
1480 gIR->ir->CreateStore(src,dst);
1481 }
1482
1483 bool DtoCanLoad(llvm::Value* ptr)
1484 {
1485 if (llvm::isa<llvm::PointerType>(ptr->getType())) {
1486 return ptr->getType()->getContainedType(0)->isFirstClassType();
1487 }
1488 return false;
1489 }
1490
1491 llvm::Value* DtoBitCast(llvm::Value* v, const llvm::Type* t)
1492 {
1493 return gIR->ir->CreateBitCast(v, t, "tmp");
1494 }
1495
1496 //////////////////////////////////////////////////////////////////////////////////////////
1497
1498 llvm::Value* DtoIndexStruct(llvm::Value* ptr, StructDeclaration* sd, Type* t, unsigned os, std::vector<unsigned>& idxs)
1499 {
1500 Logger::println("checking for offset %u type %s:", os, t->toChars());
1501 LOG_SCOPE;
1502
1503 if (idxs.empty())
1504 idxs.push_back(0);
1505
1506 const llvm::Type* llt = llvm::PointerType::get(DtoType(t));
1507
1508 for (unsigned i=0; i<sd->fields.dim; ++i) {
1509 VarDeclaration* vd = (VarDeclaration*)sd->fields.data[i];
1510 Type* vdtype = DtoDType(vd->type);
1511 Logger::println("found %u type %s", vd->offset, vdtype->toChars());
1512 assert(vd->llvmFieldIndex >= 0);
1513 if (os == vd->offset && vdtype == t) {
1514 idxs.push_back(vd->llvmFieldIndex);
1515 ptr = DtoGEP(ptr, idxs, "tmp");
1516 if (ptr->getType() != llt)
1517 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
1518 if (vd->llvmFieldIndexOffset)
1519 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
1520 return ptr;
1521 }
1522 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) {
1523 TypeStruct* ts = (TypeStruct*)vdtype;
1524 StructDeclaration* ssd = ts->sym;
1525 idxs.push_back(vd->llvmFieldIndex);
1526 if (vd->llvmFieldIndexOffset) {
1527 Logger::println("has union field offset");
1528 ptr = DtoGEP(ptr, idxs, "tmp");
1529 if (ptr->getType() != llt)
1530 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
1531 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
1532 std::vector<unsigned> tmp;
1533 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
1534 }
1535 else {
1536 const llvm::Type* sty = llvm::PointerType::get(DtoType(vd->type));
1537 if (ptr->getType() != sty) {
1538 ptr = gIR->ir->CreateBitCast(ptr, sty, "tmp");
1539 std::vector<unsigned> tmp;
1540 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
1541 }
1542 else {
1543 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, idxs);
1544 }
1545 }
1546 }
1547 }
1548
1549 size_t llt_sz = gTargetData->getTypeSize(llt->getContainedType(0));
1550 assert(os % llt_sz == 0);
1551 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
1552 return new llvm::GetElementPtrInst(ptr, DtoConstUint(os / llt_sz), "tmp", gIR->scopebb());
1553 }
1554
1555 //////////////////////////////////////////////////////////////////////////////////////////
1556
1557 bool DtoIsTemplateInstance(Dsymbol* s)
1558 {
1559 if (!s) return false;
1560 if (s->isTemplateInstance() && !s->isTemplateMixin())
1561 return true;
1562 else if (s->parent)
1563 return DtoIsTemplateInstance(s->parent);
1564 return false;
1565 }