From ca4f588c0843b09992e49d0c4b86ddd60be0b845 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Thu, 7 May 2009 02:10:29 +0200 Subject: [PATCH] Fixed deal breaker bug for more-at-once compilation when any module contained aggregates. Fixes ticket #272 . --- dmd/declaration.c | 5 +++++ dmd/declaration.h | 8 +++++++- gen/classes.cpp | 12 ++++++++++++ gen/structs.cpp | 12 ++++++++++++ ir/irtypeclass.cpp | 18 ++---------------- ir/irtypestruct.cpp | 19 ++----------------- ir/irvar.cpp | 18 +++++++++++++----- ir/irvar.h | 2 +- 8 files changed, 54 insertions(+), 40 deletions(-) diff --git a/dmd/declaration.c b/dmd/declaration.c index 6fd93f40..de03c958 100644 --- a/dmd/declaration.c +++ b/dmd/declaration.c @@ -624,10 +624,15 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer canassign = 0; value = NULL; +#if IN_LLVM + aggrIndex = 0; + // LDC anonDecl = NULL; offset2 = 0; + nakedUse = false; +#endif } Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) diff --git a/dmd/declaration.h b/dmd/declaration.h index e02cf77f..55ad6865 100644 --- a/dmd/declaration.h +++ b/dmd/declaration.h @@ -290,9 +290,15 @@ struct VarDeclaration : Declaration /// Codegen traversal virtual void codegen(Ir* ir); - // LDC + /// Index into parent aggregate. + /// Set during type generation. + unsigned aggrIndex; + + // FIXME: we're not using these anymore! AnonDeclaration* anonDecl; unsigned offset2; + + /// This var is used by a naked function. bool nakedUse; #endif }; diff --git a/gen/classes.cpp b/gen/classes.cpp index 366292bb..f492af73 100644 --- a/gen/classes.cpp +++ b/gen/classes.cpp @@ -53,6 +53,18 @@ void DtoResolveClass(ClassDeclaration* cd) IrStruct* irstruct = new IrStruct(cd); cd->ir.irStruct = irstruct; + // make sure all fields really get their ir field + ArrayIter it(cd->fields); + for (; !it.done(); it.next()) + { + VarDeclaration* vd = it.get(); + if (vd->ir.irField == NULL) { + new IrField(vd); + } else { + IF_LOG Logger::println("class field already exists!!!"); + } + } + bool needs_def = mustDefineSymbol(cd); // emit the ClassZ symbol diff --git a/gen/structs.cpp b/gen/structs.cpp index 79d258cd..9bfdc5a7 100644 --- a/gen/structs.cpp +++ b/gen/structs.cpp @@ -44,6 +44,18 @@ void DtoResolveStruct(StructDeclaration* sd) IrStruct* irstruct = new IrStruct(sd); sd->ir.irStruct = irstruct; + // make sure all fields really get their ir field + ArrayIter it(sd->fields); + for (; !it.done(); it.next()) + { + VarDeclaration* vd = it.get(); + if (vd->ir.irField == NULL) { + new IrField(vd); + } else { + IF_LOG Logger::println("struct field already exists!!!"); + } + } + // perform definition bool needs_def = mustDefineSymbol(sd); if (needs_def) diff --git a/ir/irtypeclass.cpp b/ir/irtypeclass.cpp index d55484b9..1373c64c 100644 --- a/ir/irtypeclass.cpp +++ b/ir/irtypeclass.cpp @@ -159,22 +159,8 @@ void IrTypeClass::addBaseClassData( offset = vd->offset + vd->type->size(); // create ir field - if (vd->ir.irField == NULL) - new IrField(vd, field_index); - else - assert(vd->ir.irField->index == field_index && - vd->ir.irField->unionOffset == 0 && - "inconsistent field data"); - field_index++; - } - - // make sure all fields really get their ir field - ArrayIter it(base->fields); - for (; !it.done(); it.next()) - { - VarDeclaration* vd = it.get(); - if (vd->ir.irField == NULL) - new IrField(vd, 0, vd->offset); + vd->aggrIndex = (unsigned)field_index; + ++field_index; } // any interface implementations? diff --git a/ir/irtypestruct.cpp b/ir/irtypestruct.cpp index 94127ce5..9b08d4fa 100644 --- a/ir/irtypestruct.cpp +++ b/ir/irtypestruct.cpp @@ -208,14 +208,8 @@ const llvm::Type* IrTypeStruct::buildType() // advance offset to right past this field offset = vd->offset + vd->type->size(); - // create ir field - if (vd->ir.irField == NULL) - new IrField(vd, field_index); - else - assert(vd->ir.irField->index == field_index && - vd->ir.irField->unionOffset == 0 && - "inconsistent field data"); - field_index++; + // set the field index + vd->aggrIndex = (unsigned)field_index++; } // tail padding? @@ -224,15 +218,6 @@ const llvm::Type* IrTypeStruct::buildType() add_zeros(defaultTypes, sd->structsize - offset); } - // make sure all fields really get their ir field - ArrayIter it(sd->fields); - for (; !it.done(); it.next()) - { - VarDeclaration* vd = it.get(); - if (vd->ir.irField == NULL) - new IrField(vd, 0, vd->offset); - } - // build the llvm type const llvm::Type* st = llvm::StructType::get(defaultTypes, packed); diff --git a/ir/irvar.cpp b/ir/irvar.cpp index b0b463b1..515c5c72 100644 --- a/ir/irvar.cpp +++ b/ir/irvar.cpp @@ -36,14 +36,22 @@ IrLocal::IrLocal(VarDeclaration* v) : IrVar(v) ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// -IrField::IrField(VarDeclaration* v, size_t idx, size_t offset) : IrVar(v) +IrField::IrField(VarDeclaration* v) : IrVar(v) { - index = idx; - unionOffset = offset; - constInit = NULL; - assert(V->ir.irField == NULL && "field for this variable already exists"); V->ir.irField = this; + + if (v->aggrIndex) + { + index = v->aggrIndex; + unionOffset = 0; + } + else + { + index = 0; + unionOffset = v->offset; + } + constInit = NULL; } extern LLConstant* get_default_initializer( diff --git a/ir/irvar.h b/ir/irvar.h index d1c18c10..23223297 100644 --- a/ir/irvar.h +++ b/ir/irvar.h @@ -34,7 +34,7 @@ struct IrLocal : IrVar // represents an aggregate field variable struct IrField : IrVar { - IrField(VarDeclaration* v, size_t idx, size_t offset = 0); + IrField(VarDeclaration* v); unsigned index; unsigned unionOffset;