Skip to content

Commit

Permalink
[Refactoring] Add AggregateDeclaration::finalizeSize()
Browse files Browse the repository at this point in the history
  • Loading branch information
9rnsr committed Mar 10, 2015
1 parent 53c5b59 commit 0c072e2
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 91 deletions.
3 changes: 3 additions & 0 deletions src/aggregate.h
Expand Up @@ -104,6 +104,7 @@ class AggregateDeclaration : public ScopeDsymbol
void semantic2(Scope *sc);
void semantic3(Scope *sc);
unsigned size(Loc loc);
virtual void finalizeSize(Scope *sc) = 0;
static void alignmember(structalign_t salign, unsigned size, unsigned *poffset);
static unsigned placeField(unsigned *nextoffset,
unsigned memsize, unsigned memalignsize, structalign_t memalign,
Expand Down Expand Up @@ -274,6 +275,7 @@ class ClassDeclaration : public AggregateDeclaration
bool isBaseInfoComplete();
Dsymbol *search(Loc, Identifier *ident, int flags = IgnoreNone);
ClassDeclaration *searchBase(Loc, Identifier *ident);
void finalizeSize(Scope *sc);
bool isFuncHidden(FuncDeclaration *fd);
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
void interfaceSemantic(Scope *sc);
Expand All @@ -300,6 +302,7 @@ class InterfaceDeclaration : public ClassDeclaration
InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
void finalizeSize(Scope *sc);
bool isBaseOf(ClassDeclaration *cd, int *poffset);
bool isBaseOf(BaseClass *bc, int *poffset);
const char *kind();
Expand Down
126 changes: 69 additions & 57 deletions src/class.c
Expand Up @@ -698,26 +698,9 @@ void ClassDeclaration::semantic(Scope *sc)
Dsymbol *s = (*members)[i];
s->semantic(sc2);
}
finalizeSize(sc2);

// Set the offsets of the fields and determine the size of the class

unsigned offset = structsize;
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = (*members)[i];
s->setFieldOffset(this, &offset, false);
}

if (global.errors != errors)
{
// The type is no good.
type = Type::terror;
this->errors = true;
if (deferred)
deferred->errors = true;
}

if (sizeok == SIZEOKfwd) // failed due to forward references
if (sizeok == SIZEOKfwd)
{
// semantic() failed due to forward references
// Unwind what we did, and defer it for later
Expand All @@ -737,18 +720,24 @@ void ClassDeclaration::semantic(Scope *sc)
scope->module->addDeferredSemantic(this);

Module::dprogress = dprogress_save;

//printf("\tsemantic('%s') failed due to forward references\n", toChars());
return;
}

//printf("\tsemantic('%s') successful\n", toChars());
Module::dprogress++;
semanticRun = PASSsemanticdone;

//printf("-ClassDeclaration::semantic(%s), type = %p\n", toChars(), type);
//members->print();

/* Look for special member functions.
* They must be in this class, not in a base class.
*/

// Can be in base class
aggNew = (NewDeclaration *)search(Loc(), Id::classNew);
aggDelete = (DeleteDeclaration *)search(Loc(), Id::classDelete);

ctor = searchCtor();
if (ctor && (ctor->toParent() != this || !(ctor->isCtorDeclaration() || ctor->isTemplateDeclaration())))
ctor = NULL; // search() looks through ancestor classes
Expand All @@ -763,12 +752,6 @@ void ClassDeclaration::semantic(Scope *sc)
}
}

inv = buildInv(this, sc2);

// Can be in base class
aggNew = (NewDeclaration *)search(Loc(), Id::classNew);
aggDelete = (DeleteDeclaration *)search(Loc(), Id::classDelete);

// If this class has no constructor, but base class has a default
// ctor, create a constructor:
// this() { }
Expand Down Expand Up @@ -798,43 +781,26 @@ void ClassDeclaration::semantic(Scope *sc)
}
}

// Allocate instance of each new interface
offset = structsize;
for (size_t i = 0; i < vtblInterfaces->dim; i++)
{
BaseClass *b = (*vtblInterfaces)[i];
unsigned thissize = Target::ptrsize;

alignmember(STRUCTALIGN_DEFAULT, thissize, &offset);
assert(b->offset == 0);
b->offset = offset;

// Take care of single inheritance offsets
while (b->baseInterfaces_dim)
{
b = &b->baseInterfaces[0];
b->offset = offset;
}

offset += thissize;
if (alignsize < thissize)
alignsize = thissize;
}
structsize = offset;
sizeok = SIZEOKdone;

Module::dprogress++;
semanticRun = PASSsemanticdone;

dtor = buildDtor(this, sc2);

if (FuncDeclaration *f = hasIdentityOpAssign(this, sc2))
{
if (!(f->storage_class & STCdisable))
error(f->loc, "identity assignment operator overload is illegal");
}

inv = buildInv(this, sc2);

sc2->pop();

//printf("-ClassDeclaration::semantic(%s), type = %p\n", toChars(), type);
if (global.errors != errors)
{
// The type is no good.
type = Type::terror;
this->errors = true;
if (deferred)
deferred->errors = true;
}

if (deferred && !global.gag)
{
Expand Down Expand Up @@ -980,6 +946,47 @@ ClassDeclaration *ClassDeclaration::searchBase(Loc loc, Identifier *ident)
return NULL;
}

