diff -uNr dmd-0.136/dmd/src/dmd/attrib.h dmd-0.137/dmd/src/dmd/attrib.h --- dmd-0.136/dmd/src/dmd/attrib.h 2005-09-19 14:44:08.000000000 +0200 +++ dmd-0.137/dmd/src/dmd/attrib.h 2005-10-24 01:01:24.000000000 +0200 @@ -43,6 +43,7 @@ void checkCtorConstInit(); void addLocalClass(Array *); void toCBuffer(OutBuffer *buf); + AttribDeclaration *isAttribDeclaration() { return this; } void toObjFile(); // compile to .obj file int cvMember(unsigned char *p); diff -uNr dmd-0.136/dmd/src/dmd/declaration.c dmd-0.137/dmd/src/dmd/declaration.c --- dmd-0.136/dmd/src/dmd/declaration.c 2005-10-16 15:40:32.000000000 +0200 +++ dmd-0.137/dmd/src/dmd/declaration.c 2005-10-24 12:29:40.000000000 +0200 @@ -161,7 +161,8 @@ AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Type *type) : Declaration(id) { - //printf("AliasDeclaration(id = '%s')\n", id->toChars()); + //printf("AliasDeclaration(id = '%s', type = %p)\n", id->toChars(), type); + //printf("type = '%s'\n", type->toChars()); this->loc = loc; this->type = type; this->aliassym = NULL; @@ -173,6 +174,7 @@ AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s) : Declaration(id) { + //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s); assert(s != this); this->loc = loc; this->type = NULL; @@ -355,12 +357,12 @@ : Declaration(id) { #ifdef DEBUG - if (!type) + if (!type && !init) { printf("VarDeclaration('%s')\n", id->toChars()); *(char*)0=0; } #endif - assert(type); + assert(type || init); this->type = type; this->init = init; this->loc = loc; @@ -388,9 +390,8 @@ //init->isExpInitializer()->exp->dump(0); } - sv = new VarDeclaration(loc, type->syntaxCopy(), ident, init); + sv = new VarDeclaration(loc, type ? type->syntaxCopy() : NULL, ident, init); sv->storage_class = storage_class; - //sv->storage_class |= storage_class & STCauto; } return sv; } @@ -399,13 +400,28 @@ { //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); - type = type->semantic(loc, sc); + storage_class |= sc->stc; + if (storage_class & STCextern && init) + error("extern symbols cannot have initializers"); + + /* If auto type inference, do the inference + */ + if (!type) + { type = init->inferType(sc); + + /* This is a kludge to support the existing syntax for RAII + * declarations. + */ + storage_class &= ~STCauto; + } + else + type = type->semantic(loc, sc); + type->checkDeprecated(loc, sc); linkage = sc->linkage; this->parent = sc->parent; //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); protection = sc->protection; - storage_class |= sc->stc; //printf("sc->stc = %x\n", sc->stc); //printf("storage_class = %x\n", storage_class); diff -uNr dmd-0.136/dmd/src/dmd/dsymbol.h dmd-0.137/dmd/src/dmd/dsymbol.h --- dmd-0.136/dmd/src/dmd/dsymbol.h 2005-09-19 11:18:40.000000000 +0200 +++ dmd-0.137/dmd/src/dmd/dsymbol.h 2005-10-24 01:01:24.000000000 +0200 @@ -42,6 +42,7 @@ struct UnitTestDeclaration; struct NewDeclaration; struct VarDeclaration; +struct AttribDeclaration; struct Symbol; struct Package; struct Module; @@ -179,6 +180,7 @@ virtual Import *isImport() { return NULL; } virtual EnumDeclaration *isEnumDeclaration() { return NULL; } virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; } + virtual AttribDeclaration *isAttribDeclaration() { return NULL; } }; // Dsymbol that generates a scope diff -uNr dmd-0.136/dmd/src/dmd/expression.c dmd-0.137/dmd/src/dmd/expression.c --- dmd-0.136/dmd/src/dmd/expression.c 2005-10-16 15:29:24.000000000 +0200 +++ dmd-0.137/dmd/src/dmd/expression.c 2005-10-24 12:29:10.000000000 +0200 @@ -34,6 +34,7 @@ #include "id.h" #include "dsymbol.h" #include "module.h" +#include "attrib.h" Expression *createTypeInfoArray(Scope *sc, Expression *args[], int dim); @@ -1820,7 +1821,7 @@ #if LOGSEMANTIC printf("NewExp::semantic() %s\n", toChars()); - //printf("type: %s\n", type->toChars()); + printf("type: %s\n", type->toChars()); #endif type = type->semantic(loc, sc); tb = type->toBasetype(); @@ -1913,6 +1914,9 @@ FuncDeclaration *f = sd->aggNew; TypeFunction *tf; + if (arguments && arguments->dim) + error("no constructor for %s", type->toChars()); + if (f) { Expression *e; @@ -1951,6 +1955,9 @@ } else if (tb->isscalar()) { + if (arguments && arguments->dim) + error("no constructor for %s", type->toChars()); + type = type->pointerTo(); } else @@ -2298,27 +2305,40 @@ printf("DeclarationExp::semantic() %s\n", toChars()); #endif - if (declaration->isVarDeclaration()) + /* This is here to support extern(linkage) declaration, + * where the extern(linkage) winds up being an AttribDeclaration + * wrapper. + */ + Dsymbol *s = declaration; + + AttribDeclaration *ad = declaration->isAttribDeclaration(); + if (ad) + { + if (ad->decl && ad->decl->dim == 1) + s = (Dsymbol *)ad->decl->data[0]; + } + + if (s->isVarDeclaration()) { // Do semantic() on initializer first, so: // int a = a; // will be illegal. declaration->semantic(sc); - declaration->parent = sc->parent; + s->parent = sc->parent; } - //printf("inserting '%s' %p into sc = %p\n", declaration->toChars(), declaration, sc); + //printf("inserting '%s' %p into sc = %p\n", s->toChars(), s, sc); // Insert into both local scope and function scope. // Must be unique in both. - if (declaration->ident) + if (s->ident) { - if (!sc->insert(declaration) || - (declaration->isFuncDeclaration() && !sc->func->localsymtab->insert(declaration))) - //error("declaration %s.%s is already defined", sc->func->toChars(), declaration->toChars()); - error("declaration %s is already defined", declaration->toPrettyChars()); + if (!sc->insert(s) || + (s->isFuncDeclaration() && !sc->func->localsymtab->insert(s))) + //error("declaration %s.%s is already defined", sc->func->toChars(), s->toChars()); + error("declaration %s is already defined", s->toPrettyChars()); } - if (!declaration->isVarDeclaration()) + if (!s->isVarDeclaration()) { declaration->semantic(sc); - declaration->parent = sc->parent; + s->parent = sc->parent; } if (!global.errors) { @@ -2518,6 +2538,7 @@ Array dedtypes; dedtypes.setDim(1); + dedtypes.data[0] = NULL; m = targ->deduceType(tspec, ¶meters, &dedtypes); if (m == MATCHnomatch || @@ -2525,6 +2546,7 @@ goto Lno; else { + assert(dedtypes.dim == 1); tded = (Type *)dedtypes.data[0]; if (!tded) tded = targ; diff -uNr dmd-0.136/dmd/src/dmd/init.c dmd-0.137/dmd/src/dmd/init.c --- dmd-0.136/dmd/src/dmd/init.c 2005-06-01 14:20:08.000000000 +0200 +++ dmd-0.137/dmd/src/dmd/init.c 2005-10-20 00:48:56.000000000 +0200 @@ -37,6 +37,12 @@ return this; } +Type *Initializer::inferType(Scope *sc) +{ + error(loc, "cannot infer type from initializer"); + return Type::terror; +} + Array *Initializer::arraySyntaxCopy(Array *ai) { Array *a = NULL; @@ -369,6 +375,12 @@ return this; } +Type *ExpInitializer::inferType(Scope *sc) +{ + exp = exp->semantic(sc); + return exp->type; +} + Expression *ExpInitializer::toExpression() { return exp; diff -uNr dmd-0.136/dmd/src/dmd/init.h dmd-0.137/dmd/src/dmd/init.h --- dmd-0.136/dmd/src/dmd/init.h 2005-06-01 14:20:08.000000000 +0200 +++ dmd-0.137/dmd/src/dmd/init.h 2005-10-20 00:33:04.000000000 +0200 @@ -30,6 +30,7 @@ Initializer(Loc loc); virtual Initializer *syntaxCopy(); virtual Initializer *semantic(Scope *sc, Type *t); + virtual Type *inferType(Scope *sc); virtual Expression *toExpression() = 0; virtual void toCBuffer(OutBuffer *buf) = 0; @@ -98,6 +99,7 @@ ExpInitializer(Loc loc, Expression *exp); Initializer *syntaxCopy(); Initializer *semantic(Scope *sc, Type *t); + Type *inferType(Scope *sc); Expression *toExpression(); void toCBuffer(OutBuffer *buf); diff -uNr dmd-0.136/dmd/src/dmd/lexer.c dmd-0.137/dmd/src/dmd/lexer.c --- dmd-0.136/dmd/src/dmd/lexer.c 2005-09-29 20:26:38.000000000 +0200 +++ dmd-0.137/dmd/src/dmd/lexer.c 2005-10-17 20:39:06.000000000 +0200 @@ -1457,7 +1457,6 @@ int base; unsigned c; unsigned char *start; - integer_t n; TOK result; //printf("Lexer::number()\n"); @@ -1669,6 +1668,8 @@ if (state == STATE_octale) error("Octal digit expected"); + uinteger_t n; // unsigned >=64 bit integer type + if (stringbuffer.offset == 1 && (state == STATE_decimal || state == STATE_0)) n = stringbuffer.data[0] - '0'; else @@ -1717,6 +1718,9 @@ p++; } #endif + if (sizeof(n) > 8 && + n > 0xFFFFFFFFFFFFFFFFULL) // if n needs more than 64 bits + error("integer overflow"); } // Parse trailing 'u', 'U', 'l' or 'L' in any combination @@ -1743,7 +1747,6 @@ break; } - assert(sizeof(long) == 4); // some dependencies switch (flags) { case 0: diff -uNr dmd-0.136/dmd/src/dmd/mars.c dmd-0.137/dmd/src/dmd/mars.c --- dmd-0.136/dmd/src/dmd/mars.c 2005-10-09 12:32:14.000000000 +0200 +++ dmd-0.137/dmd/src/dmd/mars.c 2005-10-17 20:39:24.000000000 +0200 @@ -51,7 +51,7 @@ copyright = "Copyright (c) 1999-2005 by Digital Mars"; written = "written by Walter Bright"; - version = "v0.136"; + version = "v0.137"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); diff -uNr dmd-0.136/dmd/src/dmd/parse.c dmd-0.137/dmd/src/dmd/parse.c --- dmd-0.136/dmd/src/dmd/parse.c 2005-09-29 19:43:56.000000000 +0200 +++ dmd-0.137/dmd/src/dmd/parse.c 2005-10-24 12:42:58.000000000 +0200 @@ -282,12 +282,51 @@ case TOKabstract: stc |= STCabstract; goto Lstc; case TOKsynchronized: stc |= STCsynchronized; goto Lstc; case TOKdeprecated: stc |= STCdeprecated; goto Lstc; + default: + break; } - a = parseBlock(); - s = new StorageClassDeclaration(stc, a); - break; + /* Look for auto initializers: + * storage_class identifier = initializer; + */ + if (token.value == TOKidentifier && + peek(&token)->value == TOKassign) + { + a = new Array(); + Identifier *ident = token.ident; + nextToken(); + nextToken(); + Initializer *init = parseInitializer(); + VarDeclaration *v = new VarDeclaration(loc, NULL, ident, init); + v->storage_class = stc; + a->push(v); + if (token.value == TOKsemicolon) + { + nextToken(); + addComment(v, comment); + } + else + error("semicolon expected following auto declaration, not '%s'", token.toChars()); + } + else + { a = parseBlock(); + s = new StorageClassDeclaration(stc, a); + } + break; + case TOKextern: + if (peek(&token)->value != TOKlparen) + { stc = STCextern; + goto Lstc; + } + { + enum LINK linksave = linkage; + linkage = parseLinkage(); + a = parseBlock(); + s = new LinkDeclaration(linkage, a); + linkage = linksave; + break; + } case TOKprivate: prot = PROTprivate; goto Lprot; case TOKpackage: prot = PROTpackage; goto Lprot; case TOKprotected: prot = PROTprotected; goto Lprot; @@ -350,58 +389,6 @@ break; } - case TOKextern: - { enum LINK link = LINKdefault; - enum LINK linksave; - - s = NULL; - nextToken(); - if (token.value == TOKlparen) - { - nextToken(); - if (token.value == TOKidentifier) - { Identifier *id = token.ident; - - nextToken(); - if (id == Id::Windows) - link = LINKwindows; - else if (id == Id::Pascal) - link = LINKpascal; - else if (id == Id::D) - link = LINKd; - else if (id == Id::C) - { - link = LINKc; - if (token.value == TOKplusplus) - { link = LINKcpp; - nextToken(); - } - } - else - { - error("valid linkage identifiers are D, C, C++, Pascal, Windows"); - link = LINKd; - break; - } - } - else - { - link = LINKd; // default - } - check(TOKrparen); - } - else - { stc = STCextern; - goto Lstc2; - } - linksave = linkage; - linkage = link; - a = parseBlock(); - linkage = linksave; - s = new LinkDeclaration(link, a); - break; - } - case TOKdebug: nextToken(); if (token.value == TOKassign) @@ -545,6 +532,50 @@ return new StaticAssert(loc, exp); } + +/*********************************** + * Parse extern (linkage) + * The parser is on the 'extern' token. + */ + +enum LINK Parser::parseLinkage() +{ + enum LINK link = LINKdefault; + nextToken(); + assert(token.value == TOKlparen); + nextToken(); + if (token.value == TOKidentifier) + { Identifier *id = token.ident; + + nextToken(); + if (id == Id::Windows) + link = LINKwindows; + else if (id == Id::Pascal) + link = LINKpascal; + else if (id == Id::D) + link = LINKd; + else if (id == Id::C) + { + link = LINKc; + if (token.value == TOKplusplus) + { link = LINKcpp; + nextToken(); + } + } + else + { + error("valid linkage identifiers are D, C, C++, Pascal, Windows"); + link = LINKd; + } + } + else + { + link = LINKd; // default + } + check(TOKrparen); + return link; +} + /************************************** * Parse a debug conditional */ @@ -1935,7 +1966,7 @@ Array *Parser::parseDeclaration() { enum STC storage_class; - enum STC sc; + enum STC stc; Type *ts; Type *t; Type *tfirst; @@ -1943,6 +1974,7 @@ Array *a; enum TOK tok; unsigned char *comment = token.blockComment; + enum LINK link = linkage; //printf("parseDeclaration()\n"); switch (token.value) @@ -1963,26 +1995,62 @@ { switch (token.value) { - case TOKconst: sc = STCconst; goto L1; - case TOKstatic: sc = STCstatic; goto L1; - case TOKfinal: sc = STCfinal; goto L1; - case TOKauto: sc = STCauto; goto L1; - case TOKoverride: sc = STCoverride; goto L1; - case TOKabstract: sc = STCabstract; goto L1; - case TOKsynchronized: sc = STCsynchronized; goto L1; - case TOKdeprecated: sc = STCdeprecated; goto L1; + case TOKconst: stc = STCconst; goto L1; + case TOKstatic: stc = STCstatic; goto L1; + case TOKfinal: stc = STCfinal; goto L1; + case TOKauto: stc = STCauto; goto L1; + case TOKoverride: stc = STCoverride; goto L1; + case TOKabstract: stc = STCabstract; goto L1; + case TOKsynchronized: stc = STCsynchronized; goto L1; + case TOKdeprecated: stc = STCdeprecated; goto L1; L1: - if (storage_class & sc) + if (storage_class & stc) error("redundant storage class '%s'", token.toChars()); - storage_class = (STC) (storage_class | sc); + storage_class = (STC) (storage_class | stc); nextToken(); continue; + + case TOKextern: + if (peek(&token)->value != TOKlparen) + { stc = STCextern; + goto L1; + } + + link = parseLinkage(); + continue; + + default: + break; } break; } a = new Array(); + /* Look for auto initializers: + * storage_class identifier = initializer; + */ + if (storage_class && + token.value == TOKidentifier && + peek(&token)->value == TOKassign) + { + ident = token.ident; + nextToken(); + nextToken(); + Initializer *init = parseInitializer(); + VarDeclaration *v = new VarDeclaration(loc, NULL, ident, init); + v->storage_class = storage_class; + a->push(v); + if (token.value == TOKsemicolon) + { + nextToken(); + addComment(v, comment); + } + else + error("semicolon expected following auto declaration, not '%s'", token.toChars()); + return a; + } + if (token.value == TOKclass) { AggregateDeclaration *s; @@ -2051,10 +2119,20 @@ { FuncDeclaration *f; f = new FuncDeclaration(loc, 0, ident, storage_class, t); - a->push(f); addComment(f, comment); parseContracts(f); addComment(f, NULL); + if (link == linkage) + { + a->push(f); + } + else + { + Array *ax = new Array(); + ax->push(f); + Dsymbol *s = new LinkDeclaration(link, ax); + a->push(s); + } } else { VarDeclaration *v; @@ -2465,6 +2543,7 @@ case TOKalias: case TOKconst: case TOKauto: + case TOKextern: // case TOKtypeof: Ldeclaration: { Array *a; diff -uNr dmd-0.136/dmd/src/dmd/parse.h dmd-0.137/dmd/src/dmd/parse.h --- dmd-0.136/dmd/src/dmd/parse.h 2005-09-12 21:42:30.000000000 +0200 +++ dmd-0.137/dmd/src/dmd/parse.h 2005-10-20 23:54:58.000000000 +0200 @@ -58,6 +58,7 @@ Dsymbol *parseMixin(); Array *parseTemplateArgumentList(); StaticAssert *parseStaticAssert(); + enum LINK parseLinkage(); Condition *parseDebugCondition(); Condition *parseVersionCondition(); Condition *parseStaticIfCondition(); diff -uNr dmd-0.136/dmd/src/dmd/toobj.c dmd-0.137/dmd/src/dmd/toobj.c --- dmd-0.136/dmd/src/dmd/toobj.c 2005-06-02 13:52:14.000000000 +0200 +++ dmd-0.137/dmd/src/dmd/toobj.c 2005-10-24 01:51:44.000000000 +0200 @@ -785,7 +785,7 @@ //printf("VarDeclaration::toObjFile(%p '%s') protection %d\n", this, toChars(), protection); - if (isDataseg()) + if (isDataseg() && !(storage_class & STCextern)) { s = toSymbol(); sz = type->size(); diff -uNr dmd-0.136/dmd/src/phobos/object.d dmd-0.137/dmd/src/phobos/object.d --- dmd-0.136/dmd/src/phobos/object.d 2005-10-17 00:40:30.000000000 +0200 +++ dmd-0.137/dmd/src/phobos/object.d 2005-10-24 15:58:08.000000000 +0200 @@ -5,20 +5,8 @@ alias bit bool; -version (X86_64) -{ - alias ulong size_t; - alias long ptrdiff_t; -} -else version (X86) -{ - alias uint size_t; - alias int ptrdiff_t; -} -else -{ - static assert(0); -} +alias typeof(int.sizeof) size_t; +alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t; extern (C) { int printf(char *, ...); diff -uNr dmd-0.136/dmd/src/phobos/std/c/stdio.d dmd-0.137/dmd/src/phobos/std/c/stdio.d --- dmd-0.136/dmd/src/phobos/std/c/stdio.d 2005-10-17 00:40:30.000000000 +0200 +++ dmd-0.137/dmd/src/phobos/std/c/stdio.d 2005-10-24 15:58:08.000000000 +0200 @@ -96,8 +96,8 @@ version (Win32) { - FILE _iob[_NFILE]; - void function() _fcloseallp; + extern FILE _iob[_NFILE]; + extern void function() _fcloseallp; } version (Win32) @@ -140,9 +140,9 @@ version (linux) { - FILE *stdin; - FILE *stdout; - FILE *stderr; + extern FILE *stdin; + extern FILE *stdout; + extern FILE *stderr; } version (Win32)