mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-04-18 09:49:02 +02:00
Fixed deal breaker bug for more-at-once compilation when any module contained aggregates. Fixes ticket #272 .
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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<VarDeclaration> 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
|
||||
|
||||
@@ -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<VarDeclaration> 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)
|
||||
|
||||
@@ -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<VarDeclaration> 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?
|
||||
|
||||
@@ -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<VarDeclaration> 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);
|
||||
|
||||
|
||||
18
ir/irvar.cpp
18
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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user