# HG changeset patch # User lindquist # Date 1193532366 -7200 # Node ID f918f3e2e99eddc4a9864f014380885a17124fe5 # Parent 0c5f410d973c09fe9c6ab0ed0578d4b8e449b4fe [svn r71] Fixed accessing parent function arguments from inside nested delegates. Some cleanups in VarExp::toElem. diff -r 0c5f410d973c -r f918f3e2e99e gen/toir.c --- a/gen/toir.c Sun Oct 28 02:03:42 2007 +0200 +++ b/gen/toir.c Sun Oct 28 02:46:06 2007 +0200 @@ -113,10 +113,6 @@ { Logger::println("VarDeclaration %s", vd->toChars()); - if (vd->nestedref) { - Logger::println("has nested ref"); - } - // _arguments if (vd->ident == Id::_arguments) { @@ -124,7 +120,6 @@ assert(vd->llvmValue); e->mem = vd->llvmValue; e->type = elem::VAR; - return e; } // _argptr else if (vd->ident == Id::_argptr) @@ -133,54 +128,39 @@ assert(vd->llvmValue); e->mem = vd->llvmValue; e->type = elem::VAR; - return e; } - - // needed to take care of forward references of global variables - if (!vd->llvmTouched && vd->isDataseg()) - vd->toObjFile(); - - if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) + // _dollar + else if (vd->ident == Id::dollar) + { + assert(!p->arrays.empty()); + llvm::Value* tmp = LLVM_DtoGEPi(p->arrays.back(),0,0,"tmp",p->scopebb()); + e->val = new llvm::LoadInst(tmp,"tmp",p->scopebb()); + e->type = elem::VAL; + } + // typeinfo + else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) { Logger::println("TypeInfoDeclaration"); + tid->toObjFile(); + assert(tid->llvmValue); + const llvm::Type* vartype = LLVM_DtoType(type); + if (tid->llvmValue->getType() != llvm::PointerType::get(vartype)) + e->mem = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp"); + else + e->mem = tid->llvmValue; + e->type = elem::VAR; } - - // this must be a dollar expression or some other magic value - // 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()) - { - llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - //llvm::Value* tmp = new llvm::GetElementPtrInst(p->arrays.back(),zero,zero,"tmp",p->scopebb()); - llvm::Value* tmp = LLVM_DtoGEP(p->arrays.back(),zero,zero,"tmp",p->scopebb()); - e->val = new llvm::LoadInst(tmp,"tmp",p->scopebb()); - e->type = elem::VAL; - } - // typeinfo - else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) - { - tid->toObjFile(); - assert(tid->llvmValue); - e->val = tid->llvmValue; - e->type = elem::VAR; - } - // global forward ref - else { - Logger::println("unsupported magic: %s\n", vd->toChars()); - assert(0 && "only magic supported is $, _arguments, _argptr"); - } - return e; + // nested variable + else if (vd->nestedref) { + e->mem = LLVM_DtoNestedVariable(vd); + e->type = elem::VAR; + e->vardecl = vd; } - // function parameter - if (vd->storage_class & STCparameter) { - assert(!vd->nestedref); + else if (vd->isParameter()) { Logger::println("function param"); - if (vd->storage_class & (STCref | STCout)) { + assert(vd->llvmValue); + if (vd->isRef() || vd->isOut()) { e->mem = vd->llvmValue; e->type = elem::VAR; } @@ -205,30 +185,16 @@ } } else { - // nested variable - if (vd->nestedref) { - e->mem = LLVM_DtoNestedVariable(vd); - } - // normal local variable - else { - if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) { - Logger::println("typeinfo varexp"); - const llvm::Type* vartype = LLVM_DtoType(type); - if (tid->llvmValue->getType() != llvm::PointerType::get(vartype)) { - e->mem = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp"); - } - else { - e->mem = tid->llvmValue; - } - Logger::cout() << "got:" << '\n' << *tid->llvmValue << "returned:" << '\n' << *e->mem << '\n'; - } - else { - e->mem = vd->llvmValue; - } - } + // take care of forward references of global variables + if (!vd->llvmTouched && vd->isDataseg()) + vd->toObjFile(); + assert(vd->llvmValue); + e->mem = vd->llvmValue; e->vardecl = vd; e->type = elem::VAR; } + + assert(e->mem || e->val); } else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) { @@ -238,7 +204,6 @@ e->val = fdecl->llvmValue; e->type = elem::FUNC; e->funcdecl = fdecl; - return e; } else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) { @@ -256,7 +221,6 @@ assert(0 && "Unimplemented VarExp type"); } - assert(e->mem || e->val); return e; } @@ -1260,10 +1224,12 @@ call->setCallingConv(LLVM_DtoCallingConv(dlink)); } } - else if (delegateCall) + else if (delegateCall) { call->setCallingConv(LLVM_DtoCallingConv(dlink)); - else if (fn->callconv != (unsigned)-1) + } + else if (fn->callconv != (unsigned)-1) { call->setCallingConv(fn->callconv); + } delete fn; return e; diff -r 0c5f410d973c -r f918f3e2e99e gen/tollvm.c --- a/gen/tollvm.c Sun Oct 28 02:03:42 2007 +0200 +++ b/gen/tollvm.c Sun Oct 28 02:46:06 2007 +0200 @@ -1306,7 +1306,10 @@ // on this stack if (fd == f) { - return LLVM_DtoGEPi(vd->llvmValue,0,unsigned(vd->llvmNestedIndex),"tmp"); + llvm::Value* v = LLVM_DtoGEPi(vd->llvmValue,0,unsigned(vd->llvmNestedIndex),"tmp"); + if (vd->isParameter() && (vd->isRef() || vd->isOut())) + v = gIR->ir->CreateLoad(v,"tmp"); + return v; } // on a caller stack @@ -1325,7 +1328,10 @@ while (f) { if (fd == f) { - return LLVM_DtoGEPi(ptr,0,vd->llvmNestedIndex,"tmp"); + llvm::Value* v = LLVM_DtoGEPi(ptr,0,vd->llvmNestedIndex,"tmp"); + if (vd->isParameter() && (vd->isRef() || vd->isOut())) + v = gIR->ir->CreateLoad(v,"tmp"); + return v; } else { ptr = LLVM_DtoGEPi(ptr,0,0,"tmp"); diff -r 0c5f410d973c -r f918f3e2e99e gen/toobj.c --- a/gen/toobj.c Sun Oct 28 02:03:42 2007 +0200 +++ b/gen/toobj.c Sun Oct 28 02:46:06 2007 +0200 @@ -769,7 +769,13 @@ for (std::set::iterator i=llvmNestedVars.begin(); i!=llvmNestedVars.end(); ++i) { VarDeclaration* vd = *i; vd->llvmNestedIndex = j++; - nestTypes.push_back(LLVM_DtoType(vd->type)); + if (vd->isParameter()) { + assert(vd->llvmValue); + nestTypes.push_back(vd->llvmValue->getType()); + } + else { + nestTypes.push_back(LLVM_DtoType(vd->type)); + } } const llvm::StructType* nestSType = llvm::StructType::get(nestTypes); Logger::cout() << "nested var struct has type:" << '\n' << *nestSType; @@ -779,6 +785,12 @@ llvm::Value* ptr = gIR->ir->CreateBitCast(llvmThisVar, parentNested->getType(), "tmp"); gIR->ir->CreateStore(ptr, LLVM_DtoGEPi(llvmNested, 0,0, "tmp")); } + for (std::set::iterator i=llvmNestedVars.begin(); i!=llvmNestedVars.end(); ++i) { + VarDeclaration* vd = *i; + if (vd->isParameter()) { + gIR->ir->CreateStore(vd->llvmValue, LLVM_DtoGEPi(llvmNested, 0, vd->llvmNestedIndex, "tmp")); + } + } } // copy _argptr to a memory location diff -r 0c5f410d973c -r f918f3e2e99e test/nested1.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/nested1.d Sun Oct 28 02:46:06 2007 +0200 @@ -0,0 +1,13 @@ +module nested1; + +void func(int i) +{ + (){ + assert(i == 3); + }(); +} + +void main() +{ + func(3); +} diff -r 0c5f410d973c -r f918f3e2e99e test/nested2.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/nested2.d Sun Oct 28 02:46:06 2007 +0200 @@ -0,0 +1,16 @@ +module nested2; + +void func(ref int i) +{ + delegate { + assert(i == 3); + i++; + }(); +} + +void main() +{ + int i = 3; + func(i); + assert(i == 4); +}