Added hasUnalignedFields helper to check if a type has unaligned fields - as per request from fvbommel. Result is cached in TypeStruct.

This commit is contained in:
Tomas Lindquist Olsen 2009-03-03 15:08:26 +01:00
parent 8cad8d6c7a
commit c3a53c0128
6 changed files with 49 additions and 0 deletions

View file

@ -4278,6 +4278,9 @@ TypeStruct::TypeStruct(StructDeclaration *sym)
: Type(Tstruct, NULL)
{
this->sym = sym;
// LDC
this->unaligned = 0;
}
char *TypeStruct::toChars()

View file

@ -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

View file

@ -4929,6 +4929,9 @@ TypeStruct::TypeStruct(StructDeclaration *sym)
: Type(Tstruct)
{
this->sym = sym;
// LDC
this->unaligned = 0;
}
char *TypeStruct::toChars()

View file

@ -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

View file

@ -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;
}

View file

@ -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
////////////////////////////////////////////