Merged dmd 2.059beta

This commit is contained in:
Alexey Prokhin
2012-04-05 11:47:00 +04:00
77 changed files with 6909 additions and 2243 deletions

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -39,7 +39,7 @@ AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
alignsize = 0; // size of struct for alignment purposes
structalign = 0; // struct member alignment in effect
hasUnions = 0;
sizeok = 0; // size not determined yet
sizeok = SIZEOKnone; // size not determined yet
deferred = NULL;
isdeprecated = false;
inv = NULL;
@@ -129,9 +129,46 @@ unsigned AggregateDeclaration::size(Loc loc)
//printf("AggregateDeclaration::size() %s, scope = %p\n", toChars(), scope);
if (!members)
error(loc, "unknown size");
if (sizeok != 1 && scope)
if (sizeok != SIZEOKdone && scope)
semantic(NULL);
if (sizeok != 1)
StructDeclaration *sd = isStructDeclaration();
if (sizeok != SIZEOKdone && sd && sd->members)
{
/* See if enough is done to determine the size,
* meaning all the fields are done.
*/
struct SV
{
static int func(Dsymbol *s, void *param)
{ SV *psv = (SV *)param;
VarDeclaration *v = s->isVarDeclaration();
if (v)
{
if (v->scope)
v->semantic(NULL);
if (v->storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCconst | STCimmutable | STCmanifest | STCctfe | STCtemplateparameter))
return 0;
if (v->storage_class & STCfield && v->sem >= SemanticDone)
return 0;
return 1;
}
return 0;
}
};
SV sv;
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = (*members)[i];
if (s->apply(&SV::func, &sv))
goto L1;
}
sd->finalizeSize(NULL);
L1: ;
}
if (sizeok != SIZEOKdone)
{ error(loc, "no size yet for forward reference");
//*(char*)0=0;
}
@@ -175,76 +212,38 @@ void AggregateDeclaration::alignmember(
//printf("result = %d\n",offset);
}
void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v)
/****************************************
* Place a member (mem) into an aggregate (agg), which can be a struct, union or class
* Returns:
* offset to place field at
*/
unsigned AggregateDeclaration::placeField(
unsigned *nextoffset, // next location in aggregate
unsigned memsize, // size of member
unsigned memalignsize, // size of member for alignment purposes
unsigned memalign, // alignment in effect for this member
unsigned *paggsize, // size of aggregate (updated)
unsigned *paggalignsize, // size of aggregate for alignment purposes (updated)
bool isunion // the aggregate is a union
)
{
unsigned memsize; // size of member
unsigned memalignsize; // size of member for alignment purposes
unsigned xalign; // alignment boundaries
//printf("AggregateDeclaration::addField('%s') %s\n", v->toChars(), toChars());
assert(!(v->storage_class & (STCstatic | STCextern | STCparameter | STCtls)));
// Check for forward referenced types which will fail the size() call
Type *t = v->type->toBasetype();
if (v->storage_class & STCref)
{ // References are the size of a pointer
t = Type::tvoidptr;
}
if (t->ty == Tstruct /*&& isStructDeclaration()*/)
{ TypeStruct *ts = (TypeStruct *)t;
#if DMDV2
if (ts->sym == this)
{
error("cannot have field %s with same struct type", v->toChars());
}
#endif
if (ts->sym->sizeok != 1 && ts->sym->scope)
ts->sym->semantic(NULL);
if (ts->sym->sizeok != 1)
{
sizeok = 2; // cannot finish; flag as forward referenced
return;
}
}
if (t->ty == Tident)
{
sizeok = 2; // cannot finish; flag as forward referenced
return;
}
memsize = t->size(loc);
memalignsize = t->alignsize();
xalign = t->memalign(sc->structalign);
#if 0
alignmember(xalign, memalignsize, &sc->offset);
v->offset = sc->offset;
sc->offset += memsize;
if (sc->offset > structsize)
structsize = sc->offset;
#else
unsigned ofs = sc->offset;
alignmember(xalign, memalignsize, &ofs);
v->offset = ofs;
unsigned ofs = *nextoffset;
alignmember(memalign, memalignsize, &ofs);
unsigned memoffset = ofs;
ofs += memsize;
if (ofs > structsize)
structsize = ofs;
if (!isUnionDeclaration())
sc->offset = ofs;
#endif
if (global.params.is64bit && sc->structalign == 8 && memalignsize == 16 && isUnionDeclaration())
if (ofs > *paggsize)
*paggsize = ofs;
if (!isunion)
*nextoffset = ofs;
if (global.params.is64bit && memalign == 8 && memalignsize == 16)
/* Not sure how to handle this */
;
else if (sc->structalign < memalignsize)
memalignsize = sc->structalign;
if (alignsize < memalignsize)
alignsize = memalignsize;
//printf("\t%s: alignsize = %d\n", toChars(), alignsize);
else if (memalign < memalignsize)
memalignsize = memalign;
if (*paggalignsize < memalignsize)
*paggalignsize = memalignsize;
v->storage_class |= STCfield;
//printf(" addField '%s' to '%s' at offset %d, size = %d\n", v->toChars(), toChars(), v->offset, memsize);
fields.push(v);
return memoffset;
}
@@ -363,7 +362,7 @@ void StructDeclaration::semantic(Scope *sc)
return;
if (symtab)
{ if (sizeok == 1 || !scope)
{ if (sizeok == SIZEOKdone || !scope)
{ //printf("already completed\n");
scope = NULL;
return; // semantic() already completed
@@ -398,16 +397,8 @@ void StructDeclaration::semantic(Scope *sc)
assert(!isAnonymous());
if (sc->stc & STCabstract)
error("structs, unions cannot be abstract");
#if DMDV2
if (storage_class & STCimmutable)
type = type->addMod(MODimmutable);
if (storage_class & STCconst)
type = type->addMod(MODconst);
if (storage_class & STCshared)
type = type->addMod(MODshared);
#endif
if (sizeok == 0) // if not already done the addMember step
if (sizeok == SIZEOKnone) // if not already done the addMember step
{
int hasfunctions = 0;
for (size_t i = 0; i < members->dim; i++)
@@ -453,7 +444,7 @@ void StructDeclaration::semantic(Scope *sc)
}
}
sizeok = 0;
sizeok = SIZEOKnone;
sc2 = sc->push(this);
sc2->stc &= STCsafe | STCtrusted | STCsystem;
sc2->parent = this;
@@ -472,7 +463,7 @@ void StructDeclaration::semantic(Scope *sc)
/* There are problems doing this in the general case because
* Scope keeps track of things like 'offset'
*/
if (s->isEnumDeclaration() || (s->isAggregateDeclaration() && s->ident))
//if (s->isEnumDeclaration() || (s->isAggregateDeclaration() && s->ident))
{
//printf("setScope %s %s\n", s->kind(), s->toChars());
s->setScope(sc2);
@@ -490,15 +481,27 @@ void StructDeclaration::semantic(Scope *sc)
*/
if (i + 1 == members_dim)
{
if (sizeok == 0 && s->isAliasDeclaration())
finalizeSize();
if (sizeok == SIZEOKnone && s->isAliasDeclaration())
finalizeSize(sc2);
}
// Ungag errors when not speculative
unsigned oldgag = global.gag;
if (global.isSpeculativeGagging() && !isSpeculative())
global.gag = 0;
s->semantic(sc2);
global.gag = oldgag;
}
finalizeSize(sc2);
if (sizeok == 2)
if (sizeok == SIZEOKfwd)
{ // semantic() failed because of forward references.
// Unwind what we did, and defer it for later
for (size_t i = 0; i < fields.dim; i++)
{ Dsymbol *s = fields[i];
VarDeclaration *vd = s->isVarDeclaration();
if (vd)
vd->offset = 0;
}
fields.setDim(0);
structsize = 0;
alignsize = 0;
@@ -513,7 +516,6 @@ void StructDeclaration::semantic(Scope *sc)
return;
}
finalizeSize();
Module::dprogress++;
//printf("-StructDeclaration::semantic(this=%p, '%s')\n", this, toChars());
@@ -522,7 +524,7 @@ void StructDeclaration::semantic(Scope *sc)
zeroInit = 1;
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields.tdata()[i];
Dsymbol *s = fields[i];
VarDeclaration *vd = s->isVarDeclaration();
if (vd && !vd->isDataseg())
{
@@ -661,8 +663,21 @@ Dsymbol *StructDeclaration::search(Loc loc, Identifier *ident, int flags)
return ScopeDsymbol::search(loc, ident, flags);
}
void StructDeclaration::finalizeSize()
void StructDeclaration::finalizeSize(Scope *sc)
{
if (sizeok != SIZEOKnone)
return;
// Set the offsets of the fields and determine the size of the struct
unsigned offset = 0;
bool isunion = isUnionDeclaration() != NULL;
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = (*members)[i];
s->setFieldOffset(this, &offset, isunion);
}
if (sizeok == SIZEOKfwd)
return;
// 0 sized struct's are set to 1 byte
if (structsize == 0)
{
@@ -675,7 +690,7 @@ void StructDeclaration::finalizeSize()
// aligned properly.
structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
sizeok = 1;
sizeok = SIZEOKdone;
}
void StructDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)