Mercurial > projects > ldc
diff dmd2/struct.c @ 1452:638d16625da2
LDC 2 compiles again.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sat, 30 May 2009 17:23:32 +0100 |
parents | de97188378bc |
children | f62347c22d81 |
line wrap: on
line diff
--- a/dmd2/struct.c Thu May 28 00:07:21 2009 +0200 +++ b/dmd2/struct.c Sat May 30 17:23:32 2009 +0100 @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2008 by Digital Mars +// Copyright (c) 1999-2009 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -19,6 +19,7 @@ #include "module.h" #include "id.h" #include "statement.h" +#include "template.h" /********************************* AggregateDeclaration ****************************/ @@ -41,13 +42,20 @@ aggNew = NULL; aggDelete = NULL; +#if IN_DMD stag = NULL; sinit = NULL; +#endif scope = NULL; - dtor = NULL; + isnested = 0; + vthis = NULL; +#if DMDV2 ctor = NULL; defaultCtor = NULL; + aliasthis = NULL; +#endif + dtor = NULL; } enum PROT AggregateDeclaration::prot() @@ -132,31 +140,21 @@ * Align sizes of 0, as we may not know array sizes yet. */ -void AggregateDeclaration::alignmember(unsigned salign, unsigned size, unsigned *poffset) +void AggregateDeclaration::alignmember( + unsigned salign, // struct alignment that is in effect + unsigned size, // alignment requirement of field + unsigned *poffset) { - //printf("salign = %d, size = %d, offset = %d\n",salign,size,*poffset); + //printf("salign = %d, size = %d, offset = %d\n",salign,size,offset); if (salign > 1) - { int sa; - - switch (size) - { case 1: - break; - case 2: - case_2: - *poffset = (*poffset + 1) & ~1; // align to word - break; - case 3: - case 4: - if (salign == 2) - goto case_2; - *poffset = (*poffset + 3) & ~3; // align to dword - break; - default: - *poffset = (*poffset + size - 1) & ~(size - 1); - break; - } + { + assert(size != 3); + int sa = size; + if (sa == 0 || salign < sa) + sa = salign; + *poffset = (*poffset + sa - 1) & ~(sa - 1); } - //printf("result = %d\n",*poffset); + //printf("result = %d\n",offset); } @@ -171,13 +169,18 @@ // 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) { @@ -191,9 +194,9 @@ return; } - memsize = v->type->size(loc); - memalignsize = v->type->alignsize(); - xalign = v->type->memalign(sc->structalign); + memsize = t->size(loc); + memalignsize = t->alignsize(); + xalign = t->memalign(sc->structalign); alignmember(xalign, memalignsize, &sc->offset); v->offset = sc->offset; sc->offset += memsize; @@ -211,15 +214,28 @@ } +/**************************************** + * Returns !=0 if there's an extra member which is the 'this' + * pointer to the enclosing context (enclosing aggregate or function) + */ + +int AggregateDeclaration::isNested() +{ + return isnested; +} + + /********************************* StructDeclaration ****************************/ StructDeclaration::StructDeclaration(Loc loc, Identifier *id) : AggregateDeclaration(loc, id) { zeroInit = 0; // assume false until we do semantic processing +#if DMDV2 hasIdentityAssign = 0; cpctor = NULL; postblit = NULL; +#endif // For forward references type = new TypeStruct(this); @@ -277,24 +293,64 @@ assert(!isAnonymous()); if (sc->stc & STCabstract) error("structs, unions cannot be abstract"); - if (storage_class & STCinvariant) +#if DMDV2 + if (storage_class & STCimmutable) type = type->invariantOf(); else if (storage_class & STCconst) type = type->constOf(); + else if (storage_class & STCshared) + type = type->sharedOf(); +#endif if (sizeok == 0) // if not already done the addMember step { + int hasfunctions = 0; for (i = 0; i < members->dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; //printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars()); s->addMember(sc, this, 1); + if (s->isFuncDeclaration()) + hasfunctions = 1; } + + // If nested struct, add in hidden 'this' pointer to outer scope + if (hasfunctions && !(storage_class & STCstatic)) + { Dsymbol *s = toParent2(); + if (s) + { + AggregateDeclaration *ad = s->isAggregateDeclaration(); + FuncDeclaration *fd = s->isFuncDeclaration(); + + TemplateInstance *ti; + if (ad && (ti = ad->parent->isTemplateInstance()) != NULL && ti->isnested || fd) + { isnested = 1; + Type *t; + if (ad) + t = ad->handle; + else if (fd) + { AggregateDeclaration *ad = fd->isMember2(); + if (ad) + t = ad->handle; + else + t = Type::tvoidptr; + } + else + assert(0); + if (t->ty == Tstruct) + t = Type::tvoidptr; // t should not be a ref type + assert(!vthis); + vthis = new ThisDeclaration(loc, t); + //vthis->storage_class |= STCref; + members->push(vthis); + } + } + } } sizeok = 0; sc2 = sc->push(this); - sc2->stc &= storage_class & (STCconst | STCinvariant); + sc2->stc &= storage_class & STC_TYPECTOR; sc2->parent = this; if (isUnionDeclaration()) sc2->inunion = 1; @@ -314,6 +370,14 @@ break; } #endif + Type *t; + if (s->isDeclaration() && + (t = s->isDeclaration()->type) != NULL && + t->toBasetype()->ty == Tstruct) + { StructDeclaration *sd = (StructDeclaration *)t->toDsymbol(sc); + if (sd->isnested) + error("inner struct %s cannot be a field", sd->toChars()); + } } /* The TypeInfo_Struct is expecting an opEquals and opCmp with @@ -349,9 +413,9 @@ Dsymbol *s = search_function(this, id); FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL; if (fdx) - { FuncDeclaration *fd = fdx->overloadExactMatch(tfeqptr); + { FuncDeclaration *fd = fdx->overloadExactMatch(tfeqptr, getModule()); if (!fd) - { fd = fdx->overloadExactMatch(tfeq); + { fd = fdx->overloadExactMatch(tfeq, getModule()); if (fd) { // Create the thunk, fdptr FuncDeclaration *fdptr = new FuncDeclaration(loc, loc, fdx->ident, STCundefined, tfeqptr); @@ -373,11 +437,12 @@ id = Id::cmp; } - +#if DMDV2 dtor = buildDtor(sc2); postblit = buildPostBlit(sc2); cpctor = buildCpCtor(sc2); buildOpAssign(sc2); +#endif sc2->pop(); @@ -429,7 +494,7 @@ } else { - if (!vd->type->isZeroInit()) + if (!vd->type->isZeroInit(loc)) { zeroInit = 0; break; @@ -440,7 +505,9 @@ /* Look for special member functions. */ - ctor = (CtorDeclaration *)search(0, Id::ctor, 0); +#if DMDV2 + ctor = search(0, Id::ctor, 0); +#endif inv = (InvariantDeclaration *)search(0, Id::classInvariant, 0); aggNew = (NewDeclaration *)search(0, Id::classNew, 0); aggDelete = (DeleteDeclaration *)search(0, Id::classDelete, 0);