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

root/gen/functions.cpp

Revision 1650:40bd4a0d4870, 27.2 kB (checked in by Tomas Lindquist Olsen, 2 years 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/llvm.h"
2 #include "llvm/Support/CFG.h"
3 #include "llvm/Intrinsics.h"
4
5 #include "mtype.h"
6 #include "aggregate.h"
7 #include "init.h"
8 #include "declaration.h"
9 #include "template.h"
10 #include "module.h"
11 #include "statement.h"
12
13 #include "gen/irstate.h"
14 #include "gen/tollvm.h"
15 #include "gen/llvmhelpers.h"
16 #include "gen/runtime.h"
17 #include "gen/arrays.h"
18 #include "gen/logger.h"
19 #include "gen/functions.h"
20 #include "gen/todebug.h"
21 #include "gen/classes.h"
22 #include "gen/dvalue.h"
23 #include "gen/abi.h"
24 #include "gen/nested.h"
25
26 using namespace llvm::Attribute;
27
28 const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype, bool ismain)
29 {
30     if (Logger::enabled())
31         Logger::println("DtoFunctionType(%s)", type->toChars());
32     LOG_SCOPE
33
34     // sanity check
35     assert(type->ty == Tfunction);
36     TypeFunction* f = (TypeFunction*)type;
37
38     TargetABI* abi = (f->linkage == LINKintrinsic ? TargetABI::getIntrinsic() : gABI);
39     // Tell the ABI we're resolving a new function type
40     abi->newFunctionType(f);
41
42     // Do not modify f->fty yet; this function may be called recursively if any
43     // of the argument types refer to this type.
44     IrFuncTy fty;
45
46     // llvm idx counter
47     size_t lidx = 0;
48
49     // main needs a little special handling
50     if (ismain)
51     {
52         fty.ret = new IrFuncTyArg(Type::tint32, false);
53     }
54     // sane return value
55     else
56     {
57         Type* rt = f->next;
58         unsigned a = 0;
59         // sret return
60         if (abi->returnInArg(f))
61         {
62             fty.arg_sret = new IrFuncTyArg(rt, true, StructRet | NoAlias | NoCapture);
63             rt = Type::tvoid;
64             lidx++;
65         }
66         // sext/zext return
67         else if (unsigned se = DtoShouldExtend(rt))
68         {
69             a = se;
70         }
71         fty.ret = new IrFuncTyArg(rt, false, a);
72     }
73     lidx++;
74
75     // member functions
76     if (thistype)
77     {
78         bool toref = (thistype->toBasetype()->ty == Tstruct);
79         fty.arg_this = new IrFuncTyArg(thistype, toref);
80         lidx++;
81     }
82
83     // and nested functions
84     else if (nesttype)
85     {
86         fty.arg_nest = new IrFuncTyArg(nesttype, false);
87         lidx++;
88     }
89
90     // vararg functions are special too
91     if (f->varargs)
92     {
93         if (f->linkage == LINKd)
94         {
95             // d style with hidden args
96             // 2 (array) is handled by the frontend
97             if (f->varargs == 1)
98             {
99                 // _arguments
100                 fty.arg_arguments = new IrFuncTyArg(Type::typeinfo->type->arrayOf(), false);
101                 lidx++;
102                 // _argptr
103                 fty.arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false, NoAlias | NoCapture);
104                 lidx++;
105             }
106         }
107         else if (f->linkage == LINKc)
108         {
109             fty.c_vararg = true;
110         }
111         else
112         {
113             type->error(0, "invalid linkage for variadic function");
114             fatal();
115         }
116     }
117
118     // if this _Dmain() doesn't have an argument, we force it to have one
119     int nargs = Parameter::dim(f->parameters);
120
121     if (ismain && nargs == 0)
122     {
123         Type* mainargs = Type::tchar->arrayOf()->arrayOf();
124         fty.args.push_back(new IrFuncTyArg(mainargs, false));
125         lidx++;
126     }
127     // add explicit parameters
128     else for (int i = 0; i < nargs; i++)
129     {
130         // get argument
131         Parameter* arg = Parameter::getNth(f->parameters, i);
132
133         // reference semantics? ref, out and static arrays are
134         bool byref = (arg->storageClass & (STCref|STCout)) || (arg->type->toBasetype()->ty == Tsarray);
135
136         Type* argtype = arg->type;
137         unsigned a = 0;
138
139         // handle lazy args
140         if (arg->storageClass & STClazy)
141         {
142             Logger::println("lazy param");
143             TypeFunction *ltf = new TypeFunction(NULL, arg->type, 0, LINKd);
144             TypeDelegate *ltd = new TypeDelegate(ltf);
145             argtype = ltd;
146         }
147         // byval
148         else if (abi->passByVal(byref ? argtype->pointerTo() : argtype))
149         {
150             if (!byref) a |= llvm::Attribute::ByVal;
151             byref = true;
152         }
153         // sext/zext
154         else if (!byref)
155         {
156             a |= DtoShouldExtend(argtype);
157         }
158
159         fty.args.push_back(new IrFuncTyArg(argtype, byref, a));
160         lidx++;
161     }
162
163     // Now we can modify f->fty safely.
164     f->fty = fty;
165
166     // let the abi rewrite the types as necesary
167     abi->rewriteFunctionType(f);
168
169     // Tell the ABI we're done with this function type
170     abi->doneWithFunctionType();
171
172     // build the function type
173     std::vector<const LLType*> argtypes;
174     argtypes.reserve(lidx);
175
176     if (f->fty.arg_sret) argtypes.push_back(f->fty.arg_sret->ltype);
177     if (f->fty.arg_this) argtypes.push_back(f->fty.arg_this->ltype);
178     if (f->fty.arg_nest) argtypes.push_back(f->fty.arg_nest->ltype);
179     if (f->fty.arg_arguments) argtypes.push_back(f->fty.arg_arguments->ltype);
180     if (f->fty.arg_argptr) argtypes.push_back(f->fty.arg_argptr->ltype);
181
182     size_t beg = argtypes.size();
183     size_t nargs2 = f->fty.args.size();
184     for (size_t i = 0; i < nargs2; i++)
185     {
186         argtypes.push_back(f->fty.args[i]->ltype);
187     }
188
189     // reverse params?
190     if (f->fty.reverseParams && nargs2 > 1)
191     {
192         std::reverse(argtypes.begin() + beg, argtypes.end());
193     }
194
195     llvm::FunctionType* functype = llvm::FunctionType::get(f->fty.ret->ltype, argtypes, f->fty.c_vararg);
196
197     Logger::cout() << "Final function type: " << *functype << "\n";
198
199     return functype;
200 }
201
202 //////////////////////////////////////////////////////////////////////////////////////////
203
204 static const llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl)
205 {
206     TypeFunction* f = (TypeFunction*)fdecl->type;
207     const llvm::FunctionType* fty = 0;
208
209     // create new ir funcTy
210     f->fty.reset();
211     f->fty.ret = new IrFuncTyArg(Type::tvoid, false);
212
213     f->fty.args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false));
214
215     if (fdecl->llvmInternal == LLVMva_start)
216         fty = GET_INTRINSIC_DECL(vastart)->getFunctionType();
217     else if (fdecl->llvmInternal == LLVMva_copy) {
218         fty = GET_INTRINSIC_DECL(vacopy)->getFunctionType();
219         f->fty.args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false));
220     }
221     else if (fdecl->llvmInternal == LLVMva_end)
222         fty = GET_INTRINSIC_DECL(vaend)->getFunctionType();
223     assert(fty);
224
225     return fty;
226 }
227
228 //////////////////////////////////////////////////////////////////////////////////////////
229
230 const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
231 {
232     // handle for C vararg intrinsics
233     if (fdecl->isVaIntrinsic())
234         return DtoVaFunctionType(fdecl);
235
236     Type *dthis=0, *dnest=0;
237
238     if (fdecl->needThis()) {
239         if (AggregateDeclaration* ad = fdecl->isMember2()) {
240             Logger::println("isMember = this is: %s", ad->type->toChars());
241             dthis = ad->type;
242             const LLType* thisty = DtoType(dthis);
243             //Logger::cout() << "this llvm type: " << *thisty << '\n';
244             if (ad->isStructDeclaration())
245                 thisty = getPtrToType(thisty);
246         }
247         else {
248             Logger::println("chars: %s type: %s kind: %s", fdecl->toChars(), fdecl->type->toChars(), fdecl->kind());
249             assert(0);
250         }
251     }
252     else if (fdecl->isNested()) {
253         dnest = Type::tvoid->pointerTo();
254     }
255
256     const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, dthis, dnest, fdecl->isMain());
257
258     return functype;
259 }
260
261 //////////////////////////////////////////////////////////////////////////////////////////
262
263 static llvm::Function* DtoDeclareVaFunction(FuncDeclaration* fdecl)
264 {
265     TypeFunction* f = (TypeFunction*)fdecl->type->toBasetype();
266     const llvm::FunctionType* fty = DtoVaFunctionType(fdecl);
267     llvm::Function* func = 0;
268
269     if (fdecl->llvmInternal == LLVMva_start)
270         func = GET_INTRINSIC_DECL(vastart);
271     else if (fdecl->llvmInternal == LLVMva_copy)
272         func = GET_INTRINSIC_DECL(vacopy);
273     else if (fdecl->llvmInternal == LLVMva_end)
274         func = GET_INTRINSIC_DECL(vaend);
275     assert(func);
276
277     fdecl->ir.irFunc->func = func;
278     return func;
279 }
280
281 //////////////////////////////////////////////////////////////////////////////////////////
282
283 void DtoResolveFunction(FuncDeclaration* fdecl)
284 {
285     if (!global.params.useUnitTests && fdecl->isUnitTestDeclaration()) {
286         Logger::println("Ignoring unittest %s", fdecl->toPrettyChars());
287         return; // ignore declaration completely
288     }
289
290     if (fdecl->ir.resolved) return;
291     fdecl->ir.resolved = true;
292
293     //printf("resolve function: %s\n", fdecl->toPrettyChars());
294
295     if (fdecl->parent)
296     if (TemplateInstance* tinst = fdecl->parent->isTemplateInstance())
297     {
298         TemplateDeclaration* tempdecl = tinst->tempdecl;
299         if (tempdecl->llvmInternal == LLVMva_arg)
300         {
301             Logger::println("magic va_arg found");
302             fdecl->llvmInternal = LLVMva_arg;
303             fdecl->ir.resolved = true;
304             fdecl->ir.declared = true;
305             fdecl->ir.initialized = true;
306             fdecl->ir.defined = true;
307             return; // this gets mapped to an instruction so a declaration makes no sence
308         }
309         else if (tempdecl->llvmInternal == LLVMva_start)
310         {
311             Logger::println("magic va_start found");
312             fdecl->llvmInternal = LLVMva_start;
313         }
314         else if (tempdecl->llvmInternal == LLVMintrinsic)
315         {
316             Logger::println("overloaded intrinsic found");
317             fdecl->llvmInternal = LLVMintrinsic;
318             DtoOverloadedIntrinsicName(tinst, tempdecl, fdecl->intrinsicName);
319             fdecl->linkage = LINKintrinsic;
320             ((TypeFunction*)fdecl->type)->linkage = LINKintrinsic;
321         }
322         else if (tempdecl->llvmInternal == LLVMinline_asm)
323         {
324             Logger::println("magic inline asm found");
325             TypeFunction* tf = (TypeFunction*)fdecl->type;
326             if (tf->varargs != 1 || (fdecl->parameters && fdecl->parameters->dim != 0))
327             {
328                 error("invalid __asm declaration, must be a D style variadic with no explicit parameters");
329                 fatal();
330             }
331             fdecl->llvmInternal = LLVMinline_asm;
332             fdecl->ir.resolved = true;
333             fdecl->ir.declared = true;
334             fdecl->ir.initialized = true;
335             fdecl->ir.defined = true;
336             return; // this gets mapped to a special inline asm call, no point in going on.
337         }
338     }
339
340     DtoType(fdecl->type);
341
342     Logger::println("DtoResolveFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars());
343     LOG_SCOPE;
344
345     // queue declaration unless the function is abstract without body
346     if (!fdecl->isAbstract() || fdecl->fbody)
347     {
348         DtoDeclareFunction(fdecl);
349     }
350 }
351
352 //////////////////////////////////////////////////////////////////////////////////////////
353
354 static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclaration* fdecl)
355 {
356     int funcNumArgs = func->getArgumentList().size();
357
358     LLSmallVector<llvm::AttributeWithIndex, 9> attrs;
359     llvm::AttributeWithIndex PAWI;
360
361     int idx = 0;
362
363     // handle implicit args
364     #define ADD_PA(X) \
365     if (f->fty.X) { \
366         if (f->fty.X->attrs) { \
367             PAWI.Index = idx; \
368             PAWI.Attrs = f->fty.X->attrs; \
369             attrs.push_back(PAWI); \
370         } \
371         idx++; \
372     }
373
374     ADD_PA(ret)
375     ADD_PA(arg_sret)
376     ADD_PA(arg_this)
377     ADD_PA(arg_nest)
378     ADD_PA(arg_arguments)
379     ADD_PA(arg_argptr)
380
381     #undef ADD_PA
382
383     // set attrs on the rest of the arguments
384     size_t n = Parameter::dim(f->parameters);
385     LLSmallVector<unsigned,8> attrptr(n, 0);
386
387     for (size_t k = 0; k < n; ++k)
388     {
389         Parameter* fnarg = Parameter::getNth(f->parameters, k);
390         assert(fnarg);
391
392         attrptr[k] = f->fty.args[k]->attrs;
393     }
394
395     // reverse params?
396     if (f->fty.reverseParams)
397     {
398         std::reverse(attrptr.begin(), attrptr.end());
399     }
400
401     // build rest of attrs list
402     for (int i = 0; i < n; i++)
403     {
404         if (attrptr[i])
405         {
406             PAWI.Index = idx+i;
407             PAWI.Attrs = attrptr[i];
408             attrs.push_back(PAWI);
409         }
410     }
411
412     llvm::AttrListPtr attrlist = llvm::AttrListPtr::get(attrs.begin(), attrs.end());
413     func->setAttributes(attrlist);
414 }
415
416 //////////////////////////////////////////////////////////////////////////////////////////
417
418 void DtoDeclareFunction(FuncDeclaration* fdecl)
419 {
420     DtoResolveFunction(fdecl);
421
422     if (fdecl->ir.declared) return;
423     fdecl->ir.declared = true;
424
425     Logger::println("DtoDeclareFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars());
426     LOG_SCOPE;
427
428     //printf("declare function: %s\n", fdecl->toPrettyChars());
429
430     // intrinsic sanity check
431     if (fdecl->llvmInternal == LLVMintrinsic && fdecl->fbody) {
432         error(fdecl->loc, "intrinsics cannot have function bodies");
433         fatal();
434     }
435
436     // get TypeFunction*
437     Type* t = fdecl->type->toBasetype();
438     TypeFunction* f = (TypeFunction*)t;
439
440     bool declareOnly = !mustDefineSymbol(fdecl);
441
442     if (fdecl->llvmInternal == LLVMva_start)
443         declareOnly = true;
444
445     if (!fdecl->ir.irFunc) {
446         fdecl->ir.irFunc = new IrFunction(fdecl);
447     }
448
449     // mangled name
450     const char* mangled_name;
451     if (fdecl->llvmInternal == LLVMintrinsic)
452         mangled_name = fdecl->intrinsicName.c_str();
453     else
454         mangled_name = fdecl->mangle();
455
456     llvm::Function* vafunc = 0;
457     if (fdecl->isVaIntrinsic())
458         vafunc = DtoDeclareVaFunction(fdecl);
459
460     // construct function
461     const llvm::FunctionType* functype = DtoFunctionType(fdecl);
462     llvm::Function* func = vafunc ? vafunc : gIR->module->getFunction(mangled_name);
463     if (!func)
464         func = llvm::Function::Create(functype, DtoLinkage(fdecl), mangled_name, gIR->module);
465
466     if (Logger::enabled())
467         Logger::cout() << "func = " << *func << std::endl;
468
469     // add func to IRFunc
470     fdecl->ir.irFunc->func = func;
471
472     // calling convention
473     if (!vafunc && fdecl->llvmInternal != LLVMintrinsic)
474         func->setCallingConv(DtoCallingConv(fdecl->loc, f->linkage));
475     else // fall back to C, it should be the right thing to do
476         func->setCallingConv(llvm::CallingConv::C);
477
478     fdecl->ir.irFunc->func = func;
479
480     // parameter attributes
481     if (!fdecl->isIntrinsic()) {
482         set_param_attrs(f, func, fdecl);
483     }
484
485     // main
486     if (fdecl->isMain()) {
487         gIR->mainFunc = func;
488     }
489
490     // static ctor
491     if (fdecl->isStaticCtorDeclaration()) {
492         if (mustDefineSymbol(fdecl)) {
493             gIR->ctors.push_back(fdecl);
494         }
495     }
496     // static dtor
497     else if (fdecl->isStaticDtorDeclaration()) {
498         if (mustDefineSymbol(fdecl)) {
499             gIR->dtors.push_back(fdecl);
500         }
501     }
502
503     // we never reference parameters of function prototypes
504     std::string str;
505     if (!declareOnly)
506     {
507         // name parameters
508         llvm::Function::arg_iterator iarg = func->arg_begin();
509
510         if (f->fty.arg_sret) {
511             iarg->setName(".sret_arg");
512             fdecl->ir.irFunc->retArg = iarg;
513             ++iarg;
514         }
515
516         if (f->fty.arg_this) {
517             iarg->setName(".this_arg");
518             fdecl->ir.irFunc->thisArg = iarg;
519             assert(fdecl->ir.irFunc->thisArg);
520             ++iarg;
521         }
522         else if (f->fty.arg_nest) {
523             iarg->setName(".nest_arg");
524             fdecl->ir.irFunc->nestArg = iarg;
525             assert(fdecl->ir.irFunc->nestArg);
526             ++iarg;
527         }
528
529         if (f->fty.arg_argptr) {
530             iarg->setName("._arguments");
531             fdecl->ir.irFunc->_arguments = iarg;
532             ++iarg;
533             iarg->setName("._argptr");
534             fdecl->ir.irFunc->_argptr = iarg;
535             ++iarg;
536         }
537
538         int k = 0;
539
540         for (; iarg != func->arg_end(); ++iarg)
541         {
542             if (fdecl->parameters && fdecl->parameters->dim > k)
543             {
544                 Dsymbol* argsym;
545                 if (f->fty.reverseParams)
546                     argsym = (Dsymbol*)fdecl->parameters->data[fdecl->parameters->dim-k-1];
547                 else
548                     argsym = (Dsymbol*)fdecl->parameters->data[k];
549
550                 VarDeclaration* argvd = argsym->isVarDeclaration();
551                 assert(argvd);
552                 assert(!argvd->ir.irLocal);
553                 argvd->ir.irLocal = new IrLocal(argvd);
554                 argvd->ir.irLocal->value = iarg;
555
556                 str = argvd->ident->toChars();
557                 str.append("_arg");
558                 iarg->setName(str);
559
560                 k++;
561             }
562             else
563             {
564                 iarg->setName("unnamed");
565             }
566         }
567     }
568
569     if (fdecl->isUnitTestDeclaration() && !declareOnly)
570         gIR->unitTests.push_back(fdecl);
571
572     if (!declareOnly)
573         Type::sir->addFunctionBody(fdecl->ir.irFunc);
574     else
575         assert(func->getLinkage() != llvm::GlobalValue::InternalLinkage);
576 }
577
578 //////////////////////////////////////////////////////////////////////////////////////////
579
580 // FIXME: this isn't too pretty!
581
582 void DtoDefineFunction(FuncDeclaration* fd)
583 {
584     DtoDeclareFunction(fd);
585
586     if (fd->ir.defined) return;
587     fd->ir.defined = true;
588
589     assert(fd->ir.declared);
590
591     if (Logger::enabled())
592         Logger::println("DtoDefineFunc(%s): %s", fd->toPrettyChars(), fd->loc.toChars());
593     LOG_SCOPE;
594
595     // if this function is naked, we take over right away! no standard processing!
596     if (fd->naked)
597     {
598         DtoDefineNakedFunction(fd);
599         return;
600     }
601
602     #ifndef DISABLE_DEBUG_INFO
603     // debug info
604     if (global.params.symdebug)
605         fd->ir.irFunc->diSubprogram = DtoDwarfSubProgram(fd);
606     #endif
607
608     Type* t = fd->type->toBasetype();
609     TypeFunction* f = (TypeFunction*)t;
610     assert(f->irtype);
611
612     llvm::Function* func = fd->ir.irFunc->func;
613     const llvm::FunctionType* functype = func->getFunctionType();
614
615     // sanity check
616     assert(mustDefineSymbol(fd));
617
618     // set module owner
619     fd->ir.DModule = gIR->dmodule;
620
621     // is there a body?
622     if (fd->fbody == NULL)
623         return;
624
625     Logger::println("Doing function body for: %s", fd->toChars());
626     assert(fd->ir.irFunc);
627     IrFunction* irfunction = fd->ir.irFunc;
628     gIR->functions.push_back(irfunction);
629
630     if (fd->isMain())
631         gIR->emitMain = true;
632
633     std::string entryname("entry");
634
635     llvm::BasicBlock* beginbb = llvm::BasicBlock::Create(gIR->context(), entryname,func);
636     llvm::BasicBlock* endbb = llvm::BasicBlock::Create(gIR->context(), "endentry",func);
637
638     //assert(gIR->scopes.empty());
639     gIR->scopes.push_back(IRScope(beginbb, endbb));
640
641     // create alloca point
642     // this gets erased when the function is complete, so alignment etc does not matter at all
643     llvm::Instruction* allocaPoint = new llvm::AllocaInst(LLType::getInt32Ty(gIR->context()), "alloca point", beginbb);
644     irfunction->allocapoint = allocaPoint;
645
646     #ifndef DISABLE_DEBUG_INFO
647     // debug info - after all allocas, but before any llvm.dbg.declare etc
648     if (global.params.symdebug) DtoDwarfFuncStart(fd);
649     #endif
650
651     // this hack makes sure the frame pointer elimination optimization is disabled.
652     // this this eliminates a bunch of inline asm related issues.
653     if (fd->inlineAsm)
654     {
655         // emit a call to llvm_eh_unwind_init
656         LLFunction* hack = GET_INTRINSIC_DECL(eh_unwind_init);
657         gIR->ir->CreateCall(hack, "");
658     }
659
660     // give the 'this' argument storage and debug info
661     if (f->fty.arg_this)
662     {
663         LLValue* thisvar = irfunction->thisArg;
664         assert(thisvar);
665
666         LLValue* thismem = DtoRawAlloca(thisvar->getType(), 0, "this"); // FIXME: align?
667         DtoStore(thisvar, thismem);
668         irfunction->thisArg = thismem;
669
670         assert(!fd->vthis->ir.irLocal);
671         fd->vthis->ir.irLocal = new IrLocal(fd->vthis);
672         fd->vthis->ir.irLocal->value = thismem;
673
674         #ifndef DISABLE_DEBUG_INFO
675         if (global.params.symdebug)
676             DtoDwarfLocalVariable(thismem, fd->vthis);
677         #endif
678
679     #if DMDV1
680         if (fd->vthis->nestedref)
681         {
682             fd->nestedVars.insert(fd->vthis);
683         }
684     #endif
685     }
686
687     // give arguments storage
688     // and debug info
689     if (fd->parameters)
690     {
691         size_t n = f->fty.args.size();
692         assert(n == fd->parameters->dim);
693         for (int i=0; i < n; ++i)
694         {
695             Dsymbol* argsym = (Dsymbol*)fd->parameters->data[i];
696             VarDeclaration* vd = argsym->isVarDeclaration();
697             assert(vd);
698
699             IrLocal* irloc = vd->ir.irLocal;
700             assert(irloc);
701
702         #if DMDV1
703             if (vd->nestedref)
704             {
705                 fd->nestedVars.insert(vd);
706             }
707         #endif
708
709             bool refout = vd->storage_class & (STCref | STCout);
710             bool lazy = vd->storage_class & STClazy;
711
712             if (!refout && (!f->fty.args[i]->byref || lazy))
713             {
714                 // alloca a stack slot for this first class value arg
715                 const LLType* argt;
716                 if (lazy)
717                     argt = irloc->value->getType();
718                 else
719                     argt = DtoType(vd->type);
720                 LLValue* mem = DtoRawAlloca(argt, 0, vd->ident->toChars());
721
722                 // let the abi transform the argument back first
723                 DImValue arg_dval(vd->type, irloc->value);
724                 f->fty.getParam(vd->type, i, &arg_dval, mem);
725
726                 // set the arg var value to the alloca
727                 irloc->value = mem;
728             }
729
730             #ifndef DISABLE_DEBUG_INFO
731             if (global.params.symdebug && !(isaArgument(irloc->value) && !isaArgument(irloc->value)->hasByValAttr()) && !refout)
732                 DtoDwarfLocalVariable(irloc->value, vd);
733             #endif
734         }
735     }
736
737 // need result variable? (nested)
738 #if DMDV1
739     if (fd->vresult && fd->vresult->nestedref) {
740         Logger::println("nested vresult value: %s", fd->vresult->toChars());
741         fd->nestedVars.insert(fd->vresult);
742     }
743 #endif
744
745 #if DMDV2
746     // fill nestedVars
747     size_t nnest = fd->closureVars.dim;
748     for (size_t i = 0; i < nnest; ++i)
749     {
750         VarDeclaration* vd = (VarDeclaration*)fd->closureVars.data[i];
751         fd->nestedVars.insert(vd);
752     }
753 #endif
754
755     DtoCreateNestedContext(fd);
756
757 #if DMDV2
758     if (fd->vresult && fd->vresult->nestedrefs.dim) // FIXME: not sure here :/
759 #else
760     if (fd->vresult && fd->vresult->nestedref)
761 #endif
762     {
763         DtoNestedInit(fd->vresult);
764     } else if (fd->vresult) {
765         fd->vresult->ir.irLocal = new IrLocal(fd->vresult);
766         fd->vresult->ir.irLocal->value = DtoAlloca(fd->vresult->type, fd->vresult->toChars());
767     }
768
769     // copy _argptr and _arguments to a memory location
770     if (f->linkage == LINKd && f->varargs == 1)
771     {
772         // _argptr
773         LLValue* argptrmem = DtoRawAlloca(fd->ir.irFunc->_argptr->getType(), 0, "_argptr_mem");
774         new llvm::StoreInst(fd->ir.irFunc->_argptr, argptrmem, gIR->scopebb());
775         fd->ir.irFunc->_argptr = argptrmem;
776
777         // _arguments
778         LLValue* argumentsmem = DtoRawAlloca(fd->ir.irFunc->_arguments->getType(), 0, "_arguments_mem");
779         new llvm::StoreInst(fd->ir.irFunc->_arguments, argumentsmem, gIR->scopebb());
780         fd->ir.irFunc->_arguments = argumentsmem;
781     }
782
783     // output function body
784     {
785         FuncGen fg;
786         irfunction->gen = &fg;
787         fd->fbody->toIR(gIR);
788         irfunction->gen = 0;
789     }
790
791     // TODO: clean up this mess
792
793 //     std::cout << *func << std::endl;
794
795     llvm::BasicBlock* bb = gIR->scopebb();
796     if (pred_begin(bb) == pred_end(bb) && bb != &bb->getParent()->getEntryBlock()) {
797         // This block is trivially unreachable, so just delete it.
798         // (This is a common case because it happens when 'return'
799         // is the last statement in a function)
800         bb->eraseFromParent();
801     } else if (!gIR->scopereturned()) {
802         // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement
803         // in automatically, so we do it here.
804
805         // pass the previous block into this block
806         #ifndef DISABLE_DEBUG_INFO
807         if (global.params.symdebug) DtoDwarfFuncEnd(fd);
808         #endif
809         if (func->getReturnType() == LLType::getVoidTy(gIR->context())) {
810             llvm::ReturnInst::Create(gIR->context(), gIR->scopebb());
811         }
812         else if (!fd->isMain()) {
813             AsmBlockStatement* asmb = fd->fbody->endsWithAsm();
814             if (asmb) {
815                 assert(asmb->abiret);
816                 llvm::ReturnInst::Create(gIR->context(), asmb->abiret, bb);
817             }
818             else {
819                 llvm::ReturnInst::Create(gIR->context(), llvm::UndefValue::get(func->getReturnType()), bb);
820             }
821         }
822         else
823             llvm::ReturnInst::Create(gIR->context(), LLConstant::getNullValue(func->getReturnType()), bb);
824     }
825
826 //     std::cout << *func << std::endl;
827
828     // erase alloca point
829     allocaPoint->eraseFromParent();
830     allocaPoint = 0;
831     gIR->func()->allocapoint = 0;
832
833     gIR->scopes.pop_back();
834
835     // get rid of the endentry block, it's never used
836     assert(!func->getBasicBlockList().empty());
837     func->getBasicBlockList().pop_back();
838
839     gIR->functions.pop_back();
840
841 //     std::cout << *func << std::endl;
842 }
843
844 //////////////////////////////////////////////////////////////////////////////////////////
845
846 const llvm::FunctionType* DtoBaseFunctionType(FuncDeclaration* fdecl)
847 {
848     Dsymbol* parent = fdecl->toParent();
849     ClassDeclaration* cd = parent->isClassDeclaration();
850     assert(cd);
851
852     FuncDeclaration* f = fdecl;
853
854     while (cd)
855     {
856         ClassDeclaration* base = cd->baseClass;
857         if (!base)
858             break;
859         FuncDeclaration* f2 = base->findFunc(fdecl->ident, (TypeFunction*)fdecl->type);
860         if (f2) {
861             f = f2;
862             cd = base;
863         }
864         else
865             break;
866     }
867
868     DtoResolveDsymbol(f);
869     return llvm::cast<llvm::FunctionType>(DtoType(f->type));
870 }
871
872 //////////////////////////////////////////////////////////////////////////////////////////
873
874 DValue* DtoArgument(Parameter* fnarg, Expression* argexp)
875 {
876     Logger::println("DtoArgument");
877     LOG_SCOPE;
878
879     DValue* arg = argexp->toElem(gIR);
880
881     // ref/out arg
882     if (fnarg && (fnarg->storageClass & (STCref | STCout)))
883     {
884         if (arg->isVar())
885             arg = new DImValue(argexp->type, arg->getLVal());
886         else
887             arg = new DImValue(argexp->type, arg->getRVal());
888     }
889     // lazy arg
890     else if (fnarg && (fnarg->storageClass & STClazy))
891     {
892         assert(argexp->type->toBasetype()->ty == Tdelegate);
893         assert(!arg->isLVal());
894         return arg;
895     }
896     // byval arg, but expr has no storage yet
897     else if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isNull()))
898     {
899         LLValue* alloc = DtoAlloca(argexp->type, ".tmp_arg");
900         DVarValue* vv = new DVarValue(argexp->type, alloc);
901         DtoAssign(argexp->loc, vv, arg);
902         arg = vv;
903     }
904
905     return arg;
906 }
907
908 //////////////////////////////////////////////////////////////////////////////////////////
909
910 void DtoVariadicArgument(Expression* argexp, LLValue* dst)
911 {
912     Logger::println("DtoVariadicArgument");
913     LOG_SCOPE;
914     DVarValue vv(argexp->type, dst);
915     DtoAssign(argexp->loc, &vv, argexp->toElem(gIR));
916 }
917
918 //////////////////////////////////////////////////////////////////////////////////////////
919
920 bool FuncDeclaration::isIntrinsic()
921 {
922     return (llvmInternal == LLVMintrinsic || isVaIntrinsic());
923 }
924
925 bool FuncDeclaration::isVaIntrinsic()
926 {
927     return (llvmInternal == LLVMva_start ||
928             llvmInternal == LLVMva_copy ||
929             llvmInternal == LLVMva_end);
930 }
Note: See TracBrowser for help on using the browser.
Copyright © 2008, LDC Development Team.