diff -uNr dmd-0.163/dmd/src/dmd/aggregate.h dmd-0.164/dmd/src/dmd/aggregate.h --- dmd-0.163/dmd/src/dmd/aggregate.h 2006-07-14 15:00:56.000000000 +0200 +++ dmd-0.164/dmd/src/dmd/aggregate.h 2006-08-09 09:10:24.000000000 +0200 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2005 by Digital Mars +// Copyright (c) 1999-2006 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -108,6 +108,7 @@ void toCBuffer(OutBuffer *buf, HdrGenState *hgs); char *mangle(); char *kind(); + void toDocBuffer(OutBuffer *buf); PROT getAccess(Dsymbol *smember); // determine access to smember diff -uNr dmd-0.163/dmd/src/dmd/declaration.c dmd-0.164/dmd/src/dmd/declaration.c --- dmd-0.163/dmd/src/dmd/declaration.c 2006-07-12 12:31:20.000000000 +0200 +++ dmd-0.164/dmd/src/dmd/declaration.c 2006-08-08 23:44:38.000000000 +0200 @@ -135,6 +135,7 @@ { sem = 1; basetype = basetype->semantic(loc, sc); sem = 2; + type = type->semantic(loc, sc); if (sc->parent->isFuncDeclaration() && init) semantic2(sc); } @@ -146,7 +147,7 @@ void TypedefDeclaration::semantic2(Scope *sc) { - //printf("TypedefDeclaration::semantic2()\n"); + //printf("TypedefDeclaration::semantic2(%s) sem = %d\n", toChars(), sem); if (sem == 2) { sem = 3; if (init) @@ -607,7 +608,7 @@ // If it's a member template AggregateDeclaration *ad = ti->tempdecl->isMember(); - if (ad) + if (ad && storage_class != STCundefined) { error("cannot use template to add field to aggregate '%s'", ad->toChars()); } diff -uNr dmd-0.163/dmd/src/dmd/declaration.h dmd-0.164/dmd/src/dmd/declaration.h --- dmd-0.163/dmd/src/dmd/declaration.h 2006-07-12 12:31:20.000000000 +0200 +++ dmd-0.164/dmd/src/dmd/declaration.h 2006-08-09 10:26:18.000000000 +0200 @@ -353,7 +353,7 @@ DsymbolTable *localsymtab; // used to prevent symbols in different // scopes from having the same name - VarDeclaration *vthis; // 'this' parameter + VarDeclaration *vthis; // 'this' parameter (member and nested) VarDeclaration *v_arguments; // '_arguments' parameter #if IN_GCC VarDeclaration *v_argptr; // '_argptr' variable @@ -415,6 +415,7 @@ int canInline(int hasthis, int hdrscan = 0); Expression *doInline(InlineScanState *iss, Expression *ethis, Array *arguments); char *kind(); + void toDocBuffer(OutBuffer *buf); static FuncDeclaration *genCfunc(Type *treturn, char *name); diff -uNr dmd-0.163/dmd/src/dmd/doc.c dmd-0.164/dmd/src/dmd/doc.c --- dmd-0.163/dmd/src/dmd/doc.c 2006-06-29 01:12:32.000000000 +0200 +++ dmd-0.164/dmd/src/dmd/doc.c 2006-08-10 01:55:58.000000000 +0200 @@ -1,5 +1,5 @@ -// Copyright (c) 1999-2005 by Digital Mars +// Copyright (c) 1999-2006 by Digital Mars // All Rights Reserved // written by Walter Bright // www.digitalmars.com @@ -42,6 +42,13 @@ #include "doc.h" #include "mtype.h" +struct Escape +{ + char *strings[256]; + + static char *escapeChar(unsigned c); +}; + struct Section { unsigned char *name; @@ -73,11 +80,13 @@ Section *copyright; Section *macros; Macro **pmacrotable; + Escape **pescapetable; DocComment(); static DocComment *parse(Scope *sc, Dsymbol *s, unsigned char *comment); - static void parseMacros(Macro **pmacrotable, unsigned char *m, unsigned mlen); + static void parseMacros(Escape **pescapetable, Macro **pmacrotable, unsigned char *m, unsigned mlen); + static void parseEscapes(Escape **pescapetable, unsigned char *textstart, unsigned textlen); void parseSections(unsigned char *comment); void writeSections(Scope *sc, Dsymbol *s, OutBuffer *buf); @@ -139,6 +148,7 @@ D_PSYMBOL = $(U $0)\n\ D_PARAM = $(I $0)\n\ \n\ +DDOC_COMMENT = \n\ DDOC_DECL = $(DT $(BIG $0))\n\ DDOC_DECL_DD = $(DD $0)\n\ DDOC_DITTO = $(BR)$0\n\ @@ -175,6 +185,10 @@ DDOC_PSYMBOL = $(U $0)\n\ DDOC_KEYWORD = $(B $0)\n\ DDOC_PARAM = $(I $0)\n\ +\n\ +ESCAPES = //>/\n\ + /&/&/\n\ "; static char ddoc_decl_s[] = "$(DDOC_DECL "; @@ -219,13 +233,14 @@ mbuf.write(file.buffer, file.len); } } - DocComment::parseMacros(¯otable, mbuf.data, mbuf.offset); + DocComment::parseMacros(&escapetable, ¯otable, mbuf.data, mbuf.offset); Scope *sc = Scope::createGlobal(this); // create root scope sc->docbuf = &buf; DocComment *dc = DocComment::parse(sc, this, comment); dc->pmacrotable = ¯otable; + dc->pescapetable = &escapetable; // Generate predefined macros @@ -248,7 +263,7 @@ Macro::define(¯otable, (unsigned char *)"COPYRIGHT", 9, dc->copyright->body, dc->copyright->bodylen); } - buf.printf("\n", srcfile->toChars()); + buf.printf("$(DDOC_COMMENT Generated by Ddoc from %s)\n", srcfile->toChars()); if (isDocFile) { @@ -491,6 +506,7 @@ OutBuffer *buf = sc->docbuf; DocComment *dc = DocComment::parse(sc, this, comment); unsigned o; + int hasmembers = 1; if (!dc) { @@ -499,25 +515,35 @@ } dc->pmacrotable = &sc->module->macrotable; - ScopeDsymbol *ss = this; + Dsymbol *ss = this; if (onemember) { ss = onemember->isAggregateDeclaration(); if (!ss) - ss = this; + { +#if 0 // Do template functions later + ss = onemember->isFuncDeclaration(); + if (ss) + hasmembers = 0; + else +#endif + ss = this; + } } buf->writestring(ddoc_decl_s); o = buf->offset; ss->toDocBuffer(buf); - //highlightCode(sc, this, buf, o); + if (ss == this) + highlightCode(sc, this, buf, o); sc->lastoffset = buf->offset; buf->writestring(ddoc_decl_e); buf->writestring(ddoc_decl_dd_s); dc->writeSections(sc, this, buf); - ss->emitMemberComments(sc); + if (hasmembers) + ((ScopeDsymbol *)ss)->emitMemberComments(sc); buf->writestring(ddoc_decl_dd_e); } @@ -595,6 +621,7 @@ void Dsymbol::toDocBuffer(OutBuffer *buf) { + //printf("Dsymbol::toDocbuffer() %s\n", toChars()); HdrGenState hgs; toCBuffer(buf, &hgs); @@ -662,6 +689,30 @@ } +void FuncDeclaration::toDocBuffer(OutBuffer *buf) +{ + //printf("FuncDeclaration::toDocbuffer() %s\n", toChars()); + if (ident) + { +#if 0 + emitProtection(buf, protection); +#endif + TemplateDeclaration *td; + + if (parent && + (td = parent->isTemplateDeclaration()) != NULL && + td->onemember == this) + { unsigned o = buf->offset; + td->toDocBuffer(buf); + highlightCode(NULL, this, buf, o); + } + else + { + Declaration::toDocBuffer(buf); + } + } +} + void CtorDeclaration::toDocBuffer(OutBuffer *buf) { HdrGenState hgs; @@ -684,6 +735,31 @@ } } +void StructDeclaration::toDocBuffer(OutBuffer *buf) +{ + //printf("StructDeclaration::toDocbuffer() %s\n", toChars()); + if (ident) + { +#if 0 + emitProtection(buf, protection); +#endif + TemplateDeclaration *td; + + if (parent && + (td = parent->isTemplateDeclaration()) != NULL && + td->onemember == this) + { unsigned o = buf->offset; + td->toDocBuffer(buf); + highlightCode(NULL, this, buf, o); + } + else + { + buf->printf("%s $(DDOC_PSYMBOL %s)", kind(), toChars()); + } + buf->writestring(";\n"); + } +} + void ClassDeclaration::toDocBuffer(OutBuffer *buf) { //printf("ClassDeclaration::toDocbuffer() %s\n", toChars()); @@ -1093,7 +1169,7 @@ void MacroSection::write(DocComment *dc, Scope *sc, Dsymbol *s, OutBuffer *buf) { //printf("MacroSection::write()\n"); - DocComment::parseMacros(dc->pmacrotable, body, bodylen); + DocComment::parseMacros(dc->pescapetable, dc->pmacrotable, body, bodylen); } /************************************************ @@ -1104,7 +1180,7 @@ * name2 = value2 */ -void DocComment::parseMacros(Macro **pmacrotable, unsigned char *m, unsigned mlen) +void DocComment::parseMacros(Escape **pescapetable, Macro **pmacrotable, unsigned char *m, unsigned mlen) { unsigned char *p = m; unsigned len = mlen; @@ -1181,7 +1257,10 @@ { // Output existing macro L1: //printf("macro '%.*s' = '%.*s'\n", namelen, namestart, textlen, textstart); - Macro::define(pmacrotable, namestart, namelen, textstart, textlen); + if (icmp("ESCAPES", namestart, namelen) == 0) + parseEscapes(pescapetable, textstart, textlen); + else + Macro::define(pmacrotable, namestart, namelen, textstart, textlen); namelen = 0; if (p >= pend) break; @@ -1219,6 +1298,57 @@ goto L1; // write out last one } +/************************************** + * Parse escapes of the form: + * /c/string/ + * where c is a single character. + * Multiple escapes can be separated + * by whitespace and/or commas. + */ + +void DocComment::parseEscapes(Escape **pescapetable, unsigned char *textstart, unsigned textlen) +{ Escape *escapetable = *pescapetable; + + if (!escapetable) + { escapetable = new Escape; + *pescapetable = escapetable; + } + unsigned char *p = textstart; + unsigned char *pend = p + textlen; + + while (1) + { + while (1) + { + if (p + 4 >= pend) + return; + if (!(*p == ' ' || *p == '\t' || *p == '\n' || *p == ',')) + break; + p++; + } + if (p[0] != '/' || p[2] != '/') + return; + unsigned char c = p[1]; + p += 3; + unsigned char *start = p; + while (1) + { + if (p >= pend) + return; + if (*p == '/') + break; + p++; + } + size_t len = p - start; + char *s = (char *)memcpy(mem.malloc(len + 1), start, len); + s[len] = 0; + escapetable->strings[c] = s; + //printf("%c = '%s'\n", c, s); + p++; + } +} + + /****************************************** * Compare 0-terminated string with length terminated string. * Return < 0, ==0, > 0 @@ -1369,6 +1499,7 @@ char *sid = s->ident->toChars(); FuncDeclaration *f = s->isFuncDeclaration(); unsigned char *p; + char *se; int leadingBlank = 1; int inCode = 0; @@ -1443,19 +1574,28 @@ } L1: - // Replace '<' with < character entity - buf->remove(i, 1); - buf->insert(i, "<", 4); - i += 3; // point to ';' + // Replace '<' with '<' character entity + se = Escape::escapeChar('<'); + if (se) + { size_t len = strlen(se); + buf->remove(i, 1); + i = buf->insert(i, se, len); + i--; // point to ';' + } break; case '>': leadingBlank = 0; if (inCode) break; - buf->remove(i, 1); - i = buf->insert(i, ">", 4); - i--; // point to ';' + // Replace '>' with '>' character entity + se = Escape::escapeChar('>'); + if (se) + { size_t len = strlen(se); + buf->remove(i, 1); + i = buf->insert(i, se, len); + i--; // point to ';' + } break; case '&': @@ -1465,9 +1605,14 @@ p = &buf->data[i]; if (p[1] == '#' || isalpha(p[1])) break; // already a character entity - buf->remove(i, 1); - i = buf->insert(i, "&", 5); - i--; // point to ';' + // Replace '&' with '&' character entity + se = Escape::escapeChar('&'); + if (se) + { size_t len = strlen(se); + buf->remove(i, 1); + i = buf->insert(i, se, len); + i--; // point to ';' + } break; case '-': @@ -1594,52 +1739,38 @@ //printf("highlightCode(s = '%s', kind = %s)\n", sid, s->kind()); for (unsigned i = offset; i < buf->offset; i++) { unsigned char c = buf->data[i]; + char *se; - switch (c) + se = Escape::escapeChar(c); + if (se) { - case '<': // replace '<' with '<' - buf->remove(i, 1); - i = buf->insert(i, "<", 4); - i--; // point to ';' - break; - - case '>': - buf->remove(i, 1); - i = buf->insert(i, ">", 4); - i--; // point to ';' - break; - - case '&': - buf->remove(i, 1); - i = buf->insert(i, "&", 5); - i--; // point to ';' - break; - - default: - if (isalpha(c) || c == '_') - { unsigned j; + size_t len = strlen(se); + buf->remove(i, 1); + i = buf->insert(i, se, len); + i--; // point to ';' + } + else if (isalpha(c) || c == '_') + { unsigned j; - j = skippastident(buf, i); - if (j > i) + j = skippastident(buf, i); + if (j > i) + { + if (cmp(sid, buf->data + i, j - i) == 0) + { + i = buf->bracket(i, "$(DDOC_PSYMBOL ", j, ")") - 1; + continue; + } + else if (f) + { + if (isFunctionParameter(f, buf->data + i, j - i)) { - if (cmp(sid, buf->data + i, j - i) == 0) - { - i = buf->bracket(i, "$(DDOC_PSYMBOL ", j, ")") - 1; - break; - } - else if (f) - { - if (isFunctionParameter(f, buf->data + i, j - i)) - { - //printf("highlighting arg '%s', i = %d, j = %d\n", arg->ident->toChars(), i, j); - i = buf->bracket(i, "$(DDOC_PARAM ", j, ")") - 1; - break; - } - } - i = j - 1; + //printf("highlighting arg '%s', i = %d, j = %d\n", arg->ident->toChars(), i, j); + i = buf->bracket(i, "$(DDOC_PARAM ", j, ")") - 1; + continue; } } - break; + i = j - 1; + } } } } @@ -1650,22 +1781,11 @@ void highlightCode3(OutBuffer *buf, unsigned char *p, unsigned char *pend) { for (; p < pend; p++) - { - switch (*p) - { - case '<': - buf->writestring("<"); - break; - case '>': - buf->writestring(">"); - break; - case '&': - buf->writestring("&"); - break; - default: - buf->writeByte(*p); - break; - } + { char *s = Escape::escapeChar(*p); + if (s) + buf->writestring(s); + else + buf->writeByte(*p); } } @@ -1739,3 +1859,29 @@ buf->write(&res); global.errors = errorsave; } + +/*************************************** + * Find character string to replace c with. + */ + +char *Escape::escapeChar(unsigned c) +{ char *s; + + switch (c) + { + case '<': + s = "<"; + break; + case '>': + s = ">"; + break; + case '&': + s = "&"; + break; + default: + s = NULL; + break; + } + return s; +} + diff -uNr dmd-0.163/dmd/src/dmd/dsymbol.c dmd-0.164/dmd/src/dmd/dsymbol.c --- dmd-0.163/dmd/src/dmd/dsymbol.c 2006-06-19 18:08:36.000000000 +0200 +++ dmd-0.164/dmd/src/dmd/dsymbol.c 2006-07-28 00:00:00.000000000 +0200 @@ -555,7 +555,7 @@ s2 = ss->search(ident, ss->isModule() ? 1 : 0); if (!s) s = s2; - else if (s2 && s != s2) + else if (s2 && s != s2 && s->toAlias() != s2->toAlias()) { /* Two imports of the same module should be regarded as * the same. diff -uNr dmd-0.163/dmd/src/dmd/expression.c dmd-0.164/dmd/src/dmd/expression.c --- dmd-0.163/dmd/src/dmd/expression.c 2006-07-15 13:09:38.000000000 +0200 +++ dmd-0.164/dmd/src/dmd/expression.c 2006-08-08 16:55:40.000000000 +0200 @@ -3794,7 +3794,13 @@ // class type. Dsymbol *s = tcd->toParent(); while (s && s->isFuncDeclaration()) + { FuncDeclaration *f = s->isFuncDeclaration(); + if (f->vthis) + { + e1 = new VarExp(loc, f->vthis); + } s = s->toParent(); + } if (s && s->isClassDeclaration()) e1->type = s->isClassDeclaration()->type; @@ -6876,8 +6882,8 @@ if (ve1->var == ve2->var /*|| ve1->var->toSymbol() == ve2->var->toSymbol()*/) { - // They are the same, result is 'true' - e = new IntegerExp(loc, 1, Type::tboolean); + // They are the same, result is 'true' for ==, 'false' for != + e = new IntegerExp(loc, (op == TOKequal), Type::tboolean); return e; } } diff -uNr dmd-0.163/dmd/src/dmd/import.c dmd-0.164/dmd/src/dmd/import.c --- dmd-0.163/dmd/src/dmd/import.c 2006-07-17 14:37:38.000000000 +0200 +++ dmd-0.164/dmd/src/dmd/import.c 2006-07-27 01:36:52.000000000 +0200 @@ -41,6 +41,9 @@ void Import::addAlias(Identifier *name, Identifier *alias) { + if (isstatic) + error("cannot have an import bind list"); + if (!aliasId) this->ident = NULL; // make it an anonymous import @@ -50,7 +53,7 @@ char *Import::kind() { - return "import"; + return isstatic ? (char *)"static import" : (char *)"import"; } diff -uNr dmd-0.163/dmd/src/dmd/inifile.c dmd-0.164/dmd/src/dmd/inifile.c --- dmd-0.163/dmd/src/dmd/inifile.c 2006-06-04 11:49:34.000000000 +0200 +++ dmd-0.164/dmd/src/dmd/inifile.c 2006-08-08 23:26:58.000000000 +0200 @@ -51,7 +51,6 @@ #if LOG printf("inifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile); #endif - path = FileName::path(argv0); if (FileName::absolute(inifile)) { filename = inifile; @@ -72,17 +71,33 @@ { filename = FileName::combine(getenv("HOME"), inifile); if (!FileName::exists(filename)) - { //mem.free(filename); + { filename = FileName::replaceName(argv0, inifile); -#if linux if (!FileName::exists(filename)) - { //mem.free(filename); + { +#if linux + // Search PATH for argv0 + const char *p = getenv("PATH"); + Array *paths = FileName::splitPath(p); + filename = FileName::searchPath(paths, argv0, 0); + if (!filename) + goto Letc; // argv0 not found on path + filename = FileName::replaceName(filename, inifile); + if (FileName::exists(filename)) + goto Ldone; +#endif + + // Search /etc/ for inifile + Letc: filename = FileName::combine("/etc/", inifile); + + Ldone: + ; } -#endif } } } + path = FileName::path(filename); #if LOG printf("\tpath = '%s', filename = '%s'\n", path, filename); #endif diff -uNr dmd-0.163/dmd/src/dmd/mars.c dmd-0.164/dmd/src/dmd/mars.c --- dmd-0.163/dmd/src/dmd/mars.c 2006-07-07 00:43:28.000000000 +0200 +++ dmd-0.164/dmd/src/dmd/mars.c 2006-07-23 12:24:22.000000000 +0200 @@ -58,7 +58,7 @@ copyright = "Copyright (c) 1999-2006 by Digital Mars"; written = "written by Walter Bright"; - version = "v0.163"; + version = "v0.164"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); diff -uNr dmd-0.163/dmd/src/dmd/module.c dmd-0.164/dmd/src/dmd/module.c --- dmd-0.163/dmd/src/dmd/module.c 2006-07-15 02:14:50.000000000 +0200 +++ dmd-0.164/dmd/src/dmd/module.c 2006-08-10 01:19:30.000000000 +0200 @@ -97,6 +97,7 @@ versionidsNot = NULL; macrotable = NULL; + escapetable = NULL; cov = NULL; covb = NULL; diff -uNr dmd-0.163/dmd/src/dmd/module.h dmd-0.164/dmd/src/dmd/module.h --- dmd-0.163/dmd/src/dmd/module.h 2006-05-11 01:47:12.000000000 +0200 +++ dmd-0.164/dmd/src/dmd/module.h 2006-08-10 01:19:16.000000000 +0200 @@ -21,6 +21,7 @@ struct ClassDeclaration; struct ModuleDeclaration; struct Macro; +struct Escape; struct VarDeclaration; // Back end @@ -94,6 +95,7 @@ Array *versionidsNot; // forward referenced version identifiers Macro *macrotable; // document comment macros + Escape *escapetable; // document comment escapes Module(char *arg, Identifier *ident, int doDocComment, int doHdrGen); ~Module(); diff -uNr dmd-0.163/dmd/src/dmd/mtype.c dmd-0.164/dmd/src/dmd/mtype.c --- dmd-0.163/dmd/src/dmd/mtype.c 2006-07-12 12:34:26.000000000 +0200 +++ dmd-0.164/dmd/src/dmd/mtype.c 2006-08-09 19:00:30.000000000 +0200 @@ -533,7 +533,8 @@ e->loc = loc; } else if (ident == Id::mangleof) - { assert(deco); + { + assert(deco); e = new StringExp(loc, deco, strlen(deco), 'c'); Scope sc; e = e->semantic(&sc); @@ -1605,6 +1606,7 @@ case Tfunction: case Tnone: error(loc, "can't have array of %s", tbn->toChars()); + tbn = next = tint32; break; } if (tbn->isauto()) @@ -1737,6 +1739,7 @@ case Tfunction: case Tnone: error(loc, "can't have array of %s", tn->toChars()); + tn = next = tint32; break; } if (tn->isauto()) diff -uNr dmd-0.163/dmd/src/dmd/parse.c dmd-0.164/dmd/src/dmd/parse.c --- dmd-0.163/dmd/src/dmd/parse.c 2006-07-15 16:03:50.000000000 +0200 +++ dmd-0.164/dmd/src/dmd/parse.c 2006-08-09 10:19:08.000000000 +0200 @@ -2070,6 +2070,7 @@ tempdecl = new TemplateDeclaration(loc, s->ident, tpl, decldefs); s = tempdecl; } + addComment(s, comment); a->push(s); } else diff -uNr dmd-0.163/dmd/src/dmd/statement.c dmd-0.164/dmd/src/dmd/statement.c --- dmd-0.163/dmd/src/dmd/statement.c 2006-06-16 09:47:54.000000000 +0200 +++ dmd-0.164/dmd/src/dmd/statement.c 2006-08-09 15:26:00.000000000 +0200 @@ -1046,7 +1046,7 @@ tret = func->type->next; // Need a variable to hold value from any return statements in body. - if (!sc->func->vresult && tret != Type::tvoid) + if (!sc->func->vresult && tret && tret != Type::tvoid) { VarDeclaration *v; v = new VarDeclaration(loc, tret, Id::result, NULL); @@ -2016,7 +2016,21 @@ //printf("ReturnStatement::semantic() %s\n", toChars()); FuncDeclaration *fd = sc->parent->isFuncDeclaration(); - FuncDeclaration *fdx = fd; + Scope *scx = sc; + + if (sc->fes) + { + // Find scope of function foreach is in + for (; 1; scx = scx->enclosing) + { + assert(scx); + if (scx->func != fd) + { fd = scx->func; // fd is now function enclosing foreach + break; + } + } + } + Type *tret = fd->type->next; if (fd->tintro) tret = fd->tintro->next; @@ -2027,26 +2041,80 @@ if (!exp && (!tbret || tbret->ty == Tvoid) && fd->isMain()) exp = new IntegerExp(0); - Scope *scx = sc; - if (sc->fes) + if (sc->incontract || scx->incontract) + error("return statements cannot be in contracts"); + if (sc->tf || scx->tf) + error("return statements cannot be in finally, scope(exit) or scope(success) bodies"); + + if (fd->isCtorDeclaration()) { - Statement *s; + // Constructors implicitly do: + // return this; + if (exp && exp->op != TOKthis) + error("cannot return expression from constructor"); + exp = new ThisExp(0); + } - // Find scope of function foreach is in - for (; 1; scx = scx->enclosing) + if (exp) + { + fd->hasReturnExp |= 1; + + exp = exp->semantic(sc); + exp = resolveProperties(sc, exp); + + if (fd->returnLabel && tbret->ty != Tvoid) { - assert(scx); - if (scx->func != fd) - { fdx = scx->func; - break; + } + else if (fd->inferRetType) + { + if (fd->type->next) + { + if (!exp->type->equals(fd->type->next)) + error("mismatched function return type inference of %s and %s", + exp->type->toChars(), fd->type->next->toChars()); + } + else + { + fd->type->next = exp->type; + fd->type = fd->type->semantic(loc, sc); + if (!fd->tintro) + { tret = fd->type->next; + tbret = tret->toBasetype(); + } + } + } + else if (tbret->ty != Tvoid) + { + exp = exp->implicitCastTo(tret); + } + } + else if (fd->inferRetType) + { + if (fd->type->next) + { + if (fd->type->next->ty != Tvoid) + error("mismatched function return type inference of void and %s", + fd->type->next->toChars()); + } + else + { + fd->type->next = Type::tvoid; + fd->type = fd->type->semantic(loc, sc); + if (!fd->tintro) + { tret = Type::tvoid; + tbret = tret; } } + } + else if (tbret->ty != Tvoid) // if non-void return + error("return expression expected"); - tret = fdx->type->next; + if (sc->fes) + { + Statement *s; if (exp) - { exp = exp->semantic(sc); - exp = resolveProperties(sc, exp); + { exp = exp->implicitCastTo(tret); } if (!exp || exp->op == TOKint64 || exp->op == TOKfloat64 || @@ -2057,7 +2125,7 @@ sc->fes->cases.push(this); s = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1)); } - else if (fdx->type->next->toBasetype() == Type::tvoid) + else if (fd->type->next->toBasetype() == Type::tvoid) { Statement *s1; Statement *s2; @@ -2077,13 +2145,24 @@ Statement *s2; // Construct: return vresult; - assert(fdx->vresult); - v = new VarExp(0, fdx->vresult); + if (!fd->vresult) + { VarDeclaration *v; + + v = new VarDeclaration(loc, tret, Id::result, NULL); + v->noauto = 1; + v->semantic(scx); + if (!scx->insert(v)) + assert(0); + v->parent = fd; + fd->vresult = v; + } + + v = new VarExp(0, fd->vresult); s = new ReturnStatement(0, v); sc->fes->cases.push(s); // Construct: { vresult = exp; return cases.dim + 1; } - v = new VarExp(0, fdx->vresult); + v = new VarExp(0, fd->vresult); exp = new AssignExp(loc, v, exp); exp = exp->semantic(sc); s1 = new ExpStatement(loc, exp); @@ -2093,84 +2172,20 @@ return s; } - if (sc->incontract) - error("return statements cannot be in contracts"); - if (sc->tf) - error("return statements cannot be in finally, scope(exit) or scope(success) bodies"); - - if (fd->isCtorDeclaration()) - { - // Constructors implicitly do: - // return this; - if (exp && exp->op != TOKthis) - error("cannot return expression from constructor"); - exp = new ThisExp(0); - } - if (exp) { - fd->hasReturnExp |= 1; - if (fd->returnLabel && tbret->ty != Tvoid) { assert(fd->vresult); VarExp *v = new VarExp(0, fd->vresult); - exp = resolveProperties(sc, exp); exp = new AssignExp(loc, v, exp); exp = exp->semantic(sc); } - else - { - exp = exp->semantic(sc); - exp = resolveProperties(sc, exp); - if (fd->inferRetType) - { - if (fd->type->next) - { - if (!exp->type->equals(fd->type->next)) - error("mismatched function return type inference of %s and %s", - exp->type->toChars(), fd->type->next->toChars()); - } - else - { - fd->type->next = exp->type; - fd->type = fd->type->semantic(loc, sc); - if (!fd->tintro) - { tret = fd->type->next; - tbret = tret->toBasetype(); - } - } - } - else if (tbret->ty != Tvoid) - { - exp = exp->implicitCastTo(tret); - } - } //exp->dump(0); //exp->print(); exp->checkEscape(); } - else if (fd->inferRetType) - { - if (fd->type->next) - { - if (fd->type->next->ty != Tvoid) - error("mismatched function return type inference of void and %s", - fd->type->next->toChars()); - } - else - { - fd->type->next = Type::tvoid; - fd->type = fd->type->semantic(loc, sc); - if (!fd->tintro) - { tret = Type::tvoid; - tbret = tret; - } - } - } - else if (tbret->ty != Tvoid) // if non-void return - error("return expression expected"); /* BUG: need to issue an error on: * this diff -uNr dmd-0.163/dmd/src/dmd/template.c dmd-0.164/dmd/src/dmd/template.c --- dmd-0.163/dmd/src/dmd/template.c 2006-07-09 01:41:10.000000000 +0200 +++ dmd-0.164/dmd/src/dmd/template.c 2006-08-09 10:41:44.000000000 +0200 @@ -739,14 +739,15 @@ void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { - int i; - - +#if 0 // Should handle template functions + if (onemember && onemember->isFuncDeclaration()) + buf->writestring("foo "); +#endif buf->writestring(kind()); buf->writeByte(' '); buf->writestring(ident->toChars()); buf->writeByte('('); - for (i = 0; i < parameters->dim; i++) + for (int i = 0; i < parameters->dim; i++) { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; if (i) @@ -761,7 +762,7 @@ buf->writenl(); buf->writebyte('{'); buf->writenl(); - for (i = 0; i < members->dim; i++) + for (int i = 0; i < members->dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; s->toCBuffer(buf, hgs); @@ -1785,7 +1786,7 @@ return; } #if LOG - printf("+TemplateInstance::semantic('%s', this=%p)\n", toChars(), this); + printf("\n+TemplateInstance::semantic('%s', this=%p)\n", toChars(), this); #endif if (inst) // if semantic() was already run { @@ -1833,7 +1834,7 @@ { TemplateInstance *ti = (TemplateInstance *)tempdecl->instances.data[i]; #if LOG - printf("\tchecking for match with instance %d (%p): '%s'\n", i, ti, ti->toChars()); + printf("\t%s: checking for match with instance %d (%p): '%s'\n", toChars(), i, ti, ti->toChars()); #endif assert(tdtypes.dim == ti->tdtypes.dim); @@ -1883,7 +1884,8 @@ } else if (s1) { - if (!s2 || !s1->equals(s2)) + //printf("test1: %p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars()); + if (!s2 || !s1->equals(s2) || s1->parent != s2->parent) goto L1; } } diff -uNr dmd-0.163/dmd/src/phobos/std/socket.d dmd-0.164/dmd/src/phobos/std/socket.d --- dmd-0.163/dmd/src/phobos/std/socket.d 2006-07-18 12:58:44.000000000 +0200 +++ dmd-0.164/dmd/src/phobos/std/socket.d 2006-08-11 12:42:00.000000000 +0200 @@ -84,7 +84,6 @@ { int errorCode; /// Platform-specific error code. - this(char[] msg, int err = 0) { errorCode = err; @@ -890,7 +889,7 @@ } - // Return maximum amount of sockets that can be added, like FD_SETSIZE. + /// Return maximum amount of sockets that can be added, like FD_SETSIZE. uint max() { version(Win32) @@ -1053,14 +1052,20 @@ } - // Get underlying socket handle. - socket_t handle() // getter + /// Get underlying socket handle. + socket_t handle() { return sock; } - - - bool blocking() // getter + + /** + * Get/set socket's blocking flag. + * + * When a socket is blocking, calls to receive(), accept(), and send() + * will block and wait for data/action. + * A non-blocking socket will immediately return instead of blocking. + */ + bool blocking() { version(Win32) { @@ -1072,8 +1077,8 @@ } } - - void blocking(bool byes) // setter + /// ditto + void blocking(bool byes) { version(Win32) { diff -uNr dmd-0.163/dmd/src/phobos/std/thread.d dmd-0.164/dmd/src/phobos/std/thread.d --- dmd-0.163/dmd/src/phobos/std/thread.d 2006-07-18 12:58:44.000000000 +0200 +++ dmd-0.164/dmd/src/phobos/std/thread.d 2006-08-11 12:42:00.000000000 +0200 @@ -426,7 +426,7 @@ * Create a Thread for global main(). */ - static void thread_init() + public static void thread_init() { threadLock = new Object(); @@ -977,7 +977,7 @@ * Create a Thread for global main(). */ - static void thread_init() + public static void thread_init() { threadLock = new Object(); @@ -1087,7 +1087,7 @@ t.flags |= 1; } - static void* getESP() + public static void* getESP() { asm { naked ;