void ClassDeclaration::finalizeSize(Scope *sc)
{
if (sizeok != SIZEOKnone)
return;

// Set the offsets of the fields and determine the size of the class
unsigned offset = structsize;
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = (*members)[i];
s->setFieldOffset(this, &offset, false);
}
if (sizeok == SIZEOKfwd)
return;

// Allocate instance of each new interface
offset = structsize;
for (size_t i = 0; i < vtblInterfaces->dim; i++)
{
BaseClass *b = (*vtblInterfaces)[i];
unsigned thissize = Target::ptrsize;

alignmember(STRUCTALIGN_DEFAULT, thissize, &offset);
assert(b->offset == 0);
b->offset = offset;

// Take care of single inheritance offsets
while (b->baseInterfaces_dim)
{
b = &b->baseInterfaces[0];
b->offset = offset;
}

offset += thissize;
if (alignsize < thissize)
alignsize = thissize;
}
structsize = offset;
sizeok = SIZEOKdone;
}

/**********************************************************
* fd is in the vtbl[] for this class.
* Return 1 if function is hidden (not findable through search).
Expand Down Expand Up @@ -1491,7 +1498,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
sc2->structalign = STRUCTALIGN_DEFAULT;
sc2->userAttribDecl = NULL;

structsize = Target::ptrsize * 2;
finalizeSize(sc2);

/* Set scope so if there are forward references, we still might be able to
* resolve individual members like enums.
Expand Down Expand Up @@ -1543,6 +1550,11 @@ void InterfaceDeclaration::semantic(Scope *sc)
assert(type->ty != Tclass || ((TypeClass *)type)->sym == this);
}

void InterfaceDeclaration::finalizeSize(Scope *sc)
{
structsize = Target::ptrsize * 2;
sizeok = SIZEOKdone;
}

/*******************************************
* Determine if 'this' is a base class of cd.
Expand Down
70 changes: 36 additions & 34 deletions src/struct.c
Expand Up @@ -338,8 +338,7 @@ unsigned AggregateDeclaration::size(Loc loc)
if (sizeok != SIZEOKdone && scope)
semantic(NULL);

StructDeclaration *sd = isStructDeclaration();
if (sizeok != SIZEOKdone && sd && sd->members)
if (sizeok != SIZEOKdone && members)
{
/* See if enough is done to determine the size,
* meaning all the fields are done.
Expand Down Expand Up @@ -374,7 +373,7 @@ unsigned AggregateDeclaration::size(Loc loc)
if (s->apply(&SV::func, &sv))
goto L1;
}
sd->finalizeSize(NULL);
finalizeSize(NULL);

L1: ;
}
Expand Down Expand Up @@ -796,13 +795,15 @@ void StructDeclaration::semantic(Scope *sc)
// Unwind what we did, and defer it for later
for (size_t i = 0; i < fields.dim; i++)
{
VarDeclaration *vd = fields[i];
vd->offset = 0;
VarDeclaration *v = fields[i];
v->offset = 0;
}
fields.setDim(0);
structsize = 0;
alignsize = 0;

sc2->pop();

scope = scx ? scx : sc->copy();
scope->setNoFree();
scope->module->addDeferredSemantic(this);
Expand All @@ -817,29 +818,12 @@ void StructDeclaration::semantic(Scope *sc)

//printf("-StructDeclaration::semantic(this=%p, '%s')\n", this, toChars());

// Determine if struct is all zeros or not
zeroInit = 1;
for (size_t i = 0; i < fields.dim; i++)
{
VarDeclaration *vd = fields[i];
if (!vd->isDataseg())
{
if (vd->init)
{
// Should examine init to see if it is really all 0's
zeroInit = 0;
break;
}
else
{
if (!vd->type->isZeroInit(loc))
{
zeroInit = 0;
break;
}
}
}
}
/* Look for special member functions.
*/
aggNew = (NewDeclaration *)search(Loc(), Id::classNew);
aggDelete = (DeleteDeclaration *)search(Loc(), Id::classDelete);

ctor = searchCtor();

dtor = buildDtor(this, sc2);
postblit = buildPostBlit(this, sc2);
Expand All @@ -864,12 +848,6 @@ void StructDeclaration::semantic(Scope *sc)

sc2->pop();

/* Look for special member functions.
*/
ctor = searchCtor();
aggNew = (NewDeclaration *)search(Loc(), Id::classNew);
aggDelete = (DeleteDeclaration *)search(Loc(), Id::classDelete);

if (ctor)
{
Dsymbol *scall = search(Loc(), Id::call);
Expand Down Expand Up @@ -981,6 +959,30 @@ void StructDeclaration::finalizeSize(Scope *sc)

// Calculate fields[i]->overlapped
fill(loc, NULL, true);

// Determine if struct is all zeros or not
zeroInit = 1;
for (size_t i = 0; i < fields.dim; i++)
{
VarDeclaration *vd = fields[i];
if (!vd->isDataseg())
{
if (vd->init)
{
// Should examine init to see if it is really all 0's
zeroInit = 0;
break;
}
else
{
if (!vd->type->isZeroInit(loc))
{
zeroInit = 0;
break;
}
}
}
}
}

/***************************************
Expand Down

0 comments on commit 0c072e2

Please sign in to comment.