diff --git a/gen/runtime.cpp b/gen/runtime.cpp index c0cde0a1..02292200 100644 --- a/gen/runtime.cpp +++ b/gen/runtime.cpp @@ -145,6 +145,14 @@ static const llvm::Type* rt_array(const llvm::Type* elemty) return rt_ptr(llvm::StructType::get(t)); } +static const llvm::Type* rt_array2(const llvm::Type* elemty) +{ + std::vector t; + t.push_back(DtoSize_t()); + t.push_back(rt_ptr(elemty)); + return llvm::StructType::get(t); +} + static const llvm::Type* rt_dg1() { std::vector types; @@ -705,7 +713,7 @@ static void LLVM_D_BuildRuntimeModule() { std::string fname("_d_switch_string"); std::vector types; - types.push_back(rt_array(stringTy)); + types.push_back(rt_array(rt_array2(byteTy))); types.push_back(stringTy); const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); @@ -715,7 +723,7 @@ static void LLVM_D_BuildRuntimeModule() { std::string fname("_d_switch_ustring"); std::vector types; - types.push_back(rt_array(wstringTy)); + types.push_back(rt_array(rt_array2(shortTy))); types.push_back(wstringTy); const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); @@ -725,7 +733,7 @@ static void LLVM_D_BuildRuntimeModule() { std::string fname("_d_switch_dstring"); std::vector types; - types.push_back(rt_array(dstringTy)); + types.push_back(rt_array(rt_array2(intTy))); types.push_back(dstringTy); const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M); diff --git a/gen/statements.cpp b/gen/statements.cpp index 8c49e66d..b1a4138b 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -602,8 +602,27 @@ static llvm::Value* call_string_switch_runtime(llvm::GlobalVariable* table, Expr llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname); std::vector args; + Logger::cout() << *table->getType() << '\n'; + Logger::cout() << *fn->getFunctionType()->getParamType(0) << '\n'; + assert(table->getType() == fn->getFunctionType()->getParamType(0)); args.push_back(table); - args.push_back(e->toElem(gIR)->getRVal()); + + DValue* val = e->toElem(gIR); + llvm::Value* llval; + if (DSliceValue* sval = val->isSlice()) + { + // give storage + llval = new llvm::AllocaInst(DtoType(e->type), "tmp", gIR->topallocapoint()); + DVarValue* vv = new DVarValue(e->type, llval, true); + DtoAssign(vv, val); + } + else + { + llval = val->getRVal(); + } + assert(llval->getType() == fn->getFunctionType()->getParamType(1)); + args.push_back(llval); + return gIR->ir->CreateCall(fn, args.begin(), args.end(), "tmp"); } diff --git a/gen/toir.cpp b/gen/toir.cpp index 13ffd01d..cd8093bd 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1510,6 +1510,9 @@ DValue* ThisExp::toElem(IRState* p) v = p->func()->decl->ir.irFunc->thisVar; if (llvm::isa(v)) v = new llvm::LoadInst(v, "tmp", p->scopebb()); + const llvm::Type* t = DtoType(type); + if (v->getType() != t) + v = DtoBitCast(v, t, "tmp"); return new DThisValue(vd, v); } @@ -1680,7 +1683,7 @@ DValue* CmpExp::toElem(IRState* p) Type* t = DtoDType(e1->type); Type* e2t = DtoDType(e2->type); - assert(t == e2t); + assert(DtoType(t) == DtoType(e2t)); llvm::Value* eval = 0;