changeset 67:f918f3e2e99e trunk

[svn r71] Fixed accessing parent function arguments from inside nested delegates. Some cleanups in VarExp::toElem.
author lindquist
date Sun, 28 Oct 2007 02:46:06 +0200
parents 0c5f410d973c
children c4b3f5d2cd9b
files gen/toir.c gen/tollvm.c gen/toobj.c test/nested1.d test/nested2.d
diffstat 5 files changed, 87 insertions(+), 74 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- 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");
--- 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<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 @@
                         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
--- /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);
+}
--- /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);
+}