From c3a53c0128037b9604741f27ccb095909e758ef9 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Tue, 3 Mar 2009 15:08:26 +0100 Subject: [PATCH] Added hasUnalignedFields helper to check if a type has unaligned fields - as per request from fvbommel. Result is cached in TypeStruct. --- dmd/mtype.c | 3 +++ dmd/mtype.h | 5 +++++ dmd2/mtype.c | 3 +++ dmd2/mtype.h | 5 +++++ gen/llvmhelpers.cpp | 30 ++++++++++++++++++++++++++++++ gen/llvmhelpers.h | 3 +++ 6 files changed, 49 insertions(+) diff --git a/dmd/mtype.c b/dmd/mtype.c index f2a4b94a..7ac0714a 100644 --- a/dmd/mtype.c +++ b/dmd/mtype.c @@ -4278,6 +4278,9 @@ TypeStruct::TypeStruct(StructDeclaration *sym) : Type(Tstruct, NULL) { this->sym = sym; + + // LDC + this->unaligned = 0; } char *TypeStruct::toChars() diff --git a/dmd/mtype.h b/dmd/mtype.h index 0b16aaa8..fd636811 100644 --- a/dmd/mtype.h +++ b/dmd/mtype.h @@ -542,6 +542,11 @@ struct TypeStruct : Type int hasPointers(); type *toCtype(); + + // LDC + // cache the hasUnalignedFields check + // 0 = not checked, 1 = aligned, 2 = unaligned + int unaligned; }; struct TypeEnum : Type diff --git a/dmd2/mtype.c b/dmd2/mtype.c index abb8739d..2812b59f 100644 --- a/dmd2/mtype.c +++ b/dmd2/mtype.c @@ -4929,6 +4929,9 @@ TypeStruct::TypeStruct(StructDeclaration *sym) : Type(Tstruct) { this->sym = sym; + + // LDC + this->unaligned = 0; } char *TypeStruct::toChars() diff --git a/dmd2/mtype.h b/dmd2/mtype.h index b33e549a..698f46d4 100644 --- a/dmd2/mtype.h +++ b/dmd2/mtype.h @@ -628,6 +628,11 @@ struct TypeStruct : Type #endif type *toCtype(); + + // LDC + // cache the hasUnalignedFields check + // 0 = not checked, 1 = aligned, 2 = unaligned + int unaligned; }; struct TypeEnum : Type diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index bf05b06b..0f901ecd 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -1565,3 +1565,33 @@ bool needsTemplateLinkage(Dsymbol* s) 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 --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index 487c0b64..3cf5b47d 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -114,6 +114,9 @@ bool mustDefineSymbol(Dsymbol* s); // 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 ////////////////////////////////////////////