diff -uNr dmd-0.109/dmd/src/dmd/aggregate.h dmd-0.110/dmd/src/dmd/aggregate.h --- dmd-0.109/dmd/src/dmd/aggregate.h 2004-12-03 01:12:44.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/aggregate.h 2004-12-30 00:15:36.000000000 +0100 @@ -42,6 +42,10 @@ unsigned structalign; // struct member alignment in effect Array fields; // VarDeclaration fields unsigned sizeok; // set when structsize contains valid data + // 0: no size + // 1: size is correct + // 2: cannot determine size; fwd referenced + Scope *scope; // !=NULL means context to use // Special member functions InvariantDeclaration *inv; // invariant @@ -53,7 +57,7 @@ void semantic2(Scope *sc); void semantic3(Scope *sc); void inlineScan(); - unsigned size(); + unsigned size(Loc loc); static void alignmember(unsigned salign, unsigned size, unsigned *poffset); Type *getType(); void addField(Scope *sc, VarDeclaration *v); @@ -150,7 +154,6 @@ ClassInfoDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration int com; // !=0 if this is a COM class int isauto; // !=0 if this is an auto class - Scope *scope; // !=NULL means context to use ClassDeclaration(Loc loc, Identifier *id, Array *baseclasses); Dsymbol *syntaxCopy(Dsymbol *s); diff -uNr dmd-0.109/dmd/src/dmd/cast.c dmd-0.110/dmd/src/dmd/cast.c --- dmd-0.109/dmd/src/dmd/cast.c 2004-11-29 15:02:14.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/cast.c 2004-12-19 13:08:20.000000000 +0100 @@ -39,6 +39,8 @@ type->print(); 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); #endif //*(char*)0=0; error("cannot implicitly convert expression %s of type %s to %s", toChars(), type->toChars(), t->toChars()); diff -uNr dmd-0.109/dmd/src/dmd/class.c dmd-0.110/dmd/src/dmd/class.c --- dmd-0.109/dmd/src/dmd/class.c 2004-12-01 01:42:18.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/class.c 2004-12-30 00:19:38.000000000 +0100 @@ -57,6 +57,9 @@ vtblsym = NULL; vclassinfo = NULL; + if (id == Id::__sizeof) + error("illegal class name"); + // BUG: What if this is the wrong ClassInfo, i.e. it is nested? if (!classinfo && id == Id::ClassInfo) classinfo = this; @@ -72,6 +75,9 @@ if (!Type::typeinfoclass && id == Id::TypeInfo_Class) Type::typeinfoclass = this; + if (!Type::typeinfostruct && id == Id::TypeInfo_Struct) + Type::typeinfostruct = this; + if (!Type::typeinfotypedef && id == Id::TypeInfo_Typedef) Type::typeinfotypedef = this; @@ -81,7 +87,6 @@ com = 1; #endif isauto = 0; - scope = NULL; } Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s) @@ -110,7 +115,7 @@ { int i; unsigned offset; - //printf("ClassDeclaration::semantic(%s), type = %p\n", toChars(), type); + //printf("ClassDeclaration::semantic(%s), type = %p, sizeok = %d\n", toChars(), type, sizeok); //{ static int n; if (++n == 20) *(char*)0=0; } @@ -119,12 +124,14 @@ handle = handle->semantic(loc, sc); } if (!members) // if forward reference - { //printf("\tclass '%s' is forward referenced\n", toChars()); + { printf("\tclass '%s' is forward referenced\n", toChars()); return; } if (symtab) { if (!scope) + { //printf("\tsemantic for '%s' is already completed\n", toChars()); return; // semantic() already completed + } } else symtab = new DsymbolTable(); @@ -165,7 +172,7 @@ { //error("forward reference of base class %s", baseClass->toChars()); // Forward reference of base class, try again later - //printf("\ttry later, forward reference of base class %s\n", baseClass->toChars()); + //printf("\ttry later, forward reference of base class %s\n", tc->sym->toChars()); scope = scx ? scx : new Scope(*sc); scope->setNoFree(); scope->module->addDeferredSemantic(this); @@ -255,24 +262,28 @@ else { // No base class, so this is the root of the class heirarchy + vtbl.setDim(0); vtbl.push(this); // leave room for classinfo as first member } + if (sizeok == 0) + { + interfaceSemantic(sc); + + for (i = 0; i < members->dim; i++) + { + Dsymbol *s = (Dsymbol *)members->data[i]; + s->addMember(this); + } + } + if (sc->stc & STCauto) isauto = 1; - interfaceSemantic(sc); - sc = sc->push(this); sc->stc &= ~(STCauto | STCstatic); sc->parent = this; - for (i = 0; i < members->dim; i++) - { - Dsymbol *s = (Dsymbol *)members->data[i]; - s->addMember(this); - } - if (isCOMclass()) sc->linkage = LINKwindows; sc->protection = PROTpublic; @@ -289,11 +300,31 @@ structsize = sc->offset; Scope scsave = *sc; int members_dim = members->dim; + sizeok = 0; for (i = 0; i < members_dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; s->semantic(sc); } + + if (sizeok == 2) + { // semantic() failed because of forward references. + // Unwind what we did, and defer it for later + fields.setDim(0); + structsize = 0; + alignsize = 0; + structalign = 0; + + sc->pop(); + + scope = scx ? scx : new Scope(*sc); + scope->setNoFree(); + scope->module->addDeferredSemantic(this); + return; + } + + //printf("\tsemantic('%s') successful\n", toChars()); + structsize = sc->offset; //members->print(); diff -uNr dmd-0.109/dmd/src/dmd/declaration.c dmd-0.110/dmd/src/dmd/declaration.c --- dmd-0.109/dmd/src/dmd/declaration.c 2004-12-02 19:49:14.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/declaration.c 2004-12-14 01:29:50.000000000 +0100 @@ -41,7 +41,7 @@ return "declaration"; } -unsigned Declaration::size() +unsigned Declaration::size(Loc loc) { assert(type); return type->size(); @@ -706,6 +706,13 @@ assert(linkage == LINKc); } +/***************************** TypeInfoStructDeclaration ***********************/ + +TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo) + : TypeInfoDeclaration(tinfo, 0) +{ +} + /***************************** TypeInfoClassDeclaration ***********************/ TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo) diff -uNr dmd-0.109/dmd/src/dmd/declaration.h dmd-0.110/dmd/src/dmd/declaration.h --- dmd-0.109/dmd/src/dmd/declaration.h 2004-10-03 15:03:38.000000000 +0200 +++ dmd-0.110/dmd/src/dmd/declaration.h 2004-12-14 01:05:26.000000000 +0100 @@ -74,7 +74,7 @@ Declaration(Identifier *id); void semantic(Scope *sc); char *kind(); - unsigned size(); + unsigned size(Loc loc); char *mangle(); int isStatic() { return storage_class & STCstatic; } @@ -215,6 +215,13 @@ virtual void toDt(dt_t **pdt); }; +struct TypeInfoStructDeclaration : TypeInfoDeclaration +{ + TypeInfoStructDeclaration(Type *tinfo); + + void toDt(dt_t **pdt); +}; + struct TypeInfoClassDeclaration : TypeInfoDeclaration { TypeInfoClassDeclaration(Type *tinfo); diff -uNr dmd-0.109/dmd/src/dmd/dsymbol.c dmd-0.110/dmd/src/dmd/dsymbol.c --- dmd-0.109/dmd/src/dmd/dsymbol.c 2004-10-27 19:14:04.000000000 +0200 +++ dmd-0.110/dmd/src/dmd/dsymbol.c 2004-12-30 00:16:32.000000000 +0100 @@ -192,7 +192,7 @@ buf->writenl(); } -unsigned Dsymbol::size() +unsigned Dsymbol::size(Loc loc) { error("Dsymbol '%s' has no size\n", toChars()); return 0; @@ -274,6 +274,11 @@ sd->multiplyDefined(this, s2); } } + if (sd->isAggregateDeclaration() || sd->isEnumDeclaration()) + { + if (ident == Id::__sizeof) + error(".sizeof property cannot be redefined"); + } } } @@ -611,7 +616,7 @@ assert(ident); assert(tab); //#endif - sv = tab->lookup(ident->toChars(),strlen(ident->toChars())); + sv = tab->lookup((char*)ident->string, ident->len); return (Dsymbol *)(sv ? sv->ptrvalue : NULL); } @@ -625,7 +630,7 @@ assert(ident); assert(tab); #endif - sv = tab->insert(ident->toChars(),strlen(ident->toChars())); + sv = tab->insert(ident->toChars(), ident->len); if (!sv) return NULL; // already in table sv->ptrvalue = s; @@ -636,7 +641,7 @@ { StringValue *sv; //printf("DsymbolTable::insert()\n"); - sv = tab->insert(ident->toChars(),strlen(ident->toChars())); + sv = tab->insert(ident->toChars(), ident->len); if (!sv) return NULL; // already in table sv->ptrvalue = s; @@ -648,7 +653,7 @@ Identifier *ident; ident = s->ident; - sv = tab->update(ident->toChars(),strlen(ident->toChars())); + sv = tab->update(ident->toChars(), ident->len); sv->ptrvalue = s; return s; } diff -uNr dmd-0.109/dmd/src/dmd/dsymbol.h dmd-0.110/dmd/src/dmd/dsymbol.h --- dmd-0.109/dmd/src/dmd/dsymbol.h 2004-11-04 21:30:36.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/dsymbol.h 2004-12-30 00:17:50.000000000 +0100 @@ -26,6 +26,7 @@ struct TypedefDeclaration; struct AliasDeclaration; struct AggregateDeclaration; +struct EnumDeclaration; struct ClassDeclaration; struct InterfaceDeclaration; struct StructDeclaration; @@ -107,7 +108,7 @@ virtual Dsymbol *search(Identifier *ident, int flags); virtual int overloadInsert(Dsymbol *s); virtual void toCBuffer(OutBuffer *buf); - virtual unsigned size(); + virtual unsigned size(Loc loc); virtual int isforwardRef(); virtual void defineRef(Dsymbol *s); virtual AggregateDeclaration *isThis(); // is a 'this' required to access the member @@ -165,6 +166,7 @@ virtual WithScopeSymbol *isWithScopeSymbol() { return NULL; } virtual ArrayScopeSymbol *isArrayScopeSymbol() { return NULL; } virtual Import *isImport() { return NULL; } + virtual EnumDeclaration *isEnumDeclaration() { return NULL; } }; // Dsymbol that generates a scope diff -uNr dmd-0.109/dmd/src/dmd/enum.c dmd-0.110/dmd/src/dmd/enum.c --- dmd-0.109/dmd/src/dmd/enum.c 2004-04-16 12:18:18.000000000 +0200 +++ dmd-0.110/dmd/src/dmd/enum.c 2004-12-30 00:16:08.000000000 +0100 @@ -44,14 +44,6 @@ return ed; } -void EnumDeclaration::addMember(ScopeDsymbol *sd) -{ int i; - - //printf("EnumDeclaration::addMember(sd = %p, '%s')\n", sd, sd->toChars()); - if (!isAnonymous()) - Dsymbol::addMember(sd); -} - void EnumDeclaration::semantic(Scope *sc) { int i; integer_t number; diff -uNr dmd-0.109/dmd/src/dmd/enum.h dmd-0.110/dmd/src/dmd/enum.h --- dmd-0.109/dmd/src/dmd/enum.h 2004-10-03 16:28:04.000000000 +0200 +++ dmd-0.110/dmd/src/dmd/enum.h 2004-12-30 00:17:06.000000000 +0100 @@ -31,13 +31,14 @@ EnumDeclaration(Identifier *id, Type *memtype); Dsymbol *syntaxCopy(Dsymbol *s); - void addMember(ScopeDsymbol *s); void semantic(Scope *sc); Dsymbol *oneMember(); void toCBuffer(OutBuffer *buf); Type *getType(); char *kind(); + EnumDeclaration *isEnumDeclaration() { return this; } + void toObjFile(); // compile to .obj file void toDebug(); int cvMember(unsigned char *p); diff -uNr dmd-0.109/dmd/src/dmd/expression.c dmd-0.110/dmd/src/dmd/expression.c --- dmd-0.109/dmd/src/dmd/expression.c 2004-12-04 18:11:12.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/expression.c 2004-12-29 14:26:18.000000000 +0100 @@ -1633,7 +1633,9 @@ //printf("tb: %s, deco = %s\n", tb->toChars(), tb->deco); arrayExpressionSemantic(newargs, sc); + preFunctionArguments(loc, sc, newargs); arrayExpressionSemantic(arguments, sc); + preFunctionArguments(loc, sc, arguments); if (tb->ty == Tclass) { ClassDeclaration *cd; @@ -1676,7 +1678,7 @@ f = cd->aggNew; // Prepend the uint size argument to newargs[] - e = new IntegerExp(loc, cd->size(), Type::tuns32); + e = new IntegerExp(loc, cd->size(loc), Type::tuns32); if (!newargs) newargs = new Array(); newargs->shift(e); @@ -1708,7 +1710,7 @@ Expression *e; // Prepend the uint size argument to newargs[] - e = new IntegerExp(loc, sd->size(), Type::tuns32); + e = new IntegerExp(loc, sd->size(loc), Type::tuns32); if (!newargs) newargs = new Array(); newargs->shift(e); @@ -2271,31 +2273,34 @@ AggregateDeclaration *ad; ad = sc->getStructClassScope(); - cd = ad->isClassDeclaration(); - if (cd) + if (ad) { - 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) + cd = ad->isClassDeclaration(); + if (cd) { if (e1->op == TOKthis) { - e = new TypeDotIdExp(loc, sd->type, ident); + 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); + } + } + } } } @@ -4942,6 +4947,9 @@ e2 = e2->semantic(sc); sc->mergeCallSuper(loc, cs1); + e1 = resolveProperties(sc, e1); + e2 = resolveProperties(sc, e2); + e1 = e1->checkToPointer(); e2 = e2->checkToPointer(); e1 = e1->checkToBoolean(); @@ -4980,6 +4988,9 @@ e2 = e2->semantic(sc); sc->mergeCallSuper(loc, cs1); + e1 = resolveProperties(sc, e1); + e2 = resolveProperties(sc, e2); + e1 = e1->checkToPointer(); e2 = e2->checkToPointer(); e1 = e1->checkToBoolean(); diff -uNr dmd-0.109/dmd/src/dmd/func.c dmd-0.110/dmd/src/dmd/func.c --- dmd-0.109/dmd/src/dmd/func.c 2004-12-01 03:30:38.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/func.c 2004-12-19 15:11:58.000000000 +0100 @@ -85,12 +85,13 @@ InterfaceDeclaration *id; #if 0 - printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, this, toChars(), sc->linkage); + printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, this, toPrettyChars(), sc->linkage); if (isFuncLiteralDeclaration()) printf("\tFuncLiteralDeclaration()\n"); #endif type = type->semantic(loc, sc); + //type->print(); if (type->ty != Tfunction) { error("%s must be a function", toChars()); @@ -234,9 +235,15 @@ // Override //printf("\toverride %p with %p\n", fdv, this); if (cov == 2) - error("overrides but is not covariant with %s", fdv->toChars()); + { + //type->print(); + //fdv->type->print(); + //printf("%s %s\n", type->deco, fdv->type->deco); + error("of type %s overrides but is not covariant with %s of type %s", + type->toChars(), fdv->toPrettyChars(), fdv->type->toChars()); + } if (fdv->isFinal()) - error("cannot override final function %s", fdv->toChars()); + error("cannot override final function %s", fdv->toPrettyChars()); if (fdv->toParent() == parent) { // If both are mixins, then error. @@ -336,6 +343,11 @@ AggregateDeclaration *ad; VarDeclaration *argptr = NULL; + if (!parent) + { + printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc); + assert(0); + } //printf("FuncDeclaration::semantic3('%s.%s', sc = %p)\n", parent->toChars(), toChars(), sc); //fflush(stdout); //{ static int x; if (++x == 2) *(char*)0=0; } @@ -1132,7 +1144,7 @@ int FuncDeclaration::isNested() { - //printf("FuncDeclaration::isNested() '%s'\n", toChars()); +// if (!toParent()) printf("FuncDeclaration::isNested('%s') parent=%p\n", toChars(), parent); //printf("\ttoParent() = '%s'\n", toParent()->toChars()); return ((storage_class & STCstatic) == 0) && (toParent()->isFuncDeclaration() != NULL); diff -uNr dmd-0.109/dmd/src/dmd/identifier.c dmd-0.110/dmd/src/dmd/identifier.c --- dmd-0.109/dmd/src/dmd/identifier.c 2004-08-25 23:56:12.000000000 +0200 +++ dmd-0.110/dmd/src/dmd/identifier.c 2004-12-18 15:32:40.000000000 +0100 @@ -19,6 +19,7 @@ //printf("Identifier('%s', %d)\n", string, value); this->string = string; this->value = value; + this->len = strlen(string); } unsigned Identifier::hashCode() @@ -28,12 +29,12 @@ int Identifier::equals(Object *o) { - return this == o || strcmp(string,o->toChars()) == 0; + return this == o || memcmp(string,o->toChars(),len+1) == 0; } int Identifier::compare(Object *o) { - return strcmp(string,o->toChars()); + return memcmp(string, o->toChars(), len + 1); } char *Identifier::toChars() diff -uNr dmd-0.109/dmd/src/dmd/identifier.h dmd-0.110/dmd/src/dmd/identifier.h --- dmd-0.109/dmd/src/dmd/identifier.h 2004-08-25 23:56:04.000000000 +0200 +++ dmd-0.110/dmd/src/dmd/identifier.h 2004-12-18 15:32:40.000000000 +0100 @@ -20,6 +20,7 @@ { int value; const char *string; + unsigned len; Identifier(const char *string, int value); int equals(Object *o); diff -uNr dmd-0.109/dmd/src/dmd/idgen.c dmd-0.110/dmd/src/dmd/idgen.c --- dmd-0.109/dmd/src/dmd/idgen.c 2004-11-23 14:53:54.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/idgen.c 2004-12-14 01:49:28.000000000 +0100 @@ -61,6 +61,7 @@ { "TypeInfo" }, { "TypeInfo_Class" }, + { "TypeInfo_Struct" }, { "TypeInfo_Typedef" }, { "_arguments" }, { "_argptr" }, @@ -156,6 +157,9 @@ // For pragma's { "msg" }, + // For toHash + { "tohash", "toHash" }, + // Special functions { "alloca" }, }; diff -uNr dmd-0.109/dmd/src/dmd/lexer.c dmd-0.110/dmd/src/dmd/lexer.c --- dmd-0.109/dmd/src/dmd/lexer.c 2004-11-23 22:20:14.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/lexer.c 2004-12-21 13:47:50.000000000 +0100 @@ -2097,6 +2097,7 @@ Token::tochars[TOKdotexp] = "dotexp"; Token::tochars[TOKdotti] = "dotti"; Token::tochars[TOKdotvar] = "dotvar"; + Token::tochars[TOKdottype] = "dottype"; Token::tochars[TOKsymoff] = "symoff"; Token::tochars[TOKtypedot] = "typedot"; Token::tochars[TOKarraylength] = "arraylength"; diff -uNr dmd-0.109/dmd/src/dmd/mangle.c dmd-0.110/dmd/src/dmd/mangle.c --- dmd-0.109/dmd/src/dmd/mangle.c 2004-12-01 02:59:38.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/mangle.c 2004-12-14 01:08:30.000000000 +0100 @@ -137,6 +137,7 @@ * names for them. */ if (ident == Id::TypeInfo || + ident == Id::TypeInfo_Struct || ident == Id::TypeInfo_Class || ident == Id::TypeInfo_Typedef || ident == Id::Exception || diff -uNr dmd-0.109/dmd/src/dmd/mars.c dmd-0.110/dmd/src/dmd/mars.c --- dmd-0.109/dmd/src/dmd/mars.c 2004-12-01 01:18:22.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/mars.c 2004-12-21 01:08:40.000000000 +0100 @@ -49,7 +49,7 @@ copyright = "Copyright (c) 1999-2004 by Digital Mars"; written = "written by Walter Bright"; - version = "v0.109"; + version = "v0.110"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); @@ -570,6 +570,8 @@ printf("code %s\n", m->toChars()); m->genobjfile(); // m->gensymfile(); + if (global.errors) + m->deleteObjFile(); } backend_term(); diff -uNr dmd-0.109/dmd/src/dmd/mars.h dmd-0.110/dmd/src/dmd/mars.h --- dmd-0.109/dmd/src/dmd/mars.h 2004-11-24 20:23:10.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/mars.h 2004-12-08 16:13:54.000000000 +0100 @@ -150,7 +150,7 @@ Loc(int x) { - linnum = 0; + linnum = x; filename = NULL; } diff -uNr dmd-0.109/dmd/src/dmd/module.c dmd-0.110/dmd/src/dmd/module.c --- dmd-0.109/dmd/src/dmd/module.c 2004-11-26 02:59:54.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/module.c 2004-12-19 11:30:32.000000000 +0100 @@ -43,7 +43,7 @@ FileName *objfilename; FileName *symfilename; - //printf("Module::Module(filename = '%s', ident = '%s')\n", filename, ident->toChars()); +// printf("Module::Module(filename = '%s', ident = '%s')\n", filename, ident->toChars()); this->arg = filename; md = NULL; errors = 0; @@ -51,6 +51,9 @@ isHtml = 0; needmoduleinfo = 0; insearch = 0; + searchCacheIdent = NULL; + searchCacheSymbol = NULL; + searchCacheFlags = 0; semanticdone = 0; decldefs = NULL; vmoduleinfo = NULL; @@ -417,9 +420,10 @@ void Module::semantic() { int i; - //printf("Module::semantic('%s'): parent = %p\n", toChars(), parent); if (semanticdone) return; + + //printf("+Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent); semanticdone = 1; // Note that modules get their own scope, from scratch. @@ -450,19 +454,20 @@ { Dsymbol *s; s = (Dsymbol *)members->data[i]; + //printf("\tModule('%s'): '%s'.semantic()\n", toChars(), s->toChars()); s->semantic(sc); - runDeferredSemantic(); } sc = sc->pop(); sc->pop(); - //printf("-Module::semantic('%s'): parent = %p\n", toChars(), parent); + //printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent); } void Module::semantic2() { int i; + assert(!deferred.dim); //printf("Module::semantic2('%s'): parent = %p\n", toChars(), parent); if (semanticdone >= 2) return; @@ -580,11 +585,17 @@ Dsymbol *s; if (insearch) s = NULL; + else if (searchCacheIdent == ident && searchCacheFlags == flags) + s = searchCacheSymbol; else { insearch = 1; s = ScopeDsymbol::search(ident, flags); insearch = 0; + + searchCacheIdent = ident; + searchCacheSymbol = s; + searchCacheFlags = flags; } return s; } @@ -595,6 +606,16 @@ void Module::addDeferredSemantic(Dsymbol *s) { + // Don't add it if it is already there + for (int i = 0; i < deferred.dim; i++) + { + Dsymbol *sd = (Dsymbol *)deferred.data[i]; + + if (sd == s) + return; + } + +// printf("Module::addDeferredSemantic('%s')\n", s->toChars()); deferred.push(s); } @@ -604,12 +625,12 @@ void Module::runDeferredSemantic() { - int len; - int newlen; + size_t len; static int nested; if (nested) return; +// if (deferred.dim) printf("Module::runDeferredSemantic('%s'), len = %d\n", toChars(), deferred.dim); nested++; do @@ -618,18 +639,27 @@ if (!len) break; + Dsymbol **todo; + Dsymbol *tmp; + if (len == 1) + { + todo = &tmp; + } + else + { + todo = (Dsymbol **)alloca(len * sizeof(Dsymbol *)); + assert(todo); + } + memcpy(todo, deferred.data, len * sizeof(Dsymbol *)); + deferred.setDim(0); + for (int i = 0; i < len; i++) { - Dsymbol *s = (Dsymbol *)deferred.data[i]; + Dsymbol *s = todo[i]; s->semantic(NULL); } - - newlen = deferred.dim - len; - memmove(deferred.data, deferred.data + len, - newlen * sizeof(deferred.data[0])); - deferred.setDim(newlen); - } while (newlen < len); + } while (deferred.dim < len); // while making progress nested--; } diff -uNr dmd-0.109/dmd/src/dmd/module.h dmd-0.110/dmd/src/dmd/module.h --- dmd-0.109/dmd/src/dmd/module.h 2004-09-06 22:39:32.000000000 +0200 +++ dmd-0.110/dmd/src/dmd/module.h 2004-12-18 15:12:24.000000000 +0100 @@ -53,7 +53,12 @@ unsigned errors; // if any errors in file int isHtml; // if it is an HTML file int needmoduleinfo; + int insearch; + Identifier *searchCacheIdent; + Dsymbol *searchCacheSymbol; // cached value of search + int searchCacheFlags; // cached flags + int semanticdone; // has semantic() been done? Module *importedFrom; // module from command line we're imported from, // i.e. a module that will be taken all the diff -uNr dmd-0.109/dmd/src/dmd/mtype.c dmd-0.110/dmd/src/dmd/mtype.c --- dmd-0.109/dmd/src/dmd/mtype.c 2004-12-02 01:36:06.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/mtype.c 2004-12-20 21:53:54.000000000 +0100 @@ -58,6 +58,7 @@ ClassDeclaration *Type::typeinfo; ClassDeclaration *Type::typeinfoclass; +ClassDeclaration *Type::typeinfostruct; ClassDeclaration *Type::typeinfotypedef; Type *Type::basic[TMAX]; @@ -189,15 +190,18 @@ d_uns64 Type::size() { - Loc loc; + return size(0); +} +d_uns64 Type::size(Loc loc) +{ error(loc, "no size for type %s", toChars()); return 0; } unsigned Type::alignsize() { - return size(); + return size(0); } Type *Type::semantic(Loc loc, Scope *sc) @@ -446,13 +450,13 @@ if (ident == Id::__sizeof) { - e = new IntegerExp(loc, size(), Type::tsize_t); + e = new IntegerExp(loc, size(loc), Type::tsize_t); } else if (ident == Id::size) { if (!global.params.useDeprecated) error(loc, ".size property is deprecated, use .sizeof"); - e = new IntegerExp(loc, size(), Type::tsize_t); + e = new IntegerExp(loc, size(loc), Type::tsize_t); } else if (ident == Id::alignof) { @@ -543,7 +547,7 @@ fflush(stdout); global.errors++; - fatal(); + //fatal(); } Identifier *Type::getTypeInfoIdent(int internal) @@ -743,7 +747,7 @@ } } -d_uns64 TypeBasic::size() +d_uns64 TypeBasic::size(Loc loc) { unsigned size; //printf("TypeBasic::size()\n"); @@ -803,7 +807,7 @@ break; default: - sz = size(); + sz = size(0); break; } return sz; @@ -1266,7 +1270,7 @@ Expression *ec; FuncDeclaration *fd; Array *arguments; - int size = next->size(); + int size = next->size(e->loc); char *nm; static char *name[2][2] = { { "_adReverse", "_adDup" }, { "_adReverseBit", "_adDupBit" } }; @@ -1295,7 +1299,7 @@ arguments = new Array(); arguments->push(e); arguments->push(n->ty == Tsarray ? n->getTypeInfo(sc) // don't convert to dynamic array - : n->getInternalTypeInfo()); + : n->getInternalTypeInfo(sc)); e = new CallExp(e->loc, ec, arguments); e->type = next->arrayOf(); } @@ -1374,11 +1378,11 @@ return t; } -d_uns64 TypeSArray::size() +d_uns64 TypeSArray::size(Loc loc) { integer_t sz; if (!dim) - return Type::size(); + return Type::size(loc); sz = dim->toInteger(); if (next->toBasetype()->ty == Tbit) // if array of bits { @@ -1398,7 +1402,7 @@ return sz; Loverflow: - error(0, "index %lld overflow for static array", sz); + error(loc, "index %lld overflow for static array", sz); return 1; } @@ -1436,7 +1440,7 @@ /* Only do this for types that don't need to have semantic() * run on them for the size, since they may be forward referenced. */ - n = next->size(); + n = next->size(loc); n2 = n * d2; if ((int)n2 < 0) goto Loverflow; @@ -1562,7 +1566,7 @@ return t; } -d_uns64 TypeDArray::size() +d_uns64 TypeDArray::size(Loc loc) { //printf("TypeDArray::size()\n"); return PTRSIZE * 2; @@ -1576,17 +1580,21 @@ } Type *TypeDArray::semantic(Loc loc, Scope *sc) -{ - next = next->semantic(loc,sc); - switch (next->ty) +{ Type *tn = next; + + tn = next->semantic(loc,sc); + switch (tn->ty) { case Tfunction: case Tnone: - error(loc, "can't have array of %s", next->toChars()); + error(loc, "can't have array of %s", tn->toChars()); break; } - if (next->isauto()) - error(loc, "cannot have array of auto %s", next->toChars()); + if (tn->isauto()) + error(loc, "cannot have array of auto %s", tn->toChars()); + if (next != tn) + //deco = NULL; // redo + return tn->arrayOf(); return merge(); } @@ -1695,7 +1703,7 @@ return t; } -d_uns64 TypeAArray::size() +d_uns64 TypeAArray::size(Loc loc) { return PTRSIZE * 2; } @@ -1796,7 +1804,7 @@ FuncDeclaration *fd; Array *arguments; char aakeys[7+3*sizeof(int)+1]; - int size = key->size(); + int size = key->size(e->loc); assert(size); #if 0 @@ -1827,8 +1835,8 @@ ec = new VarExp(0, fd); arguments = new Array(); arguments->push(e); - arguments->push(new IntegerExp(0, key->size(), Type::tint32)); - arguments->push(new IntegerExp(0, next->size(), Type::tint32)); + arguments->push(new IntegerExp(0, key->size(e->loc), Type::tint32)); + arguments->push(new IntegerExp(0, next->size(e->loc), Type::tint32)); e = new CallExp(e->loc, ec, arguments); e->type = next->arrayOf(); } @@ -1842,7 +1850,7 @@ ec = new VarExp(0, fd); arguments = new Array(); arguments->push(e->addressOf()); - arguments->push(key->getInternalTypeInfo()); + arguments->push(key->getInternalTypeInfo(sc)); e = new CallExp(e->loc, ec, arguments); e->type = this; } @@ -1912,7 +1920,7 @@ } -d_uns64 TypePointer::size() +d_uns64 TypePointer::size(Loc loc) { return PTRSIZE; } @@ -2000,7 +2008,7 @@ return t; } -d_uns64 TypeReference::size() +d_uns64 TypeReference::size(Loc loc) { return PTRSIZE; } @@ -2107,9 +2115,15 @@ goto Lnotcovariant; if (t1->linkage != t2->linkage) goto Lnotcovariant; - if (t1->next->ty != Tclass || t2->next->ty != Tclass) + + Type *t1n = t1->next; + Type *t2n = t2->next; + + if (t1n->equals(t2n)) + goto Lcovariant; + if (t1n->ty != Tclass || t2n->ty != Tclass) goto Lnotcovariant; - if (t1->next->implicitConvTo(t2->next)) + if (t1n->implicitConvTo(t2n)) goto Lcovariant; goto Lnotcovariant; } @@ -2380,7 +2394,7 @@ return merge(); } -d_uns64 TypeDelegate::size() +d_uns64 TypeDelegate::size(Loc loc) { return PTRSIZE * 2; } @@ -2481,9 +2495,9 @@ } } -d_uns64 TypeQualified::size() +d_uns64 TypeQualified::size(Loc loc) { - error(loc, "size of type %s is not known", toChars()); + error(this->loc, "size of type %s is not known", toChars()); return 1; } @@ -2778,6 +2792,7 @@ error(loc, "%s is used as a type", toChars()); t = tvoid; } + //t->print(); return t; } @@ -2990,14 +3005,14 @@ return merge(); } -d_uns64 TypeEnum::size() +d_uns64 TypeEnum::size(Loc loc) { if (!sym->memtype) { - error(0, "enum %s is forward referenced", sym->toChars()); + error(loc, "enum %s is forward referenced", sym->toChars()); return 4; } - return sym->memtype->size(); + return sym->memtype->size(loc); } unsigned TypeEnum::alignsize() @@ -3156,9 +3171,9 @@ return merge(); } -d_uns64 TypeTypedef::size() +d_uns64 TypeTypedef::size(Loc loc) { - return sym->basetype->size(); + return sym->basetype->size(loc); } unsigned TypeTypedef::alignsize() @@ -3329,15 +3344,15 @@ return merge(); } -d_uns64 TypeStruct::size() +d_uns64 TypeStruct::size(Loc loc) { - return sym->size(); + return sym->size(loc); } unsigned TypeStruct::alignsize() { unsigned sz; - sym->size(); // give error for forward references + sym->size(0); // give error for forward references sz = sym->alignsize; if (sz > sym->structalign) sz = sym->structalign; @@ -3491,7 +3506,7 @@ unsigned TypeStruct::memalign(unsigned salign) { - sym->size(); // give error for forward references + sym->size(0); // give error for forward references return sym->structalign; } @@ -3541,7 +3556,7 @@ return merge(); } -d_uns64 TypeClass::size() +d_uns64 TypeClass::size(Loc loc) { return PTRSIZE; } diff -uNr dmd-0.109/dmd/src/dmd/mtype.h dmd-0.110/dmd/src/dmd/mtype.h --- dmd-0.109/dmd/src/dmd/mtype.h 2004-09-19 23:42:14.000000000 +0200 +++ dmd-0.110/dmd/src/dmd/mtype.h 2004-12-15 15:19:38.000000000 +0100 @@ -149,6 +149,7 @@ static ClassDeclaration *typeinfo; static ClassDeclaration *typeinfoclass; + static ClassDeclaration *typeinfostruct; static ClassDeclaration *typeinfotypedef; static Type *basic[TMAX]; @@ -168,7 +169,8 @@ int covariant(Type *t); char *toChars(); static void init(); - virtual d_uns64 size(); + d_uns64 size(); + virtual d_uns64 size(Loc loc); virtual unsigned alignsize(); virtual Type *semantic(Loc loc, Scope *sc); virtual void toDecoBuffer(OutBuffer *buf); @@ -204,7 +206,7 @@ Identifier *getTypeInfoIdent(int internal); virtual MATCH deduceType(Type *tparam, Array *parameters, Array *atypes); virtual void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps); - Expression *getInternalTypeInfo(); + Expression *getInternalTypeInfo(Scope *sc); Expression *getTypeInfo(Scope *sc); virtual TypeInfoDeclaration *getTypeInfoDeclaration(); virtual int builtinTypeInfo(); @@ -229,7 +231,7 @@ TypeBasic(TY ty); Type *syntaxCopy(); - d_uns64 size(); + d_uns64 size(Loc loc); unsigned alignsize(); Expression *getProperty(Loc loc, Identifier *ident); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); @@ -267,7 +269,7 @@ TypeSArray(Type *t, Expression *dim); Type *syntaxCopy(); - d_uns64 size(); + d_uns64 size(Loc loc); unsigned alignsize(); Type *semantic(Loc loc, Scope *sc); void toDecoBuffer(OutBuffer *buf); @@ -290,7 +292,7 @@ { TypeDArray(Type *t); Type *syntaxCopy(); - d_uns64 size(); + d_uns64 size(Loc loc); unsigned alignsize(); Type *semantic(Loc loc, Scope *sc); void toDecoBuffer(OutBuffer *buf); @@ -313,7 +315,7 @@ TypeAArray(Type *t, Type *index); Type *syntaxCopy(); - d_uns64 size(); + d_uns64 size(Loc loc); Type *semantic(Loc loc, Scope *sc); void toDecoBuffer(OutBuffer *buf); void toPrettyBracket(OutBuffer *buf); @@ -333,7 +335,7 @@ TypePointer(Type *t); Type *syntaxCopy(); Type *semantic(Loc loc, Scope *sc); - d_uns64 size(); + d_uns64 size(Loc loc); void toCBuffer2(OutBuffer *buf, Identifier *ident); int implicitConvTo(Type *to); int isscalar(); @@ -347,7 +349,7 @@ { TypeReference(Type *t); Type *syntaxCopy(); - d_uns64 size(); + d_uns64 size(Loc loc); void toCBuffer2(OutBuffer *buf, Identifier *ident); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); Expression *defaultInit(); @@ -386,7 +388,7 @@ TypeDelegate(Type *t); Type *syntaxCopy(); Type *semantic(Loc loc, Scope *sc); - d_uns64 size(); + d_uns64 size(Loc loc); void toCBuffer2(OutBuffer *buf, Identifier *ident); Expression *defaultInit(); int isZeroInit(); @@ -404,7 +406,7 @@ void syntaxCopyHelper(TypeQualified *t); void addIdent(Identifier *ident); void toCBuffer2Helper(OutBuffer *buf, Identifier *ident); - d_uns64 size(); + d_uns64 size(Loc loc); void resolveHelper(Loc loc, Scope *sc, Dsymbol *s, Dsymbol *scopesym, Expression **pe, Type **pt, Dsymbol **ps); }; @@ -455,7 +457,7 @@ StructDeclaration *sym; TypeStruct(StructDeclaration *sym); - d_uns64 size(); + d_uns64 size(Loc loc); unsigned alignsize(); char *toChars(); Type *syntaxCopy(); @@ -470,6 +472,7 @@ int isZeroInit(); dt_t **toDt(dt_t **pdt); MATCH deduceType(Type *tparam, Array *parameters, Array *atypes); + TypeInfoDeclaration *getTypeInfoDeclaration(); type *toCtype(); }; @@ -479,7 +482,7 @@ EnumDeclaration *sym; TypeEnum(EnumDeclaration *sym); - d_uns64 size(); + d_uns64 size(Loc loc); unsigned alignsize(); char *toChars(); Type *semantic(Loc loc, Scope *sc); @@ -508,7 +511,7 @@ TypeTypedef(TypedefDeclaration *sym); Type *syntaxCopy(); - d_uns64 size(); + d_uns64 size(Loc loc); unsigned alignsize(); char *toChars(); Type *semantic(Loc loc, Scope *sc); @@ -540,7 +543,7 @@ ClassDeclaration *sym; TypeClass(ClassDeclaration *sym); - d_uns64 size(); + d_uns64 size(Loc loc); char *toChars(); Type *syntaxCopy(); Type *semantic(Loc loc, Scope *sc); diff -uNr dmd-0.109/dmd/src/dmd/parse.c dmd-0.110/dmd/src/dmd/parse.c --- dmd-0.109/dmd/src/dmd/parse.c 2004-12-03 01:19:56.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/parse.c 2004-12-16 15:14:30.000000000 +0100 @@ -479,7 +479,7 @@ continue; default: - error("Declaration expected, not '%s'\n",token.toChars()); + error("Declaration expected, not '%s'",token.toChars()); Lerror: while (token.value != TOKsemicolon && token.value != TOKeof) nextToken(); @@ -1880,7 +1880,7 @@ error("multiple declarations must have the same type, not %s and %s", tfirst->toChars(), t->toChars()); if (!ident) - error("no identifier for declarator"); + error("no identifier for declarator %s", t->toChars()); if (tok == TOKtypedef || tok == TOKalias) { Declaration *v; @@ -2484,7 +2484,7 @@ tb = parseBasicType(); at = parseDeclarator(tb, &ai); if (!ai) - error("no identifier for declarator"); + error("no identifier for declarator %s", at->toChars()); a = new Argument(inout, at, ai, NULL); arguments->push(a); if (token.value == TOKcomma) diff -uNr dmd-0.109/dmd/src/dmd/statement.c dmd-0.110/dmd/src/dmd/statement.c --- dmd-0.109/dmd/src/dmd/statement.c 2004-12-02 02:08:22.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/statement.c 2004-12-29 14:28:20.000000000 +0100 @@ -591,6 +591,7 @@ Type *tnv = NULL; aggr = aggr->semantic(sc); + aggr = resolveProperties(sc, aggr); sym = new ScopeDsymbol(); sym->parent = sc->scopesym; @@ -1141,6 +1142,7 @@ Statement *SwitchStatement::semantic(Scope *sc) { condition = condition->semantic(sc); + condition = resolveProperties(sc, condition); if (condition->type->isString()) { // If it's not an array, cast it to one @@ -1970,6 +1972,7 @@ if (sc->incontract) error("Throw statements cannot be in contracts"); exp = exp->semantic(sc); + exp = resolveProperties(sc, exp); if (!exp->type->isClassHandle()) error("can only throw class objects, not type %s", exp->type->toChars()); return this; diff -uNr dmd-0.109/dmd/src/dmd/struct.c dmd-0.110/dmd/src/dmd/struct.c --- dmd-0.109/dmd/src/dmd/struct.c 2004-12-03 01:55:02.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/struct.c 2004-12-30 00:18:44.000000000 +0100 @@ -35,6 +35,7 @@ stag = NULL; sinit = NULL; + scope = NULL; } void AggregateDeclaration::semantic2(Scope *sc) @@ -83,13 +84,15 @@ } } -unsigned AggregateDeclaration::size() +unsigned AggregateDeclaration::size(Loc loc) { //printf("AggregateDeclaration::size() = %d\n", structsize); if (!members) - error("unknown size"); - if (!sizeok) - error("no size yet for forward reference"); + error(loc, "unknown size"); + if (sizeok != 1) + { error(loc, "no size yet for forward reference"); + //*(char*)0=0; + } return structsize; } @@ -138,7 +141,19 @@ unsigned memalignsize; // size of member for alignment purposes unsigned xalign; // alignment boundaries - memsize = v->type->size(); + // Check for forward referenced types which will fail the size() call + Type *t = v->type->toBasetype(); + if (t->ty == Tstruct /*&& isStructDeclaration()*/) + { TypeStruct *ts = (TypeStruct *)t; + + if (ts->sym->sizeok != 1) + { + sizeok = 2; // cannot finish; flag as forward referenced + return; + } + } + + memsize = v->type->size(loc); memalignsize = v->type->alignsize(); xalign = v->type->memalign(sc->structalign); alignmember(xalign, memalignsize, &sc->offset); @@ -183,104 +198,82 @@ Scope *sc2; //printf("+StructDeclaration::semantic(this=%p, '%s')\n", this, toChars()); - if (!type) - type = new TypeStruct(this); + assert(type); if (!members) // if forward reference return; - if (!symtab) // if not already done semantic() - { - parent = sc->parent; - handle = type->pointerTo(); - symtab = new DsymbolTable(); - structalign = sc->structalign; - if (!isAnonymous()) - { - 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(this); - } - } - sc2 = sc->push(this); - sc2->parent = this; - if (isUnionDeclaration()) - sc2->inunion = 1; - sc2->stc &= ~(STCauto | STCstatic); - int members_dim = members->dim; - for (i = 0; i < members_dim; i++) - { - Dsymbol *s = (Dsymbol *)members->data[i]; - s->semantic(sc2); - if (isUnionDeclaration()) - sc2->offset = 0; - } - sc2->pop(); - // 0 sized struct's are set to 1 byte - if (structsize == 0) - { - structsize = 1; - alignsize = 1; - } - sizeok = 1; + if (symtab) + { if (!scope) + return; // semantic() already completed } + else + symtab = new DsymbolTable(); - AggregateDeclaration *sd; + Scope *scx = NULL; + if (scope) + { sc = scope; + scx = scope; // save so we don't make redundant copies + scope = NULL; + } -#if 0 - if (isAnonymous()) - { // Anonymous structures aren't independent, all their members are - // added to the enclosing struct. - unsigned offset; - int isunionsave; + parent = sc->parent; + handle = type->pointerTo(); + structalign = sc->structalign; + assert(!isAnonymous()); - sd = isMember(); - if (!sd) + if (sizeok == 0) // if not already done the addMember step + { + for (i = 0; i < members->dim; i++) { - error("anonymous struct can only be member of an aggregate"); + Dsymbol *s = (Dsymbol *)members->data[i]; + //printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars()); + s->addMember(this); } - else - { - // Align size of enclosing struct - sd->alignmember(structalign, alignsize, &sd->structsize); + } - // Add members to enclosing struct - for (i = 0; i < members->dim; i++) - { - Dsymbol *s = (Dsymbol *)members->data[i]; - VarDeclaration *vd = s->isVarDeclaration(); - if (vd && vd->storage_class & STCfield) - { - vd->addMember(sd); - if (!sd->isUnionDeclaration()) - vd->offset += sd->structsize; - sd->fields.push(vd); - sd->members->push(s); - } - else if (!s->isAnonymous()) - { - sd->members->push(s); - } - } + sizeok = 0; + sc2 = sc->push(this); + sc2->parent = this; + if (isUnionDeclaration()) + sc2->inunion = 1; + sc2->stc &= ~(STCauto | STCstatic); + int members_dim = members->dim; + for (i = 0; i < members_dim; i++) + { + Dsymbol *s = (Dsymbol *)members->data[i]; + s->semantic(sc2); + if (isUnionDeclaration()) + sc2->offset = 0; + if (sizeok == 2) + break; + } + sc2->pop(); - if (sd->isUnionDeclaration()) - { - if (structsize > sd->structsize) - sd->structsize = structsize; - sc->offset = 0; - } - else - { - sd->structsize += structsize; - sc->offset = sd->structsize; - } + if (sizeok == 2) + { // semantic() failed because of forward references. + // Unwind what we did, and defer it for later + fields.setDim(0); + structsize = 0; + alignsize = 0; + structalign = 0; + + scope = scx ? scx : new Scope(*sc); + scope->setNoFree(); + scope->module->addDeferredSemantic(this); + return; + } - if (sd->alignsize < alignsize) - sd->alignsize = alignsize; - } + // 0 sized struct's are set to 1 byte + if (structsize == 0) + { + structsize = 1; + alignsize = 1; } -#endif + + sizeok = 1; + + AggregateDeclaration *sd; + //printf("-StructDeclaration::semantic(this=%p, '%s')\n", this, toChars()); // Determine if struct is all zeros or not diff -uNr dmd-0.109/dmd/src/dmd/typinf.c dmd-0.110/dmd/src/dmd/typinf.c --- dmd-0.109/dmd/src/dmd/typinf.c 2004-11-05 01:26:50.000000000 +0100 +++ dmd-0.110/dmd/src/dmd/typinf.c 2004-12-15 17:02:42.000000000 +0100 @@ -46,7 +46,7 @@ * so we can use the custom internal ones more. */ -Expression *Type::getInternalTypeInfo() +Expression *Type::getInternalTypeInfo(Scope *sc) { TypeInfoDeclaration *tid; Expression *e; Type *t; @@ -81,7 +81,7 @@ break; } //printf("\tcalling getTypeInfo() %s\n", t->toChars()); - return t->getTypeInfo(NULL); + return t->getTypeInfo(sc); } @@ -125,6 +125,11 @@ return new TypeInfoTypedefDeclaration(this); } +TypeInfoDeclaration *TypeStruct::getTypeInfoDeclaration() +{ + return new TypeInfoStructDeclaration(this); +} + TypeInfoDeclaration *TypeClass::getTypeInfoDeclaration() { return new TypeInfoClassDeclaration(this); @@ -157,6 +162,93 @@ dtxoff(pdt, tc->sym->basetype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for basetype } +void TypeInfoStructDeclaration::toDt(dt_t **pdt) +{ + //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars()); + + dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Struct + dtdword(pdt, 0); // monitor + + assert(tinfo->ty == Tstruct); + + TypeStruct *tc = (TypeStruct *)tinfo; + StructDeclaration *sd = tc->sym; + + /* Put out: + * char[] name; + * uint xsize; + * uint function(void*) xtoHash; + * int function(void*,void*) xopEquals; + * int function(void*,void*) xopCmp; + */ + + char *name = sd->toPrettyChars(); + size_t namelen = strlen(name); + dtdword(pdt, namelen); + dtabytes(pdt, TYnptr, 0, namelen + 1, name); + + dtdword(pdt, sd->structsize); // xsize + + FuncDeclaration *fd; + FuncDeclaration *fdx; + TypeFunction *tf; + Type *ta; + + static TypeFunction *tftohash; + + if (!tftohash) + { + Scope sc; + tftohash = new TypeFunction(NULL, Type::tuns32, 0, LINKd); + tftohash = (TypeFunction *)tftohash->semantic(0, &sc); + } + + TypeFunction *tfeq; + { + Scope sc; + Array *arguments = new Array; + Argument *arg = new Argument(In, tc->pointerTo(), NULL, NULL); + + arguments->push(arg); + tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd); + tfeq = (TypeFunction *)tfeq->semantic(0, &sc); + } + + fdx = search_function(sd, Id::tohash); + if (fdx) + { fd = fdx->overloadExactMatch(tftohash); + if (fd) + dtxoff(pdt, fd->toSymbol(), 0, TYnptr); + else + fdx->error("must be declared as extern (D) uint toHash()"); + } + else + dtdword(pdt, 0); + + fdx = search_function(sd, Id::eq); + if (fdx) + { fd = fdx->overloadExactMatch(tfeq); + if (fd) + dtxoff(pdt, fd->toSymbol(), 0, TYnptr); + else + fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars()); + } + else + dtdword(pdt, 0); + + fdx = search_function(sd, Id::cmp); + if (fdx) + { + fd = fdx->overloadExactMatch(tfeq); + if (fd) + dtxoff(pdt, fd->toSymbol(), 0, TYnptr); + else + fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars()); + } + else + dtdword(pdt, 0); +} + void TypeInfoClassDeclaration::toDt(dt_t **pdt) { //printf("TypeInfoClassDeclaration::toDt()\n"); diff -uNr dmd-0.109/dmd/src/phobos/internal/aaA.d dmd-0.110/dmd/src/phobos/internal/aaA.d --- dmd-0.109/dmd/src/phobos/internal/aaA.d 2004-12-05 01:15:56.000000000 +0100 +++ dmd-0.110/dmd/src/phobos/internal/aaA.d 2004-12-30 16:22:50.000000000 +0100 @@ -267,7 +267,7 @@ { c = keyti.compare(pkey, e + 1); if (c == 0) - return cast(void *)(e + 1) + keyti.sizeof; + return cast(void *)(e + 1) + keyti.tsize(); } if (c < 0) diff -uNr dmd-0.109/dmd/src/phobos/internal/critical.c dmd-0.110/dmd/src/phobos/internal/critical.c --- dmd-0.109/dmd/src/phobos/internal/critical.c 2004-12-05 01:15:56.000000000 +0100 +++ dmd-0.110/dmd/src/phobos/internal/critical.c 2004-12-30 16:22:50.000000000 +0100 @@ -52,6 +52,7 @@ { if (!inited) { InitializeCriticalSection(&critical_section.cs); + dcs_list = &critical_section; inited = 1; } } @@ -65,7 +66,6 @@ DeleteCriticalSection(&dcs_list->cs); dcs_list = dcs_list->next; } - DeleteCriticalSection(&critical_section.cs); } } diff -uNr dmd-0.109/dmd/src/phobos/internal/dmain2.d dmd-0.110/dmd/src/phobos/internal/dmain2.d --- dmd-0.109/dmd/src/phobos/internal/dmain2.d 2004-12-05 01:15:56.000000000 +0100 +++ dmd-0.110/dmd/src/phobos/internal/dmain2.d 2004-12-30 16:22:50.000000000 +0100 @@ -70,7 +70,7 @@ { printf("Error: "); o.print(); - result = EXIT_FAILURE; + exit(EXIT_FAILURE); } _moduleDtor(); diff -uNr dmd-0.109/dmd/src/phobos/internal/object.d dmd-0.110/dmd/src/phobos/internal/object.d --- dmd-0.109/dmd/src/phobos/internal/object.d 2004-12-05 01:15:58.000000000 +0100 +++ dmd-0.110/dmd/src/phobos/internal/object.d 2004-12-30 16:22:50.000000000 +0100 @@ -3,6 +3,7 @@ extern (C) { int printf(char *, ...); + int memcmp(void *, void *, size_t); } alias bit bool; @@ -172,6 +173,79 @@ ClassInfo info; } +class TypeInfo_Struct : TypeInfo +{ + char[] toString() { return name; } + + uint getHash(void *p) + { uint h; + + assert(p); + if (xtoHash) + h = (*xtoHash)(p); + else + { + // A sorry hash algorithm. + // Should use the one for strings. + // BUG: relies on the GC not moving objects + for (size_t i = 0; i < xsize; i++) + { h = h * 9 + *cast(ubyte*)p; + p++; + } + } + return h; + } + + int equals(void *p2, void *p1) + { int c; + + if (p1 == p2) + c = 1; + else if (!p1 || !p2) + c = 0; + else if (xopEquals) + c = (*xopEquals)(p1, p2); + else + // BUG: relies on the GC not moving objects + c = (memcmp(p1, p2, xsize) == 0); + return c; + } + + int compare(void *p2, void *p1) + { + int c = 0; + + // Regard null references as always being "less than" + if (p1 != p2) + { + if (p1) + { if (!p2) + c = 1; + else if (xopCmp) + c = (*xopCmp)(p1, p2); + else + // BUG: relies on the GC not moving objects + c = memcmp(p1, p2, xsize); + } + else + c = -1; + } + return c; + } + + int tsize() + { + return xsize; + } + + char[] name; + uint xsize; + + uint function(void*) xtoHash; + int function(void*,void*) xopEquals; + int function(void*,void*) xopCmp; +} + class Exception : Object { char[] msg; diff -uNr dmd-0.109/dmd/src/phobos/object.d dmd-0.110/dmd/src/phobos/object.d --- dmd-0.109/dmd/src/phobos/object.d 2004-12-05 01:15:50.000000000 +0100 +++ dmd-0.110/dmd/src/phobos/object.d 2004-12-30 16:22:48.000000000 +0100 @@ -73,6 +73,16 @@ ClassInfo info; } +class TypeInfo_Struct : TypeInfo +{ + char[] name; + uint xsize; + + uint function(void*) xtoHash; + int function(void*,void*) xopEquals; + int function(void*,void*) xopCmp; +} + // Recoverable errors class Exception : Object diff -uNr dmd-0.109/dmd/src/phobos/std/c/stdarg.d dmd-0.110/dmd/src/phobos/std/c/stdarg.d --- dmd-0.109/dmd/src/phobos/std/c/stdarg.d 2004-12-05 01:15:54.000000000 +0100 +++ dmd-0.110/dmd/src/phobos/std/c/stdarg.d 2004-12-30 16:22:50.000000000 +0100 @@ -3,6 +3,8 @@ * Written by Hauke Duden and Walter Bright */ +/* This is for use with extern(C) variable argument lists. */ + module std.c.stdarg; alias void* va_list; diff -uNr dmd-0.109/dmd/src/phobos/std/c/stdlib.d dmd-0.110/dmd/src/phobos/std/c/stdlib.d --- dmd-0.109/dmd/src/phobos/std/c/stdlib.d 2004-12-05 01:15:54.000000000 +0100 +++ dmd-0.110/dmd/src/phobos/std/c/stdlib.d 2004-12-30 16:22:50.000000000 +0100 @@ -60,3 +60,6 @@ long strtoll(char *,char **,int); ulong strtoull(char *,char **,int); +char* itoa(int, char*, int); +char* ultoa(uint, char*, int); + diff -uNr dmd-0.109/dmd/src/phobos/std/c/windows/windows.d dmd-0.110/dmd/src/phobos/std/c/windows/windows.d --- dmd-0.109/dmd/src/phobos/std/c/windows/windows.d 2004-12-05 01:15:58.000000000 +0100 +++ dmd-0.110/dmd/src/phobos/std/c/windows/windows.d 2004-12-30 16:22:52.000000000 +0100 @@ -1,6 +1,14 @@ module std.c.windows.windows; +version (Windows) +{ +} +else +{ + static assert(0); // Windows only +} + extern (Windows) { alias uint ULONG; diff -uNr dmd-0.109/dmd/src/phobos/std/date.d dmd-0.110/dmd/src/phobos/std/date.d --- dmd-0.109/dmd/src/phobos/std/date.d 2004-12-05 01:15:52.000000000 +0100 +++ dmd-0.110/dmd/src/phobos/std/date.d 2004-12-30 16:22:48.000000000 +0100 @@ -348,6 +348,12 @@ return d_time_nan; +/ + if (hour == d_time_nan || + min == d_time_nan || + sec == d_time_nan || + ms == d_time_nan) + return d_time_nan; + hour = toInteger(hour); min = toInteger(min); sec = toInteger(sec); @@ -375,6 +381,11 @@ return d_time.init; +/ + if (year == d_time_nan || + month == d_time_nan || + date == d_time_nan) + return d_time_nan; + year = toInteger(year); month = toInteger(month); date = toInteger(date); @@ -477,10 +488,8 @@ // "Tue Apr 02 1996" char[] buffer = new char[29 + 7 + 1]; - /+ - if (Port::isnan(time)) + if (time == d_time_nan) return "Invalid Date"; - +/ dst = DaylightSavingTA(time); offset = LocalTZA + dst; @@ -511,10 +520,8 @@ // "02:04:57 GMT-0800" char[] buffer = new char[17 + 1]; - /+ - if (Port::isnan(time)) + if (time == d_time_nan) return "Invalid Date"; - +/ dst = DaylightSavingTA(time); offset = LocalTZA + dst; diff -uNr dmd-0.109/dmd/src/phobos/std/format.d dmd-0.110/dmd/src/phobos/std/format.d --- dmd-0.109/dmd/src/phobos/std/format.d 2004-12-05 01:15:54.000000000 +0100 +++ dmd-0.110/dmd/src/phobos/std/format.d 2004-12-30 16:22:50.000000000 +0100 @@ -266,9 +266,11 @@ case Mangle.Tchar: - if (fc != 's') - goto Lerror; vchar = va_arg!(char)(argptr); + if (fc != 's') + { vnumber = vchar; + goto Lnumber; + } L2: putstr((&vchar)[0 .. 1]); return; @@ -281,7 +283,9 @@ vdchar = va_arg!(dchar)(argptr); L1: if (fc != 's') - goto Lerror; + { vnumber = vdchar; + goto Lnumber; + } if (vdchar <= 0x7F) { vchar = cast(char)vdchar; goto L2; diff -uNr dmd-0.109/dmd/src/phobos/std/regexp.d dmd-0.110/dmd/src/phobos/std/regexp.d --- dmd-0.109/dmd/src/phobos/std/regexp.d 2004-12-05 01:15:52.000000000 +0100 +++ dmd-0.110/dmd/src/phobos/std/regexp.d 2004-12-30 16:22:50.000000000 +0100 @@ -81,11 +81,11 @@ int rm_eo; // index past end of match } -alias char tchar; // so we can make a wchar version +private alias char rchar; // so we can make a wchar version class RegExp { - public this(tchar[] pattern, tchar[] attributes) + public this(rchar[] pattern, rchar[] attributes) { pmatch = (&gmatch)[0 .. 1]; compile(pattern, attributes); @@ -94,13 +94,13 @@ uint re_nsub; // number of parenthesized subexpression matches regmatch_t[] pmatch; // array [re_nsub + 1] - tchar[] input; // the string to search + rchar[] input; // the string to search // per instance: - tchar[] pattern; // source text of the regular expression + rchar[] pattern; // source text of the regular expression - tchar[] flags; // source text of the attributes parameter + rchar[] flags; // source text of the attributes parameter int errors; @@ -172,7 +172,7 @@ }; // BUG: should this include '$'? -private int isword(tchar c) { return isalnum(c) || c == '_'; } +private int isword(rchar c) { return isalnum(c) || c == '_'; } private uint inf = ~0u; @@ -180,7 +180,7 @@ * Throws RegExpError on error */ -void compile(tchar[] pattern, tchar[] attributes) +public void compile(rchar[] pattern, rchar[] attributes) { //printf("RegExp.compile('%.*s', '%.*s')\n", pattern, attributes); @@ -241,11 +241,11 @@ * array of slices into string[] */ -public tchar[][] split(tchar[] string) +public rchar[][] split(rchar[] string) { debug(regexp) printf("regexp.split()\n"); - tchar[][] result; + rchar[][] result; if (string.length) { @@ -289,8 +289,8 @@ debug(regexp) printf("regexp.split.unittest()\n"); RegExp r = new RegExp("a*?", null); - tchar[][] result; - tchar[] j; + rchar[][] result; + rchar[] j; int i; result = r.split("ab"); @@ -341,7 +341,7 @@ * -1 no match */ -public int search(tchar[] string) +public int search(rchar[] string) { int i; @@ -373,9 +373,9 @@ * if not global, return array of all matches */ -public tchar[][] match(tchar[] string) +public rchar[][] match(rchar[] string) { - tchar[][] result; + rchar[][] result; if (attributes & REA.global) { @@ -403,8 +403,8 @@ debug(regexp) printf("regexp.match.unittest()\n"); int i; - tchar[][] result; - tchar[] j; + rchar[][] result; + rchar[] j; RegExp r; r = new RegExp("a[bc]", null); @@ -429,9 +429,9 @@ * Return the new string. */ -public tchar[] replace(tchar[] string, tchar[] format) +public rchar[] replace(rchar[] string, rchar[] format) { - tchar[] result; + rchar[] result; int lastindex; int offset; @@ -446,7 +446,7 @@ int so = pmatch[0].rm_so; int eo = pmatch[0].rm_eo; - tchar[] replacement = replace(format); + rchar[] replacement = replace(format); result = replaceSlice(result, result[offset + so .. offset + eo], replacement); if (attributes & REA.global) @@ -470,7 +470,7 @@ debug(regexp) printf("regexp.replace.unittest()\n"); int i; - tchar[] result; + rchar[] result; RegExp r; r = new RegExp("a[bc]", "g"); @@ -486,7 +486,7 @@ * array of slices into string[] representing matches */ -public tchar[][] exec(tchar[] string) +public rchar[][] exec(rchar[] string) { debug(regexp) printf("regexp.exec(string = '%.*s')\n", string); input = string; @@ -501,14 +501,14 @@ * array of slices into string[] representing matches */ -public tchar[][] exec() +public rchar[][] exec() { if (!test()) return null; - tchar[][] result; + rchar[][] result; - result = new tchar[][pmatch.length]; + result = new rchar[][pmatch.length]; for (int i = 0; i < pmatch.length; i++) { if (pmatch[i].rm_so == pmatch[i].rm_eo) @@ -527,7 +527,7 @@ * !=0 match */ -public int test(tchar[] string) +public int test(rchar[] string) { return test(string, 0 /*pmatch[0].rm_eo*/); } @@ -551,9 +551,9 @@ * !=0 match */ -int test(char[] string, int startindex) +public int test(char[] string, int startindex) { - tchar firstc; + rchar firstc; uint si; input = string; @@ -620,7 +620,7 @@ return 0; // no match } -int chr(inout uint si, tchar c) +int chr(inout uint si, rchar c) { for (; si < input.length; si++) { @@ -679,14 +679,14 @@ len = *cast(uint *)&prog[pc + 1]; printf("\tREstring x%x, '%.*s'\n", len, (&prog[pc + 1 + uint.sizeof])[0 .. len]); - pc += 1 + uint.sizeof + len * tchar.sizeof; + pc += 1 + uint.sizeof + len * rchar.sizeof; break; case REistring: len = *cast(uint *)&prog[pc + 1]; printf("\tREistring x%x, '%.*s'\n", len, (&prog[pc + 1 + uint.sizeof])[0 .. len]); - pc += 1 + uint.sizeof + len * tchar.sizeof; + pc += 1 + uint.sizeof + len * rchar.sizeof; break; case REtestbit: @@ -887,8 +887,8 @@ c2 = input[src]; if (c1 != c2) { - if (islower(cast(tchar)c2)) - c2 = std.ctype.toupper(cast(tchar)c2); + if (islower(cast(rchar)c2)) + c2 = std.ctype.toupper(cast(rchar)c2); else goto Lnomatch; if (c1 != c2) @@ -916,8 +916,8 @@ c2 = input[src]; if (c1 != c2) { - if (islower(cast(tchar)c2)) - c2 = std.ctype.toupper(cast(tchar)c2); + if (islower(cast(rchar)c2)) + c2 = std.ctype.toupper(cast(rchar)c2); else goto Lnomatch; if (c1 != c2) @@ -931,7 +931,7 @@ debug(regexp) printf("\tREanychar\n"); if (src == input.length) goto Lnomatch; - if (!(attributes & REA.dotmatchlf) && input[src] == cast(tchar)'\n') + if (!(attributes & REA.dotmatchlf) && input[src] == cast(rchar)'\n') goto Lnomatch; src++; pc++; @@ -943,10 +943,10 @@ (&program[pc + 1 + uint.sizeof])[0 .. len]); if (src + len > input.length) goto Lnomatch; - if (memcmp(&program[pc + 1 + uint.sizeof], &input[src], len * tchar.sizeof)) + if (memcmp(&program[pc + 1 + uint.sizeof], &input[src], len * rchar.sizeof)) goto Lnomatch; src += len; - pc += 1 + uint.sizeof + len * tchar.sizeof; + pc += 1 + uint.sizeof + len * rchar.sizeof; break; case REistring: @@ -957,7 +957,7 @@ goto Lnomatch; version (Win32) { - if (memicmp(cast(char*)&program[pc + 1 + uint.sizeof], &input[src], len * tchar.sizeof)) + if (memicmp(cast(char*)&program[pc + 1 + uint.sizeof], &input[src], len * rchar.sizeof)) goto Lnomatch; } else @@ -967,7 +967,7 @@ goto Lnomatch; } src += len; - pc += 1 + uint.sizeof + len * tchar.sizeof; + pc += 1 + uint.sizeof + len * rchar.sizeof; break; case REtestbit: @@ -1256,8 +1256,8 @@ c1 = input[src - 1]; c2 = input[src]; if (!( - (isword(cast(tchar)c1) && !isword(cast(tchar)c2)) || - (!isword(cast(tchar)c1) && isword(cast(tchar)c2)) + (isword(cast(rchar)c1) && !isword(cast(rchar)c2)) || + (!isword(cast(rchar)c1) && isword(cast(rchar)c2)) ) ) goto Lnomatch; @@ -1272,8 +1272,8 @@ c1 = input[src - 1]; c2 = input[src]; if ( - (isword(cast(tchar)c1) && !isword(cast(tchar)c2)) || - (!isword(cast(tchar)c1) && isword(cast(tchar)c2)) + (isword(cast(rchar)c1) && !isword(cast(rchar)c2)) || + (!isword(cast(rchar)c1) && isword(cast(rchar)c2)) ) goto Lnomatch; pc++; @@ -1354,7 +1354,7 @@ if (icmp(input[src .. src + len], input[so .. eo])) goto Lnomatch; } - else if (memcmp(&input[src], &input[so], len * tchar.sizeof)) + else if (memcmp(&input[src], &input[so], len * rchar.sizeof)) goto Lnomatch; src += len; pc += 2; @@ -1526,7 +1526,7 @@ int parseAtom() { ubyte op; uint offset; - tchar c; + rchar c; //printf("parseAtom() '%.*s'\n", pattern[p .. pattern.length]); if (p < pattern.length) @@ -1655,7 +1655,7 @@ int len; for (q = p; q < pattern.length; ++q) - { tchar qc = pattern[q]; + { rchar qc = pattern[q]; switch (qc) { @@ -1685,7 +1685,7 @@ if (len > 0) { debug(regexp) printf("writing string len %d, c = '%c', pattern[p] = '%c'\n", len+1, c, pattern[p]); - buf.reserve(5 + (1 + len) * tchar.sizeof); + buf.reserve(5 + (1 + len) * rchar.sizeof); buf.write((attributes & REA.ignoreCase) ? REistring : REstring); buf.write(len + 1); buf.write(c); @@ -1853,13 +1853,13 @@ case 'w': for (i = 0; i <= cmax; i++) - if (isword(cast(tchar)i)) + if (isword(cast(rchar)i)) r.bits[i] = 1; goto Lrs; case 'W': for (i = 1; i <= cmax; i++) - if (!isword(cast(tchar)i)) + if (!isword(cast(rchar)i)) r.bits[i] = 1; goto Lrs; @@ -1962,7 +1962,7 @@ body { int c; int i; - tchar tc; + rchar tc; c = pattern[p]; // none of the cases are multibyte switch (c) @@ -2129,7 +2129,7 @@ uint offset; offset = i; - if (startchars(r, prog[i .. prog.length])) + if (starrchars(r, prog[i .. prog.length])) { debug(regexp) printf("\tfilter built\n"); buf.spread(offset, 1 + 4 + r.maxb); @@ -2154,8 +2154,8 @@ // Return 1 if success, 0 if we can't build a filter or // if there is no point to one. -int startchars(Range r, ubyte[] prog) -{ tchar c; +int starrchars(Range r, ubyte[] prog) +{ rchar c; uint maxc; uint maxb; uint len; @@ -2165,7 +2165,7 @@ ubyte* pop; int i; - //printf("RegExp.startchars(prog = %p, progend = %p)\n", prog, progend); + //printf("RegExp.starrchars(prog = %p, progend = %p)\n", prog, progend); for (i = 0; i < prog.length;) { switch (prog[i]) @@ -2180,7 +2180,7 @@ c = prog[i + 1]; if (c <= 0x7F) { r.setbit2(c); - r.setbit2(std.ctype.tolower(cast(tchar)c)); + r.setbit2(std.ctype.tolower(cast(rchar)c)); } return 1; @@ -2194,7 +2194,7 @@ case REstring: len = *cast(uint *)&prog[i + 1]; assert(len); - c = *cast(tchar *)&prog[i + 1 + uint.sizeof]; + c = *cast(rchar *)&prog[i + 1 + uint.sizeof]; debug(regexp) printf("\tREstring %d, '%c'\n", len, c); if (c <= 0x7F) r.setbit2(c); @@ -2203,11 +2203,11 @@ case REistring: len = *cast(uint *)&prog[i + 1]; assert(len); - c = *cast(tchar *)&prog[i + 1 + uint.sizeof]; + c = *cast(rchar *)&prog[i + 1 + uint.sizeof]; debug(regexp) printf("\tREistring %d, '%c'\n", len, c); if (c <= 0x7F) - { r.setbit2(std.ctype.toupper(cast(tchar)c)); - r.setbit2(std.ctype.tolower(cast(tchar)c)); + { r.setbit2(std.ctype.toupper(cast(rchar)c)); + r.setbit2(std.ctype.tolower(cast(rchar)c)); } return 1; @@ -2240,8 +2240,8 @@ case REor: len = (cast(uint *)&prog[i + 1])[0]; - return startchars(r, prog[i + 1 + uint.sizeof .. prog.length]) && - startchars(r, prog[i + 1 + uint.sizeof + len .. prog.length]); + return starrchars(r, prog[i + 1 + uint.sizeof .. prog.length]) && + starrchars(r, prog[i + 1 + uint.sizeof + len .. prog.length]); case REgoto: len = (cast(uint *)&prog[i + 1])[0]; @@ -2258,7 +2258,7 @@ n = (cast(uint *)&prog[i + 1])[1]; m = (cast(uint *)&prog[i + 1])[2]; pop = &prog[i + 1 + uint.sizeof * 3]; - if (!startchars(r, pop[0 .. len])) + if (!starrchars(r, pop[0 .. len])) return 0; if (n) return 1; @@ -2270,7 +2270,7 @@ len = (cast(uint *)&prog[i + 1])[0]; n = (cast(uint *)&prog[i + 1])[1]; pop = &prog[0] + i + 1 + uint.sizeof * 2; - return startchars(r, pop[0 .. len]); + return starrchars(r, pop[0 .. len]); case REend: return 0; @@ -2310,14 +2310,14 @@ case REword: r.setbitmax(0x7F); for (c = 0; c <= r.maxc; c++) - if (isword(cast(tchar)c)) + if (isword(cast(rchar)c)) r.bits[c] = 1; return 1; case REnotword: r.setbitmax(0x7F); for (c = 0; c <= r.maxc; c++) - if (!isword(cast(tchar)c)) + if (!isword(cast(rchar)c)) r.bits[c] = 1; return 1; @@ -2337,16 +2337,16 @@ * \c replace with char c */ -public tchar[] replaceOld(tchar[] format) +public rchar[] replaceOld(rchar[] format) { OutBuffer buf; - tchar[] result; - tchar c; + rchar[] result; + rchar c; //printf("replace: this = %p so = %d, eo = %d\n", this, pmatch[0].rm_so, pmatch[0].rm_eo); //printf("3input = '%.*s'\n", input); buf = new OutBuffer(); - buf.reserve(format.length * tchar.sizeof); + buf.reserve(format.length * rchar.sizeof); for (uint i; i < format.length; i++) { c = format[i]; @@ -2378,7 +2378,7 @@ break; } } - result = cast(tchar[])buf.toBytes(); + result = cast(rchar[])buf.toBytes(); return result; } @@ -2397,18 +2397,18 @@ // // Any other $ are left as is. -public tchar[] replace(tchar[] format) +public rchar[] replace(rchar[] format) { return replace3(format, input, pmatch[0 .. re_nsub + 1]); } // Static version that doesn't require a RegExp object to be created -private tchar[] replace3(tchar[] format, tchar[] input, regmatch_t[] pmatch) +private static rchar[] replace3(rchar[] format, rchar[] input, regmatch_t[] pmatch) { OutBuffer buf; - tchar[] result; - tchar c; + rchar[] result; + rchar c; uint c2; int rm_so; int rm_eo; @@ -2417,7 +2417,7 @@ // printf("replace3(format = '%.*s', input = '%.*s')\n", format, input); buf = new OutBuffer(); - buf.reserve(format.length * tchar.sizeof); + buf.reserve(format.length * rchar.sizeof); for (f = 0; f < format.length; f++) { c = format[f]; @@ -2430,7 +2430,7 @@ ++f; if (f == format.length) { - buf.write(cast(tchar)'$'); + buf.write(cast(rchar)'$'); break; } c = format[f]; @@ -2458,7 +2458,7 @@ { if (i == 0) { - buf.write(cast(tchar)'$'); + buf.write(cast(rchar)'$'); buf.write(c); continue; } @@ -2472,7 +2472,7 @@ } if (i == 0) { - buf.write(cast(tchar)'$'); + buf.write(cast(rchar)'$'); buf.write(c); c = c2; goto L1; @@ -2492,12 +2492,12 @@ break; default: - buf.write(cast(tchar)'$'); + buf.write(cast(rchar)'$'); buf.write(c); break; } } - result = cast(tchar[])buf.toBytes(); + result = cast(rchar[])buf.toBytes(); return result; } diff -uNr dmd-0.109/dmd/src/phobos/std/stdarg.d dmd-0.110/dmd/src/phobos/std/stdarg.d --- dmd-0.109/dmd/src/phobos/std/stdarg.d 2004-12-05 01:15:54.000000000 +0100 +++ dmd-0.110/dmd/src/phobos/std/stdarg.d 2004-12-30 16:22:50.000000000 +0100 @@ -4,6 +4,8 @@ * Written by Hauke Duden and Walter Bright */ +/* This is for use with variable argument lists with extern(D) linkage. */ + module std.stdarg; alias void* va_list; diff -uNr dmd-0.109/dmd/src/phobos/std/uri.d dmd-0.110/dmd/src/phobos/std/uri.d --- dmd-0.109/dmd/src/phobos/std/uri.d 2004-12-05 01:15:52.000000000 +0100 +++ dmd-0.110/dmd/src/phobos/std/uri.d 2004-12-30 16:22:48.000000000 +0100 @@ -368,4 +368,8 @@ r = encode( decode("%E3%81%82%E3%81%82") ); assert(r == "%E3%81%82%E3%81%82"); + + r = encodeComponent("c++"); + //printf("r = '%.*s'\n", r); + assert(r == "c%2B%2B"); } diff -uNr dmd-0.109/dmd/src/phobos/unittest.d dmd-0.110/dmd/src/phobos/unittest.d --- dmd-0.109/dmd/src/phobos/unittest.d 2004-12-05 01:15:50.000000000 +0100 +++ dmd-0.110/dmd/src/phobos/unittest.d 2004-12-30 16:22:48.000000000 +0100 @@ -24,6 +24,7 @@ import std.uri; import std.zlib; import std.md5; +import std.stdio; int main(char[][] args) { @@ -53,6 +54,8 @@ ubyte[16] buf; std.md5.sum(buf,""); + writefln("hello world!"); // std.format + { creal c = 3.0 + 4.0i; c = sqrt(c);