diff -uNr dmd-0.118/dmd/src/dmd/cast.c dmd-0.119/dmd/src/dmd/cast.c --- dmd-0.118/dmd/src/dmd/cast.c 2005-03-01 10:28:28.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/cast.c 2005-03-16 19:12:04.000000000 +0100 @@ -55,7 +55,8 @@ printf("to:\n"); t->print(); printf("%p %p %s %s\n", type->deco, t->deco, type->deco, t->deco); -printf("%p %p %p\n", type->next->arrayOf(), type, t); +//printf("%p %p %p\n", type->next->arrayOf(), type, t); +fflush(stdout); #endif //*(char*)0=0; error("cannot implicitly convert expression (%s) of type %s to %s", @@ -275,7 +276,7 @@ int StringExp::implicitConvTo(Type *t) { MATCH m; - //printf("StringExp::implicitConvTo()\n"); + //printf("StringExp::implicitConvTo(), committed = %d\n", committed); if (!committed) { if (!committed && t->ty == Tpointer && t->next->ty == Tvoid) @@ -455,7 +456,8 @@ Type *tb; int unique; - //printf("StringExp::castTo()\n"); + //printf("StringExp::castTo('%s')\n", string); + //if (((char*)string)[0] == 'd') *(char*)0=0; if (!committed && t->ty == Tpointer && t->next->ty == Tvoid) { error("cannot convert string literal to void*"); @@ -956,6 +958,7 @@ { goto Lt2; } +//else if (e2->op == TOKstring) { printf("test2\n"); } else if ((e2->op == TOKstring || e2->op == TOKnull) && e2->implicitConvTo(t1)) { goto Lt1; diff -uNr dmd-0.118/dmd/src/dmd/class.c dmd-0.119/dmd/src/dmd/class.c --- dmd-0.118/dmd/src/dmd/class.c 2005-03-12 14:52:10.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/class.c 2005-03-16 12:13:30.000000000 +0100 @@ -470,12 +470,21 @@ int ClassDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset) { + //printf("ClassDeclaration::isBaseOf(this = '%s', cd = '%s')\n", toChars(), cd->toChars()); if (poffset) *poffset = 0; while (cd) { if (this == cd->baseClass) return 1; + + /* cd->baseClass might not be set if cd is forward referenced. + */ + if (!cd->baseClass && cd->baseclasses.dim) + { + cd->error("base class is forward referenced by %s", toChars()); + } + cd = cd->baseClass; } return 0; @@ -872,6 +881,7 @@ BaseClass::BaseClass(Type *type, enum PROT protection) { + //printf("BaseClass(this = %p, '%s')\n", this, type->toChars()); this->type = type; this->protection = protection; base = NULL; diff -uNr dmd-0.118/dmd/src/dmd/constfold.c dmd-0.119/dmd/src/dmd/constfold.c --- dmd-0.118/dmd/src/dmd/constfold.c 2004-12-01 01:29:56.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/constfold.c 2005-03-17 12:18:08.000000000 +0100 @@ -328,7 +328,7 @@ e2 = e2->constFold(); value = e1->toInteger(); count = e2->toInteger(); - switch (e1->type->ty) + switch (e1->type->toBasetype()->ty) { case Tint8: case Tuns8: @@ -349,6 +349,9 @@ case Tuns64: value = (d_int64)(value) >> count; break; + + default: + assert(0); } return new IntegerExp(loc, value, type); } @@ -362,7 +365,7 @@ e2 = e2->constFold(); value = e1->toInteger(); count = e2->toInteger(); - switch (e1->type->ty) + switch (e1->type->toBasetype()->ty) { case Tint8: case Tuns8: @@ -383,6 +386,9 @@ case Tuns64: value = (d_uns64)(value) >> count; break; + + default: + assert(0); } return new IntegerExp(loc, value, type); } diff -uNr dmd-0.118/dmd/src/dmd/debcond.c dmd-0.119/dmd/src/dmd/debcond.c --- dmd-0.118/dmd/src/dmd/debcond.c 2005-03-09 19:03:04.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/debcond.c 2005-03-17 23:06:22.000000000 +0100 @@ -108,7 +108,7 @@ global.params.versionlevel = level; } -void VersionCondition::addGlobalIdent(char *ident) +void VersionCondition::checkPredefined(char *ident) { static char* reserved[] = { @@ -129,13 +129,18 @@ if (ident[0] == 'D' && ident[1] == '_') goto Lerror; - addPredefinedGlobalIdent(ident); return; Lerror: error("version identifier '%s' is reserved and cannot be set", ident); } +void VersionCondition::addGlobalIdent(char *ident) +{ + checkPredefined(ident); + addPredefinedGlobalIdent(ident); +} + void VersionCondition::addPredefinedGlobalIdent(char *ident) { if (!global.params.versionids) diff -uNr dmd-0.118/dmd/src/dmd/debcond.h dmd-0.119/dmd/src/dmd/debcond.h --- dmd-0.118/dmd/src/dmd/debcond.h 2004-11-03 15:44:36.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/debcond.h 2005-03-17 23:07:06.000000000 +0100 @@ -43,6 +43,7 @@ struct VersionCondition : Condition { static void setGlobalLevel(unsigned level); + static void checkPredefined(char *ident); static void addGlobalIdent(char *ident); static void addPredefinedGlobalIdent(char *ident); diff -uNr dmd-0.118/dmd/src/dmd/declaration.c dmd-0.119/dmd/src/dmd/declaration.c --- dmd-0.118/dmd/src/dmd/declaration.c 2005-03-10 15:59:24.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/declaration.c 2005-03-17 23:14:06.000000000 +0100 @@ -422,6 +422,10 @@ { error("variable %s cannot be synchronized", toChars()); } + else if (isOverride()) + { + error("override cannot be applied to variable"); + } else { AnonymousAggregateDeclaration *aad = sc->anonAgg; @@ -472,7 +476,7 @@ if (!(storage_class & STCauto)) { - if (!(storage_class & STCparameter)) + if (!(storage_class & STCparameter) && ident != Id::withSym) error("reference to auto class must be auto"); } } diff -uNr dmd-0.118/dmd/src/dmd/entity.c dmd-0.119/dmd/src/dmd/entity.c --- dmd-0.118/dmd/src/dmd/entity.c 2005-03-03 23:28:16.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/entity.c 2005-03-14 12:48:26.000000000 +0100 @@ -56,7 +56,7 @@ "dagger", 8224, "Dagger", 8225, "permil", 8240, - "lsquo", 8249, + "lsaquo", 8249, "rsaquo", 8250, "euro", 8364, diff -uNr dmd-0.118/dmd/src/dmd/expression.c dmd-0.119/dmd/src/dmd/expression.c --- dmd-0.118/dmd/src/dmd/expression.c 2005-03-10 16:00:40.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/expression.c 2005-03-17 22:11:44.000000000 +0100 @@ -57,7 +57,7 @@ while (1) { if (!fd) - { //printf("test1\n"); + { goto Lno; } if (!fd->isNested()) @@ -1037,8 +1037,8 @@ if (sc->func) thiscd = sc->func->parent->isClassDeclaration(); - // This should happen after overload resolution for functions, not before - if (s->needThis() && hasThis(sc)) + // BUG: This should happen after overload resolution for functions, not before + if (s->needThis() && hasThis(sc) /*&& !s->isFuncDeclaration()*/) { // Supply an implicit 'this', as in // this.ident @@ -1072,8 +1072,6 @@ e = ei->exp->copy(); // make copy so we can change loc if (e->op == TOKstring || !e->type) e = e->semantic(sc); -//printf("test5\n"); -//e->print(); e = e->implicitCastTo(type); e->loc = loc; return e; @@ -1274,7 +1272,8 @@ assert(s); cd = s->isClassDeclaration(); //printf("parent is %s %s\n", fd->toParent()->kind(), fd->toParent()->toChars()); - assert(cd); + if (!cd) + goto Lerr; if (!cd->baseClass) { error("no base class for %s", cd->toChars()); @@ -1297,7 +1296,7 @@ Lerr: - error("'super' is only allowed in non-static member functions"); + error("'super' is only allowed in non-static class member functions"); type = Type::tint32; return this; } @@ -1647,7 +1646,7 @@ Type *tb; #if LOGSEMANTIC - printf("NewExp::semantic()\n"); + printf("NewExp::semantic() %s\n", toChars()); //printf("type: %s\n", type->toChars()); #endif type = type->semantic(loc, sc); @@ -2517,8 +2516,25 @@ type = var->type; assert(type); - if (!var->isFuncDeclaration()) // do access check after overload resolution + if (!var->isFuncDeclaration()) // do checks after overload resolution + { + AggregateDeclaration *ad = var->parent->isAggregateDeclaration(); + Type *t = e1->type; + + if (ad && !(t->ty == Tpointer && t->next->ty == Tstruct && + ((TypeStruct *)t->next)->sym == ad)) + { + ClassDeclaration *cd = ad->isClassDeclaration(); + + if (!cd || + t->ty != Tclass || + !(((TypeClass *)t)->sym == cd || cd->isBaseOf(((TypeClass *)t)->sym, NULL)) + ) + error("this for %s needs to be type %s not type %s", + var->toChars(), ad->toChars(), t->toChars()); + } accessCheck(loc, sc, e1, var); + } } return this; } @@ -2827,6 +2843,7 @@ } } +Lagain: if (e1->op == TOKthis || e1->op == TOKsuper) { // semantic() run later for these @@ -2913,7 +2930,7 @@ if (ad && cd && ad->isClassDeclaration() && ad != cd && dve->e1->op != TOKsuper) { - dve->e1 = new CastExp(loc, dve->e1, ad->type); + dve->e1 = dve->e1->castTo(ad->type); //new CastExp(loc, dve->e1, ad->type); dve->e1 = dve->e1->semantic(sc); } } @@ -3033,6 +3050,16 @@ assert(f); f = f->overloadResolve(loc, arguments); checkDeprecated(sc, f); + + if (f->needThis() && hasThis(sc)) + { + // Supply an implicit 'this', as in + // this.ident + + e1 = new DotVarExp(loc, new ThisExp(loc), f); + goto Lagain; + } + ve->var = f; ve->type = f->type; t1 = f->type; @@ -3391,6 +3418,9 @@ #if LOGSEMANTIC printf("CastExp::semantic('%s')\n", toChars()); #endif + +//static int x; assert(++x < 10); + if (type) return this; UnaExp::semantic(sc); @@ -4636,10 +4666,12 @@ Type *tb1 = e1->type->toBasetype(); Type *tb2 = e2->type->toBasetype(); +#if 0 if (tb1->ty == Tsarray) e1 = e1->castTo(tb1->next->arrayOf()); if (tb2->ty == Tsarray) e2 = e2->castTo(tb2->next->arrayOf()); +#endif /* BUG: Should handle things like: * char c; @@ -4648,6 +4680,7 @@ */ typeCombine(); + #if 0 e1->type->print(); e2->type->print(); diff -uNr dmd-0.118/dmd/src/dmd/func.c dmd-0.119/dmd/src/dmd/func.c --- dmd-0.118/dmd/src/dmd/func.c 2005-03-12 14:18:12.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/func.c 2005-03-18 01:06:28.000000000 +0100 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2004 by Digital Mars +// Copyright (c) 1999-2005 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -280,6 +280,8 @@ L1: ; } + else if (isOverride() && !parent->isTemplateInstance()) + error("override only applies to class member functions"); /* Do not allow template instances to add virtual functions * to a class. @@ -559,14 +561,31 @@ // Postcondition invariant if (addPostInvariant()) { - ThisExp *v = new ThisExp(0); - v->type = vthis->type; - AssertExp *e = new AssertExp(0, v); - ExpStatement *s = new ExpStatement(0, e); - if (fensure) - fensure = new CompoundStatement(0, s, fensure); + Expression *e = NULL; + if (isCtorDeclaration()) + { + // Call invariant directly only if it exists + if (ad->inv) + { + e = new DsymbolExp(0, ad->inv); + e = new CallExp(0, e); + e = e->semantic(sc2); + } + } else - fensure = s; + { // Call invariant virtually + ThisExp *v = new ThisExp(0); + v->type = vthis->type; + e = new AssertExp(0, v); + } + if (e) + { + ExpStatement *s = new ExpStatement(0, e); + if (fensure) + fensure = new CompoundStatement(0, s, fensure); + else + fensure = s; + } } if (fensure) @@ -685,15 +704,28 @@ // Precondition invariant if (addPreInvariant()) { -#if 1 - ThisExp *v = new ThisExp(0); - v->type = vthis->type; -#else - VarExp *v = new VarExp(0, vthis); -#endif - AssertExp *e = new AssertExp(0, v); - ExpStatement *s = new ExpStatement(0, e); - a->push(s); + Expression *e = NULL; + if (isDtorDeclaration()) + { + // Call invariant directly only if it exists + if (ad->inv) + { + e = new DsymbolExp(0, ad->inv); + e = new CallExp(0, e); + e = e->semantic(sc2); + } + } + else + { // Call invariant virtually + ThisExp *v = new ThisExp(0); + v->type = vthis->type; + e = new AssertExp(0, v); + } + if (e) + { + ExpStatement *s = new ExpStatement(0, e); + a->push(s); + } } if (fbody) @@ -1089,7 +1121,7 @@ if (!thisfd || !thisfd->isNested()) { error(loc, "cannot access frame of function %s", fd->toChars()); - break; + return 1; } s = thisfd->toParent(); thisfd = s->isFuncDeclaration(); @@ -1197,6 +1229,7 @@ return (ad && //ad->isClassDeclaration() && global.params.useInvariants && + (protection == PROTpublic || protection == PROTexport) && !naked); } @@ -1207,6 +1240,7 @@ ad->inv && //ad->isClassDeclaration() && global.params.useInvariants && + (protection == PROTpublic || protection == PROTexport) && !naked); } diff -uNr dmd-0.118/dmd/src/dmd/lexer.c dmd-0.119/dmd/src/dmd/lexer.c --- dmd-0.118/dmd/src/dmd/lexer.c 2005-03-11 12:44:50.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/lexer.c 2005-03-16 14:58:50.000000000 +0100 @@ -401,7 +401,7 @@ do { c = *++p; - } while (isidchar(c) || (c & 0x80 && isUniIdent(c))); + } while (isidchar(c) || (c & 0x80 && isUniAlpha(decodeUTF()))); sv = stringtable.update((char *)t->ptr, p - t->ptr); id = (Identifier *) sv->ptrvalue; if (!id) @@ -477,8 +477,8 @@ while (1) { while (1) - { - switch (*p) + { unsigned char c = *p; + switch (c) { case '/': break; @@ -502,6 +502,8 @@ return; default: + if (c & 0x80) + decodeUTF(); p++; continue; } @@ -515,8 +517,8 @@ case '/': while (1) - { - switch (*++p) + { unsigned char c = *++p; + switch (c) { case '\n': break; @@ -533,6 +535,8 @@ return; default: + if (c & 0x80) + decodeUTF(); continue; } break; @@ -547,8 +551,8 @@ p++; nest = 1; while (1) - { - switch (*p) + { unsigned char c = *p; + switch (c) { case '/': p++; @@ -588,6 +592,8 @@ return; default: + if (c & 0x80) + decodeUTF(); p++; continue; } @@ -840,7 +846,7 @@ if (c & 0x80) { // Check for start of unicode identifier - if (isUniIdent(c)) + if (isUniAlpha(decodeUTF())) goto case_ident; } if (isprint(c)) @@ -938,7 +944,8 @@ break; default: - if (isalpha(*p)) + if (isalpha(*p) || + (p != idstart + 1 && isdigit(*p))) continue; error("unterminated named entity"); break; @@ -1152,31 +1159,10 @@ default: if (c & 0x80) - { unsigned char octet[6]; - unsigned idx = 0; - unsigned ndigits = 1; - char *s; - - octet[0] = c; - while (*p & 0x80) - { - if (*p & 0x40) - break; - if (ndigits >= 6) - { - Lutferr: - error("invalid UTF character sequence"); - break; - } - octet[ndigits] = *p; - ndigits++; - p++; - } - s = utf_decodeChar(octet, ndigits, &idx, &c); - if (s || idx != ndigits) - { error(s); - break; - } + { + p--; + c = decodeUTF(); + p++; stringbuffer.writeUTF8(c); continue; } @@ -1230,26 +1216,10 @@ default: if (c & 0x80) - { unsigned idx = 0; - unsigned ndigits = 1; - unsigned char octet[6]; - char *s; - - octet[0] = c; - while (*p & 0x80) - { - if (ndigits >= 6) - { - error("invalid UTF-8 sequence"); - break; - } - octet[ndigits] = *p; - ndigits++; - p++; - } - s = utf_decodeChar(octet, ndigits, &idx, &c); - if (s || idx != ndigits) - error(s); + { + p--; + c = decodeUTF(); + p++; if (c < 0xD800 || (c >= 0xE000 && c < 0xFFFE)) tk = TOKwcharv; else @@ -1943,19 +1913,26 @@ error("#line integer [\"filespec\"]\\n expected"); } -/********************************************* - * If c is the start of a Unicode identifier char, - * advance p past that character and return non-zero. + +/******************************************** + * Decode UTF character. + * Issue error messages for invalid sequences. + * Return decoded character, advance p to last character in UTF sequence. */ -int Lexer::isUniIdent(unsigned char c) +unsigned Lexer::decodeUTF() { + dchar_t u; + unsigned char c; unsigned char *s = p; unsigned len; unsigned idx; - dchar_t u; char *msg; + c = *s; + if (!(c & 0x80)) + return c; + // Check length of remaining string up to 6 UTF-8 characters for (len = 1; len < 6 && s[len]; len++) ; @@ -1966,15 +1943,8 @@ if (msg) { error(msg); - return 0; } - - if (isUniAlpha(u)) - { - return 1; - } - - return 0; + return u; } /******************************************** @@ -2221,4 +2191,5 @@ Token::tochars[TOKsymoff] = "symoff"; Token::tochars[TOKtypedot] = "typedot"; Token::tochars[TOKarraylength] = "arraylength"; + Token::tochars[TOKstring] = "string"; } diff -uNr dmd-0.118/dmd/src/dmd/lexer.h dmd-0.119/dmd/src/dmd/lexer.h --- dmd-0.118/dmd/src/dmd/lexer.h 2005-03-09 18:06:18.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/lexer.h 2005-03-14 16:38:12.000000000 +0100 @@ -240,7 +240,7 @@ TOK inreal(Token *t); void error(const char *format, ...); void pragma(); - int isUniIdent(unsigned char c); + unsigned decodeUTF(); }; #endif /* DMD_LEXER_H */ diff -uNr dmd-0.118/dmd/src/dmd/mangle.c dmd-0.119/dmd/src/dmd/mangle.c --- dmd-0.118/dmd/src/dmd/mangle.c 2005-03-12 14:52:36.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/mangle.c 2005-03-17 19:30:56.000000000 +0100 @@ -70,29 +70,33 @@ do { //printf("s = %p, '%s', parent = %p\n", s, s->toChars(), s->parent); -#if 1 if (s->ident) - { id = s->ident->toChars(); - int len = strlen(id); - char tmp[sizeof(len) * 3 + 1]; - buf.prependstring(id); - sprintf(tmp, "%d", len); - buf.prependstring(tmp); + { + FuncDeclaration *fd = s->isFuncDeclaration(); + if (s != this && fd) + { + id = fd->mangle(); + buf.prependstring(id); + goto L1; + } + else + { + id = s->ident->toChars(); + int len = strlen(id); + char tmp[sizeof(len) * 3 + 1]; + buf.prependstring(id); + sprintf(tmp, "%d", len); + buf.prependstring(tmp); + } } else buf.prependstring("0"); -#else - if (s->ident) - { buf.prependstring("_"); - buf.prependstring(s->ident->toChars()); - } - else - buf.prependstring("_"); -#endif s = s->parent; } while (s); buf.prependstring("_D"); + L1: + //printf("deco = '%s'\n", type->deco); buf.writestring(type->deco); id = buf.toChars(); @@ -158,6 +162,7 @@ char *TemplateInstance::mangle() { + //printf("TemplateInstance::mangle() '%s'\n", toChars()); return Dsymbol::mangle(); } diff -uNr dmd-0.118/dmd/src/dmd/mars.c dmd-0.119/dmd/src/dmd/mars.c --- dmd-0.118/dmd/src/dmd/mars.c 2005-03-12 13:48:28.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/mars.c 2005-03-14 12:58:30.000000000 +0100 @@ -49,7 +49,7 @@ copyright = "Copyright (c) 1999-2005 by Digital Mars"; written = "written by Walter Bright"; - version = "v0.118"; + version = "v0.119"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); diff -uNr dmd-0.118/dmd/src/dmd/mtype.c dmd-0.119/dmd/src/dmd/mtype.c --- dmd-0.118/dmd/src/dmd/mtype.c 2005-03-07 14:36:22.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/mtype.c 2005-03-17 22:42:38.000000000 +0100 @@ -41,6 +41,8 @@ #include "import.h" #include "aggregate.h" +FuncDeclaration *hasThis(Scope *sc); + #define LOGDOTEXP 0 // log ::dotExp() #define LOGDEFAULTINIT 0 // log ::defaultInit() @@ -1939,7 +1941,10 @@ Type *TypePointer::semantic(Loc loc, Scope *sc) { //printf("TypePointer::semantic()\n"); - next = next->semantic(loc,sc); + Type *n = next->semantic(loc, sc); + if (n != next) + deco = NULL; + next = n; return merge(); } @@ -3472,6 +3477,8 @@ { return getProperty(e->loc, ident); } + s = s->toAlias(); + v = s->isVarDeclaration(); if (v && v->isConst()) { ExpInitializer *ei = v->getExpInitializer(); @@ -3482,7 +3489,8 @@ if (s->getType()) { - return new DotTypeExp(e->loc, e, s); + //return new DotTypeExp(e->loc, e, s); + return new TypeExp(e->loc, s->getType()); } EnumMember *em = s->isEnumMember(); @@ -3537,6 +3545,9 @@ if (v) { + if (v->toParent() != sym) + sym->error(e->loc, "'%s' is not a member", v->toChars()); + // *(&e + offset) b = new AddrExp(e->loc, e); b->type = e->type->pointerTo(); @@ -3587,7 +3598,7 @@ char *TypeClass::toChars() { - return sym->toChars(); + return sym->toPrettyChars(); } Type *TypeClass::syntaxCopy() @@ -3618,6 +3629,7 @@ char *name; name = sym->mangle(); + //printf("TypeClass::toDecoBuffer('%s') = '%s'\n", toChars(), name); //len = strlen(name); //buf->printf("%c%d%s", mangleChar[ty], len, name); buf->printf("%c%s", mangleChar[ty], name); @@ -3722,9 +3734,9 @@ if (s->getType()) { - if (e->op == TOKtype) +// if (e->op == TOKtype) return new TypeExp(e->loc, s->getType()); - return new DotTypeExp(e->loc, e, s); +// return new DotTypeExp(e->loc, e, s); } EnumMember *em = s->isEnumMember(); @@ -3754,7 +3766,7 @@ { VarExp *ve; - if (d->needThis()) + if (d->needThis() && (hasThis(sc) || !d->isFuncDeclaration())) { if (sc->func) { diff -uNr dmd-0.118/dmd/src/dmd/parse.c dmd-0.119/dmd/src/dmd/parse.c --- dmd-0.118/dmd/src/dmd/parse.c 2005-03-09 10:17:34.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/parse.c 2005-03-17 21:10:16.000000000 +0100 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2004 by Digital Mars +// Copyright (c) 1999-2005 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -1281,12 +1281,12 @@ goto Lerr; } id = token.ident; + nextToken(); } idents = new Array(); while (1) { - nextToken(); tiargs = NULL; if (token.value == TOKnot) { @@ -1311,6 +1311,7 @@ break; } id = token.ident; + nextToken(); } idents->push(id); @@ -2788,6 +2789,7 @@ Catch *c; Type *t; Identifier *id; + Loc loc = this->loc; nextToken(); if (token.value == TOKlcurly) @@ -3183,6 +3185,7 @@ case TOKcomma: case TOKsemicolon: case TOKlcurly: + case TOKin: // The !parens is to disallow unnecessary parentheses if (!parens && (endtok == TOKreserved || endtok == t->value)) { *pt = t; @@ -4016,8 +4019,7 @@ { e = parseUnaryExp(); e = new CastExp(loc, e, t); - if (!global.params.useDeprecated) - error("C style cast deprecated, use %s", e->toChars()); + error("C style cast illegal, use %s", e->toChars()); } return e; } diff -uNr dmd-0.118/dmd/src/dmd/scope.c dmd-0.119/dmd/src/dmd/scope.c --- dmd-0.118/dmd/src/dmd/scope.c 2005-03-05 09:25:02.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/scope.c 2005-03-13 15:20:48.000000000 +0100 @@ -44,6 +44,7 @@ this->enclosing = NULL; this->parent = NULL; this->sw = NULL; + this->tf = NULL; this->sbreak = NULL; this->scontinue = NULL; this->fes = NULL; @@ -70,6 +71,7 @@ this->parent = enclosing->parent; this->scopesym = NULL; this->sw = enclosing->sw; + this->tf = enclosing->tf; this->sbreak = enclosing->sbreak; this->scontinue = enclosing->scontinue; this->fes = enclosing->fes; diff -uNr dmd-0.118/dmd/src/dmd/scope.h dmd-0.119/dmd/src/dmd/scope.h --- dmd-0.118/dmd/src/dmd/scope.h 2004-12-02 19:35:46.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/scope.h 2005-03-13 15:20:48.000000000 +0100 @@ -21,6 +21,7 @@ struct Module; struct Statement; struct SwitchStatement; +struct TryFinallyStatement; struct LabelStatement; struct ForeachStatement; struct ClassDeclaration; @@ -40,6 +41,7 @@ Dsymbol *parent; // parent to use LabelStatement *slabel; // enclosing labelled statement SwitchStatement *sw; // enclosing switch statement + TryFinallyStatement *tf; // enclosing try finally statement Statement *sbreak; // enclosing statement that supports "break" Statement *scontinue; // enclosing statement that supports "continue" ForeachStatement *fes; // if nested function for ForeachStatement, this is it diff -uNr dmd-0.118/dmd/src/dmd/statement.c dmd-0.119/dmd/src/dmd/statement.c --- dmd-0.118/dmd/src/dmd/statement.c 2005-03-11 13:26:06.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/statement.c 2005-03-17 21:11:24.000000000 +0100 @@ -1632,6 +1632,8 @@ if (sc->incontract) error("return statements cannot be in contracts"); + if (sc->tf) + error("return statements cannot be in finally bodies"); if (fd->isCtorDeclaration()) { @@ -1762,6 +1764,8 @@ if (!s->hasBreak()) error("label '%s' has no break", ident->toChars()); + if (ls->tf != sc->tf) + error("cannot break out of finally block"); return this; } } @@ -1837,6 +1841,8 @@ if (!s->hasContinue()) error("label '%s' has no continue", ident->toChars()); + if (ls->tf != sc->tf) + error("cannot continue out of finally block"); return this; } } @@ -2043,6 +2049,16 @@ c = (Catch *)catches->data[i]; c->semantic(sc); + + // Determine if current catch 'hides' any previous catches + for (int j = 0; j < i; j++) + { Catch *cj = (Catch *)catches->data[j]; + char *si = c->loc.toChars(); + char *sj = cj->loc.toChars(); + + if (c->type->implicitConvTo(cj->type)) + error("catch at %s hides catch at %s", sj, si); + } } return this; } @@ -2076,6 +2092,7 @@ Catch::Catch(Loc loc, Type *t, Identifier *id, Statement *handler) { + //printf("Catch(loc = %s)\n", loc.toChars()); this->loc = loc; this->type = t; this->ident = id; @@ -2096,6 +2113,17 @@ //printf("Catch::semantic()\n"); + if (sc->tf) + { + /* This is because the _d_local_unwind() gets the stack munged + * up on this. The workaround is to place any try-catches into + * a separate function, and call that. + * To fix, have the compiler automatically convert the finally + * body into a nested function. + */ + error(loc, "cannot put catch statement inside finally block"); + } + sym = new ScopeDsymbol(); sym->parent = sc->scopesym; sc = sc->push(sym); @@ -2135,7 +2163,12 @@ Statement *TryFinallyStatement::semantic(Scope *sc) { body = body->semantic(sc); + sc = sc->push(); + sc->tf = this; + sc->sbreak = NULL; + sc->scontinue = NULL; // no break or continue out of finally block finalbody = finalbody->semantic(sc); + sc->pop(); return this; } @@ -2190,7 +2223,7 @@ error("Throw statements cannot be in contracts"); exp = exp->semantic(sc); exp = resolveProperties(sc, exp); - if (!exp->type->isClassHandle()) + if (!exp->type->toBasetype()->isClassHandle()) error("can only throw class objects, not type %s", exp->type->toChars()); return this; } @@ -2251,6 +2284,7 @@ { this->ident = ident; this->label = NULL; + this->tf = NULL; } Statement *GotoStatement::syntaxCopy() @@ -2263,6 +2297,7 @@ { FuncDeclaration *fd = sc->parent->isFuncDeclaration(); //printf("GotoStatement::semantic()\n"); + tf = sc->tf; label = fd->searchLabel(ident); if (!label->statement && sc->fes) { @@ -2280,6 +2315,8 @@ sc->fes->gotos.push(s); // 'look at this later' list return s; } + if (label->statement && label->statement->tf != sc->tf) + error("cannot goto in or out of finally block"); return this; } @@ -2295,6 +2332,7 @@ { this->ident = ident; this->statement = statement; + this->tf = NULL; this->lblock = NULL; this->isReturnLabel = 0; } @@ -2309,17 +2347,19 @@ { LabelDsymbol *ls; FuncDeclaration *fd = sc->parent->isFuncDeclaration(); + //printf("LabelStatement::semantic()\n"); + ls = fd->searchLabel(ident); + if (ls->statement) + error("Label '%s' already defined", ls->toChars()); + else + ls->statement = this; + tf = sc->tf; sc = sc->push(); sc->scopesym = sc->enclosing->scopesym; sc->callSuper |= CSXlabel; sc->slabel = this; statement = statement->semantic(sc); - ls = fd->searchLabel(ident); sc->pop(); - if (ls->statement) - error("Label '%s' already defined", ls->toChars()); - else - ls->statement = this; return this; } diff -uNr dmd-0.118/dmd/src/dmd/statement.h dmd-0.119/dmd/src/dmd/statement.h --- dmd-0.118/dmd/src/dmd/statement.h 2005-03-01 02:08:46.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/statement.h 2005-03-13 16:30:00.000000000 +0100 @@ -557,6 +557,7 @@ { Identifier *ident; LabelDsymbol *label; + TryFinallyStatement *tf; GotoStatement(Loc loc, Identifier *ident); Statement *syntaxCopy(); @@ -570,6 +571,7 @@ { Identifier *ident; Statement *statement; + TryFinallyStatement *tf; block *lblock; // back end int isReturnLabel; diff -uNr dmd-0.118/dmd/src/dmd/template.c dmd-0.119/dmd/src/dmd/template.c --- dmd-0.118/dmd/src/dmd/template.c 2005-03-10 00:57:04.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/template.c 2005-03-17 19:41:26.000000000 +0100 @@ -1671,6 +1671,12 @@ ea = NULL; goto Lsa; } + if (ea->op == TOKfunction) + { + sa = ((FuncExp *)ea)->fd; + ea = NULL; + goto Lsa; + } buf.writeByte('_'); buf.printf("%u", ea->toInteger()); } @@ -1678,7 +1684,7 @@ { Lsa: Declaration *d = sa->isDeclaration(); - if (d && !d->isDataseg() && !d->isFuncDeclaration()) + if (d && !d->isDataseg() && !d->isFuncDeclaration() && !isTemplateMixin()) { error("cannot use local '%s' as template parameter", d->toChars()); } @@ -1930,6 +1936,7 @@ Array *idents, Array *tiargs) : TemplateInstance(loc, (Identifier *)idents->data[idents->dim - 1]) { + //printf("TemplateMixin(ident = '%s')\n", ident ? ident->toChars() : ""); this->ident = ident; this->tqual = tqual; this->idents = idents; @@ -2058,8 +2065,8 @@ return; // error recovery } -// if (!ident) -// ident = genIdent(); + if (!ident) + ident = genIdent(); inst = this; parent = sc->parent; diff -uNr dmd-0.118/dmd/src/dmd/toobj.c dmd-0.119/dmd/src/dmd/toobj.c --- dmd-0.118/dmd/src/dmd/toobj.c 2005-02-25 21:23:12.000000000 +0100 +++ dmd-0.119/dmd/src/dmd/toobj.c 2005-03-16 12:32:44.000000000 +0100 @@ -740,6 +740,11 @@ sinit->Sfl = FLdata; toDt(&sinit->Sdt); +#if !ELFOBJ + /* ELF comdef's generate multiple + * definition errors for them from the gnu linker. + * Need to figure out how to generate proper comdef's for ELF. + */ // See if we can convert a comdat to a comdef, // which saves on exe file space. if (sinit->Sclass == SCcomdat && @@ -749,6 +754,7 @@ sinit->Sclass = SCglobal; sinit->Sdt->dt = DT_common; } +#endif #if ELFOBJ // Burton sinit->Sseg = CDATA; diff -uNr dmd-0.118/dmd/src/dmd/version.c dmd-0.119/dmd/src/dmd/version.c --- dmd-0.118/dmd/src/dmd/version.c 2004-08-30 00:51:18.000000000 +0200 +++ dmd-0.119/dmd/src/dmd/version.c 2005-03-17 23:07:06.000000000 +0100 @@ -101,6 +101,7 @@ m = sd->isModule(); if (ident) { + VersionCondition::checkPredefined(ident->toChars()); if (!m) error("declaration must be at module level"); else @@ -136,7 +137,7 @@ char *VersionSymbol::kind() { - return "kind"; + return "version"; } diff -uNr dmd-0.118/dmd/src/phobos/internal/deh2.d dmd-0.119/dmd/src/phobos/internal/deh2.d --- dmd-0.118/dmd/src/phobos/internal/deh2.d 2005-03-12 16:52:52.000000000 +0100 +++ dmd-0.119/dmd/src/phobos/internal/deh2.d 2005-03-18 09:29:40.000000000 +0100 @@ -1,7 +1,25 @@ -// -// Copyright (c) 1999-2003 by Digital Mars, www.digitalmars.com -// All Rights Reserved -// Written by Walter Bright +/* + * Copyright (C) 1999-2005 by Digital Mars, www.digitalmars.com + * Written by Walter Bright + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, in both source and binary form, subject to the following + * restrictions: + * + * o The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * o Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * o This notice may not be removed or altered from any source + * distribution. + */ // Exception handling support for linux diff -uNr dmd-0.118/dmd/src/phobos/linux.mak dmd-0.119/dmd/src/phobos/linux.mak --- dmd-0.118/dmd/src/phobos/linux.mak 2005-03-12 16:52:48.000000000 +0100 +++ dmd-0.119/dmd/src/phobos/linux.mak 2005-03-18 09:29:36.000000000 +0100 @@ -67,6 +67,7 @@ ti_Aint.o ti_Auint.o ti_Along.o ti_Aulong.o ti_Awchar.o \ ti_Afloat.o ti_Adouble.o ti_Areal.o \ ti_Acfloat.o ti_Acdouble.o ti_Acreal.o \ + ti_Abit.o ti_void.o \ date.o dateparse.o llmath.o math2.o Czlib.o Dzlib.o zip.o recls.o ZLIB_OBJS= etc/c/zlib/adler32.o etc/c/zlib/compress.o \ @@ -120,10 +121,11 @@ std/typeinfo/ti_int.d std/typeinfo/ti_char.d \ std/typeinfo/ti_Aint.d std/typeinfo/ti_Auint.d \ std/typeinfo/ti_Along.d std/typeinfo/ti_Aulong.d \ - std\typeinfo/ti_Afloat.d std\typeinfo/ti_Adouble.d \ - std\typeinfo/ti_Areal.d \ - std\typeinfo/ti_Acfloat.d std\typeinfo/ti_Acdouble.d \ - std\typeinfo/ti_Acreal.d \ + std/typeinfo/ti_Afloat.d std/typeinfo/ti_Adouble.d \ + std/typeinfo/ti_Areal.d \ + std/typeinfo/ti_Acfloat.d std/typeinfo/ti_Acdouble.d \ + std/typeinfo/ti_Acreal.d \ + std/typeinfo/ti_Abit.d std/typeinfo/ti_void.d \ std/typeinfo/ti_Awchar.d std/typeinfo/ti_dchar.d SRC_INT= \ @@ -599,6 +601,9 @@ ### std/typeinfo +ti_void.o : std/typeinfo/ti_void.d + $(DMD) -c $(DFLAGS) std/typeinfo/ti_void.d + ti_wchar.o : std/typeinfo/ti_wchar.d $(DMD) -c $(DFLAGS) std/typeinfo/ti_wchar.d @@ -668,6 +673,9 @@ ti_Ag.o : std/typeinfo/ti_Ag.d $(DMD) -c $(DFLAGS) std/typeinfo/ti_Ag.d +ti_Abit.o : std/typeinfo/ti_Abit.d + $(DMD) -c $(DFLAGS) std/typeinfo/ti_Abit.d + ti_Aubyte.o : std/typeinfo/ti_Aubyte.d $(DMD) -c $(DFLAGS) std/typeinfo/ti_Aubyte.d diff -uNr dmd-0.118/dmd/src/phobos/std/typeinfo/ti_Abit.d dmd-0.119/dmd/src/phobos/std/typeinfo/ti_Abit.d --- dmd-0.118/dmd/src/phobos/std/typeinfo/ti_Abit.d 1970-01-01 01:00:00.000000000 +0100 +++ dmd-0.119/dmd/src/phobos/std/typeinfo/ti_Abit.d 2005-03-18 09:29:38.000000000 +0100 @@ -0,0 +1,95 @@ + +private import std.string; + +// bit[] + +class TypeInfo_Ab : TypeInfo +{ + char[] toString() { return "bit[]"; } + + uint getHash(void *p) + { ubyte[] s = *cast(ubyte[]*)p; + uint len = (s.length + 7) / 8; + ubyte *str = s; + uint hash = 0; + + while (1) + { + switch (len) + { + case 0: + return hash; + + case 1: + hash *= 9; + hash += *cast(ubyte *)str; + return hash; + + case 2: + hash *= 9; + hash += *cast(ushort *)str; + return hash; + + case 3: + hash *= 9; + hash += (*cast(ushort *)str << 8) + + (cast(ubyte *)str)[2]; + return hash; + + default: + hash *= 9; + hash += *cast(uint *)str; + str += 4; + len -= 4; + break; + } + } + + return hash; + } + + int equals(void *p1, void *p2) + { + bit[] s1 = *cast(bit[]*)p1; + bit[] s2 = *cast(bit[]*)p2; + + uint len = s1.length; + + if (s2.length != len) + return 0;; + + // Woefully inefficient bit-by-bit comparison + for (uint u = 0; u < len; u++) + { + if (s1[u] != s2[u]) + return 0; + } + return 1; + } + + int compare(void *p1, void *p2) + { + bit[] s1 = *cast(bit[]*)p1; + bit[] s2 = *cast(bit[]*)p2; + + uint len = s1.length; + + if (s2.length < len) + len = s2.length; + + // Woefully inefficient bit-by-bit comparison + for (uint u = 0; u < len; u++) + { + int result = s1[u] - s2[u]; + if (result) + return result; + } + return cast(int)s1.length - cast(int)s2.length; + } + + int tsize() + { + return (bit[]).sizeof; + } +} + diff -uNr dmd-0.118/dmd/src/phobos/std/typeinfo/ti_Aubyte.d dmd-0.119/dmd/src/phobos/std/typeinfo/ti_Aubyte.d --- dmd-0.118/dmd/src/phobos/std/typeinfo/ti_Aubyte.d 2005-03-12 16:52:52.000000000 +0100 +++ dmd-0.119/dmd/src/phobos/std/typeinfo/ti_Aubyte.d 2005-03-18 09:29:38.000000000 +0100 @@ -5,6 +5,8 @@ class TypeInfo_Ah : TypeInfo { + char[] toString() { return "ubyte[]"; } + uint getHash(void *p) { ubyte[] s = *cast(ubyte[]*)p; uint len = s.length; @@ -69,3 +71,9 @@ } } +// void[] + +class TypeInfo_Av : TypeInfo_Ah +{ + char[] toString() { return "void[]"; } +} diff -uNr dmd-0.118/dmd/src/phobos/std/typeinfo/ti_void.d dmd-0.119/dmd/src/phobos/std/typeinfo/ti_void.d --- dmd-0.118/dmd/src/phobos/std/typeinfo/ti_void.d 1970-01-01 01:00:00.000000000 +0100 +++ dmd-0.119/dmd/src/phobos/std/typeinfo/ti_void.d 2005-03-18 09:29:38.000000000 +0100 @@ -0,0 +1,42 @@ + +// void + +class TypeInfo_v : TypeInfo +{ + char[] toString() { return "void"; } + + uint getHash(void *p) + { + assert(0); + return *cast(byte *)p; + } + + int equals(void *p1, void *p2) + { + assert(0); + return *cast(byte *)p1 == *cast(byte *)p2; + } + + int compare(void *p1, void *p2) + { + assert(0); + return *cast(byte *)p1 - *cast(byte *)p2; + } + + int tsize() + { + assert(0); + return byte.sizeof; + } + + void swap(void *p1, void *p2) + { + byte t; + + assert(0); + t = *cast(byte *)p1; + *cast(byte *)p1 = *cast(byte *)p2; + *cast(byte *)p2 = t; + } +} + diff -uNr dmd-0.118/dmd/src/phobos/win32.mak dmd-0.119/dmd/src/phobos/win32.mak --- dmd-0.118/dmd/src/phobos/win32.mak 2005-03-12 16:52:48.000000000 +0100 +++ dmd-0.119/dmd/src/phobos/win32.mak 2005-03-18 09:29:36.000000000 +0100 @@ -47,7 +47,7 @@ $(DMD) -c test -g test.exe : test.obj phobos.lib - $(DMD) test.obj -g + $(DMD) test.obj -g -L/map unittest.exe : unittest.d phobos.lib $(DMD) unittest -g @@ -76,7 +76,7 @@ ti_Aint.obj ti_Auint.obj ti_Along.obj ti_Aulong.obj ti_Awchar.obj \ ti_Afloat.obj ti_Adouble.obj ti_Areal.obj \ ti_Acfloat.obj ti_Acdouble.obj ti_Acreal.obj \ - ti_dchar.obj ti_Adchar.obj ti_bit.obj + ti_dchar.obj ti_Adchar.obj ti_bit.obj ti_Abit.obj ti_void.obj SRC= errno.c object.d unittest.d crc32.d gcstats.d @@ -116,7 +116,8 @@ std\typeinfo\ti_Areal.d \ std\typeinfo\ti_Acfloat.d std\typeinfo\ti_Acdouble.d \ std\typeinfo\ti_Acreal.d \ - std\typeinfo\ti_Awchar.d std\typeinfo\ti_dchar.d + std\typeinfo\ti_Awchar.d std\typeinfo\ti_dchar.d \ + std\typeinfo\ti_Abit.d std\typeinfo\ti_void.d SRC_INT= \ internal\switch.d internal\complex.c internal\critical.c \ @@ -579,6 +580,9 @@ ### std\typeinfo +ti_void.obj : std\typeinfo\ti_void.d + $(DMD) -c $(DFLAGS) std\typeinfo\ti_void.d + ti_bit.obj : std\typeinfo\ti_bit.d $(DMD) -c $(DFLAGS) std\typeinfo\ti_bit.d @@ -651,6 +655,9 @@ ti_Ag.obj : std\typeinfo\ti_Ag.d $(DMD) -c $(DFLAGS) std\typeinfo\ti_Ag.d +ti_Abit.obj : std\typeinfo\ti_Abit.d + $(DMD) -c $(DFLAGS) std\typeinfo\ti_Abit.d + ti_Aubyte.obj : std\typeinfo\ti_Aubyte.d $(DMD) -c $(DFLAGS) std\typeinfo\ti_Aubyte.d