changeset 737:041c1596d217

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.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 28 Oct 2008 15:41:09 +0100
parents e4e50f4b58cd
children 96484f5bf5af
files dmd/attrib.c dmd/declaration.c dmd/declaration.h dmd/parse.c dmd/scope.h gen/classes.cpp gen/structs.cpp gen/toobj.cpp ir/irstruct.cpp ir/irstruct.h
diffstat 10 files changed, 81 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- 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);
 	}
 
--- 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)
--- 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;
 };
 
 /**************************************************************/
--- 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;
 	    }
 
--- 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;
 
--- 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; j<bcs->dim; 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]);
--- 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;
--- 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");
 }
 
--- 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)));
+}
--- 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;