changeset 1029:4d366a75d95f

Added hasUnalignedFields helper to check if a type has unaligned fields - as per request from fvbommel. Result is cached in TypeStruct.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 03 Mar 2009 15:08:26 +0100
parents 964af20461a9
children 3ead5c40b7d6
files dmd/mtype.c dmd/mtype.h dmd2/mtype.c dmd2/mtype.h gen/llvmhelpers.cpp gen/llvmhelpers.h
diffstat 6 files changed, 49 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/mtype.c	Tue Mar 03 14:10:37 2009 +0100
+++ b/dmd/mtype.c	Tue Mar 03 15:08:26 2009 +0100
@@ -4278,6 +4278,9 @@
 	: Type(Tstruct, NULL)
 {
     this->sym = sym;
+
+    // LDC
+    this->unaligned = 0;
 }
 
 char *TypeStruct::toChars()
--- a/dmd/mtype.h	Tue Mar 03 14:10:37 2009 +0100
+++ b/dmd/mtype.h	Tue Mar 03 15:08:26 2009 +0100
@@ -542,6 +542,11 @@
     int hasPointers();
 
     type *toCtype();
+
+    // LDC
+    // cache the hasUnalignedFields check
+    // 0 = not checked, 1 = aligned, 2 = unaligned
+    int unaligned;
 };
 
 struct TypeEnum : Type
--- a/dmd2/mtype.c	Tue Mar 03 14:10:37 2009 +0100
+++ b/dmd2/mtype.c	Tue Mar 03 15:08:26 2009 +0100
@@ -4929,6 +4929,9 @@
 	: Type(Tstruct)
 {
     this->sym = sym;
+
+    // LDC
+    this->unaligned = 0;
 }
 
 char *TypeStruct::toChars()
--- a/dmd2/mtype.h	Tue Mar 03 14:10:37 2009 +0100
+++ b/dmd2/mtype.h	Tue Mar 03 15:08:26 2009 +0100
@@ -628,6 +628,11 @@
 #endif
 
     type *toCtype();
+
+    // LDC
+    // cache the hasUnalignedFields check
+    // 0 = not checked, 1 = aligned, 2 = unaligned
+    int unaligned;
 };
 
 struct TypeEnum : Type
--- a/gen/llvmhelpers.cpp	Tue Mar 03 14:10:37 2009 +0100
+++ b/gen/llvmhelpers.cpp	Tue Mar 03 15:08:26 2009 +0100
@@ -1565,3 +1565,33 @@
     return false;
 #endif
 }
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+bool hasUnalignedFields(Type* t)
+{
+    t = t->toBasetype();
+    if (t->ty != Tstruct)
+        return false;
+
+    TypeStruct* ts = (TypeStruct*)t;
+    if (ts->unaligned)
+        return (ts->unaligned == 2);
+
+    StructDeclaration* sym = ts->sym;
+
+    // go through all the fields and try to find something unaligned
+    ts->unaligned = 2;
+    for (int i = 0; i < sym->fields.dim; i++)
+    {
+        VarDeclaration* f = (VarDeclaration*)sym->fields.data[i];
+        unsigned a = f->type->alignsize() - 1;
+        if (((f->offset + a) & ~a) != f->offset)
+            return true;
+        else if (f->type->toBasetype()->ty == Tstruct && hasUnalignedFields(f->type))
+            return true;
+    }
+
+    ts->unaligned = 1;
+    return false;
+}
--- a/gen/llvmhelpers.h	Tue Mar 03 14:10:37 2009 +0100
+++ b/gen/llvmhelpers.h	Tue Mar 03 15:08:26 2009 +0100
@@ -114,6 +114,9 @@
 // returns true if the symbol needs template linkage, or just external
 bool needsTemplateLinkage(Dsymbol* s);
 
+// returns true if there is any unaligned type inside the aggregate
+bool hasUnalignedFields(Type* t);
+
 ////////////////////////////////////////////
 // gen/tocall.cpp stuff below
 ////////////////////////////////////////////