changeset 1186:7562457bb7f3

Automated merge with http://hg.dsource.org/projects/ldc
author Frits van Bommel <fvbommel wxs.nl>
date Wed, 01 Apr 2009 00:13:21 +0200
parents a6dbd571d417 (current diff) 8baf611f0009 (diff)
children a95fc9fcad5c
files
diffstat 6 files changed, 68 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/gen/llvmhelpers.cpp	Tue Mar 31 20:21:28 2009 +0200
+++ b/gen/llvmhelpers.cpp	Wed Apr 01 00:13:21 2009 +0200
@@ -1075,7 +1075,7 @@
 }
 
 // does pretty much the same as DtoDeclarationExp, except it doesn't initialize, and only handles var declarations
-LLValue* DtoRawVarDeclaration(VarDeclaration* var)
+LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr)
 {
     // we don't handle globals with this one
     assert(!var->isDataseg());
@@ -1083,10 +1083,6 @@
     // we don't handle aliases either
     assert(!var->aliassym);
         
-    // if this already has storage, it must've been handled already
-    if (var->ir.irLocal && var->ir.irLocal->value)
-        return var->ir.irLocal->value;
-
     // referenced by nested function?
 #if DMDV2
     if (var->nestedrefs.dim)
@@ -1095,10 +1091,10 @@
 #endif
     {
         assert(var->ir.irLocal);
-        assert(!var->ir.irLocal->value);
-
-        // alloca
-        var->ir.irLocal->value = DtoAlloca(DtoType(var->type), var->toChars());
+        if(!var->ir.irLocal->value)
+            var->ir.irLocal->value = addr ? addr : DtoAlloca(DtoType(var->type), var->toChars());
+        else
+            assert(!addr || addr == var->ir.irLocal->value);
 
         // store the address into the nested vars array
         assert(var->ir.irLocal->nestedIndex >= 0);
@@ -1110,9 +1106,15 @@
     // normal local variable
     else
     {
+        // if this already has storage, it must've been handled already
+        if (var->ir.irLocal && var->ir.irLocal->value) {
+            assert(!addr || addr == var->ir.irLocal->value);
+            return var->ir.irLocal->value;
+        }
+
         assert(!var->ir.isSet());
         var->ir.irLocal = new IrLocal(var);
-        var->ir.irLocal->value = DtoAlloca(DtoType(var->type), var->toChars());
+        var->ir.irLocal->value = addr ? addr : DtoAlloca(DtoType(var->type), var->toChars());
     }
 
     // add debug info
--- a/gen/llvmhelpers.h	Tue Mar 31 20:21:28 2009 +0200
+++ b/gen/llvmhelpers.h	Wed Apr 01 00:13:21 2009 +0200
@@ -101,7 +101,7 @@
 
 // declaration inside a declarationexp
 DValue* DtoDeclarationExp(Dsymbol* declaration);
-LLValue* DtoRawVarDeclaration(VarDeclaration* var);
+LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr = 0);
 
 // initializer helpers
 LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init);
--- a/gen/statements.cpp	Tue Mar 31 20:21:28 2009 +0200
+++ b/gen/statements.cpp	Wed Apr 01 00:13:21 2009 +0200
@@ -1030,11 +1030,12 @@
 
     // value
     Logger::println("value = %s", value->toPrettyChars());
-    DtoRawVarDeclaration(value);
-    const LLType* valtype = DtoType(value->type);
     LLValue* valvar = NULL;
-    if (!value->isRef() && !value->isOut())
+    if (!value->isRef() && !value->isOut()) {
+        // Create a local variable to serve as the value.
+        DtoRawVarDeclaration(value);
         valvar = value->ir.irLocal->value;
+    }
 
     // what to iterate
     DValue* aggrval = aggr->toElem(p);
@@ -1093,13 +1094,17 @@
     // get value for this iteration
     LLConstant* zero = llvm::ConstantInt::get(keytype,0,false);
     LLValue* loadedKey = p->ir->CreateLoad(keyvar,"tmp");
-    value->ir.irLocal->value = DtoGEP1(val,loadedKey);
+    LLValue* gep = DtoGEP1(val,loadedKey);
 
     if (!value->isRef() && !value->isOut()) {
+        // Copy value to local variable, and use it as the value variable.
         DVarValue dst(value->type, valvar);
-        DVarValue src(value->type, value->ir.irLocal->value);
+        DVarValue src(value->type, gep);
         DtoAssign(loc, &dst, &src);
         value->ir.irLocal->value = valvar;
+    } else {
+        // Use the GEP as the address of the value variable.
+        DtoRawVarDeclaration(value, gep);
     }
 
     // emit body
--- a/tests/mini/compile_rawvardeclinfinally.d	Tue Mar 31 20:21:28 2009 +0200
+++ b/tests/mini/compile_rawvardeclinfinally.d	Wed Apr 01 00:13:21 2009 +0200
@@ -1,1 +1,8 @@
-void foo() { void delegate()[] bar; try {} finally { foreach (dg; bar) dg(); } }
+void foo() {
+    void delegate()[] bar;
+    try {
+    } finally {
+        foreach (dg; bar)
+            dg();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/mini/foreach10.d	Wed Apr 01 00:13:21 2009 +0200
@@ -0,0 +1,19 @@
+module foreach10;
+
+extern(C) int printf(char*, ...);
+
+void main() {
+    char* last = null;
+    printf("The addresses should increment:\n");
+    foreach (ref c; "bar") {
+        auto a = {
+            printf("%x '%c'\n", c, c);
+            return &c;
+        };
+        auto nw = a();
+        printf("ptr = %p\n", nw);
+        if (last != null)
+            assert(nw == last+1);
+        last = nw;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/mini/foreach11.d	Wed Apr 01 00:13:21 2009 +0200
@@ -0,0 +1,18 @@
+module foreach11;
+
+extern(C) int printf(char*, ...);
+
+void main() {
+    char* last = null;
+    printf("The addresses should remain constant:\n");
+    foreach (c; "bar") {
+        auto a = {
+            printf("%x '%c'\n", c, c);
+            printf("ptr = %p\n", &c);
+            if (last)
+                assert(last == &c);
+        };
+        a();
+        last = &c;
+    }
+}