Mercurial > projects > ldc
diff gen/toir.cpp @ 133:44a95ac7368a trunk
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
In particular, assertions has been fixed to include file/line info, and much more!
author | lindquist |
---|---|
date | Mon, 14 Jan 2008 05:11:54 +0100 |
parents | 1700239cab2e |
children | 0e28624814e8 |
line wrap: on
line diff
--- a/gen/toir.cpp Fri Jan 11 17:57:40 2008 +0100 +++ b/gen/toir.cpp Mon Jan 14 05:11:54 2008 +0100 @@ -179,7 +179,7 @@ assert(tid->llvmValue); const llvm::Type* vartype = DtoType(type); llvm::Value* m; - if (tid->llvmValue->getType() != llvm::PointerType::get(vartype)) + if (tid->llvmValue->getType() != getPtrToType(vartype)) m = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp"); else m = tid->llvmValue; @@ -278,7 +278,7 @@ const llvm::Type* vartype = DtoType(type); llvm::Constant* m = isaConstant(ti->llvmValue); assert(m); - if (ti->llvmValue->getType() != llvm::PointerType::get(vartype)) + if (ti->llvmValue->getType() != getPtrToType(vartype)) m = llvm::ConstantExpr::getBitCast(m, vartype); return m; } @@ -403,11 +403,13 @@ Type* cty = DtoDType(dtype->next); const llvm::Type* ct = DtoType(cty); + if (ct == llvm::Type::VoidTy) + ct = llvm::Type::Int8Ty; //printf("ct = %s\n", type->next->toChars()); const llvm::ArrayType* at = llvm::ArrayType::get(ct,len+1); llvm::Constant* _init; - if (cty->ty == Tchar) { + if (cty->ty == Tchar || cty->ty == Tvoid) { uint8_t* str = (uint8_t*)string; std::string cont((char*)str, len); _init = llvm::ConstantArray::get(cont,true); @@ -434,6 +436,7 @@ assert(0); llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; + Logger::cout() << "type: " << *at << "\ninit: " << *_init << '\n'; llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,"stringliteral",gIR->module); llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); @@ -461,7 +464,7 @@ assert(0); } else if (dtype->ty == Tsarray) { - const llvm::Type* dstType = llvm::PointerType::get(llvm::ArrayType::get(ct, len)); + const llvm::Type* dstType = getPtrToType(llvm::ArrayType::get(ct, len)); llvm::Value* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType); return new DVarValue(type, emem, true); } @@ -877,7 +880,7 @@ Type* t = DtoDType(type); const llvm::Type* llt = DtoType(type); if (DtoIsPassedByRef(t)) - llt = llvm::PointerType::get(llt); + llt = getPtrToType(llt); // TODO if (strcmp(global.params.llvmArch, "x86") != 0) { warning("%s: va_arg for C variadic functions is broken for anything but x86", loc.toChars()); @@ -972,7 +975,7 @@ } if (dfn && dfn->func && dfn->func->llvmRunTimeHack) { - const llvm::Type* rettype = llvm::PointerType::get(DtoType(type)); + const llvm::Type* rettype = getPtrToType(DtoType(type)); if (llargs[j]->getType() != llfnty->getParamType(j)) { Logger::println("llvmRunTimeHack==true - force casting return value param"); Logger::cout() << "casting: " << *llargs[j] << " to type: " << *llfnty->getParamType(j) << '\n'; @@ -986,9 +989,9 @@ // this arguments if (dfn && dfn->vthis) { - Logger::println("This Call"); + Logger::cout() << "This Call func val:" << *funcval << '\n'; if (dfn->vthis->getType() != argiter->get()) { - //Logger::cout() << *fn->thisparam << '|' << *argiter->get() << '\n'; + //Logger::cout() << "value: " << *dfn->vthis << " totype: " << *argiter->get() << '\n'; llargs[j] = DtoBitCast(dfn->vthis, argiter->get()); } else { @@ -1010,8 +1013,8 @@ Logger::println("Nested Call"); llvm::Value* contextptr = DtoNestedContext(dfn->func->toParent2()->isFuncDeclaration()); if (!contextptr) - contextptr = llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)); - llargs[j] = DtoBitCast(contextptr, llvm::PointerType::get(llvm::Type::Int8Ty)); + contextptr = llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)); + llargs[j] = DtoBitCast(contextptr, getPtrToType(llvm::Type::Int8Ty)); ++j; ++argiter; } @@ -1025,7 +1028,7 @@ Argument* fnarg = Argument::getNth(tf->parameters, i); Expression* exp = (Expression*)arguments->data[i]; DValue* expelem = exp->toElem(p); - llargs[j] = DtoBitCast(expelem->getLVal(), llvm::PointerType::get(llvm::Type::Int8Ty)); + llargs[j] = DtoBitCast(expelem->getLVal(), getPtrToType(llvm::Type::Int8Ty)); } } // regular arguments @@ -1062,7 +1065,7 @@ // build type info array assert(Type::typeinfo->llvmConstInit); - const llvm::Type* typeinfotype = llvm::PointerType::get(Type::typeinfo->llvmConstInit->getType()); + const llvm::Type* typeinfotype = getPtrToType(Type::typeinfo->llvmConstInit->getType()); Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n'; const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements()); @@ -1081,13 +1084,13 @@ // put data in d-array llvm::Value* typeinfoarrayparam = new llvm::AllocaInst(llfnty->getParamType(j)->getContainedType(0),"_arguments_array",p->topallocapoint()); p->ir->CreateStore(DtoConstSize_t(vtype->getNumElements()), DtoGEPi(typeinfoarrayparam,0,0,"tmp")); - llvm::Value* casttypeinfomem = p->ir->CreateBitCast(typeinfomem, llvm::PointerType::get(typeinfotype), "tmp"); + llvm::Value* casttypeinfomem = p->ir->CreateBitCast(typeinfomem, getPtrToType(typeinfotype), "tmp"); p->ir->CreateStore(casttypeinfomem, DtoGEPi(typeinfoarrayparam,0,1,"tmp")); // specify arguments llargs[j] = typeinfoarrayparam;; j++; - llargs[j] = p->ir->CreateBitCast(mem, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp"); + llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(llvm::Type::Int8Ty), "tmp"); j++; llargs.resize(nimplicit+2); } @@ -1128,14 +1131,14 @@ if (llfnty->getReturnType() != llvm::Type::VoidTy) varname = "tmp"; - Logger::cout() << "Calling: " << *funcval << '\n'; + //Logger::cout() << "Calling: " << *funcval << '\n'; // call the function llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb()); llvm::Value* retllval = (retinptr) ? llargs[0] : call; if (retinptr && dfn && dfn->func && dfn->func->llvmRunTimeHack) { - const llvm::Type* rettype = llvm::PointerType::get(DtoType(type)); + const llvm::Type* rettype = getPtrToType(DtoType(type)); if (retllval->getType() != rettype) { Logger::println("llvmRunTimeHack==true - force casting return value"); Logger::cout() << "from: " << *retllval->getType() << " to: " << *rettype << '\n'; @@ -1243,7 +1246,7 @@ } else { const llvm::Type* elemtype = llvalue->getType()->getContainedType(0)->getContainedType(0); - size_t elemsz = gTargetData->getTypeSize(elemtype); + size_t elemsz = getABITypeSize(elemtype); varmem = DtoGEPi(llvalue, 0, offset / elemsz, "tmp"); } } @@ -1388,8 +1391,14 @@ if (!vthis2) vthis2 = vthis; //unsigned cc = (unsigned)-1; - // virtual call - if (!fdecl->isFinal() && fdecl->isVirtual()) { + // super call + if (e1->op == TOKsuper) { + DtoForceDeclareDsymbol(fdecl); + funcval = fdecl->llvmValue; + assert(funcval); + } + // normal virtual call + else if (fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())) { assert(fdecl->vtblIndex > 0); assert(e1type->ty == Tclass); @@ -1428,7 +1437,8 @@ LOG_SCOPE; if (VarDeclaration* vd = var->isVarDeclaration()) { - llvm::Value* v = p->func()->decl->llvmThisVar; + llvm::Value* v; + v = p->func()->decl->llvmThisVar; if (llvm::isa<llvm::AllocaInst>(v)) v = new llvm::LoadInst(v, "tmp", p->scopebb()); return new DThisValue(vd, v); @@ -1818,7 +1828,7 @@ else if (e1type->isfloating()) { assert(e2type->isfloating()); - llvm::Value* one = llvm::ConstantFP::get(val->getType(), 1.0f); + llvm::Value* one = llvm::ConstantFP::get(val->getType(), llvm::APFloat(1.0f)); if (op == TOKplusplus) { post = llvm::BinaryOperator::createAdd(val,one,"tmp",p->scopebb()); } @@ -1847,113 +1857,47 @@ Type* ntype = DtoDType(newtype); + if (ntype->ty == Tclass) { + return DtoNewClass((TypeClass*)ntype, this); + } + const llvm::Type* t = DtoType(ntype); llvm::Value* emem = 0; bool inplace = false; - { - Logger::println("Allocating memory"); - LOG_SCOPE; - if (onstack) { - assert(ntype->ty == Tclass); - emem = new llvm::AllocaInst(t->getContainedType(0),"tmp",p->topallocapoint()); - } - else if (ntype->ty == Tclass) { - emem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb()); - } - else if (ntype->ty == Tarray) { - assert(arguments); - if (arguments->dim == 1) { - DValue* sz = ((Expression*)arguments->data[0])->toElem(p); - llvm::Value* dimval = sz->getRVal(); - Type* nnt = DtoDType(ntype->next); - if (nnt->ty == Tvoid) - nnt = Type::tint8; - - if (p->topexp() && p->topexp()->e2 == this) { - assert(p->topexp()->v); - emem = p->topexp()->v->getLVal(); - DtoNewDynArray(emem, dimval, nnt); - inplace = true; - } - else { - const llvm::Type* restype = DtoType(type); - Logger::cout() << "restype = " << *restype << '\n'; - emem = new llvm::AllocaInst(restype,"newstorage",p->topallocapoint()); - DtoNewDynArray(emem, dimval, nnt); - return new DVarValue(newtype, emem, true); - } + if (ntype->ty == Tarray) { + assert(arguments); + if (arguments->dim == 1) { + DValue* sz = ((Expression*)arguments->data[0])->toElem(p); + llvm::Value* dimval = sz->getRVal(); + Type* nnt = DtoDType(ntype->next); + if (nnt->ty == Tvoid) + nnt = Type::tint8; + + if (p->topexp() && p->topexp()->e2 == this) { + assert(p->topexp()->v); + emem = p->topexp()->v->getLVal(); + DtoNewDynArray(emem, dimval, nnt); + inplace = true; } else { - assert(0 && "num args to 'new' != 1"); + const llvm::Type* restype = DtoType(type); + Logger::cout() << "restype = " << *restype << '\n'; + emem = new llvm::AllocaInst(restype,"newstorage",p->topallocapoint()); + DtoNewDynArray(emem, dimval, nnt); + return new DVarValue(newtype, emem, true); } } else { - emem = new llvm::MallocInst(t,"tmp",p->scopebb()); + assert(0 && "num args to 'new' != 1"); } } - - if (ntype->ty == Tclass) { - // first apply the static initializer - TypeClass* tc = (TypeClass*)ntype; - DtoInitClass(tc, emem); - - // set the this var for nested classes - if (thisexp) { - Logger::println("Resolving 'this' expression"); - LOG_SCOPE; - DValue* thisval = thisexp->toElem(p); - size_t idx = 2; - idx += tc->sym->llvmIRStruct->interfaces.size(); - llvm::Value* dst = thisval->getRVal(); - llvm::Value* src = DtoGEPi(emem,0,idx,"tmp"); - Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n'; - DtoStore(dst, src); - } - else if (tc->sym->isNested()) - { - Logger::println("Resolving nested context"); - LOG_SCOPE; - size_t idx = 2; - idx += tc->sym->llvmIRStruct->interfaces.size(); - llvm::Value* nest = p->func()->decl->llvmNested; - if (!nest) - nest = p->func()->decl->llvmThisVar; - assert(nest); - llvm::Value* gep = DtoGEPi(emem,0,idx,"tmp"); - nest = DtoBitCast(nest, gep->getType()->getContainedType(0)); - DtoStore(nest, gep); - } - - // then call constructor - if (arguments) { - Logger::println("Calling constructor"); - LOG_SCOPE; - assert(member); - assert(member->llvmValue); - llvm::Function* fn = llvm::cast<llvm::Function>(member->llvmValue); - TypeFunction* tf = (TypeFunction*)DtoDType(member->type); - - std::vector<llvm::Value*> ctorargs; - ctorargs.push_back(emem); - for (size_t i=0; i<arguments->dim; ++i) - { - Expression* ex = (Expression*)arguments->data[i]; - Argument* fnarg = Argument::getNth(tf->parameters, i); - DValue* argval = DtoArgument(fnarg, ex); - llvm::Value* a = argval->getRVal(); - const llvm::Type* aty = fn->getFunctionType()->getParamType(i+1); - if (a->getType() != aty) // this param might have type mismatch - a = DtoBitCast(a, aty); - ctorargs.push_back(a); - } - llvm::CallInst* call = new llvm::CallInst(fn, ctorargs.begin(), ctorargs.end(), "tmp", p->scopebb()); - call->setCallingConv(DtoCallingConv(LINKd)); - emem = call; - } + else { + emem = new llvm::MallocInst(t,"tmp",p->scopebb()); } - else if (ntype->ty == Tstruct) { + + if (ntype->ty == Tstruct) { TypeStruct* ts = (TypeStruct*)ntype; if (ts->isZeroInit()) { DtoStructZeroInit(emem); @@ -2053,12 +1997,33 @@ Logger::print("AssertExp::toElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - DValue* u = e1->toElem(p); - DValue* m = msg ? msg->toElem(p) : NULL; - - DtoAssert(u->getRVal(), &loc, m); - - return 0; + // condition + DValue* cond = e1->toElem(p); + + // create basic blocks + llvm::BasicBlock* oldend = p->scopeend(); + llvm::BasicBlock* assertbb = new llvm::BasicBlock("assert", p->topfunc(), oldend); + llvm::BasicBlock* endbb = new llvm::BasicBlock("endassert", p->topfunc(), oldend); + + // test condition + llvm::Value* condval = cond->getRVal(); + condval = DtoBoolean(condval); + + // branch + new llvm::BranchInst(endbb, assertbb, condval, p->scopebb()); + + // call assert runtime functions + p->scope() = IRScope(assertbb,endbb); + DtoAssert(&loc, msg ? msg->toElem(p) : NULL); + + if (!gIR->scopereturned()) + new llvm::BranchInst(endbb, p->scopebb()); + + // rewrite the scope + p->scope() = IRScope(endbb,oldend); + + // no meaningful return value + return NULL; } ////////////////////////////////////////////////////////////////////////////////////////// @@ -2192,7 +2157,7 @@ Logger::print("HaltExp::toElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - DtoAssert(DtoConstBool(false), &loc, NULL); + DtoAssert(&loc, NULL); new llvm::UnreachableInst(p->scopebb()); return 0; @@ -2207,10 +2172,7 @@ DValue* u = e1->toElem(p); - llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); - - const llvm::Type* int8ptrty = llvm::PointerType::get(llvm::Type::Int8Ty); + const llvm::PointerType* int8ptrty = getPtrToType(llvm::Type::Int8Ty); llvm::Value* lval; if (p->topexp() && p->topexp()->e2 == this) { @@ -2229,21 +2191,32 @@ if (nestvar) uval = nestvar; else - uval = llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)); + uval = llvm::ConstantPointerNull::get(int8ptrty); } else { uval = u->getRVal(); } - llvm::Value* context = DtoGEP(lval,zero,zero,"tmp",p->scopebb()); - llvm::Value* castcontext = DtoBitCast(uval,int8ptrty); - new llvm::StoreInst(castcontext, context, p->scopebb()); - - llvm::Value* fptr = DtoGEP(lval,zero,one,"tmp",p->scopebb()); - - assert(func->llvmValue); - llvm::Value* castfptr = DtoBitCast(func->llvmValue,fptr->getType()->getContainedType(0)); - new llvm::StoreInst(castfptr, fptr, p->scopebb()); + llvm::Value* context = DtoGEPi(lval,0,0,"tmp"); + llvm::Value* castcontext = DtoBitCast(uval, int8ptrty); + DtoStore(castcontext, context); + + llvm::Value* fptr = DtoGEPi(lval,0,1,"tmp"); + + Logger::println("func: '%s'", func->toPrettyChars()); + + llvm::Value* castfptr; + if (func->isVirtual()) + castfptr = DtoVirtualFunctionPointer(u, func); + else if (func->isAbstract()) + assert(0 && "TODO delegate to abstract method"); + else if (func->toParent()->isInterfaceDeclaration()) + assert(0 && "TODO delegate to interface method"); + else + castfptr = func->llvmValue; + + castfptr = DtoBitCast(castfptr, fptr->getType()->getContainedType(0)); + DtoStore(castfptr, fptr); return new DVarValue(type, lval, true); } @@ -2279,7 +2252,7 @@ if (t1->ty == Tpointer && v->isNull() && l->getType() != r->getType()) { r = llvm::ConstantPointerNull::get(isaPointer(l->getType())); } - Logger::cout() << "l = " << *l << " r = " << *r << '\n'; + //Logger::cout() << "l = " << *l << " r = " << *r << '\n'; eval = new llvm::ICmpInst(pred, l, r, "tmp", p->scopebb()); } return new DImValue(type, eval); @@ -2368,9 +2341,9 @@ zero = llvm::ConstantInt::get(val->getType(), 0, true); else if (t->isfloating()) { if (t->ty == Tfloat32 || t->ty == Timaginary32) - zero = llvm::ConstantFP::get(val->getType(), float(0)); + zero = llvm::ConstantFP::get(val->getType(), llvm::APFloat(0.0f)); else if (t->ty == Tfloat64 || t->ty == Tfloat80 || t->ty == Timaginary64 || t->ty == Timaginary80) - zero = llvm::ConstantFP::get(val->getType(), double(0)); + zero = llvm::ConstantFP::get(val->getType(), llvm::APFloat(0.0)); else assert(0); } @@ -2619,11 +2592,11 @@ } const llvm::StructType* t = llvm::StructType::get(tys); if (t != llt) { - if (gTargetData->getTypeSize(t) != gTargetData->getTypeSize(llt)) { - Logger::cout() << "got size " << gTargetData->getTypeSize(t) << ", expected " << gTargetData->getTypeSize(llt) << '\n'; + if (getABITypeSize(t) != getABITypeSize(llt)) { + Logger::cout() << "got size " << getABITypeSize(t) << ", expected " << getABITypeSize(llt) << '\n'; assert(0 && "type size mismatch"); } - sptr = p->ir->CreateBitCast(sptr, llvm::PointerType::get(t), "tmp"); + sptr = DtoBitCast(sptr, getPtrToType(t)); Logger::cout() << "sptr type is now: " << *t << '\n'; } }