Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

root/gen/llvmhelpers.cpp

Revision 1650:40bd4a0d4870, 50.8 kB (checked in by Tomas Lindquist Olsen, 4 months ago)

Update to work with LLVM 2.7.

Removed use of dyn_cast, llvm no compiles
without exceptions and rtti by
default. We do need exceptions for the libconfig stuff, but rtti isn't
necessary (anymore).

Debug info needs to be rewritten, as in LLVM 2.7 the format has
completely changed. To have something to look at while rewriting, the
old code has been wrapped inside #ifndef DISABLE_DEBUG_INFO , this means
that you have to define this to compile at the moment.

Updated tango 0.99.9 patch to include updated EH runtime code, which is
needed for LLVM 2.7 as well.

Line 
1 #include "gen/llvmhelpers.h"
2 #include "gen/llvm.h"
3
4 #include "mars.h"
5 #include "init.h"
6 #include "id.h"
7 #include "expression.h"
8 #include "template.h"
9 #include "module.h"
10
11 #include "gen/tollvm.h"
12 #include "gen/irstate.h"
13 #include "gen/runtime.h"
14 #include "gen/logger.h"
15 #include "gen/arrays.h"
16 #include "gen/dvalue.h"
17 #include "gen/complex.h"
18 #include "gen/classes.h"
19 #include "gen/functions.h"
20 #include "gen/typeinf.h"
21 #include "gen/todebug.h"
22 #include "gen/cl_options.h"
23 #include "gen/nested.h"
24 #include "ir/irmodule.h"
25
26 #include <stack>
27
28 /****************************************************************************************/
29 /*////////////////////////////////////////////////////////////////////////////////////////
30 // DYNAMIC MEMORY HELPERS
31 ////////////////////////////////////////////////////////////////////////////////////////*/
32
33 LLValue* DtoNew(Type* newtype)
34 {
35     // get runtime function
36     llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemoryT");
37     // get type info
38     LLConstant* ti = DtoTypeInfoOf(newtype);
39     assert(isaPointer(ti));
40     // call runtime allocator
41     LLValue* mem = gIR->CreateCallOrInvoke(fn, ti, ".gc_mem").getInstruction();
42     // cast
43     return DtoBitCast(mem, getPtrToType(DtoType(newtype)), ".gc_mem");
44 }
45
46 void DtoDeleteMemory(LLValue* ptr)
47 {
48     // get runtime function
49     llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delmemory");
50     // build args
51     LLSmallVector<LLValue*,1> arg;
52     arg.push_back(DtoBitCast(ptr, getVoidPtrType(), ".tmp"));
53     // call
54     gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end());
55 }
56
57 void DtoDeleteClass(LLValue* inst)
58 {
59     // get runtime function
60     llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delclass");
61     // build args
62     LLSmallVector<LLValue*,1> arg;
63     arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp"));
64     // call
65     gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end());
66 }
67
68 void DtoDeleteInterface(LLValue* inst)
69 {
70     // get runtime function
71     llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delinterface");
72     // build args
73     LLSmallVector<LLValue*,1> arg;
74     arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp"));
75     // call
76     gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end());
77 }
78
79 void DtoDeleteArray(DValue* arr)
80 {
81     // get runtime function
82     llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delarray");
83     // build args
84     LLSmallVector<LLValue*,2> arg;
85     arg.push_back(DtoArrayLen(arr));
86     arg.push_back(DtoBitCast(DtoArrayPtr(arr), getVoidPtrType(), ".tmp"));
87     // call
88     gIR->CreateCallOrInvoke(fn, arg.begin(), arg.end());
89 }
90
91 /****************************************************************************************/
92 /*////////////////////////////////////////////////////////////////////////////////////////
93 // ALLOCA HELPERS
94 ////////////////////////////////////////////////////////////////////////////////////////*/
95
96
97 llvm::AllocaInst* DtoAlloca(Type* type, const char* name)
98 {
99     const llvm::Type* lltype = DtoType(type);
100     llvm::AllocaInst* ai = new llvm::AllocaInst(lltype, name, gIR->topallocapoint());
101     ai->setAlignment(type->alignsize());
102     return ai;
103 }
104
105 llvm::AllocaInst* DtoArrayAlloca(Type* type, unsigned arraysize, const char* name)
106 {
107     const llvm::Type* lltype = DtoType(type);
108     llvm::AllocaInst* ai = new llvm::AllocaInst(
109         lltype, DtoConstUint(arraysize), name, gIR->topallocapoint());
110     ai->setAlignment(type->alignsize());
111     return ai;
112 }
113
114 llvm::AllocaInst* DtoRawAlloca(const llvm::Type* lltype, size_t alignment, const char* name)
115 {
116     llvm::AllocaInst* ai = new llvm::AllocaInst(lltype, name, gIR->topallocapoint());
117     if (alignment)
118         ai->setAlignment(alignment);
119     return ai;
120 }
121
122
123 /****************************************************************************************/
124 /*////////////////////////////////////////////////////////////////////////////////////////
125 // ASSERT HELPER
126 ////////////////////////////////////////////////////////////////////////////////////////*/
127
128 void DtoAssert(Module* M, Loc loc, DValue* msg)
129 {
130     std::vector<LLValue*> args;
131
132     // func
133     const char* fname = msg ? "_d_assert_msg" : "_d_assert";
134     llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname);
135
136     // msg param
137     if (msg)
138     {
139         args.push_back(msg->getRVal());
140     }
141
142     // file param
143
144     // we might be generating for an imported template function
145     const char* cur_file = M->srcfile->name->toChars();
146     if (loc.filename && strcmp(loc.filename, cur_file) != 0)
147     {
148         args.push_back(DtoConstString(loc.filename));
149     }
150     else
151     {
152         IrModule* irmod = getIrModule(M);
153         args.push_back(DtoLoad(irmod->fileName));
154     }
155
156     // line param
157     LLConstant* c = DtoConstUint(loc.linnum);
158     args.push_back(c);
159
160     // call
161     gIR->CreateCallOrInvoke(fn, args.begin(), args.end());
162
163     #ifndef DISABLE_DEBUG_INFO
164     // end debug info
165     if (global.params.symdebug)
166         DtoDwarfFuncEnd(gIR->func()->decl);
167     #endif
168
169     // after assert is always unreachable
170     gIR->ir->CreateUnreachable();
171 }
172
173
174 /****************************************************************************************/
175 /*////////////////////////////////////////////////////////////////////////////////////////
176 // LABEL HELPER
177 ////////////////////////////////////////////////////////////////////////////////////////*/
178 LabelStatement* DtoLabelStatement(Identifier* ident)
179 {
180     FuncDeclaration* fd = gIR->func()->decl;
181     FuncDeclaration::LabelMap::iterator iter = fd->labmap.find(ident->toChars());
182     if (iter == fd->labmap.end())
183     {
184         if (fd->returnLabel && fd->returnLabel->ident->equals(ident))
185         {
186             assert(fd->returnLabel->statement);
187             return fd->returnLabel->statement;
188         }
189         return NULL;
190     }
191     return iter->second;
192 }
193
194 /****************************************************************************************/
195 /*////////////////////////////////////////////////////////////////////////////////////////
196 // GOTO HELPER
197 ////////////////////////////////////////////////////////////////////////////////////////*/
198 void DtoGoto(Loc loc, Identifier* target, TryFinallyStatement* sourceFinally)
199 {
200     assert(!gIR->scopereturned());
201
202     LabelStatement* lblstmt = DtoLabelStatement(target);
203     if(!lblstmt) {
204         error(loc, "the label %s does not exist", target->toChars());
205         fatal();
206     }
207
208     // if the target label is inside inline asm, error
209     if(lblstmt->asmLabel) {
210         error(loc, "cannot goto to label %s inside an inline asm block", target->toChars());
211         fatal();
212     }
213
214     // find target basic block
215     std::string labelname = gIR->func()->gen->getScopedLabelName(target->toChars());
216     llvm::BasicBlock*& targetBB = gIR->func()->gen->labelToBB[labelname];
217     if (targetBB == NULL)
218         targetBB = llvm::BasicBlock::Create(gIR->context(), "label_" + labelname, gIR->topfunc());
219
220     // emit code for finallys between goto and label
221     DtoEnclosingHandlers(loc, lblstmt);
222
223     // goto into finally blocks is forbidden by the spec
224     // but should work fine
225     if(lblstmt->enclosingFinally != sourceFinally) {
226         error(loc, "spec disallows goto into or out of finally block");
227         fatal();
228     }
229
230     llvm::BranchInst::Create(targetBB, gIR->scopebb());
231 }
232
233 /****************************************************************************************/
234 /*////////////////////////////////////////////////////////////////////////////////////////
235 // TRY-FINALLY, VOLATILE AND SYNCHRONIZED HELPER
236 ////////////////////////////////////////////////////////////////////////////////////////*/
237
238 void EnclosingSynchro::emitCode(IRState * p)
239 {
240     if (s->exp)
241         DtoLeaveMonitor(s->exp->toElem(p)->getRVal());
242     else
243         DtoLeaveCritical(s->llsync);
244 }
245
246 ////////////////////////////////////////////////////////////////////////////////////////
247
248 void EnclosingVolatile::emitCode(IRState * p)
249 {
250     // store-load barrier
251     DtoMemoryBarrier(false, false, true, false);
252 }
253
254 ////////////////////////////////////////////////////////////////////////////////////////
255
256 void EnclosingTryFinally::emitCode(IRState * p)
257 {
258     if (tf->finalbody)
259     {
260         llvm::BasicBlock* oldpad = p->func()->gen->landingPad;
261         p->func()->gen->landingPad = landingPad;
262         tf->finalbody->toIR(p);
263         p->func()->gen->landingPad = oldpad;
264     }
265 }
266
267 ////////////////////////////////////////////////////////////////////////////////////////
268
269 void DtoEnclosingHandlers(Loc loc, Statement* target)
270 {
271     // labels are a special case: they are not required to enclose the current scope
272     // for them we use the enclosing scope handler as a reference point
273     LabelStatement* lblstmt = target ? target->isLabelStatement() : 0;
274     if (lblstmt)
275         target = lblstmt->enclosingScopeExit;
276
277     // figure out up until what handler we need to emit
278     FuncGen::TargetScopeVec::reverse_iterator targetit = gIR->func()->gen->targetScopes.rbegin();
279     FuncGen::TargetScopeVec::reverse_iterator it_end = gIR->func()->gen->targetScopes.rend();
280     while(targetit != it_end) {
281         if (targetit->s == target) {
282             break;
283         }
284         ++targetit;
285     }
286
287     if (target && targetit == it_end) {
288         if (lblstmt)
289             error(loc, "cannot goto into try, volatile or synchronized statement at %s", target->loc.toChars());
290         else
291             error(loc, "internal error, cannot find jump path to statement at %s", target->loc.toChars());
292         return;
293     }
294
295     //
296     // emit code for enclosing handlers
297     //
298
299     // since the labelstatements possibly inside are private
300     // and might already exist push a label scope
301     gIR->func()->gen->pushUniqueLabelScope("enclosing");
302     FuncGen::TargetScopeVec::reverse_iterator it = gIR->func()->gen->targetScopes.rbegin();
303     while (it != targetit) {
304         if (it->enclosinghandler)
305             it->enclosinghandler->emitCode(gIR);
306         ++it;
307     }
308     gIR->func()->gen->popLabelScope();
309 }
310
311 /****************************************************************************************/
312 /*////////////////////////////////////////////////////////////////////////////////////////
313 // SYNCHRONIZED SECTION HELPERS
314 ////////////////////////////////////////////////////////////////////////////////////////*/
315
316 void DtoEnterCritical(LLValue* g)
317 {
318     LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_criticalenter");
319     gIR->CreateCallOrInvoke(fn, g);
320 }
321
322 void DtoLeaveCritical(LLValue* g)
323 {
324     LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_criticalexit");
325     gIR->CreateCallOrInvoke(fn, g);
326 }
327
328 void DtoEnterMonitor(LLValue* v)
329 {
330     LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_monitorenter");
331     v = DtoBitCast(v, fn->getFunctionType()->getParamType(0));
332     gIR->CreateCallOrInvoke(fn, v);
333 }
334
335 void DtoLeaveMonitor(LLValue* v)
336 {
337     LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_monitorexit");
338     v = DtoBitCast(v, fn->getFunctionType()->getParamType(0));
339     gIR->CreateCallOrInvoke(fn, v);
340 }
341
342 /****************************************************************************************/
343 /*////////////////////////////////////////////////////////////////////////////////////////
344 // ASSIGNMENT HELPER (store this in that)
345 ////////////////////////////////////////////////////////////////////////////////////////*/
346
347 // is this a good approach at all ?
348
349 void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs)
350 {
351     Logger::println("DtoAssign(...);\n");
352     LOG_SCOPE;
353
354     Type* t = lhs->getType()->toBasetype();
355     Type* t2 = rhs->getType()->toBasetype();
356
357     if (t->ty == Tstruct) {
358         if (!t->equals(t2)) {
359             // FIXME: use 'rhs' for something !?!
360             DtoAggrZeroInit(lhs->getLVal());
361         }
362         else {
363             DtoAggrCopy(lhs->getLVal(), rhs->getRVal());
364         }
365     }
366     else if (t->ty == Tarray) {
367         // lhs is slice
368         if (DSliceValue* s = lhs->isSlice()) {
369             if (DSliceValue* s2 = rhs->isSlice()) {
370                 DtoArrayCopySlices(s, s2);
371             }
372             else if (t->nextOf()->toBasetype()->equals(t2)) {
373                 DtoArrayInit(loc, s, rhs);
374             }
375             else {
376                 DtoArrayCopyToSlice(s, rhs);
377             }
378         }
379         // rhs is slice
380         else if (DSliceValue* s = rhs->isSlice()) {
381             assert(s->getType()->toBasetype() == lhs->getType()->toBasetype());
382             DtoSetArray(lhs->getLVal(),DtoArrayLen(s),DtoArrayPtr(s));
383         }
384         // null
385         else if (rhs->isNull()) {
386             DtoSetArrayToNull(lhs->getLVal());
387         }
388         // reference assignment
389         else if (t2->ty == Tarray) {
390             DtoStore(rhs->getRVal(), lhs->getLVal());
391         }
392         // some implicitly converting ref assignment
393         else {
394             DtoSetArray(lhs->getLVal(), DtoArrayLen(rhs), DtoArrayPtr(rhs));
395         }
396     }
397     else if (t->ty == Tsarray) {
398         // T[n] = T[n]
399         if (DtoType(lhs->getType()) == DtoType(rhs->getType())) {
400             DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal());
401         }
402         // T[n] = T
403         else if (t->nextOf()->toBasetype()->equals(t2)) {
404             DtoArrayInit(loc, lhs, rhs);
405         }
406         // T[n] = T[] - generally only generated by frontend in rare cases
407         else if (t2->ty == Tarray && t->nextOf()->toBasetype()->equals(t2->nextOf()->toBasetype())) {
408             DtoMemCpy(lhs->getLVal(), DtoArrayPtr(rhs), DtoArrayLen(rhs));
409         } else {
410             assert(0 && "Unimplemented static array assign!");
411         }
412     }
413     else if (t->ty == Tdelegate) {
414         LLValue* l = lhs->getLVal();
415         LLValue* r = rhs->getRVal();
416         if (Logger::enabled())
417             Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n';
418         DtoStore(r, l);
419     }
420     else if (t->ty == Tclass) {
421         assert(t2->ty == Tclass);
422         LLValue* l = lhs->getLVal();
423         LLValue* r = rhs->getRVal();
424         if (Logger::enabled())
425         {
426             Logger::cout() << "l : " << *l << '\n';
427             Logger::cout() << "r : " << *r << '\n';
428         }
429         r = DtoBitCast(r, l->getType()->getContainedType(0));
430         DtoStore(r, l);
431     }
432     else if (t->iscomplex()) {
433         LLValue* dst = lhs->getLVal();
434         LLValue* src = DtoCast(loc, rhs, lhs->getType())->getRVal();
435         DtoStore(src, dst);
436     }
437     else {
438         LLValue* l = lhs->getLVal();
439         LLValue* r = rhs->getRVal();
440         if (Logger::enabled())
441             Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n';
442         const LLType* lit = l->getType()->getContainedType(0);
443         if (r->getType() != lit) {
444             r = DtoCast(loc, rhs, lhs->getType())->getRVal();
445             if (Logger::enabled())
446                 Logger::cout() << "really assign\nlhs: " << *l << "rhs: " << *r << '\n';
447             assert(r->getType() == l->getType()->getContainedType(0));
448         }
449         gIR->ir->CreateStore(r, l);
450     }
451 }
452
453 /****************************************************************************************/
454 /*////////////////////////////////////////////////////////////////////////////////////////
455 //      NULL VALUE HELPER
456 ////////////////////////////////////////////////////////////////////////////////////////*/
457
458 DValue* DtoNullValue(Type* type)
459 {
460     Type* basetype = type->toBasetype();
461     TY basety = basetype->ty;
462     const LLType* lltype = DtoType(basetype);
463
464     // complex, needs to be first since complex are also floating
465     if (basetype->iscomplex())
466     {
467         const LLType* basefp = DtoComplexBaseType(basetype);
468         LLValue* res = DtoAggrPair(DtoType(type), LLConstant::getNullValue(basefp), LLConstant::getNullValue(basefp));
469         return new DImValue(type, res);
470     }
471     // integer, floating, pointer and class have no special representation
472     else if (basetype->isintegral() || basetype->isfloating() || basety == Tpointer || basety == Tclass)
473     {
474         return new DConstValue(type, LLConstant::getNullValue(lltype));
475     }
476     // dynamic array
477     else if (basety == Tarray)
478     {
479         LLValue* len = DtoConstSize_t(0);
480         LLValue* ptr = getNullPtr(getPtrToType(DtoType(basetype->nextOf())));
481         return new DSliceValue(type, len, ptr);
482     }
483     // delegate
484     else if (basety == Tdelegate)
485     {
486         return new DNullValue(type, LLConstant::getNullValue(lltype));
487     }
488
489     // unknown
490     error("unsupported: null value for %s", type->toChars());
491     assert(0);
492     return 0;
493
494 }
495
496
497 /****************************************************************************************/
498 /*////////////////////////////////////////////////////////////////////////////////////////
499 //      CASTING HELPERS
500 ////////////////////////////////////////////////////////////////////////////////////////*/
501
502 DValue* DtoCastInt(Loc& loc, DValue* val, Type* _to)
503 {
504     const LLType* tolltype = DtoType(_to);
505
506     Type* to = _to->toBasetype();
507     Type* from = val->getType()->toBasetype();
508     assert(from->isintegral());
509
510     size_t fromsz = from->size();
511     size_t tosz = to->size();
512
513     LLValue* rval = val->getRVal();
514     if (rval->getType() == tolltype) {
515         return new DImValue(_to, rval);
516     }
517
518     if (to->ty == Tbool) {
519         LLValue* zero = LLConstantInt::get(rval->getType(), 0, false);
520         rval = gIR->ir->CreateICmpNE(rval, zero, "tmp");
521     }
522     else if (to->isintegral()) {
523         if (fromsz < tosz || from->ty == Tbool) {
524             if (Logger::enabled())
525                 Logger::cout() << "cast to: " << *tolltype << '\n';
526             if (from->isunsigned() || from->ty == Tbool) {
527                 rval = new llvm::ZExtInst(rval, tolltype, "tmp", gIR->scopebb());
528             } else {
529                 rval = new llvm::SExtInst(rval, tolltype, "tmp", gIR->scopebb());
530             }
531         }
532         else if (fromsz > tosz) {
533             rval = new llvm::TruncInst(rval, tolltype, "tmp", gIR->scopebb());
534         }
535         else {
536             rval = DtoBitCast(rval, tolltype);
537         }
538     }
539     else if (to->iscomplex()) {
540         return DtoComplex(loc, to, val);
541     }
542     else if (to->isfloating()) {
543         if (from->isunsigned()) {
544             rval = new llvm::UIToFPInst(rval, tolltype, "tmp", gIR->scopebb());
545         }
546         else {
547             rval = new llvm::SIToFPInst(rval, tolltype, "tmp", gIR->scopebb());
548         }
549     }
550     else if (to->ty == Tpointer) {
551         if (Logger::enabled())
552             Logger::cout() << "cast pointer: " << *tolltype << '\n';
553         rval = gIR->ir->CreateIntToPtr(rval, tolltype, "tmp");
554     }
555     else {
556         error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(), _to->toChars());
557         fatal();
558     }
559
560     return new DImValue(_to, rval);
561 }
562
563 DValue* DtoCastPtr(Loc& loc, DValue* val, Type* to)
564 {
565     const LLType* tolltype = DtoType(to);
566
567     Type* totype = to->toBasetype();
568     Type* fromtype = val->getType()->toBasetype();
569     assert(fromtype->ty == Tpointer || fromtype->ty == Tfunction);
570
571     LLValue* rval;
572
573     if (totype->ty == Tpointer || totype->ty == Tclass) {
574         LLValue* src = val->getRVal();
575         if (Logger::enabled())
576             Logger::cout() << "src: " << *src << "to type: " << *tolltype << '\n';
577         rval = DtoBitCast(src, tolltype);
578     }
579     else if (totype->ty == Tbool) {
580         LLValue* src = val->getRVal();
581         LLValue* zero = LLConstant::getNullValue(src->getType());
582         rval = gIR->ir->CreateICmpNE(src, zero, "tmp");
583     }
584     else if (totype->isintegral()) {
585         rval = new llvm::PtrToIntInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
586     }
587     else {
588         error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars());
589         fatal();
590     }
591
592     return new DImValue(to, rval);
593 }
594
595 DValue* DtoCastFloat(Loc& loc, DValue* val, Type* to)
596 {
597     if (val->getType() == to)
598         return val;
599
600     const LLType* tolltype = DtoType(to);
601
602     Type* totype = to->toBasetype();
603     Type* fromtype = val->getType()->toBasetype();
604     assert(fromtype->isfloating());
605
606     size_t fromsz = fromtype->size();
607     size_t tosz = totype->size();
608
609     LLValue* rval;
610
611     if (totype->ty == Tbool) {
612         rval = val->getRVal();
613         LLValue* zero = LLConstant::getNullValue(rval->getType());
614         rval = gIR->ir->CreateFCmpUNE(rval, zero, "tmp");
615     }
616     else if (totype->iscomplex()) {
617         return DtoComplex(loc, to, val);
618     }
619     else if (totype->isfloating()) {
620         if (fromsz == tosz) {
621             rval = val->getRVal();
622             assert(rval->getType() == tolltype);
623         }
624         else if (fromsz < tosz) {
625             rval = new llvm::FPExtInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
626         }
627         else if (fromsz > tosz) {
628             rval = new llvm::FPTruncInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
629         }
630         else {
631             error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars());
632             fatal();
633         }
634     }
635     else if (totype->isintegral()) {
636         if (totype->isunsigned()) {
637             rval = new llvm::FPToUIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
638         }
639         else {
640             rval = new llvm::FPToSIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
641         }
642     }
643     else {
644         error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars());
645         fatal();
646     }
647
648     return new DImValue(to, rval);
649 }
650
651 DValue* DtoCastDelegate(Loc& loc, DValue* val, Type* to)
652 {
653     if (to->toBasetype()->ty == Tdelegate)
654     {
655         return DtoPaintType(loc, val, to);
656     }
657     else if (to->toBasetype()->ty == Tbool)
658     {
659         return new DImValue(to, DtoDelegateEquals(TOKnotequal, val->getRVal(), NULL));
660     }
661     else
662     {
663         error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars());
664         fatal();
665     }
666 }
667
668 DValue* DtoCast(Loc& loc, DValue* val, Type* to)
669 {
670     Type* fromtype = val->getType()->toBasetype();
671     Type* totype = to->toBasetype();
672     if (fromtype->equals(totype))
673         return val;
674
675     Logger::println("Casting from '%s' to '%s'", fromtype->toChars(), to->toChars());
676     LOG_SCOPE;
677
678     if (fromtype->isintegral()) {
679         return DtoCastInt(loc, val, to);
680     }
681     else if (fromtype->iscomplex()) {
682         return DtoCastComplex(loc, val, to);
683     }
684     else if (fromtype->isfloating()) {
685         return DtoCastFloat(loc, val, to);
686     }
687     else if (fromtype->ty == Tclass) {
688         return DtoCastClass(val, to);
689     }
690     else if (fromtype->ty == Tarray || fromtype->ty == Tsarray) {
691         return DtoCastArray(loc, val, to);
692     }
693     else if (fromtype->ty == Tpointer || fromtype->ty == Tfunction) {
694         return DtoCastPtr(loc, val, to);
695     }
696     else if (fromtype->ty == Tdelegate) {
697         return DtoCastDelegate(loc, val, to);
698     }
699     else {
700         error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars());
701         fatal();
702     }
703 }
704
705 //////////////////////////////////////////////////////////////////////////////////////////
706
707 DValue* DtoPaintType(Loc& loc, DValue* val, Type* to)
708 {
709     Type* from = val->getType()->toBasetype();
710     Logger::println("repainting from '%s' to '%s'", from->toChars(), to->toChars());
711
712     if (from->ty == Tarray)
713     {
714         Type* at = to->toBasetype();
715         assert(at->ty == Tarray);
716         Type* elem = at->nextOf()->pointerTo();
717         if (DSliceValue* slice = val->isSlice())
718         {
719             return new DSliceValue(to, slice->len, DtoBitCast(slice->ptr, DtoType(elem)));
720         }
721         else if (val->isLVal())
722         {
723             LLValue* ptr = val->getLVal();
724             ptr = DtoBitCast(ptr, DtoType(at->pointerTo()));
725             return new DVarValue(to, ptr);
726         }
727         else
728         {
729             LLValue *len, *ptr;
730             len = DtoArrayLen(val);
731             ptr = DtoArrayPtr(val);
732             ptr = DtoBitCast(ptr, DtoType(elem));
733             return new DImValue(to, DtoAggrPair(len, ptr, "tmp"));
734         }
735     }
736     else if (from->ty == Tdelegate)
737     {
738         Type* dgty = to->toBasetype();
739         assert(dgty->ty == Tdelegate);
740         if (val->isLVal())
741         {
742             LLValue* ptr = val->getLVal();
743             assert(isaPointer(ptr));
744             ptr = DtoBitCast(ptr, getPtrToType(DtoType(dgty)));
745             if (Logger::enabled())
746                 Logger::cout() << "dg ptr: " << *ptr << '\n';
747             return new DVarValue(to, ptr);
748         }
749         else
750         {
751             LLValue* dg = val->getRVal();
752             LLValue* context = gIR->ir->CreateExtractValue(dg, 0, ".context");
753             LLValue* funcptr = gIR->ir->CreateExtractValue(dg, 1, ".funcptr");
754             funcptr = DtoBitCast(funcptr, DtoType(dgty)->getContainedType(1));
755             LLValue* aggr = DtoAggrPair(context, funcptr, "tmp");
756             if (Logger::enabled())
757                 Logger::cout() << "dg: " << *aggr << '\n';
758             return new DImValue(to, aggr);
759         }
760     }
761     else if (from->ty == Tpointer || from->ty == Tclass || from->ty == Taarray)
762     {
763         Type* b = to->toBasetype();
764         assert(b->ty == Tpointer || b->ty == Tclass || b->ty == Taarray);
765         LLValue* ptr = DtoBitCast(val->getRVal(), DtoType(b));
766         return new DImValue(to, ptr);
767     }
768     else
769     {
770         assert(!val->isLVal());
771         assert(DtoType(to) == DtoType(to));
772         return new DImValue(to, val->getRVal());
773     }
774 }
775
776 /****************************************************************************************/
777 /*////////////////////////////////////////////////////////////////////////////////////////
778 //      TEMPLATE HELPERS
779 ////////////////////////////////////////////////////////////////////////////////////////*/
780
781 TemplateInstance* DtoIsTemplateInstance(Dsymbol* s)
782 {
783     if (!s) return NULL;
784     if (s->isTemplateInstance() && !s->isTemplateMixin())
785         return s->isTemplateInstance();
786     else if (s->parent)
787         return DtoIsTemplateInstance(s->parent);
788     return NULL;
789 }
790
791 /****************************************************************************************/
792 /*////////////////////////////////////////////////////////////////////////////////////////
793 //      PROCESSING QUEUE HELPERS
794 ////////////////////////////////////////////////////////////////////////////////////////*/
795
796 void DtoResolveDsymbol(Dsymbol* dsym)
797 {
798     if (StructDeclaration* sd = dsym->isStructDeclaration()) {
799         DtoResolveStruct(sd);
800     }
801     else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
802         DtoResolveClass(cd);
803     }
804     else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
805         DtoResolveFunction(fd);
806     }
807     else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
808         DtoResolveTypeInfo(fd);
809     }
810     else {
811     error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
812     assert(0 && "unsupported dsymbol for DtoResolveDsymbol");
813     }
814 }
815
816 //////////////////////////////////////////////////////////////////////////////////////////
817
818 void DtoConstInitGlobal(VarDeclaration* vd)
819 {
820     vd->codegen(Type::sir);
821
822     if (vd->ir.initialized) return;
823     vd->ir.initialized = gIR->dmodule;
824
825     Logger::println("DtoConstInitGlobal(%s) @ %s", vd->toChars(), vd->loc.toChars());
826     LOG_SCOPE;
827
828     Dsymbol* par = vd->toParent();
829
830     // build the initializer
831     LLConstant* initVal = DtoConstInitializer(vd->loc, vd->type, vd->init);
832
833     // set the initializer if appropriate
834     IrGlobal* glob = vd->ir.irGlobal;
835     llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(glob->value);
836
837     // refine the global's opaque type to the type of the initializer
838     llvm::cast<LLOpaqueType>(glob->type.get())->refineAbstractTypeTo(initVal->getType());
839
840     assert(!glob->constInit);
841     glob->constInit = initVal;
842
843     // assign the initializer
844     llvm::GlobalVariable* globalvar = llvm::cast<llvm::GlobalVariable>(glob->value);
845
846     if (!(vd->storage_class & STCextern) && mustDefineSymbol(vd))
847     {
848         if (Logger::enabled())
849         {
850             Logger::println("setting initializer");
851             Logger::cout() << "global: " << *gvar << '\n';
852 #if 0
853             Logger::cout() << "init:   " << *initVal << '\n';
854 #endif
855         }
856
857         gvar->setInitializer(initVal);
858
859         #ifndef DISABLE_DEBUG_INFO
860         // do debug info
861         if (global.params.symdebug)
862         {
863             LLGlobalVariable* gv = DtoDwarfGlobalVariable(gvar, vd).getGV();
864             // keep a reference so GDCE doesn't delete it !
865             gIR->usedArray.push_back(llvm::ConstantExpr::getBitCast(gv, getVoidPtrType()));
866         }
867         #endif
868     }
869 }
870
871 /****************************************************************************************/
872 /*////////////////////////////////////////////////////////////////////////////////////////
873 //      DECLARATION EXP HELPER
874 ////////////////////////////////////////////////////////////////////////////////////////*/
875 DValue* DtoDeclarationExp(Dsymbol* declaration)
876 {
877     Logger::print("DtoDeclarationExp: %s\n", declaration->toChars());
878     LOG_SCOPE;
879
880     // variable declaration
881     if (VarDeclaration* vd = declaration->isVarDeclaration())
882     {
883         Logger::println("VarDeclaration");
884
885         // if aliassym is set, this VarDecl is redone as an alias to another symbol
886         // this seems to be done to rewrite Tuple!(...) v;
887         // as a TupleDecl that contains a bunch of individual VarDecls
888         if (vd->aliassym)
889             return DtoDeclarationExp(vd->aliassym);
890
891         // static
892         if (vd->isDataseg())
893         {
894             vd->codegen(Type::sir);
895         }
896         else
897         {
898             if (global.params.llvmAnnotate)
899                 DtoAnnotation(declaration->toChars());
900
901             Logger::println("vdtype = %s", vd->type->toChars());
902
903             // ref vardecls are generated when DMD lowers foreach to a for statement,
904             // and this is a hack to support them for this case only
905             if(vd->isRef())
906             {
907                 if (!vd->ir.irLocal)
908                     vd->ir.irLocal = new IrLocal(vd);
909
910                 ExpInitializer* ex = vd->init->isExpInitializer();
911                 assert(ex && "ref vars must have expression initializer");
912                 assert(ex->exp);
913                 AssignExp* as = ex->exp->isAssignExp();
914                 assert(as && "ref vars must be initialized by an assign exp");
915                 vd->ir.irLocal->value = as->e2->toElem(gIR)->getLVal();
916             }
917
918             // referenced by nested delegate?
919         #if DMDV2
920             if (vd->nestedrefs.dim) {
921         #else
922             if (vd->nestedref) {
923         #endif
924                 Logger::println("has nestedref set");
925                 assert(vd->ir.irLocal);
926
927                 DtoNestedInit(vd);
928             }
929             // normal stack variable, allocate storage on the stack if it has not already been done
930             else if(!vd->ir.irLocal && !vd->isRef()) {
931                 vd->ir.irLocal = new IrLocal(vd);
932
933                 const LLType* lltype = DtoType(vd->type);
934
935                 llvm::Value* allocainst;
936                 if(gTargetData->getTypeSizeInBits(lltype) == 0)
937                     allocainst = llvm::ConstantPointerNull::get(getPtrToType(lltype));
938                 else
939                     allocainst = DtoAlloca(vd->type, vd->toChars());
940
941                 //allocainst->setAlignment(vd->type->alignsize()); // TODO
942                 vd->ir.irLocal->value = allocainst;
943
944                 #ifndef DISABLE_DEBUG_INFO
945                 if (global.params.symdebug)
946                     DtoDwarfLocalVariable(allocainst, vd);
947                 #endif
948             }
949             else
950             {
951                 assert(vd->ir.irLocal->value);
952             }
953
954             if (Logger::enabled())
955                 Logger::cout() << "llvm value for decl: " << *vd->ir.irLocal->value << '\n';
956             if (!vd->isRef())
957                 DValue* ie = DtoInitializer(vd->ir.irLocal->value, vd->init);
958         }
959
960         return new DVarValue(vd->type, vd, vd->ir.getIrValue());
961     }
962     // struct declaration
963     else if (StructDeclaration* s = declaration->isStructDeclaration())
964     {
965         Logger::println("StructDeclaration");
966         s->codegen(Type::sir);
967     }
968     // function declaration
969     else if (FuncDeclaration* f = declaration->isFuncDeclaration())
970     {
971         Logger::println("FuncDeclaration");
972         f->codegen(Type::sir);
973     }
974     // alias declaration
975     else if (AliasDeclaration* a = declaration->isAliasDeclaration())
976     {
977         Logger::println("AliasDeclaration - no work");
978         // do nothing
979     }
980     // enum
981     else if (EnumDeclaration* e = declaration->isEnumDeclaration())
982     {
983         Logger::println("EnumDeclaration - no work");
984         // do nothing
985     }
986     // class
987     else if (ClassDeclaration* e = declaration->isClassDeclaration())
988     {
989         Logger::println("ClassDeclaration");
990         e->codegen(Type::sir);
991     }
992     // typedef
993     else if (TypedefDeclaration* tdef = declaration->isTypedefDeclaration())
994     {
995         Logger::println("TypedefDeclaration");
996         DtoTypeInfoOf(tdef->type, false);
997     }
998     // attribute declaration
999     else if (AttribDeclaration* a = declaration->isAttribDeclaration())
1000     {
1001         Logger::println("AttribDeclaration");
1002         // choose the right set in case this is a conditional declaration
1003         Array *d = a->include(NULL, NULL);
1004         if (d)
1005             for (int i=0; i < d->dim; ++i)
1006             {
1007                 DtoDeclarationExp((Dsymbol*)d->data[i]);
1008             }
1009     }
1010     // mixin declaration
1011     else if (TemplateMixin* m = declaration->isTemplateMixin())
1012     {
1013         Logger::println("TemplateMixin");
1014         for (int i=0; i < m->members->dim; ++i)
1015         {
1016             Dsymbol* mdsym = (Dsymbol*)m->members->data[i];
1017             DtoDeclarationExp(mdsym);
1018         }
1019     }
1020     // tuple declaration
1021     else if (TupleDeclaration* tupled = declaration->isTupleDeclaration())
1022     {
1023         Logger::println("TupleDeclaration");
1024         if(!tupled->isexp) {
1025             error(declaration->loc, "don't know how to handle non-expression tuple decls yet");
1026             assert(0);
1027         }
1028
1029         assert(tupled->objects);
1030         for (int i=0; i < tupled->objects->dim; ++i)
1031         {
1032             DsymbolExp* exp = (DsymbolExp*)tupled->objects->data[i];
1033             DtoDeclarationExp(exp->s);
1034         }
1035     }
1036     // unsupported declaration
1037     else
1038     {
1039         error(declaration->loc, "Unimplemented Declaration type for DeclarationExp. kind: %s", declaration->kind());
1040         assert(0);
1041     }
1042     return NULL;
1043 }
1044
1045 // does pretty much the same as DtoDeclarationExp, except it doesn't initialize, and only handles var declarations
1046 LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr)
1047 {
1048     // we don't handle globals with this one
1049     assert(!var->isDataseg());
1050
1051     // we don't handle aliases either
1052     assert(!var->aliassym);
1053
1054     // alloca if necessary
1055     LLValue* allocaval = NULL;
1056     if (!addr && (!var->ir.irLocal || !var->ir.irLocal->value))
1057     {
1058         addr = DtoAlloca(var->type, var->toChars());
1059
1060         #ifndef DISABLE_DEBUG_INFO
1061         // add debug info
1062         if (global.params.symdebug)
1063             DtoDwarfLocalVariable(addr, var);
1064         #endif
1065     }
1066
1067     // referenced by nested function?
1068 #if DMDV2
1069     if (var->nestedrefs.dim)
1070 #else
1071     if (var->nestedref)
1072 #endif
1073     {
1074         assert(var->ir.irLocal);
1075         if(!var->ir.irLocal->value)
1076         {
1077             assert(addr);
1078             var->ir.irLocal->value = addr;
1079         }
1080         else
1081             assert(!addr || addr == var->ir.irLocal->value);
1082
1083         DtoNestedInit(var);
1084     }
1085     // normal local variable
1086     else
1087     {
1088         // if this already has storage, it must've been handled already
1089         if (var->ir.irLocal && var->ir.irLocal->value) {
1090             if (addr && addr != var->ir.irLocal->value) {
1091                 // This can happen, for example, in scope(exit) blocks which
1092                 // are translated to IR multiple times.
1093                 // That *should* only happen after the first one is completely done
1094                 // though, so just set the address.
1095                 IF_LOG {
1096                     Logger::println("Replacing LLVM address of %s", var->toChars());
1097                     LOG_SCOPE;
1098                     Logger::cout() << "Old val: " << *var->ir.irLocal->value << '\n';
1099                     Logger::cout() << "New val: " << *addr << '\n';
1100                 }
1101                 var->ir.irLocal->value = addr;
1102             }
1103             return addr;
1104         }
1105
1106         assert(!var->ir.isSet());
1107         assert(addr);
1108         var->ir.irLocal = new IrLocal(var);
1109         var->ir.irLocal->value = addr;
1110     }
1111
1112     // return the alloca
1113     return var->ir.irLocal->value;
1114 }
1115
1116 /****************************************************************************************/
1117 /*////////////////////////////////////////////////////////////////////////////////////////
1118 //      INITIALIZER HELPERS
1119 ////////////////////////////////////////////////////////////////////////////////////////*/
1120
1121 LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init)
1122 {
1123     LLConstant* _init = 0; // may return zero
1124     if (!init)
1125     {
1126         Logger::println("const default initializer for %s", type->toChars());
1127         _init = DtoConstExpInit(loc, type, type->defaultInit());
1128     }
1129     else if (ExpInitializer* ex = init->isExpInitializer())
1130     {
1131         Logger::println("const expression initializer");
1132         _init = DtoConstExpInit(loc, type, ex->exp);;
1133     }
1134     else if (StructInitializer* si = init->isStructInitializer())
1135     {
1136         Logger::println("const struct initializer");
1137         si->ad->codegen(Type::sir);
1138         return si->ad->ir.irStruct->createStructInitializer(si);
1139     }
1140     else if (ArrayInitializer* ai = init->isArrayInitializer())
1141     {
1142         Logger::println("const array initializer");
1143         _init = DtoConstArrayInitializer(ai);
1144     }
1145     else if (init->isVoidInitializer())
1146     {
1147         Logger::println("const void initializer");
1148         const LLType* ty = DtoType(type);
1149         _init = LLConstant::getNullValue(ty);
1150     }
1151     else {
1152         Logger::println("unsupported const initializer: %s", init->toChars());
1153     }
1154     return _init;
1155 }
1156
1157 //////////////////////////////////////////////////////////////////////////////////////////
1158
1159 DValue* DtoInitializer(LLValue* target, Initializer* init)
1160 {
1161     if (!init)
1162         return 0;
1163     else if (ExpInitializer* ex = init->isExpInitializer())
1164     {
1165         Logger::println("expression initializer");
1166         assert(ex->exp);
1167         return ex->exp->toElem(gIR);
1168     }
1169     else if (init->isVoidInitializer())
1170     {
1171         // do nothing
1172     }
1173     else {
1174         Logger::println("unsupported initializer: %s", init->toChars());
1175         assert(0);
1176     }
1177     return 0;
1178 }
1179
1180 //////////////////////////////////////////////////////////////////////////////////////////
1181
1182 static LLConstant* expand_to_sarray(Type *base, Expression* exp)
1183 {
1184     Logger::println("building type %s from expression (%s) of type %s", base->toChars(), exp->toChars(), exp->type->toChars());
1185     const LLType* dstTy = DtoType(base);
1186     if (Logger::enabled())
1187         Logger::cout() << "final llvm type requested: " << *dstTy << '\n';
1188
1189     LLConstant* val = exp->toConstElem(gIR);
1190
1191     Type* expbase = exp->type->toBasetype();
1192     Logger::println("expbase: %s", expbase->toChars());
1193     Type* t = base->toBasetype();
1194
1195     LLSmallVector<size_t, 4> dims;
1196
1197     while(1)
1198     {
1199         Logger::println("t: %s", t->toChars());
1200         if (t->equals(expbase))
1201             break;
1202         assert(t->ty == Tsarray);
1203         TypeSArray* tsa = (TypeSArray*)t;
1204         dims.push_back(tsa->dim->toInteger());
1205         assert(t->nextOf());
1206         t = t->nextOf()->toBasetype();
1207     }
1208
1209     size_t i = dims.size();
1210     assert(i);
1211
1212     std::vector<LLConstant*> inits;
1213     while (i--)
1214     {
1215         const LLArrayType* arrty = LLArrayType::get(val->getType(), dims[i]);
1216         inits.clear();
1217         inits.insert(inits.end(), dims[i], val);
1218         val = LLConstantArray::get(arrty, inits);
1219     }
1220
1221     return val;
1222 }
1223
1224 LLConstant* DtoConstExpInit(Loc loc, Type* type, Expression* exp)
1225 {
1226     Type* expbase = exp->type->toBasetype();
1227     Type* base = type->toBasetype();
1228
1229     // if not the same basetypes, we won't get the same llvm types either
1230     if (!expbase->equals(base))
1231     {
1232         if (base->ty == Tsarray)
1233         {
1234             if (base->nextOf()->toBasetype()->ty == Tvoid) {
1235                 error(loc, "static arrays of voids have no default initializer");
1236                 fatal();
1237             }
1238             Logger::println("type is a static array, building constant array initializer to single value");
1239             return expand_to_sarray(base, exp);
1240         }
1241         else
1242         {
1243             error("cannot yet convert default initializer %s to type %s to %s", exp->toChars(), exp->type->toChars(), type->toChars());
1244             fatal();
1245         }
1246         assert(0);
1247     }
1248
1249     return exp->toConstElem(gIR);
1250 }
1251
1252 //////////////////////////////////////////////////////////////////////////////////////////
1253
1254 void DtoAnnotation(const char* str)
1255 {
1256     std::string s("CODE: ");
1257     s.append(str);
1258     char* p = &s[0];
1259     while (*p)
1260     {
1261         if (*p == '"')
1262             *p = '\'';
1263         ++p;
1264     }
1265     // create a noop with the code as the result name!
1266     // FIXME: this is const folded and eliminated immediately ... :/
1267     gIR->ir->CreateAnd(DtoConstSize_t(0),DtoConstSize_t(0),s.c_str());
1268 }
1269
1270 //////////////////////////////////////////////////////////////////////////////////////////
1271
1272 LLConstant* DtoTypeInfoOf(Type* type, bool base)
1273 {
1274 #if DMDV2
1275     // FIXME: this is probably wrong, but it makes druntime's genobj.d compile!
1276     type = type->mutableOf()->merge(); // needed.. getTypeInfo does the same
1277 #else
1278     type = type->merge(); // needed.. getTypeInfo does the same
1279 #endif
1280     type->getTypeInfo(NULL);
1281     TypeInfoDeclaration* tidecl = type->vtinfo;
1282     assert(tidecl);
1283     tidecl->codegen(Type::sir);
1284     assert(tidecl->ir.irGlobal != NULL);
1285     assert(tidecl->ir.irGlobal->value != NULL);
1286     LLConstant* c = isaConstant(tidecl->ir.irGlobal->value);
1287     assert(c != NULL);
1288     if (base)
1289         return llvm::ConstantExpr::getBitCast(c, DtoType(Type::typeinfo->type));
1290     return c;
1291 }
1292
1293 //////////////////////////////////////////////////////////////////////////////////////////
1294
1295 void DtoOverloadedIntrinsicName(TemplateInstance* ti, TemplateDeclaration* td, std::string& name)
1296 {
1297     Logger::println("DtoOverloadedIntrinsicName");
1298     LOG_SCOPE;
1299
1300     Logger::println("template instance: %s", ti->toChars());
1301     Logger::println("template declaration: %s", td->toChars());
1302     Logger::println("intrinsic name: %s", td->intrinsicName.c_str());
1303
1304     // for now use the size in bits of the first template param in the instance
1305     assert(ti->tdtypes.dim == 1);
1306     Type* T = (Type*)ti->tdtypes.data[0];
1307
1308     char prefix = T->isreal() ? 'f' : T->isintegral() ? 'i' : 0;
1309     if (!prefix) {
1310         ti->error("has invalid template parameter for intrinsic: %s", T->toChars());
1311         fatal(); // or LLVM asserts
1312     }
1313
1314     char tmp[21]; // probably excessive, but covers a uint64_t
1315     sprintf(tmp, "%lu", (unsigned long) gTargetData->getTypeSizeInBits(DtoType(T)));
1316
1317     // replace # in name with bitsize
1318     name = td->intrinsicName;
1319
1320     std::string needle("#");
1321     size_t pos;
1322     while(std::string::npos != (pos = name.find(needle))) {
1323         if (pos > 0 && name[pos-1] == prefix) {
1324             // Properly prefixed, insert bitwidth.
1325             name.replace(pos, 1, tmp);
1326         } else {
1327             if (pos && (name[pos-1] == 'i' || name[pos-1] == 'f')) {
1328                 // Wrong type character.
1329                 ti->error("has invalid parameter type for intrinsic %s: %s is not a%s type",
1330                     name.c_str(), T->toChars(),
1331                     (name[pos-1] == 'i' ? "n integral" : " floating-point"));
1332             } else {
1333                 // Just plain wrong. (Error in declaration, not instantiation)
1334                 td->error("has an invalid intrinsic name: %s", name.c_str());
1335             }
1336             fatal(); // or LLVM asserts
1337         }
1338     }
1339
1340     Logger::println("final intrinsic name: %s", name.c_str());
1341 }
1342
1343 //////////////////////////////////////////////////////////////////////////////////////////
1344
1345 bool mustDefineSymbol(Dsymbol* s)
1346 {
1347     if (FuncDeclaration* fd = s->isFuncDeclaration())
1348     {
1349         // we can't (and probably shouldn't?) define functions
1350         // that weren't semantic3'ed
1351         if (fd->semanticRun < 4)
1352             return false;
1353
1354     if (fd->isArrayOp)
1355             return true;
1356
1357         if (global.params.useAvailableExternally && fd->availableExternally) {
1358             // Emit extra functions if we're inlining.
1359             // These will get available_externally linkage,
1360             // so they shouldn't end up in object code.
1361
1362             assert(fd->type->ty == Tfunction);
1363             TypeFunction* tf = (TypeFunction*) fd->type;
1364             // * If we define extra static constructors, static destructors
1365             //   and unittests they'll get registered to run, and we won't
1366             //   be calling them directly anyway.
1367             // * If it's a large function, don't emit it unnecessarily.
1368             //   Use DMD's canInline() to determine whether it's large.
1369             //   inlineCost() members have been changed to pay less attention
1370             //   to DMDs limitations, but still have some issues. The most glaring
1371             //   offenders are any kind of control flow statements other than
1372             //   'if' and 'return'.
1373             if (   !fd->isStaticCtorDeclaration()
1374                 && !fd->isStaticDtorDeclaration()
1375                 && !fd->isUnitTestDeclaration()
1376                 && fd->canInline(true))
1377             {
1378                 return true;
1379             }
1380
1381             // This was only semantic'ed for inlining checks.
1382             // We won't be inlining this, so we only need to emit a declaration.
1383             return false;
1384         }
1385     }
1386
1387     // Inlining checks may create some variable and class declarations
1388     // we don't need to emit.
1389     if (global.params.useAvailableExternally)
1390     {
1391         if (VarDeclaration* vd = s->isVarDeclaration())
1392             if (vd->availableExternally)
1393                 return false;
1394
1395         if (ClassDeclaration* cd = s->isClassDeclaration())
1396             if (cd->availableExternally)
1397                 return false;
1398     }
1399
1400     TemplateInstance* tinst = DtoIsTemplateInstance(s);
1401     if (tinst)
1402     {
1403         if (!opts::singleObj)
1404             return true;
1405
1406         if (!tinst->emittedInModule)
1407         {
1408             gIR->seenTemplateInstances.insert(tinst);
1409             tinst->emittedInModule = gIR->dmodule;
1410         }
1411         return tinst->emittedInModule == gIR->dmodule;
1412     }
1413
1414     return s->getModule() == gIR->dmodule;
1415 }
1416
1417 //////////////////////////////////////////////////////////////////////////////////////////
1418
1419 bool needsTemplateLinkage(Dsymbol* s)
1420 {
1421     return DtoIsTemplateInstance(s) && mustDefineSymbol(s);
1422 }
1423
1424 //////////////////////////////////////////////////////////////////////////////////////////
1425
1426 bool hasUnalignedFields(Type* t)
1427 {
1428     t = t->toBasetype();
1429     if (t->ty == Tsarray) {
1430         assert(t->nextOf()->size() % t->nextOf()->alignsize() == 0);
1431         return hasUnalignedFields(t->nextOf());
1432     } else if (t->ty != Tstruct)
1433         return false;
1434
1435     TypeStruct* ts = (TypeStruct*)t;
1436     if (ts->unaligned)
1437         return (ts->unaligned == 2);
1438
1439     StructDeclaration* sym = ts->sym;
1440
1441     // go through all the fields and try to find something unaligned
1442     ts->unaligned = 2;
1443     for (int i = 0; i < sym->fields.dim; i++)
1444     {
1445         VarDeclaration* f = (VarDeclaration*)sym->fields.data[i];
1446         unsigned a = f->type->alignsize() - 1;
1447         if (((f->offset + a) & ~a) != f->offset)
1448             return true;
1449         else if (f->type->toBasetype()->ty == Tstruct && hasUnalignedFields(f->type))
1450             return true;
1451     }
1452
1453     ts->unaligned = 1;
1454     return false;
1455 }
1456
1457 //////////////////////////////////////////////////////////////////////////////////////////
1458
1459 IrModule * getIrModule(Module * M)
1460 {
1461     if (M == NULL)
1462         M = gIR->func()->decl->getModule();
1463     assert(M && "null module");
1464     if (!M->ir.irModule)
1465         M->ir.irModule = new IrModule(M, M->srcfile->toChars());
1466     return M->ir.irModule;
1467 }
1468
1469 //////////////////////////////////////////////////////////////////////////////////////////
1470
1471 size_t realignOffset(size_t offset, Type* type)
1472 {
1473     size_t alignsize = type->alignsize();
1474     size_t alignedoffset = (offset + alignsize - 1) & ~(alignsize - 1);
1475
1476     // if the aligned offset already matches the input offset
1477     // don't waste time checking things are ok!
1478     if (alignedoffset == offset)
1479         return alignedoffset;
1480
1481     // we cannot get the llvm alignment if the type is still opaque, this can happen in some
1482     // forward reference situations, so when this happens we fall back to manual padding.
1483     // also handle arbitrary "by-value" opaques nested inside aggregates.
1484     const llvm::Type* T = DtoType(type);
1485     if (!T->isSized())
1486     {
1487         return offset;
1488     }
1489
1490     // then we check against the llvm alignment
1491     size_t alignsize2 = gTargetData->getABITypeAlignment(T);
1492
1493     // if it differs we need to insert manual padding as well
1494     if (alignsize != alignsize2)
1495     {
1496         assert(alignsize > alignsize2 && "this is not good, the D and LLVM "
1497             "type alignments differ, but LLVM's is bigger! This will break "
1498             "aggregate type mapping");
1499         // don't try and align the offset, and let the mappers pad 100% manually
1500         return offset;
1501     }
1502
1503     // ok, we're good, llvm will align properly!
1504     return alignedoffset;
1505 }
1506
1507 //////////////////////////////////////////////////////////////////////////////////////////
1508
1509 Type * stripModifiers( Type * type )
1510 {
1511 #if DMDV2
1512     Type *t = type;
1513     while (t->mod)
1514     {
1515         switch (t->mod)
1516         {
1517             case MODconst:
1518                 t = type->cto;
1519                 break;
1520             case MODshared:
1521                 t = type->sto;
1522                 break;
1523             case MODinvariant:
1524                 t = type->ito;
1525                 break;
1526             case MODshared | MODconst:
1527                 t = type->scto;
1528                 break;
1529             default:
1530                 assert(0 && "Unhandled type modifier");
1531         }
1532
1533         if (!t)
1534         {
1535             unsigned sz = type->sizeTy[type->ty];
1536             t = (Type *)malloc(sz);
1537             memcpy(t, type, sz);
1538             t->mod = 0;
1539             t->deco = NULL;
1540             t->arrayof = NULL;
1541             t->pto = NULL;
1542             t->rto = NULL;
1543             t->cto = NULL;
1544             t->ito = NULL;
1545             t->sto = NULL;
1546             t->scto = NULL;
1547             t->vtinfo = NULL;
1548             t = t->merge();
1549
1550             t->fixTo(type);
1551             switch (type->mod)
1552             {
1553                 case MODconst:
1554                 t->cto = type;
1555                 break;
1556
1557                 case MODinvariant:
1558                 t->ito = type;
1559                 break;
1560
1561                 case MODshared:
1562                 t->sto = type;
1563                 break;
1564
1565                 case MODshared | MODconst:
1566                 t->scto = type;
1567                 break;
1568
1569                 default:
1570                 assert(0);
1571             }
1572         }
1573     }
1574     return t;
1575 #else
1576     return type;
1577 #endif
1578 }
1579
1580 //////////////////////////////////////////////////////////////////////////////////////////
1581
1582 LLValue* makeLValue(Loc& loc, DValue* value)
1583 {
1584     Type* valueType = value->getType();
1585     bool needsMemory;
1586     LLValue* valuePointer;
1587     if (value->isIm()) {
1588         valuePointer = value->getRVal();
1589         needsMemory = !DtoIsPassedByRef(valueType);
1590     }
1591     else if (DVarValue* var = value->isVar()) {
1592         valuePointer = value->getLVal();
1593         needsMemory = false;
1594     }
1595     else if (value->isConst()) {
1596         valuePointer = value->getRVal();
1597         needsMemory = true;
1598     }
1599     else {
1600         valuePointer = DtoAlloca(valueType, ".makelvaluetmp");
1601         DVarValue var(valueType, valuePointer);
1602         DtoAssign(loc, &var, value);
1603         needsMemory = false;
1604     }
1605
1606     if (needsMemory) {
1607         LLValue* tmp = DtoAlloca(valueType, ".makelvaluetmp");
1608         DtoStore(valuePointer, tmp);
1609         valuePointer = tmp;
1610     }
1611
1612     return valuePointer;
1613 }
Note: See TracBrowser for help on using the browser.
Copyright © 2008, LDC Development Team.