diff -uNr dmd-0.108/dmd/src/dmd/aggregate.h dmd-0.109/dmd/src/dmd/aggregate.h --- dmd-0.108/dmd/src/dmd/aggregate.h 2004-11-04 21:26:12.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/aggregate.h 2004-12-03 01:12:44.000000000 +0100 @@ -29,6 +29,7 @@ struct DeleteDeclaration; struct InterfaceDeclaration; struct ClassInfoDeclaration; +struct VarDeclaration; struct dt_t; @@ -55,6 +56,7 @@ unsigned size(); static void alignmember(unsigned salign, unsigned size, unsigned *poffset); Type *getType(); + void addField(Scope *sc, VarDeclaration *v); // Back end Symbol *stag; // tag symbol for debug data @@ -64,6 +66,16 @@ AggregateDeclaration *isAggregateDeclaration() { return this; } }; +struct AnonymousAggregateDeclaration : AggregateDeclaration +{ + AnonymousAggregateDeclaration() + : AggregateDeclaration(0, NULL) + { + } + + AnonymousAggregateDeclaration *isAnonymousAggregateDeclaration() { return this; } +}; + struct StructDeclaration : AggregateDeclaration { int zeroInit; // !=0 if initialize with 0 fill diff -uNr dmd-0.108/dmd/src/dmd/attrib.c dmd-0.109/dmd/src/dmd/attrib.c --- dmd-0.108/dmd/src/dmd/attrib.c 2004-11-11 12:30:00.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/attrib.c 2004-12-04 17:39:06.000000000 +0100 @@ -208,7 +208,7 @@ buf->writenl(); } -/********************************* StorageClassDeclaration ****************************/ +/************************* StorageClassDeclaration ****************************/ StorageClassDeclaration::StorageClassDeclaration(unsigned stc, Array *decl) : AttribDeclaration(decl) @@ -432,6 +432,119 @@ AttribDeclaration::toCBuffer(buf); } +/********************************* AnonDeclaration ****************************/ + +AnonDeclaration::AnonDeclaration(int isunion, Array *decl) + : AttribDeclaration(decl) +{ + this->isunion = isunion; +} + +Dsymbol *AnonDeclaration::syntaxCopy(Dsymbol *s) +{ + AnonDeclaration *ad; + + assert(!s); + ad = new AnonDeclaration(isunion, Dsymbol::arraySyntaxCopy(decl)); + return ad; +} + +void AnonDeclaration::semantic(Scope *sc) +{ + //printf("\tAnonDeclaration::semantic '%s'\n",toChars()); + assert(sc->parent); + + Dsymbol *parent = sc->parent->pastMixin(); + AggregateDeclaration *ad = parent->isAggregateDeclaration(); + + if (!ad || (!ad->isStructDeclaration() && !ad->isClassDeclaration())) + { + error("can only be a part of an aggregate"); + return; + } + + if (decl) + { Scope sc_save = *sc; + AnonymousAggregateDeclaration aad; + int adisunion; + + if (sc->anonAgg) + { ad = sc->anonAgg; + adisunion = sc->inunion; + } + else + adisunion = ad->isUnionDeclaration() != NULL; + + sc->anonAgg = &aad; + sc->stc &= ~(STCauto | STCstatic); + sc->inunion = isunion; + sc->offset = 0; + sc->flags = 0; + aad.structalign = sc->structalign; + + for (unsigned i = 0; i < decl->dim; i++) + { + Dsymbol *s = (Dsymbol *)decl->data[i]; + + s->semantic(sc); + if (isunion) + sc->offset = 0; + } + *sc = sc_save; + + // 0 sized structs are set to 1 byte + if (aad.structsize == 0) + { + aad.structsize = 1; + aad.alignsize = 1; + } + + // Align size of anonymous aggregate +//printf("aad.structalign = %d, aad.alignsize = %d, sc->offset = %d\n", aad.structalign, aad.alignsize, sc->offset); + ad->alignmember(aad.structalign, aad.alignsize, &sc->offset); + //ad->structsize = sc->offset; +//printf("sc->offset = %d\n", sc->offset); + + // Add members of aad to ad + //printf("\tadding members of aad to '%s'\n", ad->toChars()); + for (unsigned i = 0; i < aad.fields.dim; i++) + { + VarDeclaration *v = (VarDeclaration *)aad.fields.data[i]; + + v->offset += sc->offset; + ad->fields.push(v); + } + + // Add size of aad to ad + if (adisunion) + { + if (aad.structsize > ad->structsize) + ad->structsize = aad.structsize; + sc->offset = 0; + } + else + { + ad->structsize = sc->offset + aad.structsize; + sc->offset = ad->structsize; + } + + if (ad->alignsize < aad.alignsize) + ad->alignsize = aad.alignsize; + } +} + + +void AnonDeclaration::toCBuffer(OutBuffer *buf) +{ + buf->printf(isunion ? "union" : "struct"); + AttribDeclaration::toCBuffer(buf); +} + +char *AnonDeclaration::kind() +{ + return (char *)(isunion ? "anonymous union" : "anonymous struct"); +} + /********************************* PragmaDeclaration ****************************/ PragmaDeclaration::PragmaDeclaration(Identifier *ident, Array *args, Array *decl) diff -uNr dmd-0.108/dmd/src/dmd/attrib.h dmd-0.109/dmd/src/dmd/attrib.h --- dmd-0.108/dmd/src/dmd/attrib.h 2004-11-04 21:31:20.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/attrib.h 2004-12-03 01:43:24.000000000 +0100 @@ -87,6 +87,17 @@ void toCBuffer(OutBuffer *buf); }; +struct AnonDeclaration : AttribDeclaration +{ + int isunion; + + AnonDeclaration(int isunion, Array *decl); + Dsymbol *syntaxCopy(Dsymbol *s); + void semantic(Scope *sc); + void toCBuffer(OutBuffer *buf); + char *kind(); +}; + struct PragmaDeclaration : AttribDeclaration { Identifier *ident; Array *args; // array of Expression's diff -uNr dmd-0.108/dmd/src/dmd/class.c dmd-0.109/dmd/src/dmd/class.c --- dmd-0.108/dmd/src/dmd/class.c 2004-11-29 20:50:14.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/class.c 2004-12-01 01:42:18.000000000 +0100 @@ -294,6 +294,7 @@ Dsymbol *s = (Dsymbol *)members->data[i]; s->semantic(sc); } + structsize = sc->offset; //members->print(); /* Look for special member functions. @@ -326,6 +327,7 @@ members->push(ctor); ctor->addMember(this); *sc = scsave; + sc->offset = structsize; ctor->semantic(sc); } diff -uNr dmd-0.108/dmd/src/dmd/constfold.c dmd-0.109/dmd/src/dmd/constfold.c --- dmd-0.108/dmd/src/dmd/constfold.c 2004-11-29 01:43:50.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/constfold.c 2004-12-01 01:29:58.000000000 +0100 @@ -207,6 +207,7 @@ Expression *MulExp::constFold() { Expression *e; + //printf("MulExp::constFold(%s)\n", toChars()); e1 = e1->constFold(); e2 = e2->constFold(); if (type->isfloating()) diff -uNr dmd-0.108/dmd/src/dmd/declaration.c dmd-0.109/dmd/src/dmd/declaration.c --- dmd-0.108/dmd/src/dmd/declaration.c 2004-11-28 01:59:40.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/declaration.c 2004-12-02 19:49:14.000000000 +0100 @@ -253,25 +253,34 @@ L2: type = NULL; - FuncDeclaration *f = s->isFuncDeclaration(); - if (f) + VarDeclaration *v = s->isVarDeclaration(); + if (v && v->linkage == LINKdefault) { + error("forward reference of %s", v->toChars()); + s = NULL; + } + else + { + FuncDeclaration *f = s->isFuncDeclaration(); + if (f) + { + if (overnext) + { + FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); + if (!fa->overloadInsert(overnext)) + ScopeDsymbol::multiplyDefined(f, overnext); + overnext = NULL; + s = fa; + } + } if (overnext) + ScopeDsymbol::multiplyDefined(s, overnext); + if (s == this) { - FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); - if (!fa->overloadInsert(overnext)) - ScopeDsymbol::multiplyDefined(f, overnext); - overnext = NULL; - s = fa; + assert(global.errors); + s = NULL; } } - if (overnext) - ScopeDsymbol::multiplyDefined(s, overnext); - if (s == this) - { - assert(global.errors); - s = NULL; - } aliassym = s; this->inSemantic = 0; } @@ -407,51 +416,16 @@ } else { - StructDeclaration *sd = parent->isStructDeclaration(); - if (sd) + AnonymousAggregateDeclaration *aad = sc->anonAgg; + if (aad) { - unsigned memsize; // size of member - unsigned memalignsize; // size of member for alignment purposes - unsigned xalign; // alignment boundaries - - memsize = type->size(); - memalignsize = type->alignsize(); - xalign = type->memalign(sc->structalign); - sd->alignmember(xalign, memalignsize, &sc->offset); - offset = sc->offset; - sc->offset += memsize; - if (sc->offset > sd->structsize) - sd->structsize = sc->offset; - if (sd->alignsize < memalignsize) - sd->alignsize = memalignsize; - - storage_class |= STCfield; - //printf("1 Adding '%s' to '%s', offset %d\n", this->toChars(), sd->toChars(), offset); - sd->fields.push(this); - } - - ClassDeclaration *cd = parent->isClassDeclaration(); - if (cd) - { - unsigned memsize; - unsigned memalignsize; - unsigned xalign; - - memsize = type->size(); - memalignsize = type->alignsize(); - xalign = type->memalign(sc->structalign); - cd->alignmember(xalign, memalignsize, &sc->offset); - offset = sc->offset; - //printf("offset of '%s' is x%x\n", toChars(), offset); - sc->offset += memsize; - if (sc->offset > cd->structsize) - cd->structsize = sc->offset; - if (cd->alignsize < memalignsize) - cd->alignsize = memalignsize; - - storage_class |= STCfield; - //printf("2 Adding '%s' to '%s', offset %d\n", this->toChars(), cd->toChars(), offset); - cd->fields.push(this); + aad->addField(sc, this); + } + else + { + AggregateDeclaration *ad = parent->isAggregateDeclaration(); + if (ad) + ad->addField(sc, this); } InterfaceDeclaration *id = parent->isInterfaceDeclaration(); diff -uNr dmd-0.108/dmd/src/dmd/expression.c dmd-0.109/dmd/src/dmd/expression.c --- dmd-0.108/dmd/src/dmd/expression.c 2004-11-29 01:42:08.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/expression.c 2004-12-04 18:11:12.000000000 +0100 @@ -391,7 +391,6 @@ integer_t Expression::toInteger() { //printf("Expression %s\n", Token::toChars(op)); -*(char*)0=0; error("Integer constant expression expected instead of %s", toChars()); return 0; } @@ -449,7 +448,7 @@ void Expression::checkIntegral() { if (!type->isintegral()) - error("'%s' is not an integral type", toChars()); + error("'%s' is not of integral type, it is a %s", toChars(), type->toChars()); } void Expression::checkArithmetic() @@ -589,6 +588,11 @@ IntegerExp::IntegerExp(Loc loc, integer_t value, Type *type) : Expression(loc, TOKint64, sizeof(IntegerExp)) { + if (type && !type->isscalar()) + { + error("integral constant must be scalar type, not %s", type->toChars()); + type = Type::terror; + } this->type = type; this->value = value; } @@ -703,7 +707,8 @@ type = Type::tint32; } else - type = type->semantic(loc, sc); + { type = type->semantic(loc, sc); + } return this; } @@ -828,7 +833,11 @@ complex_t ImaginaryExp::toComplex() { - return value; +#ifdef __DMC__ + return value * I; +#else + return complex_t(0, value); +#endif } Expression *ImaginaryExp::semantic(Scope *sc) @@ -859,6 +868,7 @@ { this->value = value; this->type = type; + //printf("ComplexExp::ComplexExp(%s)\n", toChars()); } char *ComplexExp::toChars() @@ -1122,6 +1132,7 @@ } error("%s '%s' is not a variable", s->kind(), s->toChars()); + type = Type::terror; return this; } @@ -2250,6 +2261,44 @@ //{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; } + /* Special case: rewrite this.id and super.id + * to be classtype.id and baseclasstype.id + * if we have no this pointer. + */ + if ((e1->op == TOKthis || e1->op == TOKsuper) && !hasThis(sc)) + { ClassDeclaration *cd; + StructDeclaration *sd; + AggregateDeclaration *ad; + + ad = sc->getStructClassScope(); + cd = ad->isClassDeclaration(); + if (cd) + { + if (e1->op == TOKthis) + { + e = new TypeDotIdExp(loc, cd->type, ident); + return e->semantic(sc); + } + else if (cd->baseClass && e1->op == TOKsuper) + { + e = new TypeDotIdExp(loc, cd->baseClass->type, ident); + return e->semantic(sc); + } + } + else + { + sd = ad->isStructDeclaration(); + if (sd) + { + if (e1->op == TOKthis) + { + e = new TypeDotIdExp(loc, sd->type, ident); + return e->semantic(sc); + } + } + } + } + UnaExp::semantic(sc); e1 = resolveProperties(sc, e1); diff -uNr dmd-0.108/dmd/src/dmd/mangle.c dmd-0.109/dmd/src/dmd/mangle.c --- dmd-0.108/dmd/src/dmd/mangle.c 2004-11-05 01:27:06.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/mangle.c 2004-12-01 02:59:38.000000000 +0100 @@ -56,6 +56,10 @@ case LINKcpp: return ident->toChars(); + case LINKdefault: + error("forward declaration"); + return ident->toChars(); + default: printf("'%s', linkage = %d\n", toChars(), linkage); assert(0); diff -uNr dmd-0.108/dmd/src/dmd/mars.c dmd-0.109/dmd/src/dmd/mars.c --- dmd-0.108/dmd/src/dmd/mars.c 2004-11-30 00:12:40.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/mars.c 2004-12-01 01:18:22.000000000 +0100 @@ -49,7 +49,7 @@ copyright = "Copyright (c) 1999-2004 by Digital Mars"; written = "written by Walter Bright"; - version = "v0.108"; + version = "v0.109"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); diff -uNr dmd-0.108/dmd/src/dmd/mtype.c dmd-0.109/dmd/src/dmd/mtype.c --- dmd-0.108/dmd/src/dmd/mtype.c 2004-11-23 14:54:22.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/mtype.c 2004-12-02 01:36:06.000000000 +0100 @@ -318,6 +318,7 @@ //printf("merge(%s)\n", toChars()); t = this; + assert(t); if (!deco) { OutBuffer buf; @@ -2506,6 +2507,7 @@ Expression *e; //printf("TypeQualified::resolveHelper(sc = %p, idents = '%s')\n", sc, toChars()); + //printf("\tscopesym = '%s'\n", scopesym->toChars()); *pe = NULL; *pt = NULL; *ps = NULL; @@ -2629,7 +2631,18 @@ } if (t->ty == Tident && t != this) { - ((TypeIdentifier *)t)->resolve(loc, sc, pe, &t, ps); + Scope *scx; + + for (scx = sc; 1; scx = scx->enclosing) + { + if (!scx) + { error(loc, "forward reference to '%s'", t->toChars()); + return; + } + if (scx->scopesym == scopesym) + break; + } + ((TypeIdentifier *)t)->resolve(loc, scx, pe, &t, ps); } *pt = t->merge(); } diff -uNr dmd-0.108/dmd/src/dmd/optimize.c dmd-0.109/dmd/src/dmd/optimize.c --- dmd-0.108/dmd/src/dmd/optimize.c 2004-11-30 00:42:12.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/optimize.c 2004-12-01 16:44:10.000000000 +0100 @@ -58,7 +58,7 @@ } if (e1->op == TOKvar) { VarExp *ve = (VarExp *)e1; - if (!ve->var->isOut()) + if (!ve->var->isOut() && !ve->var->isImportedSymbol()) { e = new SymOffExp(loc, ve->var, 0); e->type = type; @@ -73,7 +73,8 @@ { integer_t index = ae->e2->toInteger(); VarExp *ve = (VarExp *)ae->e1; - if (ve->type->ty == Tsarray && ve->type->next->ty != Tbit) + if (ve->type->ty == Tsarray && ve->type->next->ty != Tbit + && !ve->var->isImportedSymbol()) { TypeSArray *ts = (TypeSArray *)ve->type; integer_t dim = ts->dim->toInteger(); diff -uNr dmd-0.108/dmd/src/dmd/parse.c dmd-0.109/dmd/src/dmd/parse.c --- dmd-0.108/dmd/src/dmd/parse.c 2004-10-26 11:39:20.000000000 +0200 +++ dmd-0.109/dmd/src/dmd/parse.c 2004-12-03 01:19:56.000000000 +0100 @@ -904,7 +904,8 @@ } Dsymbol *Parser::parseAggregate() -{ AggregateDeclaration *a; +{ AggregateDeclaration *a = NULL; + int anon = 0; enum TOK tok; Identifier *id; Array *tpl = NULL; @@ -918,13 +919,13 @@ else { id = token.ident; nextToken(); - } - if (token.value == TOKlparen) - { // Class template declaration. + if (token.value == TOKlparen) + { // Class template declaration. - // Gather template parameter list - tpl = parseTemplateParameterList(); + // Gather template parameter list + tpl = parseTemplateParameterList(); + } } switch (tok) @@ -985,31 +986,47 @@ } case TOKstruct: - a = new StructDeclaration(loc, id); + if (id) + a = new StructDeclaration(loc, id); + else + anon = 1; break; case TOKunion: - a = new UnionDeclaration(loc, id); + if (id) + a = new UnionDeclaration(loc, id); + else + anon = 2; break; default: assert(0); break; } - if (token.value == TOKsemicolon) - nextToken(); + if (a && token.value == TOKsemicolon) + { nextToken(); + } else if (token.value == TOKlcurly) { //printf("aggregate definition\n"); nextToken(); - a->members = parseDeclDefs(0); + Array *decl = parseDeclDefs(0); if (token.value != TOKrcurly) error("struct member expected"); nextToken(); + if (anon) + { + /* Anonymous structs/unions are more like attributes. + */ + return new AnonDeclaration(anon - 1, decl); + } + else + a->members = decl; } else { error("{ } expected following aggregate declaration"); + a = new StructDeclaration(loc, NULL); } if (tpl) diff -uNr dmd-0.108/dmd/src/dmd/scope.c dmd-0.109/dmd/src/dmd/scope.c --- dmd-0.108/dmd/src/dmd/scope.c 2004-02-21 19:04:40.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/scope.c 2004-12-02 19:35:46.000000000 +0100 @@ -60,6 +60,7 @@ this->noctor = 0; this->callSuper = 0; this->flags = 0; + this->anonAgg = NULL; } Scope::Scope(Scope *enclosing) @@ -85,6 +86,7 @@ this->noctor = enclosing->noctor; this->callSuper = enclosing->callSuper; this->flags = 0; + this->anonAgg = NULL; assert(this != enclosing); } @@ -251,6 +253,32 @@ return NULL; } +/******************************************** + * Search enclosing scopes for ClassDeclaration. + */ + +AggregateDeclaration *Scope::getStructClassScope() +{ Scope *sc; + + for (sc = this; sc; sc = sc->enclosing) + { + AggregateDeclaration *ad; + + if (sc->scopesym) + { + ad = sc->scopesym->isClassDeclaration(); + if (ad) + return ad; + else + { ad = sc->scopesym->isStructDeclaration(); + if (ad) + return ad; + } + } + } + return NULL; +} + /******************************************* * For TemplateDeclarations, we need to remember the Scope * where it was declared. So mark the Scope as not diff -uNr dmd-0.108/dmd/src/dmd/scope.h dmd-0.109/dmd/src/dmd/scope.h --- dmd-0.108/dmd/src/dmd/scope.h 2004-02-21 19:04:10.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/scope.h 2004-12-02 19:35:46.000000000 +0100 @@ -24,6 +24,8 @@ struct LabelStatement; struct ForeachStatement; struct ClassDeclaration; +struct AggregateDeclaration; +struct AnonymousAggregateDeclaration; struct FuncDeclaration; enum LINK; enum PROT; @@ -62,6 +64,8 @@ unsigned flags; #define SCOPEctor 1 // constructor type + AnonymousAggregateDeclaration *anonAgg; // for temporary analysis + static Scope *freelist; static void *operator new(size_t sz); static Scope *createGlobal(Module *module); @@ -80,6 +84,7 @@ Dsymbol *insert(Dsymbol *s); ClassDeclaration *getClassScope(); + AggregateDeclaration *getStructClassScope(); void setNoFree(); }; diff -uNr dmd-0.108/dmd/src/dmd/statement.c dmd-0.109/dmd/src/dmd/statement.c --- dmd-0.108/dmd/src/dmd/statement.c 2004-11-24 19:24:32.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/statement.c 2004-12-02 02:08:22.000000000 +0100 @@ -1707,6 +1707,7 @@ { ClassDeclaration *cd; exp = exp->semantic(sc); + exp = resolveProperties(sc, exp); cd = exp->type->isClassHandle(); if (!cd) error("can only synchronize on class objects, not '%s'", exp->type->toChars()); diff -uNr dmd-0.108/dmd/src/dmd/struct.c dmd-0.109/dmd/src/dmd/struct.c --- dmd-0.108/dmd/src/dmd/struct.c 2004-11-27 00:10:40.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/struct.c 2004-12-03 01:55:02.000000000 +0100 @@ -131,6 +131,30 @@ //printf("result = %d\n",offset); } + +void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v) +{ + unsigned memsize; // size of member + unsigned memalignsize; // size of member for alignment purposes + unsigned xalign; // alignment boundaries + + memsize = v->type->size(); + memalignsize = v->type->alignsize(); + xalign = v->type->memalign(sc->structalign); + alignmember(xalign, memalignsize, &sc->offset); + v->offset = sc->offset; + sc->offset += memsize; + if (sc->offset > structsize) + structsize = sc->offset; + if (alignsize < memalignsize) + alignsize = memalignsize; + + v->storage_class |= STCfield; + //printf(" addField '%s' to '%s' at offset %d\n", v->toChars(), toChars(), v->offset); + fields.push(v); +} + + /********************************* StructDeclaration ****************************/ StructDeclaration::StructDeclaration(Loc loc, Identifier *id) @@ -204,6 +228,7 @@ AggregateDeclaration *sd; +#if 0 if (isAnonymous()) { // Anonymous structures aren't independent, all their members are // added to the enclosing struct. @@ -255,6 +280,7 @@ sd->alignsize = alignsize; } } +#endif //printf("-StructDeclaration::semantic(this=%p, '%s')\n", this, toChars()); // Determine if struct is all zeros or not diff -uNr dmd-0.108/dmd/src/dmd/todt.c dmd-0.109/dmd/src/dmd/todt.c --- dmd-0.108/dmd/src/dmd/todt.c 2004-11-30 00:39:48.000000000 +0100 +++ dmd-0.109/dmd/src/dmd/todt.c 2004-12-03 01:56:20.000000000 +0100 @@ -60,7 +60,7 @@ dt_t **pdtend; unsigned offset; - //printf("StructInitializer::toDt()\n"); + //printf("StructInitializer::toDt('%s')\n", toChars()); dts.setDim(ad->fields.dim); dts.zero();