diff -uNr dmd-1.023/dmd/src/dmd/declaration.c dmd-1.024/dmd/src/dmd/declaration.c --- dmd-1.023/dmd/src/dmd/declaration.c 2007-10-29 03:11:08.000000000 +0100 +++ dmd-1.024/dmd/src/dmd/declaration.c 2007-11-01 22:17:24.000000000 +0100 @@ -29,6 +29,7 @@ : Dsymbol(id) { type = NULL; + originalType = NULL; storage_class = STCundefined; protection = PROTundefined; linkage = LINKdefault; @@ -616,9 +617,13 @@ * declarations. */ storage_class &= ~STCauto; + originalType = type; } else + { if (!originalType) + originalType = type; type = type->semantic(loc, sc); + } type->checkDeprecated(loc, sc); linkage = sc->linkage; diff -uNr dmd-1.023/dmd/src/dmd/declaration.h dmd-1.024/dmd/src/dmd/declaration.h --- dmd-1.023/dmd/src/dmd/declaration.h 2007-10-25 01:24:40.000000000 +0200 +++ dmd-1.024/dmd/src/dmd/declaration.h 2007-11-05 17:55:16.000000000 +0100 @@ -83,6 +83,7 @@ struct Declaration : Dsymbol { Type *type; + Type *originalType; // before semantic analysis unsigned storage_class; enum PROT protection; enum LINK linkage; @@ -106,6 +107,7 @@ int isFinal() { return storage_class & STCfinal; } int isAbstract() { return storage_class & STCabstract; } int isConst() { return storage_class & STCconst; } + int isInvariant() { return 0; } int isAuto() { return storage_class & STCauto; } int isScope() { return storage_class & (STCscope | STCauto); } int isSynchronized() { return storage_class & STCsynchronized; } diff -uNr dmd-1.023/dmd/src/dmd/doc.c dmd-1.024/dmd/src/dmd/doc.c --- dmd-1.023/dmd/src/dmd/doc.c 2007-04-10 10:38:58.000000000 +0200 +++ dmd-1.024/dmd/src/dmd/doc.c 2007-11-18 20:54:50.000000000 +0100 @@ -269,7 +269,6 @@ } buf.printf("$(DDOC_COMMENT Generated by Ddoc from %s)\n", srcfile->toChars()); - if (isDocFile) { size_t commentlen = strlen((char *)comment); @@ -283,7 +282,6 @@ } else { - dc->writeSections(sc, this, sc->docbuf); emitMemberComments(sc); } @@ -654,6 +652,10 @@ buf->writestring("static "); if (d->isConst()) buf->writestring("const "); +#if V2 + if (d->isInvariant()) + buf->writestring("invariant "); +#endif if (d->isFinal()) buf->writestring("final "); if (d->isSynchronized()) @@ -663,7 +665,7 @@ void Declaration::toDocBuffer(OutBuffer *buf) { - //printf("Declaration::toDocbuffer() %s\n", toChars()); + //printf("Declaration::toDocbuffer() %s, originalType = %p\n", toChars(), originalType); if (ident) { prefix(buf, this); @@ -671,7 +673,12 @@ if (type) { HdrGenState hgs; hgs.ddoc = 1; - type->toCBuffer(buf, ident, &hgs); + if (originalType) + { //originalType->print(); + originalType->toCBuffer(buf, ident, &hgs); + } + else + type->toCBuffer(buf, ident, &hgs); } else buf->writestring(ident->toChars()); @@ -723,10 +730,11 @@ td->onemember == this) { HdrGenState hgs; unsigned o = buf->offset; + TypeFunction *tf = (TypeFunction *)type; hgs.ddoc = 1; prefix(buf, td); - type->next->toCBuffer(buf, NULL, &hgs); + tf->next->toCBuffer(buf, NULL, &hgs); buf->writeByte(' '); buf->writestring(ident->toChars()); buf->writeByte('('); @@ -738,7 +746,6 @@ tp->toCBuffer(buf, &hgs); } buf->writeByte(')'); - TypeFunction *tf = (TypeFunction *)type; Argument::argsToCBuffer(buf, &hgs, tf->parameters, tf->varargs); buf->writestring(";\n"); diff -uNr dmd-1.023/dmd/src/dmd/expression.c dmd-1.024/dmd/src/dmd/expression.c --- dmd-1.023/dmd/src/dmd/expression.c 2007-10-31 19:07:50.000000000 +0100 +++ dmd-1.024/dmd/src/dmd/expression.c 2007-11-25 00:07:44.000000000 +0100 @@ -1268,7 +1268,7 @@ char *RealExp::toChars() { - static char buffer[sizeof(value) * 3 + 8 + 1 + 1]; + char buffer[sizeof(value) * 3 + 8 + 1 + 1]; #ifdef IN_GCC value.format(buffer, sizeof(buffer)); @@ -1278,7 +1278,7 @@ sprintf(buffer, type->isimaginary() ? "%Lgi" : "%Lg", value); #endif assert(strlen(buffer) < sizeof(buffer)); - return buffer; + return mem.strdup(buffer); } integer_t RealExp::toInteger() @@ -1482,7 +1482,7 @@ char *ComplexExp::toChars() { - static char buffer[sizeof(value) * 3 + 8 + 1]; + char buffer[sizeof(value) * 3 + 8 + 1]; #ifdef IN_GCC char buf1[sizeof(value) * 3 + 8 + 1]; @@ -1494,7 +1494,7 @@ sprintf(buffer, "(%Lg+%Lgi)", creall(value), cimagl(value)); assert(strlen(buffer) < sizeof(buffer)); #endif - return buffer; + return mem.strdup(buffer); } integer_t ComplexExp::toInteger() @@ -3138,7 +3138,13 @@ if (cd->isInterfaceDeclaration()) error("cannot create instance of interface %s", cd->toChars()); else if (cd->isAbstract()) - error("cannot create instance of abstract class %s", cd->toChars()); + { error("cannot create instance of abstract class %s", cd->toChars()); + for (int i = 0; i < cd->vtbl.dim; i++) + { FuncDeclaration *fd = ((Dsymbol *)cd->vtbl.data[i])->isFuncDeclaration(); + if (fd && fd->isAbstract()) + error("function %s is abstract", fd->toChars()); + } + } checkDeprecated(sc, cd); if (cd->isNested()) { /* We need a 'this' pointer for the nested class. @@ -5522,9 +5528,9 @@ TemplateDeclaration *td = dte->td; assert(td); if (!arguments) - // Should fix deduce() so it works on NULL argument + // Should fix deduceFunctionTemplate() so it works on NULL argument arguments = new Expressions(); - f = td->deduce(sc, loc, NULL, arguments); + f = td->deduceFunctionTemplate(sc, loc, NULL, arguments); if (!f) { type = Type::terror; return this; @@ -5699,7 +5705,7 @@ else if (e1->op == TOKtemplate) { TemplateExp *te = (TemplateExp *)e1; - f = te->td->deduce(sc, loc, NULL, arguments); + f = te->td->deduceFunctionTemplate(sc, loc, NULL, arguments); if (!f) { type = Type::terror; return this; diff -uNr dmd-1.023/dmd/src/dmd/func.c dmd-1.024/dmd/src/dmd/func.c --- dmd-1.023/dmd/src/dmd/func.c 2007-10-30 21:06:30.000000000 +0100 +++ dmd-1.024/dmd/src/dmd/func.c 2007-11-24 23:42:34.000000000 +0100 @@ -136,6 +136,9 @@ if (isAbstract() && !isVirtual()) error("non-virtual functions cannot be abstract"); + + if (isAbstract() && isFinal()) + error("cannot be both final and abstract"); #if 0 if (isAbstract() && fbody) error("abstract functions cannot have bodies"); diff -uNr dmd-1.023/dmd/src/dmd/mars.c dmd-1.024/dmd/src/dmd/mars.c --- dmd-1.023/dmd/src/dmd/mars.c 2007-10-11 01:19:02.000000000 +0200 +++ dmd-1.024/dmd/src/dmd/mars.c 2007-11-01 19:41:44.000000000 +0100 @@ -60,7 +60,7 @@ copyright = "Copyright (c) 1999-2007 by Digital Mars"; written = "written by Walter Bright"; - version = "v1.023"; + version = "v1.024"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); diff -uNr dmd-1.023/dmd/src/dmd/module.c dmd-1.024/dmd/src/dmd/module.c --- dmd-1.023/dmd/src/dmd/module.c 2007-06-29 11:32:24.000000000 +0200 +++ dmd-1.024/dmd/src/dmd/module.c 2007-11-22 00:07:22.000000000 +0100 @@ -85,6 +85,7 @@ vmoduleinfo = NULL; massert = NULL; marray = NULL; + sictor = NULL; sctor = NULL; sdtor = NULL; stest = NULL; diff -uNr dmd-1.023/dmd/src/dmd/module.h dmd-1.024/dmd/src/dmd/module.h --- dmd-1.023/dmd/src/dmd/module.h 2007-04-10 10:38:58.000000000 +0200 +++ dmd-1.024/dmd/src/dmd/module.h 2007-11-22 00:07:12.000000000 +0100 @@ -139,6 +139,7 @@ Symbol *cov; // private uint[] __coverage; unsigned *covb; // bit array of valid code line numbers + Symbol *sictor; // module order independent constructor Symbol *sctor; // module constructor Symbol *sdtor; // module destructor Symbol *stest; // module unit test diff -uNr dmd-1.023/dmd/src/dmd/mtype.c dmd-1.024/dmd/src/dmd/mtype.c --- dmd-1.023/dmd/src/dmd/mtype.c 2007-10-21 12:20:38.000000000 +0200 +++ dmd-1.024/dmd/src/dmd/mtype.c 2007-11-01 22:27:36.000000000 +0100 @@ -2720,38 +2720,50 @@ } //printf("TypeFunction::semantic() this = %p\n", this); - linkage = sc->linkage; - if (!next) + TypeFunction *tf = (TypeFunction *)mem.malloc(sizeof(TypeFunction)); + memcpy(tf, this, sizeof(TypeFunction)); + if (parameters) + { tf->parameters = (Arguments *)parameters->copy(); + for (size_t i = 0; i < parameters->dim; i++) + { Argument *arg = (Argument *)parameters->data[i]; + Argument *cpy = (Argument *)mem.malloc(sizeof(Argument)); + memcpy(cpy, arg, sizeof(Argument)); + tf->parameters->data[i] = (void *)cpy; + } + } + + tf->linkage = sc->linkage; + if (!tf->next) { assert(global.errors); - next = tvoid; + tf->next = tvoid; } - next = next->semantic(loc,sc); - if (next->toBasetype()->ty == Tsarray) - { error(loc, "functions cannot return static array %s", next->toChars()); - next = Type::terror; + tf->next = tf->next->semantic(loc,sc); + if (tf->next->toBasetype()->ty == Tsarray) + { error(loc, "functions cannot return static array %s", tf->next->toChars()); + tf->next = Type::terror; } - if (next->toBasetype()->ty == Tfunction) + if (tf->next->toBasetype()->ty == Tfunction) { error(loc, "functions cannot return a function"); - next = Type::terror; + tf->next = Type::terror; } - if (next->toBasetype()->ty == Ttuple) + if (tf->next->toBasetype()->ty == Ttuple) { error(loc, "functions cannot return a tuple"); - next = Type::terror; + tf->next = Type::terror; } - if (next->isauto() && !(sc->flags & SCOPEctor)) - error(loc, "functions cannot return auto %s", next->toChars()); + if (tf->next->isauto() && !(sc->flags & SCOPEctor)) + error(loc, "functions cannot return auto %s", tf->next->toChars()); - if (parameters) - { size_t dim = Argument::dim(parameters); + if (tf->parameters) + { size_t dim = Argument::dim(tf->parameters); for (size_t i = 0; i < dim; i++) - { Argument *arg = Argument::getNth(parameters, i); + { Argument *arg = Argument::getNth(tf->parameters, i); Type *t; - inuse++; + tf->inuse++; arg->type = arg->type->semantic(loc,sc); - if (inuse == 1) inuse--; + if (tf->inuse == 1) tf->inuse--; t = arg->type->toBasetype(); if (arg->storageClass & (STCout | STCref | STClazy)) @@ -2773,27 +2785,27 @@ * change. */ if (t->ty == Ttuple) - { dim = Argument::dim(parameters); + { dim = Argument::dim(tf->parameters); i--; } } } - deco = merge()->deco; + tf->deco = tf->merge()->deco; - if (inuse) + if (tf->inuse) { error(loc, "recursive type"); - inuse = 0; + tf->inuse = 0; return terror; } - if (varargs == 1 && linkage != LINKd && Argument::dim(parameters) == 0) + if (tf->varargs == 1 && tf->linkage != LINKd && Argument::dim(tf->parameters) == 0) error(loc, "variadic functions with non-D linkage must have at least one parameter"); /* Don't return merge(), because arg identifiers and default args * can be different * even though the types match */ - return this; + return tf; } /******************************** diff -uNr dmd-1.023/dmd/src/dmd/opover.c dmd-1.024/dmd/src/dmd/opover.c --- dmd-1.023/dmd/src/dmd/opover.c 2007-07-11 08:29:28.000000000 +0200 +++ dmd-1.024/dmd/src/dmd/opover.c 2007-11-14 11:42:40.000000000 +0100 @@ -729,7 +729,7 @@ FuncDeclaration *fd; assert(td); - fd = td->deduce(sc, loc, targsi, arguments); + fd = td->deduceFunctionTemplate(sc, loc, targsi, arguments); if (!fd) return; m->anyf = fd; diff -uNr dmd-1.023/dmd/src/dmd/template.c dmd-1.024/dmd/src/dmd/template.c --- dmd-1.023/dmd/src/dmd/template.c 2007-10-31 19:31:38.000000000 +0100 +++ dmd-1.024/dmd/src/dmd/template.c 2007-11-14 11:41:34.000000000 +0100 @@ -647,7 +647,7 @@ * dedargs Expression/Type deduced template arguments */ -MATCH TemplateDeclaration::deduceMatch(Objects *targsi, Expressions *fargs, +MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs, Objects *dedargs) { size_t i; @@ -662,7 +662,7 @@ Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T #if 0 - printf("\nTemplateDeclaration::deduceMatch() %s\n", toChars()); + printf("\nTemplateDeclaration::deduceFunctionTemplateMatch() %s\n", toChars()); for (i = 0; i < fargs->dim; i++) { Expression *e = (Expression *)fargs->data[i]; printf("\tfarg[%d] is %s, type is %s\n", i, e->toChars(), e->type->toChars()); @@ -985,7 +985,7 @@ * fargs arguments to function */ -FuncDeclaration *TemplateDeclaration::deduce(Scope *sc, Loc loc, +FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expressions *fargs) { MATCH m_best = MATCHnomatch; @@ -996,7 +996,7 @@ FuncDeclaration *fd; #if 0 - printf("TemplateDeclaration::deduce() %s\n", toChars()); + printf("TemplateDeclaration::deduceFunctionTemplate() %s\n", toChars()); printf(" targsi:\n"); if (targsi) { for (int i = 0; i < targsi->dim; i++) @@ -1028,8 +1028,8 @@ MATCH m; Objects dedargs; - m = td->deduceMatch(targsi, fargs, &dedargs); - //printf("deduceMatch = %d\n", m); + m = td->deduceFunctionTemplateMatch(targsi, fargs, &dedargs); + //printf("deduceFunctionTemplateMatch = %d\n", m); if (!m) // if no match continue; diff -uNr dmd-1.023/dmd/src/dmd/template.h dmd-1.024/dmd/src/dmd/template.h --- dmd-1.023/dmd/src/dmd/template.h 2007-10-21 19:54:28.000000000 +0200 +++ dmd-1.024/dmd/src/dmd/template.h 2007-11-14 11:41:34.000000000 +0100 @@ -70,8 +70,8 @@ MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, int flag); int leastAsSpecialized(TemplateDeclaration *td2); - MATCH deduceMatch(Objects *targsi, Expressions *fargs, Objects *dedargs); - FuncDeclaration *deduce(Scope *sc, Loc loc, Objects *targsi, Expressions *fargs); + MATCH deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs, Objects *dedargs); + FuncDeclaration *deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expressions *fargs); void declareParameter(Scope *sc, TemplateParameter *tp, Object *o); TemplateDeclaration *isTemplateDeclaration() { return this; } diff -uNr dmd-1.023/dmd/src/dmd/toobj.c dmd-1.024/dmd/src/dmd/toobj.c --- dmd-1.023/dmd/src/dmd/toobj.c 2007-09-08 18:29:06.000000000 +0200 +++ dmd-1.024/dmd/src/dmd/toobj.c 2007-11-23 11:12:26.000000000 +0100 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2006 by Digital Mars +// Copyright (c) 1999-2007 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -46,7 +46,7 @@ { Symbol *msym = toSymbol(); unsigned offset; - unsigned sizeof_ModuleInfo = 12 * PTRSIZE; + unsigned sizeof_ModuleInfo = 14 * PTRSIZE; ////////////////////////////////////////////// @@ -64,6 +64,8 @@ void *ctor; void *dtor; void *unitTest; + const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function + void *ictor; } */ dt_t *dt = NULL; @@ -114,9 +116,9 @@ dtdword(&dt, 0); if (needmoduleinfo) - dtdword(&dt, 0); // flags (4 means MIstandalone) + dtdword(&dt, 8|0); // flags (4 means MIstandalone) else - dtdword(&dt, 4); // flags (4 means MIstandalone) + dtdword(&dt, 8|4); // flags (4 means MIstandalone) if (sctor) dtxoff(&dt, sctor, 0, TYnptr); @@ -133,6 +135,13 @@ else dtdword(&dt, 0); + dtdword(&dt, 0); // xgetMembers + + if (sictor) + dtxoff(&dt, sictor, 0, TYnptr); + else + dtdword(&dt, 0); + ////////////////////////////////////////////// for (i = 0; i < aimports.dim; i++) diff -uNr dmd-1.023/dmd/src/phobos/std/moduleinit.d dmd-1.024/dmd/src/phobos/std/moduleinit.d --- dmd-1.023/dmd/src/phobos/std/moduleinit.d 2007-11-01 11:21:02.000000000 +0100 +++ dmd-1.024/dmd/src/phobos/std/moduleinit.d 2007-11-27 21:19:24.000000000 +0100 @@ -1,3 +1,4 @@ +// Written in the D programming language module std.moduleinit; @@ -17,6 +18,7 @@ MIctordone = 2, // finished construction MIstandalone = 4, // module ctor does not depend on other module // ctors being done first + MIhasictor = 8, // has ictor member } /*********************** @@ -30,9 +32,13 @@ uint flags; // initialization state - void (*ctor)(); - void (*dtor)(); - void (*unitTest)(); + void (*ctor)(); // module static constructor (order dependent) + void (*dtor)(); // module static destructor + void (*unitTest)(); // module unit tests + + void* xgetMembers; // module getMembers() function + + void (*ictor)(); // module static constructor (order independent) /****************** * Return collection of all modules in the program. @@ -47,7 +53,8 @@ { this(ModuleInfo m) { - super("circular initialization dependency with module " ~ m.name); + super(cast(string) ("circular initialization dependency with module " + ~ m.name)); } } @@ -105,6 +112,7 @@ _moduleinfo_dtors = new ModuleInfo[_moduleinfo_array.length]; debug printf("_moduleinfo_dtors = x%x\n", cast(void *)_moduleinfo_dtors); + _moduleIndependentCtors(); _moduleCtor2(_moduleinfo_array, 0); version (none) @@ -209,3 +217,20 @@ } } +/********************************** + * Run unit tests. + */ + +extern (C) void _moduleIndependentCtors() +{ + debug printf("_moduleIndependentCtors()\n"); + foreach (m; _moduleinfo_array) + { + if (m && m.flags & MIhasictor && m.ictor) + { + (*m.ictor)(); + } + } +} + +