changeset 745:5761d7e6f628

Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues (see bug #104), but a separate helper that doesn't initialize would be nicer.
author Christian Kamm <kamm incasoftware de>
date Sat, 01 Nov 2008 16:48:17 +0100
parents ef5f75ae6895
children 693d681c846c
files gen/statements.cpp ir/irlandingpad.cpp
diffstat 2 files changed, 26 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/gen/statements.cpp	Sat Nov 01 14:41:57 2008 +0100
+++ b/gen/statements.cpp	Sat Nov 01 16:48:17 2008 +0100
@@ -154,11 +154,7 @@
         DtoDwarfStopPoint(loc.linnum);
 
     if (match)
-    {
-        LLValue* allocainst = DtoAlloca(DtoType(match->type), "._tmp_if_var");
-        match->ir.irLocal = new IrLocal(match);
-        match->ir.irLocal->value = allocainst;
-    }
+        DtoDeclarationExp(match);
 
     DValue* cond_e = condition->toElem(p);
     LLValue* cond_val = cond_e->getRVal();
@@ -928,24 +924,23 @@
 
     // key
     const LLType* keytype = key ? DtoType(key->type) : DtoSize_t();
-    LLValue* keyvar = DtoAlloca(keytype, "foreachkey");
+    LLValue* keyvar;
     if (key)
     {
-        //key->llvmValue = keyvar;
-        assert(!key->ir.irLocal);
-        key->ir.irLocal = new IrLocal(key);
-        key->ir.irLocal->value = keyvar;
+        DtoDeclarationExp(key);
+        keyvar = key->ir.irLocal->value;
     }
+    else
+        keyvar = DtoAlloca(keytype, "foreachkey");
     LLValue* zerokey = llvm::ConstantInt::get(keytype,0,false);
 
     // value
     Logger::println("value = %s", value->toPrettyChars());
+    DtoDeclarationExp(value);
     const LLType* valtype = DtoType(value->type);
     LLValue* valvar = NULL;
     if (!value->isRef() && !value->isOut())
-        valvar = DtoAlloca(valtype, "foreachval");
-    if (!value->ir.irLocal)
-        value->ir.irLocal = new IrLocal(value);
+        valvar = value->ir.irLocal->value;
 
     // what to iterate
     DValue* aggrval = aggr->toElem(p);
@@ -1155,6 +1150,7 @@
 
     DValue* e = exp->toElem(p);
 
+    // DtoDeclarationExp(wthis); or preferably equivalent without initialization...
     if (wthis->ir.isSet())
     {
         assert(wthis->nestedref);
--- a/ir/irlandingpad.cpp	Sat Nov 01 14:41:57 2008 +0100
+++ b/ir/irlandingpad.cpp	Sat Nov 01 16:48:17 2008 +0100
@@ -15,10 +15,23 @@
 
     // assign storage to catch var
     if(catchstmt->var) {
-        assert(!catchstmt->var->ir.irLocal);
-        catchstmt->var->ir.irLocal = new IrLocal(catchstmt->var);
-        LLValue* catch_var = gIR->func()->landingPad.getExceptionStorage();
-        catchstmt->var->ir.irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchstmt->var->type)));
+        // use the same storage for all exceptions that are not accessed in
+        // nested functions
+        if(!catchstmt->var->nestedref) {
+            assert(!catchstmt->var->ir.irLocal);
+            catchstmt->var->ir.irLocal = new IrLocal(catchstmt->var);
+            LLValue* catch_var = gIR->func()->landingPad.getExceptionStorage();
+            catchstmt->var->ir.irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchstmt->var->type)));
+        }
+
+        // this will alloca if we haven't already and take care of nested refs
+        DtoDeclarationExp(catchstmt->var);
+
+        // the exception will only be stored in catch_var. copy it over if necessary
+        if(catchstmt->var->ir.irLocal->value != gIR->func()->landingPad.getExceptionStorage()) {
+            LLValue* exc = gIR->ir->CreateBitCast(DtoLoad(gIR->func()->landingPad.getExceptionStorage()), DtoType(catchstmt->var->type));
+            DtoStore(exc, catchstmt->var->ir.irLocal->value);
+        }
     }
 
     // emit handler, if there is one