comparison gen/functions.cpp @ 486:a34078905d01

Added pragma(llvmdc, "string") for misc per-module compiler configuration, currently "string" can only be "verbose" which forces -vv for module it appears in. Reimplemented support for nested functions/class using a new approach. Added error on taking address of intrinsic. Fixed problems with the ->syntaxCopy of TypeFunction delegate exp. Removed DtoDType and replaced all uses with ->toBasetype() instead. Removed unused inplace stuff. Fixed a bunch of issues in the runtime unittests, not complete yet. Added mini tests.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sun, 10 Aug 2008 08:37:38 +0200
parents 672eb4893b55
children c9a606d6e641
comparison
equal deleted inserted replaced
485:50f6e2337a6b 486:a34078905d01
19 #include "gen/functions.h" 19 #include "gen/functions.h"
20 #include "gen/todebug.h" 20 #include "gen/todebug.h"
21 #include "gen/classes.h" 21 #include "gen/classes.h"
22 #include "gen/dvalue.h" 22 #include "gen/dvalue.h"
23 23
24 const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bool ismain) 24 const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, const LLType* nesttype, bool ismain)
25 { 25 {
26 assert(type->ty == Tfunction); 26 assert(type->ty == Tfunction);
27 TypeFunction* f = (TypeFunction*)type; 27 TypeFunction* f = (TypeFunction*)type;
28 28
29 if (type->ir.type != NULL) { 29 if (type->ir.type != NULL) {
44 const LLType* rettype; 44 const LLType* rettype;
45 const LLType* actualRettype; 45 const LLType* actualRettype;
46 Type* rt = f->next; 46 Type* rt = f->next;
47 bool retinptr = false; 47 bool retinptr = false;
48 bool usesthis = false; 48 bool usesthis = false;
49 bool usesnest = false;
49 50
50 // parameter types 51 // parameter types
51 std::vector<const LLType*> paramvec; 52 std::vector<const LLType*> paramvec;
52 53
53 if (ismain) 54 if (ismain)
64 else{ 65 else{
65 assert(rt); 66 assert(rt);
66 if (DtoIsReturnedInArg(rt)) { 67 if (DtoIsReturnedInArg(rt)) {
67 rettype = getPtrToType(DtoType(rt)); 68 rettype = getPtrToType(DtoType(rt));
68 actualRettype = LLType::VoidTy; 69 actualRettype = LLType::VoidTy;
69 f->llvmRetInPtr = retinptr = true; 70 f->retInPtr = retinptr = true;
70 } 71 }
71 else { 72 else {
72 rettype = DtoType(rt); 73 rettype = DtoType(rt);
73 actualRettype = rettype; 74 actualRettype = rettype;
74 } 75 }
75 76
76 if (unsigned ea = DtoShouldExtend(rt)) 77 if (unsigned ea = DtoShouldExtend(rt))
77 { 78 {
78 f->llvmRetAttrs |= ea; 79 f->retAttrs |= ea;
79 } 80 }
80 } 81 }
81 82
82 if (retinptr) { 83 if (retinptr) {
83 //Logger::cout() << "returning through pointer parameter: " << *rettype << '\n'; 84 //Logger::cout() << "returning through pointer parameter: " << *rettype << '\n';
85 } 86 }
86 87
87 if (thistype) { 88 if (thistype) {
88 paramvec.push_back(thistype); 89 paramvec.push_back(thistype);
89 usesthis = true; 90 usesthis = true;
91 }
92 else if (nesttype) {
93 paramvec.push_back(nesttype);
94 usesnest = true;
90 } 95 }
91 96
92 if (typesafeVararg) { 97 if (typesafeVararg) {
93 ClassDeclaration* ti = Type::typeinfo; 98 ClassDeclaration* ti = Type::typeinfo;
94 ti->toObjFile(0); // TODO: multiobj 99 ti->toObjFile(0); // TODO: multiobj
109 size_t n = Argument::dim(f->parameters); 114 size_t n = Argument::dim(f->parameters);
110 115
111 for (int i=0; i < n; ++i) { 116 for (int i=0; i < n; ++i) {
112 Argument* arg = Argument::getNth(f->parameters, i); 117 Argument* arg = Argument::getNth(f->parameters, i);
113 // ensure scalar 118 // ensure scalar
114 Type* argT = DtoDType(arg->type); 119 Type* argT = arg->type->toBasetype();
115 assert(argT); 120 assert(argT);
116 121
117 bool refOrOut = ((arg->storageClass & STCref) || (arg->storageClass & STCout)); 122 bool refOrOut = ((arg->storageClass & STCref) || (arg->storageClass & STCout));
118 123
119 const LLType* at = DtoType(argT); 124 const LLType* at = DtoType(argT);
164 169
165 // construct function type 170 // construct function type
166 bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs; 171 bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs;
167 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); 172 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg);
168 173
169 f->llvmRetInPtr = retinptr; 174 f->retInPtr = retinptr;
170 f->llvmUsesThis = usesthis; 175 f->usesThis = usesthis;
176 f->usesNest = usesnest;
171 177
172 f->ir.type = new llvm::PATypeHolder(functype); 178 f->ir.type = new llvm::PATypeHolder(functype);
173 179
174 return functype; 180 return functype;
175 } 181 }
208 214
209 // type has already been resolved 215 // type has already been resolved
210 if (fdecl->type->ir.type != 0) 216 if (fdecl->type->ir.type != 0)
211 return llvm::cast<llvm::FunctionType>(fdecl->type->ir.type->get()); 217 return llvm::cast<llvm::FunctionType>(fdecl->type->ir.type->get());
212 218
213 const LLType* thisty = NULL; 219 const LLType* thisty = 0;
220 const LLType* nestty = 0;
221
214 if (fdecl->needThis()) { 222 if (fdecl->needThis()) {
215 if (AggregateDeclaration* ad = fdecl->isMember2()) { 223 if (AggregateDeclaration* ad = fdecl->isMember2()) {
216 Logger::println("isMember = this is: %s", ad->type->toChars()); 224 Logger::println("isMember = this is: %s", ad->type->toChars());
217 thisty = DtoType(ad->type); 225 thisty = DtoType(ad->type);
218 //Logger::cout() << "this llvm type: " << *thisty << '\n'; 226 //Logger::cout() << "this llvm type: " << *thisty << '\n';
223 Logger::println("chars: %s type: %s kind: %s", fdecl->toChars(), fdecl->type->toChars(), fdecl->kind()); 231 Logger::println("chars: %s type: %s kind: %s", fdecl->toChars(), fdecl->type->toChars(), fdecl->kind());
224 assert(0); 232 assert(0);
225 } 233 }
226 } 234 }
227 else if (fdecl->isNested()) { 235 else if (fdecl->isNested()) {
228 thisty = getPtrToType(LLType::Int8Ty); 236 nestty = getPtrToType(LLType::Int8Ty);
229 } 237 }
230 238
231 const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, thisty, fdecl->isMain()); 239 const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, thisty, nestty, fdecl->isMain());
232 240
233 return functype; 241 return functype;
234 } 242 }
235 243
236 ////////////////////////////////////////////////////////////////////////////////////////// 244 //////////////////////////////////////////////////////////////////////////////////////////
237 245
238 static llvm::Function* DtoDeclareVaFunction(FuncDeclaration* fdecl) 246 static llvm::Function* DtoDeclareVaFunction(FuncDeclaration* fdecl)
239 { 247 {
240 TypeFunction* f = (TypeFunction*)DtoDType(fdecl->type); 248 TypeFunction* f = (TypeFunction*)fdecl->type->toBasetype();
241 const llvm::FunctionType* fty = DtoVaFunctionType(fdecl); 249 const llvm::FunctionType* fty = DtoVaFunctionType(fdecl);
242 llvm::Function* func = 0; 250 llvm::Function* func = 0;
243 251
244 if (fdecl->llvmInternal == LLVMva_start) 252 if (fdecl->llvmInternal == LLVMva_start)
245 func = GET_INTRINSIC_DECL(vastart); 253 func = GET_INTRINSIC_DECL(vastart);
304 ////////////////////////////////////////////////////////////////////////////////////////// 312 //////////////////////////////////////////////////////////////////////////////////////////
305 313
306 static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclaration* fdecl) 314 static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclaration* fdecl)
307 { 315 {
308 int llidx = 1; 316 int llidx = 1;
309 if (f->llvmRetInPtr) ++llidx; 317 if (f->retInPtr) ++llidx;
310 if (f->llvmUsesThis) ++llidx; 318 if (f->usesThis) ++llidx;
319 else if (f->usesNest) ++llidx;
311 if (f->linkage == LINKd && f->varargs == 1) 320 if (f->linkage == LINKd && f->varargs == 1)
312 llidx += 2; 321 llidx += 2;
313 322
314 int funcNumArgs = func->getArgumentList().size(); 323 int funcNumArgs = func->getArgumentList().size();
315 std::vector<llvm::ParamAttrsWithIndex> attrs; 324 std::vector<llvm::ParamAttrsWithIndex> attrs;
316 int k = 0; 325 int k = 0;
317 326
318 llvm::ParamAttrsWithIndex PAWI; 327 llvm::ParamAttrsWithIndex PAWI;
319 328
320 // set return value attrs if any 329 // set return value attrs if any
321 if (f->llvmRetAttrs) 330 if (f->retAttrs)
322 { 331 {
323 PAWI.Index = 0; 332 PAWI.Index = 0;
324 PAWI.Attrs = f->llvmRetAttrs; 333 PAWI.Attrs = f->retAttrs;
325 attrs.push_back(PAWI); 334 attrs.push_back(PAWI);
326 } 335 }
327 336
328 // set sret param 337 // set sret param
329 if (f->llvmRetInPtr) 338 if (f->retInPtr)
330 { 339 {
331 PAWI.Index = 1; 340 PAWI.Index = 1;
332 PAWI.Attrs = llvm::ParamAttr::StructRet; 341 PAWI.Attrs = llvm::ParamAttr::StructRet;
333 attrs.push_back(PAWI); 342 attrs.push_back(PAWI);
334 } 343 }
376 error(fdecl->loc, "intrinsics cannot have function bodies"); 385 error(fdecl->loc, "intrinsics cannot have function bodies");
377 fatal(); 386 fatal();
378 } 387 }
379 388
380 // get TypeFunction* 389 // get TypeFunction*
381 Type* t = DtoDType(fdecl->type); 390 Type* t = fdecl->type->toBasetype();
382 TypeFunction* f = (TypeFunction*)t; 391 TypeFunction* f = (TypeFunction*)t;
383 392
384 bool declareOnly = false; 393 bool declareOnly = false;
385 bool templInst = fdecl->parent && DtoIsTemplateInstance(fdecl->parent); 394 bool templInst = fdecl->parent && DtoIsTemplateInstance(fdecl->parent);
386 if (!templInst && fdecl->getModule() != gIR->dmodule) 395 if (!templInst && fdecl->getModule() != gIR->dmodule)
415 // construct function 424 // construct function
416 const llvm::FunctionType* functype = DtoFunctionType(fdecl); 425 const llvm::FunctionType* functype = DtoFunctionType(fdecl);
417 llvm::Function* func = vafunc ? vafunc : gIR->module->getFunction(mangled_name); 426 llvm::Function* func = vafunc ? vafunc : gIR->module->getFunction(mangled_name);
418 if (!func) 427 if (!func)
419 func = llvm::Function::Create(functype, DtoLinkage(fdecl), mangled_name, gIR->module); 428 func = llvm::Function::Create(functype, DtoLinkage(fdecl), mangled_name, gIR->module);
420 else
421 assert(func->getFunctionType() == functype);
422 429
423 // add func to IRFunc 430 // add func to IRFunc
424 fdecl->ir.irFunc->func = func; 431 fdecl->ir.irFunc->func = func;
425 432
426 // calling convention 433 // calling convention
455 if (!declareOnly) 462 if (!declareOnly)
456 { 463 {
457 // name parameters 464 // name parameters
458 llvm::Function::arg_iterator iarg = func->arg_begin(); 465 llvm::Function::arg_iterator iarg = func->arg_begin();
459 int k = 0; 466 int k = 0;
460 if (f->llvmRetInPtr) { 467 if (f->retInPtr) {
461 iarg->setName("retval"); 468 iarg->setName(".sretarg");
462 fdecl->ir.irFunc->retArg = iarg; 469 fdecl->ir.irFunc->retArg = iarg;
463 ++iarg; 470 ++iarg;
464 } 471 }
465 if (f->llvmUsesThis) { 472
466 iarg->setName(fdecl->isNested()?".context":"this"); 473 if (f->usesThis) {
467 fdecl->ir.irFunc->thisVar = iarg; 474 iarg->setName("this");
468 assert(fdecl->ir.irFunc->thisVar); 475 fdecl->ir.irFunc->thisArg = iarg;
476 assert(fdecl->ir.irFunc->thisArg);
477 ++iarg;
478 }
479 else if (f->usesNest) {
480 iarg->setName(".nest");
481 fdecl->ir.irFunc->nestArg = iarg;
482 assert(fdecl->ir.irFunc->nestArg);
469 ++iarg; 483 ++iarg;
470 } 484 }
471 485
472 if (f->linkage == LINKd && f->varargs == 1) { 486 if (f->linkage == LINKd && f->varargs == 1) {
473 iarg->setName("_arguments"); 487 iarg->setName("_arguments");
518 assert(fd->ir.declared); 532 assert(fd->ir.declared);
519 533
520 Logger::println("DtoDefineFunc(%s): %s", fd->toPrettyChars(), fd->loc.toChars()); 534 Logger::println("DtoDefineFunc(%s): %s", fd->toPrettyChars(), fd->loc.toChars());
521 LOG_SCOPE; 535 LOG_SCOPE;
522 536
537 // warn about naked
538 if (fd->naked)
539 {
540 warning("%s: naked is currently ignored", fd->locToChars());
541 }
542
523 // debug info 543 // debug info
524 if (global.params.symdebug) { 544 if (global.params.symdebug) {
525 Module* mo = fd->getModule(); 545 Module* mo = fd->getModule();
526 fd->ir.irFunc->dwarfSubProg = DtoDwarfSubProgram(fd); 546 fd->ir.irFunc->dwarfSubProg = DtoDwarfSubProgram(fd);
527 } 547 }
528 548
529 Type* t = DtoDType(fd->type); 549 Type* t = fd->type->toBasetype();
530 TypeFunction* f = (TypeFunction*)t; 550 TypeFunction* f = (TypeFunction*)t;
531 assert(f->ir.type); 551 assert(f->ir.type);
532 552
533 llvm::Function* func = fd->ir.irFunc->func; 553 llvm::Function* func = fd->ir.irFunc->func;
534 const llvm::FunctionType* functype = func->getFunctionType(); 554 const llvm::FunctionType* functype = func->getFunctionType();
566 irfunction->allocapoint = allocaPoint; 586 irfunction->allocapoint = allocaPoint;
567 587
568 // debug info - after all allocas, but before any llvm.dbg.declare etc 588 // debug info - after all allocas, but before any llvm.dbg.declare etc
569 if (global.params.symdebug) DtoDwarfFuncStart(fd); 589 if (global.params.symdebug) DtoDwarfFuncStart(fd);
570 590
571 // need result variable? (not nested) 591 // need result variable?
572 if (fd->vresult && !fd->vresult->nestedref) { 592 if (fd->vresult) {
573 Logger::println("non-nested vresult value"); 593 Logger::println("vresult value");
574 fd->vresult->ir.irLocal = new IrLocal(fd->vresult); 594 fd->vresult->ir.irLocal = new IrLocal(fd->vresult);
575 fd->vresult->ir.irLocal->value = DtoAlloca(DtoType(fd->vresult->type),"function_vresult"); 595 fd->vresult->ir.irLocal->value = DtoAlloca(DtoType(fd->vresult->type), "function_vresult");
576 } 596 }
577 597
578 // give the 'this' argument storage and debug info 598 // give the 'this' argument storage and debug info
579 // only if not referenced by nested functions 599 if (f->usesThis)
580 if (fd->needThis() && !fd->vthis->nestedref) 600 {
581 { 601 LLValue* thisvar = irfunction->thisArg;
582 LLValue* thisvar = irfunction->thisVar;
583 assert(thisvar); 602 assert(thisvar);
584 603
585 LLValue* thismem = DtoAlloca(thisvar->getType(), ".newthis"); 604 LLValue* thismem = DtoAlloca(thisvar->getType(), ".this");
586 DtoStore(thisvar, thismem); 605 DtoStore(thisvar, thismem);
587 irfunction->thisVar = thismem; 606 irfunction->thisArg = thismem;
607
608 assert(!fd->vthis->ir.irLocal);
609 fd->vthis->ir.irLocal = new IrLocal(fd->vthis);
610 fd->vthis->ir.irLocal->value = thismem;
588 611
589 if (global.params.symdebug) 612 if (global.params.symdebug)
590 DtoDwarfLocalVariable(thismem, fd->vthis); 613 DtoDwarfLocalVariable(thismem, fd->vthis);
614
615 if (fd->vthis->nestedref)
616 fd->nestedVars.insert(fd->vthis);
591 } 617 }
592 618
593 // give arguments storage 619 // give arguments storage
594 // and debug info 620 // and debug info
595 if (fd->parameters) 621 if (fd->parameters)
598 for (int i=0; i < n; ++i) 624 for (int i=0; i < n; ++i)
599 { 625 {
600 Dsymbol* argsym = (Dsymbol*)fd->parameters->data[i]; 626 Dsymbol* argsym = (Dsymbol*)fd->parameters->data[i];
601 VarDeclaration* vd = argsym->isVarDeclaration(); 627 VarDeclaration* vd = argsym->isVarDeclaration();
602 assert(vd); 628 assert(vd);
629
630 if (vd->nestedref)
631 fd->nestedVars.insert(vd);
603 632
604 IrLocal* irloc = vd->ir.irLocal; 633 IrLocal* irloc = vd->ir.irLocal;
605 assert(irloc); 634 assert(irloc);
606 635
607 bool refoutlazy = vd->storage_class & (STCref | STCout | STClazy); 636 bool refoutlazy = vd->storage_class & (STCref | STCout | STClazy);
608 637
609 if (vd->nestedref || refoutlazy) 638 if (refoutlazy)
610 { 639 {
611 continue; 640 continue;
612 } 641 }
613 else if (DtoIsPassedByRef(vd->type)) 642 else if (DtoIsPassedByRef(vd->type))
614 { 643 {
623 DtoStore(a,v); 652 DtoStore(a,v);
624 irloc->value = v; 653 irloc->value = v;
625 } 654 }
626 } 655 }
627 656
628 LLValue* parentNested = NULL;
629 if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) {
630 if (!fd->isStatic()) // huh?
631 parentNested = fd2->ir.irFunc->nestedVar;
632 }
633
634 // need result variable? (nested) 657 // need result variable? (nested)
635 if (fd->vresult && fd->vresult->nestedref) { 658 if (fd->vresult && fd->vresult->nestedref) {
636 Logger::println("nested vresult value: %s", fd->vresult->toChars()); 659 Logger::println("nested vresult value: %s", fd->vresult->toChars());
637 fd->nestedVars.insert(fd->vresult); 660 fd->nestedVars.insert(fd->vresult);
638 } 661 }
639 662
640 // construct nested variables struct 663 // construct nested variables array
641 if (!fd->nestedVars.empty() || parentNested) { 664 if (!fd->nestedVars.empty())
642 std::vector<const LLType*> nestTypes; 665 {
643 int j = 0; 666 Logger::println("has nested frame");
644 if (parentNested) { 667 // start with add all enclosing parent frames
645 nestTypes.push_back(parentNested->getType()); 668 int nparelems = 0;
646 j++; 669 Dsymbol* par = fd->toParent2();
647 } 670 while (par)
648 for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) { 671 {
672 if (FuncDeclaration* parfd = par->isFuncDeclaration())
673 {
674 nparelems += parfd->nestedVars.size();
675 }
676 else if (ClassDeclaration* parcd = par->isClassDeclaration())
677 {
678 // nothing needed
679 }
680 else
681 {
682 break;
683 }
684 par = par->toParent2();
685 }
686 int nelems = fd->nestedVars.size() + nparelems;
687
688 // make array type for nested vars
689 const LLType* nestedVarsTy = LLArrayType::get(getVoidPtrType(), nelems);
690
691 // alloca it
692 LLValue* nestedVars = DtoAlloca(nestedVarsTy, ".nested_vars");
693
694 // copy parent frame into beginning
695 if (nparelems)
696 {
697 LLValue* src = irfunction->nestArg;
698 if (!src)
699 {
700 assert(irfunction->thisArg);
701 assert(fd->isMember2());
702 LLValue* thisval = DtoLoad(irfunction->thisArg);
703 ClassDeclaration* cd = fd->isMember2()->isClassDeclaration();
704 assert(cd);
705 assert(cd->vthis);
706 src = DtoLoad(DtoGEPi(thisval, 0,2+cd->vthis->ir.irField->index, ".vthis"));
707 }
708 DtoMemCpy(nestedVars, src, DtoConstSize_t(nparelems*PTRSIZE));
709 }
710
711 // store in IrFunction
712 irfunction->nestedVar = nestedVars;
713
714 // go through all nested vars and assign indices
715 int idx = nparelems;
716 for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i)
717 {
649 VarDeclaration* vd = *i; 718 VarDeclaration* vd = *i;
650 Logger::println("referenced nested variable %s", vd->toChars());
651 if (!vd->ir.irLocal) 719 if (!vd->ir.irLocal)
652 vd->ir.irLocal = new IrLocal(vd); 720 vd->ir.irLocal = new IrLocal(vd);
653 vd->ir.irLocal->nestedIndex = j++; 721
654 if (vd->isParameter()) { 722 if (vd->isParameter())
655 if (!vd->ir.irLocal->value) { 723 {
656 assert(vd == fd->vthis); 724 Logger::println("nested param: %s", vd->toChars());
657 vd->ir.irLocal->value = fd->ir.irFunc->thisVar; 725 LLValue* gep = DtoGEPi(nestedVars, 0, idx);
658 } 726 LLValue* val = DtoBitCast(vd->ir.irLocal->value, getVoidPtrType());
659 assert(vd->ir.irLocal->value); 727 DtoStore(val, gep);
660 nestTypes.push_back(vd->ir.irLocal->value->getType()); 728 }
661 } 729 else
662 else { 730 {
663 nestTypes.push_back(DtoType(vd->type)); 731 Logger::println("nested var: %s", vd->toChars());
664 } 732 }
665 } 733
666 const llvm::StructType* nestSType = llvm::StructType::get(nestTypes); 734 vd->ir.irLocal->nestedIndex = idx++;
667 Logger::cout() << "nested var struct has type:" << *nestSType << '\n'; 735 }
668 fd->ir.irFunc->nestedVar = DtoAlloca(nestSType,"nestedvars"); 736
669 if (parentNested) { 737 // fixup nested result variable
670 assert(fd->ir.irFunc->thisVar); 738 if (fd->vresult && fd->vresult->nestedref) {
671 LLValue* ptr = gIR->ir->CreateBitCast(fd->ir.irFunc->thisVar, parentNested->getType(), "tmp"); 739 Logger::println("nested vresult value: %s", fd->vresult->toChars());
672 gIR->ir->CreateStore(ptr, DtoGEPi(fd->ir.irFunc->nestedVar, 0,0, "tmp")); 740 LLValue* gep = DtoGEPi(nestedVars, 0, fd->vresult->ir.irLocal->nestedIndex);
673 } 741 LLValue* val = DtoBitCast(fd->vresult->ir.irLocal->value, getVoidPtrType());
674 for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) { 742 DtoStore(val, gep);
675 VarDeclaration* vd = *i;
676 if (vd->isParameter()) {
677 assert(vd->ir.irLocal);
678 gIR->ir->CreateStore(vd->ir.irLocal->value, DtoGEPi(fd->ir.irFunc->nestedVar, 0, vd->ir.irLocal->nestedIndex, "tmp"));
679 vd->ir.irLocal->value = fd->ir.irFunc->nestedVar;
680 }
681 } 743 }
682 } 744 }
683 745
684 // copy _argptr to a memory location 746 // copy _argptr to a memory location
685 if (f->linkage == LINKd && f->varargs == 1) 747 if (f->linkage == LINKd && f->varargs == 1)
686 { 748 {
687 LLValue* argptrmem = DtoAlloca(fd->ir.irFunc->_argptr->getType(), "_argptrmem"); 749 LLValue* argptrmem = DtoAlloca(fd->ir.irFunc->_argptr->getType(), "_argptr_mem");
688 new llvm::StoreInst(fd->ir.irFunc->_argptr, argptrmem, gIR->scopebb()); 750 new llvm::StoreInst(fd->ir.irFunc->_argptr, argptrmem, gIR->scopebb());
689 fd->ir.irFunc->_argptr = argptrmem; 751 fd->ir.irFunc->_argptr = argptrmem;
690 } 752 }
691 753
692 // output function body 754 // output function body
782 844
783 // ref/out arg 845 // ref/out arg
784 if (fnarg && ((fnarg->storageClass & STCref) || (fnarg->storageClass & STCout))) 846 if (fnarg && ((fnarg->storageClass & STCref) || (fnarg->storageClass & STCout)))
785 { 847 {
786 if (arg->isVar() || arg->isLRValue()) 848 if (arg->isVar() || arg->isLRValue())
787 arg = new DImValue(argexp->type, arg->getLVal(), false); 849 arg = new DImValue(argexp->type, arg->getLVal());
788 else 850 else
789 arg = new DImValue(argexp->type, arg->getRVal(), false); 851 arg = new DImValue(argexp->type, arg->getRVal());
790 } 852 }
791 // byval arg, but expr has no storage yet 853 // byval arg, but expr has no storage yet
792 else if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isComplex() || arg->isNull())) 854 else if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isComplex() || arg->isNull()))
793 { 855 {
794 LLValue* alloc = DtoAlloca(DtoType(argexp->type), "tmpparam"); 856 LLValue* alloc = DtoAlloca(DtoType(argexp->type), ".tmp_arg");
795 DVarValue* vv = new DVarValue(argexp->type, alloc, true); 857 DVarValue* vv = new DVarValue(argexp->type, alloc, true);
796 DtoAssign(argexp->loc, vv, arg); 858 DtoAssign(argexp->loc, vv, arg);
797 arg = vv; 859 arg = vv;
798 } 860 }
799 861