comparison gen/functions.cpp @ 468:45a67b6f1310

Removed the 'needsstorage' thing from Dsymbol. Arguments are not always given storage when applicable. This is not longer treat specially in this regard. Code for accessing nested variables and contexts rewritten. Probably more. Fairly well tested.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Mon, 04 Aug 2008 02:59:34 +0200
parents d82ebdba4191
children 672eb4893b55
comparison
equal deleted inserted replaced
467:261b05cf4d1c 468:45a67b6f1310
544 if (fd->fbody == NULL) 544 if (fd->fbody == NULL)
545 return; 545 return;
546 546
547 Logger::println("Doing function body for: %s", fd->toChars()); 547 Logger::println("Doing function body for: %s", fd->toChars());
548 assert(fd->ir.irFunc); 548 assert(fd->ir.irFunc);
549 gIR->functions.push_back(fd->ir.irFunc); 549 IrFunction* irfunction = fd->ir.irFunc;
550 gIR->functions.push_back(irfunction);
550 551
551 if (fd->isMain()) 552 if (fd->isMain())
552 gIR->emitMain = true; 553 gIR->emitMain = true;
553 554
554 std::string entryname("entry_"); 555 std::string entryname("entry_");
560 //assert(gIR->scopes.empty()); 561 //assert(gIR->scopes.empty());
561 gIR->scopes.push_back(IRScope(beginbb, endbb)); 562 gIR->scopes.push_back(IRScope(beginbb, endbb));
562 563
563 // create alloca point 564 // create alloca point
564 llvm::Instruction* allocaPoint = new llvm::AllocaInst(LLType::Int32Ty, "alloca point", beginbb); 565 llvm::Instruction* allocaPoint = new llvm::AllocaInst(LLType::Int32Ty, "alloca point", beginbb);
565 gIR->func()->allocapoint = allocaPoint; 566 irfunction->allocapoint = allocaPoint;
566 567
567 // debug info - after all allocas, but before any llvm.dbg.declare etc 568 // debug info - after all allocas, but before any llvm.dbg.declare etc
568 if (global.params.symdebug) DtoDwarfFuncStart(fd); 569 if (global.params.symdebug) DtoDwarfFuncStart(fd);
569 570
570 // need result variable? (not nested) 571 // need result variable? (not nested)
572 Logger::println("non-nested vresult value"); 573 Logger::println("non-nested vresult value");
573 fd->vresult->ir.irLocal = new IrLocal(fd->vresult); 574 fd->vresult->ir.irLocal = new IrLocal(fd->vresult);
574 fd->vresult->ir.irLocal->value = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint); 575 fd->vresult->ir.irLocal->value = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint);
575 } 576 }
576 577
577 // give 'this' argument debug info (and storage) 578 // give the 'this' argument storage and debug info
578 if (fd->needThis() && global.params.symdebug) 579 // only if not referenced by nested functions
579 { 580 if (fd->needThis() && !fd->vthis->nestedref)
580 LLValue** thisvar = &fd->ir.irFunc->thisVar; 581 {
581 assert(*thisvar); 582 LLValue* thisvar = irfunction->thisVar;
582 LLValue* thismem = new llvm::AllocaInst((*thisvar)->getType(), "newthis", allocaPoint); 583 assert(thisvar);
583 DtoDwarfLocalVariable(thismem, fd->vthis); 584
584 gIR->ir->CreateStore(*thisvar, thismem); 585 LLValue* thismem = new llvm::AllocaInst(thisvar->getType(), ".newthis", allocaPoint);
585 *thisvar = thismem; 586 DtoStore(thisvar, thismem);
587 irfunction->thisVar = thismem;
588
589 if (global.params.symdebug)
590 DtoDwarfLocalVariable(thismem, fd->vthis);
586 } 591 }
587 592
588 // give arguments storage 593 // give arguments storage
594 // and debug info
589 if (fd->parameters) 595 if (fd->parameters)
590 { 596 {
591 size_t n = fd->parameters->dim; 597 size_t n = fd->parameters->dim;
592 for (int i=0; i < n; ++i) 598 for (int i=0; i < n; ++i)
593 { 599 {
594 Dsymbol* argsym = (Dsymbol*)fd->parameters->data[i]; 600 Dsymbol* argsym = (Dsymbol*)fd->parameters->data[i];
595 VarDeclaration* vd = argsym->isVarDeclaration(); 601 VarDeclaration* vd = argsym->isVarDeclaration();
596 assert(vd); 602 assert(vd);
597 603
604 IrLocal* irloc = vd->ir.irLocal;
605 assert(irloc);
606
598 bool refoutlazy = vd->storage_class & (STCref | STCout | STClazy); 607 bool refoutlazy = vd->storage_class & (STCref | STCout | STClazy);
599 608
600 // FIXME: llvm seems to want an alloca/byval for debug info 609 if (vd->nestedref || refoutlazy)
601 if (!vd->needsStorage || vd->nestedref || refoutlazy)
602 { 610 {
603 Logger::println("skipping arg storage for (%s) %s ", vd->loc.toChars(), vd->toChars());
604 continue; 611 continue;
605 } 612 }
606 // static array params don't support debug info it seems
607 // probably because they're not passed byval
608 else if (vd->type->toBasetype()->ty == Tsarray)
609 {
610 Logger::println("skipping arg storage for static array (%s) %s ", vd->loc.toChars(), vd->toChars());
611 continue;
612 }
613 // debug info for normal aggr params seem to work fine
614 else if (DtoIsPassedByRef(vd->type)) 613 else if (DtoIsPassedByRef(vd->type))
615 { 614 {
616 Logger::println("skipping arg storage for aggregate (%s) %s ", vd->loc.toChars(), vd->toChars()); 615 LLValue* vdirval = irloc->value;
617 LLValue* vdirval = vd->ir.getIrValue();
618 if (global.params.symdebug && !(isaArgument(vdirval) && !isaArgument(vdirval)->hasByValAttr())) 616 if (global.params.symdebug && !(isaArgument(vdirval) && !isaArgument(vdirval)->hasByValAttr()))
619 DtoDwarfLocalVariable(vdirval, vd); 617 DtoDwarfLocalVariable(vdirval, vd);
620 continue; 618 continue;
621 } 619 }
622 620
623 LLValue* a = vd->ir.irLocal->value; 621 LLValue* a = irloc->value;
624 assert(a); 622 LLValue* v = new llvm::AllocaInst(a->getType(), "."+a->getName(), allocaPoint);
625 std::string s(a->getName()); 623 DtoStore(a,v);
626 Logger::println("giving argument '%s' storage", s.c_str()); 624 irloc->value = v;
627 s.append("_storage");
628
629 LLValue* v = new llvm::AllocaInst(a->getType(),s,allocaPoint);
630
631 if (global.params.symdebug)
632 DtoDwarfLocalVariable(v, vd);
633
634 gIR->ir->CreateStore(a,v);
635 vd->ir.irLocal->value = v;
636 } 625 }
637 } 626 }
638 627
639 LLValue* parentNested = NULL; 628 LLValue* parentNested = NULL;
640 if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) { 629 if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) {