Mercurial > projects > ldc
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()) { |