changeset 1592:91af6d05338c

Fix codegen for foreach with ref value being lowered to for.
author Christian Kamm <kamm incasoftware de>
date Sat, 07 Nov 2009 13:51:05 +0100
parents eaf87e36ce0d
children b0dfdd5f6006
files gen/llvmhelpers.cpp
diffstat 1 files changed, 19 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/gen/llvmhelpers.cpp	Sat Nov 07 11:16:09 2009 +0100
+++ b/gen/llvmhelpers.cpp	Sat Nov 07 13:51:05 2009 +0100
@@ -908,17 +908,18 @@
                 DtoNestedInit(vd);
             }
             // normal stack variable, allocate storage on the stack if it has not already been done
-            else if(!vd->ir.irLocal) {
+            else if(!vd->ir.irLocal && !vd->isRef()) {
+                vd->ir.irLocal = new IrLocal(vd);
+
                 const LLType* lltype = DtoType(vd->type);
 
                 llvm::Value* allocainst;
-                if(gTargetData->getTypeSizeInBits(lltype) == 0) 
+                if(gTargetData->getTypeSizeInBits(lltype) == 0)
                     allocainst = llvm::ConstantPointerNull::get(getPtrToType(lltype));
                 else
                     allocainst = DtoAlloca(vd->type, vd->toChars());
 
                 //allocainst->setAlignment(vd->type->alignsize()); // TODO
-                vd->ir.irLocal = new IrLocal(vd);
                 vd->ir.irLocal->value = allocainst;
 
                 if (global.params.symdebug)
@@ -926,6 +927,21 @@
                     DtoDwarfLocalVariable(allocainst, vd);
                 }
             }
+            else if(vd->isRef())
+            {
+                // ref vardecls are generated when DMD lowers foreach to a for statement,
+                // and this is a hack to support them for this case only
+                if (!vd->ir.irLocal)
+                    vd->ir.irLocal = new IrLocal(vd);
+                    
+                ExpInitializer* ex = vd->init->isExpInitializer();
+                assert(ex && "ref vars must have expression initializer");
+                assert(ex->exp);
+                AssignExp* as = dynamic_cast<AssignExp*>(ex->exp);
+                assert(as && "ref vars must be initialized by an assign exp");
+                vd->ir.irLocal->value = as->e2->toElem(gIR)->getLVal();
+                return new DVarValue(vd->type, vd, vd->ir.getIrValue());
+            }
             else
             {
                 assert(vd->ir.irLocal->value);