[svn r71] Fixed accessing parent function arguments from inside nested delegates.

Some cleanups in VarExp::toElem.
This commit is contained in:
Tomas Lindquist Olsen
2007-10-28 02:46:06 +02:00
parent a5d3910b57
commit feea94424c
5 changed files with 87 additions and 74 deletions

View File

@@ -113,10 +113,6 @@ elem* VarExp::toElem(IRState* p)
{
Logger::println("VarDeclaration %s", vd->toChars());
if (vd->nestedref) {
Logger::println("has nested ref");
}
// _arguments
if (vd->ident == Id::_arguments)
{
@@ -124,7 +120,6 @@ elem* VarExp::toElem(IRState* p)
assert(vd->llvmValue);
e->mem = vd->llvmValue;
e->type = elem::VAR;
return e;
}
// _argptr
else if (vd->ident == Id::_argptr)
@@ -133,54 +128,39 @@ elem* VarExp::toElem(IRState* p)
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 @@ elem* VarExp::toElem(IRState* p)
}
}
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 @@ elem* VarExp::toElem(IRState* p)
e->val = fdecl->llvmValue;
e->type = elem::FUNC;
e->funcdecl = fdecl;
return e;
}
else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration())
{
@@ -256,7 +221,6 @@ elem* VarExp::toElem(IRState* p)
assert(0 && "Unimplemented VarExp type");
}
assert(e->mem || e->val);
return e;
}
@@ -1260,10 +1224,12 @@ elem* CallExp::toElem(IRState* p)
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;

View File

@@ -1306,7 +1306,10 @@ llvm::Value* LLVM_DtoNestedVariable(VarDeclaration* vd)
// 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 @@ llvm::Value* LLVM_DtoNestedVariable(VarDeclaration* vd)
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");

View File

@@ -769,7 +769,13 @@ void FuncDeclaration::toObjFile()
for (std::set<VarDeclaration*>::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 @@ void FuncDeclaration::toObjFile()
llvm::Value* ptr = gIR->ir->CreateBitCast(llvmThisVar, parentNested->getType(), "tmp");
gIR->ir->CreateStore(ptr, LLVM_DtoGEPi(llvmNested, 0,0, "tmp"));
}
for (std::set<VarDeclaration*>::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

13
test/nested1.d Normal file
View File

@@ -0,0 +1,13 @@
module nested1;
void func(int i)
{
(){
assert(i == 3);
}();
}
void main()
{
func(3);
}

16
test/nested2.d Normal file
View File

@@ -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);
}