comparison gen/statements.cpp @ 715:30b42a283c8e

Removed TypeOpaque from DMD. Changed runtime functions taking opaque[] to void[]. Implemented proper type painting, to avoid "resizing" array casts in runtime calls that previously took opaque[]. Implemented dynamic arrays as first class types, this implements proper ABI for these types on x86. Added dwarf region end after call to assert function, fixes some problems with llvm not allowing this to be missing. Reverted change to WithStatement from rev [704] it breaks MiniD, mini/with2.d needs to be fixed some other way... Fixed tango bug 1339 in runtime, problem with _adReverseChar on invalid UTF-8. Disabled .bc generation in the compiler runtime part, genobj.d triggers some llvm bug when using debug info. the .o seems to work fine.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Wed, 22 Oct 2008 14:55:33 +0200
parents 43165a082535
children cc8ba72c0350
comparison
equal deleted inserted replaced
714:1e98c99a87cb 715:30b42a283c8e
674 Case* c2 = (Case*)obj; 674 Case* c2 = (Case*)obj;
675 return str->compare(c2->str); 675 return str->compare(c2->str);
676 } 676 }
677 }; 677 };
678 678
679 static LLValue* call_string_switch_runtime(llvm::GlobalVariable* table, Expression* e) 679 static LLValue* call_string_switch_runtime(llvm::Value* table, Expression* e)
680 { 680 {
681 Type* dt = e->type->toBasetype(); 681 Type* dt = e->type->toBasetype();
682 Type* dtnext = dt->next->toBasetype(); 682 Type* dtnext = dt->next->toBasetype();
683 TY ty = dtnext->ty; 683 TY ty = dtnext->ty;
684 const char* fname; 684 const char* fname;
703 Logger::cout() << *fn->getFunctionType()->getParamType(0) << '\n'; 703 Logger::cout() << *fn->getFunctionType()->getParamType(0) << '\n';
704 } 704 }
705 assert(table->getType() == fn->getFunctionType()->getParamType(0)); 705 assert(table->getType() == fn->getFunctionType()->getParamType(0));
706 706
707 DValue* val = e->toElem(gIR); 707 DValue* val = e->toElem(gIR);
708 LLValue* llval; 708 LLValue* llval = val->getRVal();
709 if (DSliceValue* sval = val->isSlice())
710 {
711 // give storage
712 llval = DtoAlloca(DtoType(e->type), "tmp");
713 DVarValue* vv = new DVarValue(e->type, llval);
714 DtoAssign(e->loc, vv, val);
715 }
716 else
717 {
718 llval = val->getRVal();
719 }
720 assert(llval->getType() == fn->getFunctionType()->getParamType(1)); 709 assert(llval->getType() == fn->getFunctionType()->getParamType(1));
721 710
722 CallOrInvoke* call = gIR->CreateCallOrInvoke2(fn, table, llval, "tmp"); 711 CallOrInvoke* call = gIR->CreateCallOrInvoke2(fn, table, llval, "tmp");
723
724 llvm::AttrListPtr palist;
725 palist = palist.addAttr(1, llvm::Attribute::ByVal);
726 palist = palist.addAttr(2, llvm::Attribute::ByVal);
727 call->setAttributes(palist);
728 712
729 return call->get(); 713 return call->get();
730 } 714 }
731 715
732 void SwitchStatement::toIR(IRState* p) 716 void SwitchStatement::toIR(IRState* p)
746 cs->bodyBB = NULL; 730 cs->bodyBB = NULL;
747 cs->llvmIdx = NULL; 731 cs->llvmIdx = NULL;
748 } 732 }
749 733
750 // string switch? 734 // string switch?
751 llvm::GlobalVariable* switchTable = 0; 735 llvm::Value* switchTable = 0;
752 Array caseArray; 736 Array caseArray;
753 if (!condition->type->isintegral()) 737 if (!condition->type->isintegral())
754 { 738 {
755 Logger::println("is string switch"); 739 Logger::println("is string switch");
756 // build array of the stringexpS 740 // build array of the stringexpS
788 types.push_back(elemPtrTy); 772 types.push_back(elemPtrTy);
789 const llvm::StructType* sTy = llvm::StructType::get(types); 773 const llvm::StructType* sTy = llvm::StructType::get(types);
790 std::vector<LLConstant*> sinits; 774 std::vector<LLConstant*> sinits;
791 sinits.push_back(DtoConstSize_t(inits.size())); 775 sinits.push_back(DtoConstSize_t(inits.size()));
792 sinits.push_back(arrPtr); 776 sinits.push_back(arrPtr);
793 LLConstant* sInit = llvm::ConstantStruct::get(sTy, sinits); 777 switchTable = llvm::ConstantStruct::get(sTy, sinits);
794
795 switchTable = new llvm::GlobalVariable(sTy, true, llvm::GlobalValue::InternalLinkage, sInit, ".string_switch_table", gIR->module);
796 } 778 }
797 779
798 // body block 780 // body block
799 llvm::BasicBlock* bodybb = llvm::BasicBlock::Create("switchbody", p->topfunc(), oldend); 781 llvm::BasicBlock* bodybb = llvm::BasicBlock::Create("switchbody", p->topfunc(), oldend);
800 782
1171 assert(exp); 1153 assert(exp);
1172 assert(body); 1154 assert(body);
1173 1155
1174 DValue* e = exp->toElem(p); 1156 DValue* e = exp->toElem(p);
1175 1157
1158 #if 1
1159 // this doesn't handle the mini/with2.d test case ...
1160 assert(!wthis->ir.isSet());
1161 wthis->ir.irLocal = new IrLocal(wthis);
1162 wthis->ir.irLocal->value = DtoAlloca(DtoType(wthis->type), wthis->toChars());
1163 #else
1164 // ... this does, but it also silently breaks MiniD!!!
1176 DtoDeclarationExp(wthis); 1165 DtoDeclarationExp(wthis);
1166 #endif
1167
1177 DtoStore(e->getRVal(), wthis->ir.irLocal->value); 1168 DtoStore(e->getRVal(), wthis->ir.irLocal->value);
1178 1169
1179 body->toIR(p); 1170 body->toIR(p);
1180 } 1171 }
1181 1172
1267 Logger::println("SwitchErrorStatement::toIR(): %s", loc.toChars()); 1258 Logger::println("SwitchErrorStatement::toIR(): %s", loc.toChars());
1268 LOG_SCOPE; 1259 LOG_SCOPE;
1269 1260
1270 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_switch_error"); 1261 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_switch_error");
1271 1262
1272 // param attrs
1273 llvm::AttrListPtr palist;
1274 int idx = 1;
1275
1276 std::vector<LLValue*> args; 1263 std::vector<LLValue*> args;
1277 1264
1278 // file param 1265 // file param
1279 args.push_back(gIR->dmodule->ir.irModule->fileName); 1266 args.push_back(DtoLoad(gIR->dmodule->ir.irModule->fileName));
1280 palist = palist.addAttr(idx++, llvm::Attribute::ByVal);
1281 1267
1282 // line param 1268 // line param
1283 LLConstant* c = DtoConstUint(loc.linnum); 1269 LLConstant* c = DtoConstUint(loc.linnum);
1284 args.push_back(c); 1270 args.push_back(c);
1285 1271
1286 // call 1272 // call
1287 CallOrInvoke* call = gIR->CreateCallOrInvoke(fn, args.begin(), args.end()); 1273 CallOrInvoke* call = gIR->CreateCallOrInvoke(fn, args.begin(), args.end());
1288 call->setAttributes(palist);
1289 1274
1290 gIR->ir->CreateUnreachable(); 1275 gIR->ir->CreateUnreachable();
1291 } 1276 }
1292 1277
1293 ////////////////////////////////////////////////////////////////////////////// 1278 //////////////////////////////////////////////////////////////////////////////