comparison gen/statements.c @ 32:a86fe7496b58 trunk

[svn r36] * Fixed a bug where passing a regular argument to a ref argument did not allocate storage
author lindquist
date Thu, 04 Oct 2007 18:24:05 +0200
parents 37a4fdab33fc
children bc641b23a714
comparison
equal deleted inserted replaced
31:2841234d2aea 32:a86fe7496b58
614 p->scope() = IRScope(endbb,oldend); 614 p->scope() = IRScope(endbb,oldend);
615 } 615 }
616 616
617 ////////////////////////////////////////////////////////////////////////////// 617 //////////////////////////////////////////////////////////////////////////////
618 618
619 void ForeachStatement::toIR(IRState* p)
620 {
621 Logger::println("ForeachStatement::toIR(): %s", toChars());
622 LOG_SCOPE;
623
624 //assert(arguments->dim == 1);
625 assert(key == 0);
626 assert(value != 0);
627 assert(body != 0);
628 assert(aggr != 0);
629 assert(func != 0);
630
631 //Argument* arg = (Argument*)arguments->data[0];
632 //Logger::println("Argument is %s", arg->toChars());
633
634 Logger::println("aggr = %s", aggr->toChars());
635 Logger::println("func = %s", func->toChars());
636
637 elem* arr = aggr->toElem(p);
638 llvm::Value* val = arr->getValue();
639 Logger::cout() << "aggr2llvm = " << *val << '\n';
640
641 llvm::Value* numiters = 0;
642
643 const llvm::Type* keytype = key ? LLVM_DtoType(key->type) : LLVM_DtoSize_t();
644 llvm::Value* keyvar = new llvm::AllocaInst(keytype, "foreachkey", p->topallocapoint());
645
646 const llvm::Type* valtype = LLVM_DtoType(value->type);
647 llvm::Value* valvar = new llvm::AllocaInst(keytype, "foreachval", p->topallocapoint());
648
649 if (aggr->type->ty == Tsarray)
650 {
651 assert(llvm::isa<llvm::PointerType>(val->getType()));
652 assert(llvm::isa<llvm::ArrayType>(val->getType()->getContainedType(0)));
653 size_t n = llvm::cast<llvm::ArrayType>(val->getType()->getContainedType(0))->getNumElements();
654 assert(n > 0);
655 numiters = llvm::ConstantInt::get(keytype,n,false);
656 }
657 else
658 {
659 assert(0);
660 }
661
662 if (op == TOKforeach)
663 {
664 new llvm::StoreInst(llvm::ConstantInt::get(keytype,0,false), keyvar, p->scopebb());
665 }
666 else if (op == TOKforeach_reverse)
667 {
668 llvm::Value* v = llvm::BinaryOperator::createSub(numiters, llvm::ConstantInt::get(keytype,1,false),"tmp",p->scopebb());
669 new llvm::StoreInst(v, keyvar, p->scopebb());
670 }
671 else
672 assert(0);
673
674 delete arr;
675
676 llvm::BasicBlock* oldend = gIR->scopeend();
677 llvm::BasicBlock* begbb = new llvm::BasicBlock("foreachbegin", p->topfunc(), oldend);
678 llvm::BasicBlock* nexbb = new llvm::BasicBlock("foreachnext", p->topfunc(), oldend);
679 llvm::BasicBlock* endbb = new llvm::BasicBlock("foreachend", p->topfunc(), oldend);
680
681 new llvm::BranchInst(begbb, p->scopebb());
682
683 // begin
684 p->scope() = IRScope(begbb,nexbb);
685
686 value->llvmValue = LLVM_DtoGEP(val,llvm::ConstantInt::get(keytype,0,false),keyvar,"tmp",p->scopebb());
687
688 // body
689 body->toIR(p);
690
691 // next
692 p->scope() = IRScope(nexbb,endbb);
693 new llvm::BranchInst(endbb, p->scopebb());
694
695 // end
696 if (!p->scope().returned)
697 new llvm::BranchInst(endbb, p->scopebb());
698 p->scope() = IRScope(endbb,oldend);
699 }
700
701 //////////////////////////////////////////////////////////////////////////////
702
619 ////////////////////////////////////////////////////////////////////////////// 703 //////////////////////////////////////////////////////////////////////////////
620 704
621 #define STUBST(x) void x::toIR(IRState * p) {error("Statement type "#x" not implemented: %s", toChars());fatal();} 705 #define STUBST(x) void x::toIR(IRState * p) {error("Statement type "#x" not implemented: %s", toChars());fatal();}
622 //STUBST(BreakStatement); 706 //STUBST(BreakStatement);
623 //STUBST(ForStatement); 707 //STUBST(ForStatement);
629 STUBST(CaseStatement); 713 STUBST(CaseStatement);
630 //STUBST(SwitchStatement); 714 //STUBST(SwitchStatement);
631 STUBST(SwitchErrorStatement); 715 STUBST(SwitchErrorStatement);
632 STUBST(Statement); 716 STUBST(Statement);
633 //STUBST(IfStatement); 717 //STUBST(IfStatement);
634 STUBST(ForeachStatement); 718 //STUBST(ForeachStatement);
635 //STUBST(DoStatement); 719 //STUBST(DoStatement);
636 //STUBST(WhileStatement); 720 //STUBST(WhileStatement);
637 //STUBST(ExpStatement); 721 //STUBST(ExpStatement);
638 //STUBST(CompoundStatement); 722 //STUBST(CompoundStatement);
639 //STUBST(ScopeStatement); 723 //STUBST(ScopeStatement);