# HG changeset patch # User Tomas Lindquist Olsen # Date 1236089306 -3600 # Node ID 4d366a75d95f1a25a66bd0a875fb405f5b9f18f2 # Parent 964af20461a969b7b142d6d4f1e1d12d723573eb Added hasUnalignedFields helper to check if a type has unaligned fields - as per request from fvbommel. Result is cached in TypeStruct. diff -r 964af20461a9 -r 4d366a75d95f dmd/mtype.c --- 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() diff -r 964af20461a9 -r 4d366a75d95f dmd/mtype.h --- 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 diff -r 964af20461a9 -r 4d366a75d95f dmd2/mtype.c --- 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() diff -r 964af20461a9 -r 4d366a75d95f dmd2/mtype.h --- 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 diff -r 964af20461a9 -r 4d366a75d95f gen/llvmhelpers.cpp --- 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; +} diff -r 964af20461a9 -r 4d366a75d95f gen/llvmhelpers.h --- 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 ////////////////////////////////////////////