changeset 800:d14e4594c7d7

Changed aggregate field initializers to be created lazily, fixes problem with static void arrays in aggregates.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sat, 29 Nov 2008 18:28:17 +0100
parents 340acf1535d0
children c8d9b30a0dc2
files gen/classes.cpp gen/structs.cpp ir/irstruct.cpp
diffstat 3 files changed, 11 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/gen/classes.cpp	Sat Nov 29 21:25:43 2008 +0100
+++ b/gen/classes.cpp	Sat Nov 29 18:28:17 2008 +0100
@@ -427,21 +427,6 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-// assigns constant initializers to fields introduced by cd
-static void init_field_inits(ClassDeclaration* cd)
-{
-    size_t n = cd->fields.dim;
-    for (size_t i=0; i<n; i++)
-    {
-        VarDeclaration* v = (VarDeclaration*)cd->fields.data[i];
-        IrField* f = v->ir.irField;
-        assert(!f->constInit);
-        f->constInit = DtoConstFieldInitializer(v->loc, v->type, v->init);
-    }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
 // adds data fields and interface vtables to the constant initializer of class cd
 static size_t init_class_initializer(std::vector<LLConstant*>& inits, ClassDeclaration* target, ClassDeclaration* cd, size_t offsetbegin)
 {
@@ -502,7 +487,9 @@
         }
 
         // add the field
-        assert(var->ir.irField->constInit);
+        // and build its constant initializer lazily
+        if (!var->ir.irField->constInit)
+            var->ir.irField->constInit = DtoConstFieldInitializer(var->loc, var->type, var->init);
         inits.push_back(var->ir.irField->constInit);
 
         lastoffset = offset;
@@ -731,9 +718,6 @@
     const llvm::ArrayType* vtbltype = isaArray(irstruct->vtblTy.get());
     assert(vtbltype);
 
-    // make sure each field knows its default initializer
-    init_field_inits(cd);
-
     // build initializer list
     std::vector<LLConstant*> inits;
     inits.reserve(irstruct->varDecls.size());
--- a/gen/structs.cpp	Sat Nov 29 21:25:43 2008 +0100
+++ b/gen/structs.cpp	Sat Nov 29 18:28:17 2008 +0100
@@ -208,6 +208,8 @@
 
                 // do the default
                 Logger::println("adding default field: %s : +%u", nextdef->toChars(), nextdef->offset);
+                if (!nextdef->ir.irField->constInit)
+                    nextdef->ir.irField->constInit = DtoConstFieldInitializer(nextdef->loc, nextdef->type, nextdef->init);
                 LLConstant* c = nextdef->ir.irField->constInit;
                 inits.push_back(c);
 
@@ -261,6 +263,8 @@
 
             // do the default
             Logger::println("adding default field: %s : +%u", nextdef->toChars(), nextdef->offset);
+            if (!nextdef->ir.irField->constInit)
+                nextdef->ir.irField->constInit = DtoConstFieldInitializer(nextdef->loc, nextdef->type, nextdef->init);
             LLConstant* c = nextdef->ir.irField->constInit;
             inits.push_back(c);
 
@@ -463,15 +467,6 @@
 
     const llvm::StructType* structtype = isaStruct(sd->type->ir.type->get());
 
-    // make sure each offset knows its default initializer
-    Array* fields = &sd->fields;
-    for (int k=0; k < fields->dim; k++)
-    {
-        VarDeclaration* v = (VarDeclaration*)fields->data[k];
-        LLConstant* finit = DtoConstFieldInitializer(v->loc, v->type, v->init);
-        v->ir.irField->constInit = finit;
-    }
-
     // always generate the constant initalizer
     if (sd->zeroInit)
     {
--- a/ir/irstruct.cpp	Sat Nov 29 21:25:43 2008 +0100
+++ b/ir/irstruct.cpp	Sat Nov 29 18:28:17 2008 +0100
@@ -9,6 +9,7 @@
 #include "gen/irstate.h"
 #include "gen/tollvm.h"
 #include "gen/logger.h"
+#include "gen/llvmhelpers.h"
 
 IrInterface::IrInterface(BaseClass* b)
 :   vtblInitTy(llvm::OpaqueType::get())
@@ -318,7 +319,9 @@
             }
 
             // add the field
-            assert(var->ir.irField->constInit);
+            // lazily default initialize
+            if (!var->ir.irField->constInit)
+                var->ir.irField->constInit = DtoConstFieldInitializer(var->loc, var->type, var->init);
             inits.push_back(var->ir.irField->constInit);
 
             lastoffset = offset;