# HG changeset patch # User Tomas Lindquist Olsen # Date 1225204869 -3600 # Node ID 041c1596d217f6633ff7971d0011786a51f0d558 # Parent e4e50f4b58cd1134fdffcced507024a387e1d8d8 Removed warnings on ignored aligns. Only do aligment on packed structs, align(1) struct Packed { ... } Changed the way struct/class fields are added, first small part of cleaning up these... Make struct/class/union fields aware of any anonymous struct/union they might be part of, not yet really useful, but part of getting better union support. diff -r e4e50f4b58cd -r 041c1596d217 dmd/attrib.c --- a/dmd/attrib.c Mon Oct 27 17:42:38 2008 +0100 +++ b/dmd/attrib.c Tue Oct 28 15:41:09 2008 +0100 @@ -501,9 +501,6 @@ { this->loc = loc; salign = sa; - - if (global.params.warnings && salign != 1) - warning("%s: align(%d) is not implemented and specified to be unportable anyway, use align(1) and manual fillers instead", loc.toChars(), salign); } Dsymbol *AlignDeclaration::syntaxCopy(Dsymbol *s) @@ -517,21 +514,33 @@ void AlignDeclaration::semantic(Scope *sc) { +// LDC +// we only support packed structs, as from the spec: align(1) struct Packed { ... } +// other alignments are simply ignored. my tests show this is what llvm-gcc does too ... + //printf("\tAlignDeclaration::semantic '%s'\n",toChars()); if (decl) { unsigned salign_save = sc->structalign; - sc->structalign = salign; for (unsigned i = 0; i < decl->dim; i++) { Dsymbol *s = (Dsymbol *)decl->data[i]; - s->semantic(sc); + if (s->isStructDeclaration() && salign == 1) + { + sc->structalign = salign; + s->semantic(sc); + sc->structalign = salign_save; + } + else + { + s->semantic(sc); + } } sc->structalign = salign_save; } else - sc->structalign = salign; + assert(0 && "what kind of align use triggers this?"); } @@ -658,12 +667,17 @@ //printf("sc->offset = %d\n", sc->offset); // Add members of aad to ad - //printf("\tadding members of aad to '%s'\n", ad->toChars()); + //printf("\tadding members of aad (%p) to '%s'\n", &aad, ad->toChars()); for (unsigned i = 0; i < aad.fields.dim; i++) { VarDeclaration *v = (VarDeclaration *)aad.fields.data[i]; v->offset += sc->offset; + + // LDC + if (!v->anonDecl) + v->anonDecl = this; + ad->fields.push(v); } diff -r e4e50f4b58cd -r 041c1596d217 dmd/declaration.c --- a/dmd/declaration.c Mon Oct 27 17:42:38 2008 +0100 +++ b/dmd/declaration.c Tue Oct 28 15:41:09 2008 +0100 @@ -621,6 +621,9 @@ onstack = 0; canassign = 0; value = NULL; + + // LDC + anonDecl = NULL; } Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) diff -r e4e50f4b58cd -r 041c1596d217 dmd/declaration.h --- a/dmd/declaration.h Mon Oct 27 17:42:38 2008 +0100 +++ b/dmd/declaration.h Tue Oct 28 15:41:09 2008 +0100 @@ -37,6 +37,7 @@ struct TupleType; struct InterState; struct IRState; +struct AnonDeclaration; enum PROT; enum LINK; @@ -269,6 +270,9 @@ // Eliminate need for dynamic_cast VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } + + // LDC + AnonDeclaration* anonDecl; }; /**************************************************************/ diff -r e4e50f4b58cd -r 041c1596d217 dmd/parse.c --- a/dmd/parse.c Mon Oct 27 17:42:38 2008 +0100 +++ b/dmd/parse.c Tue Oct 28 15:41:09 2008 +0100 @@ -349,6 +349,9 @@ case TOKalign: { unsigned n; + // LDC better align code locations + Loc alignloc = loc; + s = NULL; nextToken(); if (token.value == TOKlparen) @@ -367,7 +370,7 @@ n = global.structalign; // default a = parseBlock(); - s = new AlignDeclaration(loc, n, a); + s = new AlignDeclaration(alignloc, n, a); break; } diff -r e4e50f4b58cd -r 041c1596d217 dmd/scope.h --- a/dmd/scope.h Mon Oct 27 17:42:38 2008 +0100 +++ b/dmd/scope.h Tue Oct 28 15:41:09 2008 +0100 @@ -30,6 +30,7 @@ struct FuncDeclaration; struct DocComment; struct EnclosingHandler; +struct AnonDeclaration; enum LINK; enum PROT; diff -r e4e50f4b58cd -r 041c1596d217 gen/classes.cpp --- a/gen/classes.cpp Mon Oct 27 17:42:38 2008 +0100 +++ b/gen/classes.cpp Tue Oct 28 15:41:09 2008 +0100 @@ -57,7 +57,7 @@ ////////////////////////////////////////////////////////////////////////////////////////// -static void LLVM_AddBaseClassData(BaseClasses* bcs) +static void LLVM_AddBaseClassData(IrStruct* irstruct, BaseClasses* bcs) { // add base class data members first for (int j=0; jdim; j++) @@ -69,7 +69,7 @@ continue; // recursively add baseclass data - LLVM_AddBaseClassData(&bc->base->baseclasses); + LLVM_AddBaseClassData(irstruct, &bc->base->baseclasses); Array* arr = &bc->base->fields; if (arr->dim == 0) @@ -80,7 +80,9 @@ for (int k=0; k < arr->dim; k++) { VarDeclaration* v = (VarDeclaration*)(arr->data[k]); - v->toObjFile(0); // TODO: multiobj + Logger::println("Adding field: %s %s", v->type->toChars(), v->toChars()); + // init fields, used to happen in VarDeclaration::toObjFile + irstruct->addField(v); } } } @@ -143,9 +145,19 @@ fieldtypes.push_back(getVoidPtrType()); // add base class data fields first - LLVM_AddBaseClassData(&cd->baseclasses); + LLVM_AddBaseClassData(irstruct, &cd->baseclasses); - // then add own members, if any + // add own fields + Array* fields = &cd->fields; + for (int k=0; k < fields->dim; k++) + { + VarDeclaration* v = (VarDeclaration*)fields->data[k]; + Logger::println("Adding field: %s %s", v->type->toChars(), v->toChars()); + // init fields, used to happen in VarDeclaration::toObjFile + irstruct->addField(v); + } + + // then add other members of us, if any if(cd->members) { for (int k=0; k < cd->members->dim; k++) { Dsymbol* dsym = (Dsymbol*)(cd->members->data[k]); diff -r e4e50f4b58cd -r 041c1596d217 gen/structs.cpp --- a/gen/structs.cpp Mon Oct 27 17:42:38 2008 +0100 +++ b/gen/structs.cpp Tue Oct 28 15:41:09 2008 +0100 @@ -92,7 +92,7 @@ TypeStruct* ts = (TypeStruct*)sd->type->toBasetype(); // this struct is a forward declaration - // didn't even know had those ... + // didn't even know D had those ... if (sd->sizeok != 1) { sd->ir.irStruct = new IrStruct(ts); @@ -102,10 +102,21 @@ bool ispacked = (ts->alignsize() == 1); + // create the IrStruct IrStruct* irstruct = new IrStruct(ts); sd->ir.irStruct = irstruct; gIR->structs.push_back(irstruct); + // add fields + Array* fields = &sd->fields; + for (int k=0; k < fields->dim; k++) + { + VarDeclaration* v = (VarDeclaration*)fields->data[k]; + Logger::println("Adding field: %s %s", v->type->toChars(), v->toChars()); + // init fields, used to happen in VarDeclaration::toObjFile + irstruct->addField(v); + } + irstruct->packed = ispacked; bool thisModule = false; diff -r e4e50f4b58cd -r 041c1596d217 gen/toobj.cpp --- a/gen/toobj.cpp Mon Oct 27 17:42:38 2008 +0100 +++ b/gen/toobj.cpp Tue Oct 28 15:41:09 2008 +0100 @@ -991,19 +991,10 @@ else gIR->constInitList.push_back(this); } - - // inside aggregate declaration. declare a field. else { - Logger::println("Aggregate var declaration: '%s' offset=%d", toChars(), offset); - - const LLType* _type = DtoType(type); - this->ir.irField = new IrField(this); - - // add the field in the IRStruct - gIR->topstruct()->offsets.insert(std::make_pair(offset, IrStruct::Offset(this, _type))); + assert(ir.irField != 0); } - Logger::println("VarDeclaration::toObjFile is done"); } diff -r e4e50f4b58cd -r 041c1596d217 ir/irstruct.cpp --- a/ir/irstruct.cpp Mon Oct 27 17:42:38 2008 +0100 +++ b/ir/irstruct.cpp Tue Oct 28 15:41:09 2008 +0100 @@ -1,8 +1,12 @@ #include "gen/llvm.h" + #include "mtype.h" #include "aggregate.h" +#include "declaration.h" + #include "ir/irstruct.h" #include "gen/irstate.h" +#include "gen/tollvm.h" IrInterface::IrInterface(BaseClass* b) { @@ -56,3 +60,15 @@ IrStruct::~IrStruct() { } + +void IrStruct::addField(VarDeclaration* v) +{ + // might already have its irField, as classes derive each other without getting copies of the VarDeclaration + if (!v->ir.irField) + { + assert(!v->ir.isSet()); + v->ir.irField = new IrField(v); + } + const LLType* _type = DtoType(v->type); + offsets.insert(std::make_pair(v->offset, IrStruct::Offset(v, _type))); +} diff -r e4e50f4b58cd -r 041c1596d217 ir/irstruct.h --- a/ir/irstruct.h Mon Oct 27 17:42:38 2008 +0100 +++ b/ir/irstruct.h Tue Oct 28 15:41:09 2008 +0100 @@ -53,6 +53,8 @@ IrStruct(Type*); virtual ~IrStruct(); + void addField(VarDeclaration* v); + Type* type; llvm::PATypeHolder recty; OffsetMap offsets;