Mercurial > projects > ldc
diff gen/toir.cpp @ 100:5071469303d4 trunk
[svn r104] TONS OF FIXES.
Split up declaration, constant initializer gen and definition for globals, structs, classes and functions.
Improved ClassInfo support (not complete), not in vtable yet.
Fixed a bunch of forward reference problems.
Much more. Major commit! :)
author | lindquist |
---|---|
date | Fri, 16 Nov 2007 08:21:47 +0100 |
parents | a676a7743642 |
children | 169fda3a77d4 |
line wrap: on
line diff
--- a/gen/toir.cpp Thu Nov 15 00:24:44 2007 +0100 +++ b/gen/toir.cpp Fri Nov 16 08:21:47 2007 +0100 @@ -26,6 +26,7 @@ #include "gen/runtime.h" #include "gen/arrays.h" #include "gen/structs.h" +#include "gen/classes.h" #include "gen/dvalue.h" @@ -52,7 +53,7 @@ // referenced by nested delegate? if (vd->nestedref) { Logger::println("has nestedref set"); - vd->llvmValue = p->func().decl->llvmNested; + vd->llvmValue = p->func()->decl->llvmNested; assert(vd->llvmValue); assert(vd->llvmNestedIndex >= 0); } @@ -119,7 +120,7 @@ { Logger::println("Id::_arguments"); if (!vd->llvmValue) - vd->llvmValue = p->func().decl->llvmArguments; + vd->llvmValue = p->func()->decl->llvmArguments; assert(vd->llvmValue); return new DVarValue(vd, vd->llvmValue, true); } @@ -128,7 +129,7 @@ { Logger::println("Id::_argptr"); if (!vd->llvmValue) - vd->llvmValue = p->func().decl->llvmArgPtr; + vd->llvmValue = p->func()->decl->llvmArgPtr; assert(vd->llvmValue); return new DVarValue(vd, vd->llvmValue, true); } @@ -154,6 +155,13 @@ m = tid->llvmValue; return new DVarValue(vd, m, true); } + // classinfo + else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration()) + { + Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars()); + assert(cid->cd->llvmClass); + return new DVarValue(vd, cid->cd->llvmClass, true); + } // nested variable else if (vd->nestedref) { Logger::println("nested variable"); @@ -165,7 +173,7 @@ if (!vd->llvmValue) { // TODO: determine this properly // this happens when the DMD frontend generates by pointer wrappers for struct opEquals(S) and opCmp(S) - vd->llvmValue = &p->func().func->getArgumentList().back(); + vd->llvmValue = &p->func()->func->getArgumentList().back(); } if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->llvmValue)) { return new DVarValue(vd, vd->llvmValue, true); @@ -177,9 +185,11 @@ } else { // take care of forward references of global variables - if (!vd->llvmTouched && (vd->isDataseg() || (vd->storage_class & STCextern))) // !vd->onstack) + if (vd->isDataseg() || (vd->storage_class & STCextern)) { vd->toObjFile(); - if (!vd->llvmValue) { + DtoConstInitGlobal(vd); + } + if (!vd->llvmValue || vd->llvmValue->getType()->isAbstract()) { Logger::println("global variable not resolved :/ %s", vd->toChars()); assert(0); } @@ -224,6 +234,8 @@ Logger::print("Sym: type=%s\n", sdecltype->toChars()); assert(sdecltype->ty == Tstruct); TypeStruct* ts = (TypeStruct*)sdecltype; + ts->sym->toObjFile(); + DtoConstInitStruct(ts->sym); assert(ts->sym->llvmInitZ); return ts->sym->llvmInitZ; } @@ -1220,7 +1232,7 @@ // nested call else if (dfn && dfn->func && dfn->func->isNested()) { Logger::println("Nested Call"); - llvm::Value* contextptr = p->func().decl->llvmNested; + llvm::Value* contextptr = p->func()->decl->llvmNested; assert(contextptr); llargs[j] = p->ir->CreateBitCast(contextptr, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp"); ++j; @@ -1330,6 +1342,9 @@ else if (dfn && dfn->cc != (unsigned)-1) { call->setCallingConv(dfn->cc); } + else if (llvm::isa<llvm::LoadInst>(funcval)) { + call->setCallingConv(DtoCallingConv(dlink)); + } return new DImValue(type, retllval, isInPlace); } @@ -1445,9 +1460,8 @@ DValue* v = e1->toElem(p); if (v->isField()) return v; - if (DFuncValue* fv = v->isFunc()) - { - Logger::println("FuncDeclaration"); + else if (DFuncValue* fv = v->isFunc()) { + //Logger::println("FuncDeclaration"); FuncDeclaration* fd = fv->func; assert(fd); if (fd->llvmValue == 0) @@ -1562,7 +1576,7 @@ LOG_SCOPE; if (VarDeclaration* vd = var->isVarDeclaration()) { - llvm::Value* v = p->func().decl->llvmThisVar; + llvm::Value* v = p->func()->decl->llvmThisVar; if (llvm::isa<llvm::AllocaInst>(v)) v = new llvm::LoadInst(v, "tmp", p->scopebb()); return new DThisValue(vd, v); @@ -2023,7 +2037,9 @@ llvm::Value* a = DtoArgument(fn->getFunctionType()->getParamType(i+1), fnarg, ex); ctorargs.push_back(a); } - emem = new llvm::CallInst(fn, ctorargs.begin(), ctorargs.end(), "tmp", p->scopebb()); + llvm::CallInst* call = new llvm::CallInst(fn, ctorargs.begin(), ctorargs.end(), "tmp", p->scopebb()); + call->setCallingConv(DtoCallingConv(LINKd)); + emem = call; } } else if (ntype->ty == Tstruct) { @@ -2505,7 +2521,7 @@ llvm::Value* context = DtoGEPi(lval,0,0,"tmp",p->scopebb()); const llvm::PointerType* pty = isaPointer(context->getType()->getContainedType(0)); - llvm::Value* llvmNested = p->func().decl->llvmNested; + llvm::Value* llvmNested = p->func()->decl->llvmNested; if (llvmNested == NULL) { llvm::Value* nullcontext = llvm::ConstantPointerNull::get(pty); p->ir->CreateStore(nullcontext, context); @@ -2539,6 +2555,8 @@ Logger::cout() << "array literal has llvm type: " << *t << '\n'; llvm::Value* mem = 0; + bool inplace_slice = false; + if (!p->topexp() || p->topexp()->e2 != this) { assert(DtoDType(type)->ty == Tsarray); mem = new llvm::AllocaInst(t,"arrayliteral",p->topallocapoint()); @@ -2548,6 +2566,7 @@ if (DSliceValue* sv = tlv->isSlice()) { assert(sv->len == 0); mem = sv->ptr; + inplace_slice = true; } else { mem = p->topexp()->v->getLVal(); @@ -2556,6 +2575,7 @@ if (!isaPointer(mem->getType()) || !isaArray(mem->getType()->getContainedType(0))) { + assert(!inplace_slice); assert(ty->ty == Tarray); // we need to give this array literal storage const llvm::ArrayType* arrty = llvm::ArrayType::get(DtoType(ty->next), elements->dim); @@ -2582,7 +2602,7 @@ } } - if (ty->ty == Tsarray) + if (ty->ty == Tsarray || (ty->ty == Tarray && inplace_slice)) return new DImValue(type, mem, true); else if (ty->ty == Tarray) return new DSliceValue(type, DtoConstSize_t(elements->dim), DtoGEPi(mem,0,0,"tmp"));