Mercurial > projects > ldc
diff gen/toir.c @ 50:6fcc08a4d406 trunk
[svn r54] Added support for nested delegates referencing parent's stack variables.
Replaced tester.sh with a version written in D.
A few bugfixes.
author | lindquist |
---|---|
date | Mon, 22 Oct 2007 15:40:56 +0200 |
parents | e5c4bece7fa1 |
children | 61bc1b4ad3c4 |
line wrap: on
line diff
--- a/gen/toir.c Fri Oct 19 17:43:46 2007 +0200 +++ b/gen/toir.c Mon Oct 22 15:40:56 2007 +0200 @@ -41,20 +41,29 @@ { Logger::println("VarDeclaration"); + // static if (vd->isDataseg()) { vd->toObjFile(); } else { - // allocate storage on the stack Logger::println("vdtype = %s", vd->type->toChars()); - const llvm::Type* lltype = LLVM_DtoType(vd->type); - llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint()); - //allocainst->setAlignment(vd->type->alignsize()); // TODO - vd->llvmValue = allocainst; - // e->val = really needed?? - + // referenced by nested delegate? + if (vd->nestedref) { + Logger::println("has nestedref set"); + vd->llvmValue = p->func().decl->llvmNested; + assert(vd->llvmValue); + assert(vd->llvmNestedIndex >= 0); + } + // normal stack variable + else { + // allocate storage on the stack + const llvm::Type* lltype = LLVM_DtoType(vd->type); + llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint()); + //allocainst->setAlignment(vd->type->alignsize()); // TODO + vd->llvmValue = allocainst; + } LLVM_DtoInitializer(vd->init); } } @@ -97,7 +106,11 @@ if (VarDeclaration* vd = var->isVarDeclaration()) { Logger::println("VarDeclaration"); - + + if (vd->nestedref) { + Logger::println("has nested ref"); + } + // needed to take care of forward references of global variables if (!vd->llvmTouched && vd->isDataseg()) vd->toObjFile(); @@ -111,6 +124,8 @@ // or it could be a forward declaration of a global variable if (!vd->llvmValue) { + assert(!vd->nestedref); + Logger::println("special - no llvmValue"); // dollar if (!p->arrays.empty()) { @@ -137,6 +152,7 @@ // function parameter if (vd->storage_class & STCparameter) { + assert(!vd->nestedref); Logger::println("function param"); if (vd->storage_class & (STCref | STCout)) { e->mem = vd->llvmValue; @@ -163,8 +179,31 @@ } } else { - e->mem = vd->llvmValue; - //e->mem->setName(toChars()); + // nested variable + if (vd->nestedref) { + /* + FuncDeclaration* fd = vd->toParent()->isFuncDeclaration(); + assert(fd != NULL); + llvm::Value* ptr = NULL; + // inside nested function + if (fd != p->func().decl) { + ptr = p->func().decl->llvmThisVar; + Logger::cout() << "nested var reference:" << '\n' << *ptr << *vd->llvmValue->getType() << '\n'; + ptr = p->ir->CreateBitCast(ptr, vd->llvmValue->getType(), "tmp"); + } + // inside the actual parent function + else { + ptr = vd->llvmValue; + } + assert(ptr); + e->mem = LLVM_DtoGEPi(ptr,0,unsigned(vd->llvmNestedIndex),"tmp",p->scopebb()); + */ + e->mem = LLVM_DtoNestedVariable(vd); + } + // normal local variable + else { + e->mem = vd->llvmValue; + } e->vardecl = vd; e->type = elem::VAR; } @@ -1283,13 +1322,16 @@ Logger::println("VarDeclaration"); assert(vd->llvmValue); Type* t = LLVM_DtoDType(type); - Type* vdtype = LLVM_DtoDType(vd->type); + Type* vdtype = LLVM_DtoDType(vd->type); + + llvm::Value* llvalue = vd->nestedref ? LLVM_DtoNestedVariable(vd) : vd->llvmValue; + if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) { TypeStruct* vdt = (TypeStruct*)vdtype; e = new elem; std::vector<unsigned> dst(1,0); vdt->sym->offsetToIndex(t->next, offset, dst); - llvm::Value* ptr = vd->llvmValue; + llvm::Value* ptr = llvalue; assert(ptr); e->mem = LLVM_DtoGEP(ptr,dst,"tmp",p->scopebb()); e->type = elem::VAL; @@ -1302,17 +1344,14 @@ e = new elem; llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); //llvm::Value* idx1 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); - e->mem = LLVM_DtoGEP(vd->llvmValue,idx0,idx0,"tmp",p->scopebb()); - e->arg = vd->llvmValue; + e->mem = LLVM_DtoGEP(llvalue,idx0,idx0,"tmp",p->scopebb()); + e->arg = llvalue; e->type = elem::VAL; } else if (offset == 0) { - /*if (!vd->llvmValue) - vd->toObjFile();*/ - assert(vd->llvmValue); e = new elem; - e->mem = vd->llvmValue; - //e->vardecl = vd; + assert(llvalue); + e->mem = llvalue; e->type = elem::VAL; } else { @@ -1326,7 +1365,6 @@ if (fd->llvmValue == 0) fd->toObjFile(); e->val = fd->llvmValue; - //e->aspointer = true; e->type = elem::FUNC; } assert(e != 0); @@ -2595,13 +2633,29 @@ fd->toObjFile(); - llvm::Value* lval = p->toplval(); + llvm::Value* lval = NULL; + if (p->lvals.empty() || p->toplval() == NULL) { + const llvm::Type* dgty = LLVM_DtoType(type); + Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n'; + lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint()); + } + else { + lval = p->toplval(); + } elem* e = new elem; llvm::Value* context = LLVM_DtoGEPi(lval,0,0,"tmp",p->scopebb()); - //llvm::Value* castcontext = llvm::ConstantPointerNull::get(context->getType()); - //new llvm::StoreInst(castcontext, context, p->scopebb()); + const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(context->getType()->getContainedType(0)); + llvm::Value* llvmNested = p->func().decl->llvmNested; + if (llvmNested == NULL) { + llvm::Value* nullcontext = llvm::ConstantPointerNull::get(pty); + p->ir->CreateStore(nullcontext, context); + } + else { + llvm::Value* nestedcontext = p->ir->CreateBitCast(llvmNested, pty, "tmp"); + p->ir->CreateStore(nestedcontext, context); + } llvm::Value* fptr = LLVM_DtoGEPi(lval,0,1,"tmp",p->scopebb()); @@ -2610,6 +2664,8 @@ new llvm::StoreInst(castfptr, fptr, p->scopebb()); e->inplace = true; + e->mem = lval; + e->type = elem::VAR; return e; }