Mercurial > projects > ddmd
changeset 79:43073c7c7769
updated to 2.035
also implemented a few missing functions
still crashes in Import.importAll though
line wrap: on
line diff
--- a/commands.linux.txt Sun Aug 29 14:39:08 2010 +0100 +++ b/commands.linux.txt Mon Aug 30 03:57:51 2010 +0200 @@ -245,6 +245,7 @@ dmd/InterState.d dmd/InterfaceDeclaration.d dmd/InvariantDeclaration.d +dmd/Json.d dmd/LINK.d dmd/LabelDsymbol.d dmd/LabelStatement.d @@ -324,6 +325,7 @@ dmd/TypeIdentifier.d dmd/TypeInfoDeclaration.d dmd/TypeInstance.d +dmd/TypeNewArray.d dmd/TypeNext.d dmd/TypePointer.d dmd/TypeQualified.d
--- a/commands.txt Sun Aug 29 14:39:08 2010 +0100 +++ b/commands.txt Mon Aug 30 03:57:51 2010 +0200 @@ -240,6 +240,7 @@ dmd\InterState.d dmd\InterfaceDeclaration.d dmd\InvariantDeclaration.d +dmd\Json.d dmd\LINK.d dmd\LabelDsymbol.d dmd\LabelStatement.d @@ -319,6 +320,7 @@ dmd\TypeIdentifier.d dmd\TypeInfoDeclaration.d dmd\TypeInstance.d +dmd\TypeNewArray.d dmd\TypeNext.d dmd\TypePointer.d dmd\TypeQualified.d
--- a/dbg/CallStackInfo.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dbg/CallStackInfo.d Mon Aug 30 03:57:51 2010 +0200 @@ -61,7 +61,8 @@ Throwable error; StackFrameInfo[] frames; - string toString() { + override string toString() + { string text; if (error !is null) { @@ -70,8 +71,10 @@ text ~= "Stack trace:\n------------------\n"; char buffer[128]; - foreach(ref frame; frames) { - with(frame.fileLine) if(line) { + foreach(ref frame; frames) + { + with(frame.fileLine) if(line) + { auto len = snprintf(buffer.ptr, buffer.length, "%u", line); text ~= file ~ ":" ~ buffer[0 .. len] ~ "\r\n"; } @@ -82,7 +85,8 @@ return text; } - void dump() { + void dump() + { if (error !is null) { printf("%.*s\n", error.toString()); }
--- a/dmd/AggregateDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/AggregateDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -31,6 +31,7 @@ import dmd.CtorDeclaration; import dmd.FuncDeclaration; import dmd.Identifier; +import dmd.Json; import dmd.Loc; import dmd.Dsymbol; import dmd.Scope; @@ -149,7 +150,7 @@ uint alignsize; // size of struct for alignment purposes uint structalign; // struct member alignment in effect int hasUnions; // set if aggregate has overlapping fields - Array fields; // VarDeclaration fields + Dsymbols fields; // VarDeclaration fields uint sizeok; // set when structsize contains valid data // 0: no size // 1: size is correct @@ -183,7 +184,7 @@ super(id); this.loc = loc; - fields = new Array(); /// + fields = new Dsymbols(); /// dtors = new FuncDeclarations(); } @@ -323,7 +324,7 @@ v.storage_class |= STC.STCfield; //printf(" addField '%s' to '%s' at offset %d, size = %d\n", v.toChars(), toChars(), v.offset, memsize); - fields.push(cast(void*)v); + fields.push(v); } override bool isDeprecated() // is aggregate deprecated? @@ -343,10 +344,10 @@ //printf("AggregateDeclaration.buildDtor() %s\n", toChars()); Expression e = null; -version (DMDV2) { - for (size_t i = 0; i < fields.dim; i++) +version (DMDV2) +{ + foreach (Dsymbol s; fields) { - Dsymbol s = cast(Dsymbol)fields.data[i]; VarDeclaration v = s.isVarDeclaration(); assert(v && v.storage_class & STC.STCfield); if (v.storage_class & STC.STCref) @@ -443,6 +444,61 @@ assert(false); } + override void toJsonBuffer(OutBuffer buf) + { + //writef("AggregateDeclaration.toJsonBuffer()\n"); + buf.writestring("{\n"); + + JsonProperty(buf, Pname, toChars()); + JsonProperty(buf, Pkind, kind()); + if (comment) + JsonProperty(buf, Pcomment, comment); + if (loc.linnum) + JsonProperty(buf, Pline, loc.linnum); + + ClassDeclaration cd = isClassDeclaration(); + if (cd) + { + if (cd.baseClass) + { + JsonProperty(buf, "base", cd.baseClass.toChars()); + } + if (cd.interfaces_dim) + { + JsonString(buf, "interfaces"); + buf.writestring(" : [\n"); + size_t offset = buf.offset; + for (int i = 0; i < cd.interfaces_dim; i++) + { + BaseClass b = cd.interfaces[i]; + if (offset != buf.offset) + { + buf.writestring(","); + offset = buf.offset; + } + JsonString(buf, b.base.toChars()); + } + buf.writestring("],\n"); + } + } + + JsonString(buf, Pmembers); + buf.writestring(" : [\n"); + size_t offset = buf.offset; + foreach (Dsymbol s; members) + { + if (offset != buf.offset) + { + buf.writestring(","); + offset = buf.offset; + } + s.toJsonBuffer(buf); + } + buf.writestring("]\n"); + + buf.writestring("}\n"); + } + override void toDocBuffer(OutBuffer buf) { assert(false);
--- a/dmd/AliasDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/AliasDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -206,9 +206,15 @@ //printf("AliasDeclaration.overloadInsert('%s')\n", s.toChars()); if (overnext is null) - { + { +static if (true) +{ + if (s is this) + return true; +} overnext = s; return true; + } else {
--- a/dmd/AnonDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/AnonDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -134,10 +134,10 @@ //printf("\tadding members of aad to '%s'\n", ad.toChars()); for (uint i = 0; i < aad.fields.dim; i++) { - VarDeclaration v = cast(VarDeclaration)aad.fields.data[i]; + VarDeclaration v = cast(VarDeclaration)aad.fields[i]; v.offset += sc.offset; - ad.fields.push(cast(void*)v); + ad.fields.push(v); } // Add size of aad to ad
--- a/dmd/ArrayInitializer.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/ArrayInitializer.d Mon Aug 30 03:57:51 2010 +0200 @@ -2,6 +2,7 @@ import dmd.ArrayTypes; import dmd.Type; +import dmd.TypeAArray; import dmd.TypeNext; import dmd.Array; import dmd.Loc; @@ -132,7 +133,7 @@ for (size_t i = 0; i < value.dim; i++) { if (index.data[i]) - goto Lno; + goto Laa; } for (size_t i = 0; i < value.dim; i++) @@ -151,9 +152,22 @@ } return type; - Lno: - error(loc, "cannot infer type from this array initializer"); - return Type.terror; + Laa: + /* It's possibly an associative array initializer + */ + Initializer iz = cast(Initializer)value.data[0]; + Expression indexinit = cast(Expression)index.data[0]; + if (iz && indexinit) + { + Type t = iz.inferType(sc); + indexinit = indexinit.semantic(sc); + Type indext = indexinit.type; + t = new TypeAArray(t, indext); + type = t.semantic(loc, sc); + } + else + error(loc, "cannot infer type from this array initializer"); + return type; } /******************************** @@ -171,6 +185,9 @@ Type t = null; if (type) { + if (type == Type.terror) + return new ErrorExp(); + t = type.toBasetype(); switch (t.ty) {
--- a/dmd/AttribDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/AttribDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -143,7 +143,7 @@ } } - override void addComment(ubyte* comment) + override void addComment(string comment) { if (comment !is null) { @@ -216,7 +216,23 @@ { assert(false); } - + + override void toJsonBuffer(OutBuffer buf) + { + //writef("AttribDeclaration.toJsonBuffer()\n"); + + Dsymbols d = include(null, null); + + if (d) + { + foreach (Dsymbol s; d) + { + //writef("AttribDeclaration.toJsonBuffer %s\n", s.toChars()); + s.toJsonBuffer(buf); + } + } + } + override AttribDeclaration isAttribDeclaration() { return this; } override void toObjFile(int multiobj) // compile to .obj file
--- a/dmd/BinExp.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/BinExp.d Mon Aug 30 03:57:51 2010 +0200 @@ -1381,7 +1381,7 @@ error("Cannot perform array operations on void[] arrays"); return new ErrorExp(); } - + Expressions arguments = new Expressions(); /* The expression to generate an array operation for is mangled @@ -1637,6 +1637,8 @@ sc.stc = STCundefined; sc.linkage = LINKc; fd.semantic(sc); + fd.semantic2(sc); + fd.semantic3(sc); sc.pop(); } else
--- a/dmd/CallExp.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/CallExp.d Mon Aug 30 03:57:51 2010 +0200 @@ -1,5 +1,6 @@ module dmd.CallExp; +import dmd.ErrorExp; import dmd.Expression; import dmd.Cast; import dmd.WANT; @@ -122,19 +123,20 @@ { TypeFunction tf; FuncDeclaration f; - int i; Type t1; int istemp; Objects targsi; // initial list of template arguments TemplateInstance tierror; -version (LOGSEMANTIC) { +version (LOGSEMANTIC) +{ printf("CallExp.semantic() %s\n", toChars()); } if (type) return this; // semantic() already run -static if (false) { +static if (false) +{ if (arguments && arguments.dim) { Expression earg = cast(Expression)arguments.data[0]; @@ -613,8 +615,10 @@ { OverExp eo = cast(OverExp)e1; FuncDeclaration ff = null; - foreach(Dsymbol s; eo.vars.a) - { + Dsymbol s = null; + for(size_t i = 0; i<eo.vars.a.dim; i++) + { + s = eo.vars.a[i]; FuncDeclaration f2 = s.isFuncDeclaration(); if (f2) { @@ -638,11 +642,10 @@ } } if (!ff) - { - /* No overload matches, just set ff and rely on error - * message being generated later. - */ - ff = cast(FuncDeclaration)eo.vars.a[0]; + { + // No overload matches + error("no overload matches for %s", s.toChars()); + return new ErrorExp(); } e1 = new VarExp(loc, ff); goto Lagain;
--- a/dmd/Cast.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/Cast.d Mon Aug 30 03:57:51 2010 +0200 @@ -119,8 +119,8 @@ StructDeclaration sd = tb.toDsymbol(null).isStructDeclaration(); assert(sd); Expressions elements = new Expressions; - for (size_t i = 0; i < sd.fields.dim; i++) - { Dsymbol s = cast(Dsymbol)sd.fields.data[i]; + foreach (Dsymbol s; sd.fields) + { VarDeclaration v = s.isVarDeclaration(); assert(v);
--- a/dmd/CastExp.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/CastExp.d Mon Aug 30 03:57:51 2010 +0200 @@ -11,7 +11,6 @@ import dmd.Id; import dmd.Identifier; import dmd.BinExp; -import dmd.backend.elem; import dmd.UnaExp; import dmd.VarExp; import dmd.Token; @@ -35,12 +34,14 @@ import dmd.PREC; import dmd.Cast; +import dmd.codegen.Util; +import dmd.backend.elem; +import dmd.backend.mTY; import dmd.backend.Util; -import dmd.expression.Util; import dmd.backend.TYM; import dmd.backend.OPER; -import dmd.codegen.Util; import dmd.backend.RTLSYM; +import dmd.expression.Util; class CastExp : UnaExp { @@ -445,25 +446,23 @@ override elem* toElem(IRState* irs) { - elem* e; TY fty; TY tty; tym_t ftym; tym_t ttym; OPER eop; - Type t; - Type tfrom; -static if (false) { +static if (false) +{ printf("CastExp::toElem()\n"); print(); printf("\tfrom: %s\n", e1.type.toChars()); printf("\tto : %s\n", to.toChars()); } - e = e1.toElem(irs); - tfrom = e1.type.toBasetype(); - t = to.toBasetype(); // skip over typedef's + elem* e = e1.toElem(irs); + Type tfrom = e1.type.toBasetype(); + Type t = to.toBasetype(); // skip over typedef's if (t.equals(tfrom)) goto Lret; @@ -525,7 +524,8 @@ goto Lret; } -static if (false) { +static if (false) +{ // Convert from dynamic array string literal to static array if (tty == TY.Tsarray && fty == TY.Tarray && e1.op == TOK.TOKstring) { @@ -607,8 +607,8 @@ goto Lret; } - ftym = e.Ety; - ttym = t.totym(); + ftym = tybasic(e.Ety); + ttym = tybasic(t.totym()); if (ftym == ttym) goto Lret; @@ -657,7 +657,8 @@ Lagain: switch (X(fty,tty)) { -static if (false) { +static if (false) +{ case X(TY.Tbit,TY.Tint8): case X(TY.Tbit,TY.Tuns8): goto Lpaint; @@ -1221,8 +1222,8 @@ if (fty == tty) goto Lpaint; //dump(0); - //printf("fty = %d, tty = %d\n", fty, tty); - error("e2ir: cannot cast from %s to %s", e1.type.toChars(), t.toChars()); + //writef("fty = %d, tty = %d, %d\n", fty, tty, t.ty); + error("e2ir: cannot cast %s of type %s to type %s", e1.toChars(), e1.type.toChars(), t.toChars()); goto Lzero; Lzero:
--- a/dmd/ClassDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/ClassDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -1848,7 +1848,7 @@ // Note equivalence of this loop to struct's for (i = 0; i < fields.dim; i++) { - VarDeclaration v = cast(VarDeclaration)fields.data[i]; + VarDeclaration v = cast(VarDeclaration)fields[i]; Initializer init; //printf("\t\tv = '%s' v.offset = %2d, offset = %2d\n", v.toChars(), v.offset, offset);
--- a/dmd/ClassInfoDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/ClassInfoDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -5,6 +5,7 @@ import dmd.Dsymbol; import dmd.Scope; import dmd.Loc; +import dmd.OutBuffer; import dmd.Id; import dmd.STC; @@ -43,6 +44,10 @@ assert(false); } + override void toJsonBuffer(OutBuffer buf) + { + } + override Symbol* toSymbol() { return cd.toSymbol();
--- a/dmd/CmpExp.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/CmpExp.d Mon Aug 30 03:57:51 2010 +0200 @@ -38,8 +38,6 @@ override Expression semantic(Scope sc) { Expression e; - Type t1; - Type t2; version (LOGSEMANTIC) { printf("CmpExp.semantic('%s')\n", toChars()); @@ -49,8 +47,10 @@ BinExp.semanticp(sc); - if (e1.type.toBasetype().ty == Tclass && e2.op == TOKnull || - e2.type.toBasetype().ty == Tclass && e1.op == TOKnull) + Type t1 = e1.type.toBasetype(); + Type t2 = e2.type.toBasetype(); + if (t1.ty == Tclass && e2.op == TOKnull || + t2.ty == Tclass && e1.op == TOKnull) { error("do not use null when comparing class types"); } @@ -71,6 +71,14 @@ return e; } + // Disallow comparing T[]==T and T==T[] + if (e1.op == TOKslice && t1.ty == Tarray && e2.implicitConvTo(t1.nextOf()) || + e2.op == TOKslice && t2.ty == Tarray && e1.implicitConvTo(t2.nextOf())) + { + incompatibleTypes(); + return new ErrorExp(); + } + typeCombine(sc); type = Type.tboolean;
--- a/dmd/CompoundStatement.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/CompoundStatement.d Mon Aug 30 03:57:51 2010 +0200 @@ -218,12 +218,14 @@ //printf("%s\n", s->toChars()); if (!(result & BE.BEfallthru) && !s.comeFrom()) { - if (s.blockExit() != BE.BEhalt) + if (s.blockExit() != BE.BEhalt && !s.isEmpty()) s.warning("statement is not reachable"); } - - result &= ~BE.BEfallthru; - result |= s.blockExit(); + else + { + result &= ~BE.BEfallthru; + result |= s.blockExit(); + } } }
--- a/dmd/ConditionalDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/ConditionalDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -24,13 +24,13 @@ override Dsymbol syntaxCopy(Dsymbol s) { - ConditionalDeclaration dd; - - assert(!s); - dd = new ConditionalDeclaration(condition.syntaxCopy(), - Dsymbol.arraySyntaxCopy(decl), - Dsymbol.arraySyntaxCopy(elsedecl)); - return dd; + ConditionalDeclaration dd; + + assert(!s); + dd = new ConditionalDeclaration(condition.syntaxCopy(), + Dsymbol.arraySyntaxCopy(decl), + Dsymbol.arraySyntaxCopy(elsedecl)); + return dd; } override bool oneMember(Dsymbol* ps) @@ -47,20 +47,20 @@ override void emitComment(Scope sc) { - //printf("ConditionalDeclaration.emitComment(sc = %p)\n", sc); - if (condition.inc) - { - AttribDeclaration.emitComment(sc); - } - else if (sc.docbuf) - { - /* If generating doc comment, be careful because if we're inside - * a template, then include(NULL, NULL) will fail. - */ - auto d = decl ? decl : elsedecl; - foreach(s; d) - s.emitComment(sc); - } + //printf("ConditionalDeclaration.emitComment(sc = %p)\n", sc); + if (condition.inc) + { + AttribDeclaration.emitComment(sc); + } + else if (sc.docbuf) + { + /* If generating doc comment, be careful because if we're inside + * a template, then include(NULL, NULL) will fail. + */ + auto d = decl ? decl : elsedecl; + foreach(s; d) + s.emitComment(sc); + } } // Decide if 'then' or 'else' code should be included @@ -72,7 +72,7 @@ return condition.include(sc, sd) ? decl : elsedecl; } - override void addComment(ubyte* comment) + override void addComment(string comment) { /* Because addComment is called by the parser, if we called * include() it would define a version before it was used. @@ -99,38 +99,72 @@ override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - condition.toCBuffer(buf, hgs); - if (decl || elsedecl) - { - buf.writenl(); - buf.writeByte('{'); - buf.writenl(); - if (decl) - { - foreach (Dsymbol s; decl) + condition.toCBuffer(buf, hgs); + if (decl || elsedecl) { - buf.writestring(" "); - s.toCBuffer(buf, hgs); + buf.writenl(); + buf.writeByte('{'); + buf.writenl(); + if (decl) + { + foreach (Dsymbol s; decl) + { + buf.writestring(" "); + s.toCBuffer(buf, hgs); + } + } + buf.writeByte('}'); + if (elsedecl) + { + buf.writenl(); + buf.writestring("else"); + buf.writenl(); + buf.writeByte('{'); + buf.writenl(); + foreach (Dsymbol s; elsedecl) + { + buf.writestring(" "); + s.toCBuffer(buf, hgs); + } + buf.writeByte('}'); + } } - } - buf.writeByte('}'); - if (elsedecl) - { + else + buf.writeByte(':'); buf.writenl(); - buf.writestring("else"); - buf.writenl(); - buf.writeByte('{'); - buf.writenl(); - foreach (Dsymbol s; elsedecl) - { - buf.writestring(" "); - s.toCBuffer(buf, hgs); - } - buf.writeByte('}'); + } + + override void toJsonBuffer(OutBuffer buf) + { + // writef("ConditionalDeclaration::toJsonBuffer()\n"); + if (condition.inc) + { + super.toJsonBuffer(buf); + } } + + override void importAll(Scope sc) + { + Dsymbols d = include(sc, null); + + //writef("\tConditionalDeclaration::importAll '%s', d = %p\n",toChars(), d); + if (d) + { + foreach (s; d) + s.importAll(sc); + } } - else - buf.writeByte(':'); - buf.writenl(); - } -} + + override void setScope(Scope sc) + { + Dsymbols d = include(sc, null); + + //writef("\tConditionalDeclaration::setScope '%s', d = %p\n",toChars(), d); + if (d) + { + foreach (s; d) + s.setScope(sc); + } + + } +} \ No newline at end of file
--- a/dmd/Declaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/Declaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -2,9 +2,11 @@ import dmd.Dsymbol; import dmd.Type; +import dmd.TypedefDeclaration; import dmd.PROT; import dmd.LINK; import dmd.Identifier; +import dmd.Json; import dmd.Scope; import dmd.Loc; import dmd.STC; @@ -173,6 +175,32 @@ assert(false); } + override void toJsonBuffer(OutBuffer buf) + { + //writef("Declaration.toJsonBuffer()\n"); + buf.writestring("{\n"); + + JsonProperty(buf, Pname, toChars()); + JsonProperty(buf, Pkind, kind()); + if (type) + JsonProperty(buf, Ptype, type.toChars()); + + if (comment) + JsonProperty(buf, Pcomment, comment); + + if (loc.linnum) + JsonProperty(buf, Pline, loc.linnum); + + TypedefDeclaration td = isTypedefDeclaration(); + if (td) + { + JsonProperty(buf, "base", td.basetype.toChars()); + } + + JsonRemoveComma(buf); + buf.writestring("}\n"); + } + override void toDocBuffer(OutBuffer buf) { assert(false);
--- a/dmd/DeclarationExp.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/DeclarationExp.d Mon Aug 30 03:57:51 2010 +0200 @@ -6,6 +6,7 @@ import dmd.ExpInitializer; import dmd.OutBuffer; import dmd.Loc; +import dmd.STC; import dmd.Scope; import dmd.InlineCostState; import dmd.IRState; @@ -101,7 +102,14 @@ } if (!s.isVarDeclaration()) { - declaration.semantic(sc); + Scope sc2 = sc; + if (sc2.stc & (STC.STCpure | STC.STCnothrow)) + sc2 = sc.push(); + sc2.stc &= ~(STC.STCpure | STC.STCnothrow); + declaration.semantic(sc2); + if (sc2 != sc) + sc2.pop(); + s.parent = sc.parent; } if (!global.errors)
--- a/dmd/Dsymbol.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/Dsymbol.d Mon Aug 30 03:57:51 2010 +0200 @@ -130,6 +130,8 @@ return sa; } +alias Vector!Dsymbol Dsymbols; + class Dsymbol { Identifier ident; @@ -137,7 +139,7 @@ Dsymbol parent; Symbol* csym; // symbol for code generator Symbol* isym; // import version of csym - ubyte* comment; // documentation comment for this Dsymbol + string comment; // documentation comment for this Dsymbol Loc loc; // where defined Scope scope_; // !=null means context to use for semantic() @@ -403,7 +405,7 @@ parent = sd; if (!isAnonymous()) // no name, so can't add it to symbol table { - if (!sd.symtab.insert(this)) // if name is already defined + if (!sd.symtabInsert(this)) // if name is already defined { Dsymbol s2 = sd.symtab.lookup(ident); if (!s2.overloadInsert(this)) @@ -429,10 +431,14 @@ sc.setNoFree(); // may need it even after semantic() finishes scope_ = sc; } + + void importAll(Scope sc) + { + } void semantic(Scope sc) { - assert(false); + error("%p has no semantic routine", this); } /************************************* @@ -528,7 +534,8 @@ assert(false); } -version (_DH) { +version (_DH) +{ char* toHChars() { assert(false); @@ -548,6 +555,10 @@ { assert(false); } + + void toJsonBuffer(OutBuffer buf) + { + } uint size(Loc loc) { @@ -723,16 +734,21 @@ void addLocalClass(ClassDeclarations) { } void checkCtorConstInit() { } - void addComment(ubyte* comment) + // since comment is stored immutable string is correct here + void addComment(string comment) { //if (comment) - //printf("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars()); + //writef("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars()); - if (this.comment is null) { + if (this.comment is null) + { this.comment = comment; - } else { -static if (true) { - if (comment !is null && strcmp(cast(char*)comment, cast(char*)this.comment) != 0) + } + else + { +static if (true) +{ + if (comment !is null && comment != this.comment) { // Concatenate the two this.comment = Lexer.combineComments(this.comment, comment); } @@ -887,15 +903,15 @@ ArrayScopeSymbol isArrayScopeSymbol() { return null; } Import isImport() { return null; } EnumDeclaration isEnumDeclaration() { return null; } -version (_DH) { +version (_DH) +{ DeleteDeclaration isDeleteDeclaration() { return null; } } SymbolDeclaration isSymbolDeclaration() { return null; } AttribDeclaration isAttribDeclaration() { return null; } OverloadSet isOverloadSet() { return null; } -version (TARGET_NET) { +version (TARGET_NET) +{ PragmaScope isPragmaScope() { return null; } } -} - -alias Vector!Dsymbol Dsymbols; \ No newline at end of file +} \ No newline at end of file
--- a/dmd/DsymbolExp.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/DsymbolExp.d Mon Aug 30 03:57:51 2010 +0200 @@ -18,6 +18,7 @@ import dmd.FuncExp; import dmd.OverExp; import dmd.DotTypeExp; +import dmd.STC; import dmd.ScopeExp; import dmd.Module; import dmd.TypeExp; @@ -47,7 +48,8 @@ override Expression semantic(Scope sc) { -version (LOGSEMANTIC) { +version (LOGSEMANTIC) +{ printf("DsymbolExp.semantic('%s')\n", s.toChars()); } @@ -119,6 +121,13 @@ } } + if ((v.storage_class & STC.STCmanifest) && v.init) + { + e = v.init.toExpression(); + e.semantic(sc); + return e; + } + e = new VarExp(loc, v); e.type = type; e = e.semantic(sc);
--- a/dmd/DtorDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/DtorDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -62,6 +62,10 @@ { assert(false); } + + override void toJsonBuffer(OutBuffer buf) + { + } override string kind() {
--- a/dmd/EnumDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/EnumDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -25,6 +25,7 @@ import dmd.DYNCAST; import dmd.WANT; import dmd.Id; +import dmd.Json; import dmd.Lexer; import dmd.backend.SC; @@ -44,11 +45,14 @@ Type type; // the TypeEnum Type memtype; // type of the members -version (DMDV1) { +version (DMDV1) +{ ulong maxval; ulong minval; ulong defaultval; // default initializer -} else { +} +else +{ Expression maxval; Expression minval; Expression defaultval; // default initializer @@ -377,7 +381,54 @@ { assert(false); } + + override void toJsonBuffer(OutBuffer buf) + { + //writef("EnumDeclaration.toJsonBuffer()\n"); + if (isAnonymous()) + { + if (members) + { + foreach (Dsymbol s; members) + { + s.toJsonBuffer(buf); + buf.writestring(",\n"); + } + JsonRemoveComma(buf); + } + return; + } + buf.writestring("{\n"); + + JsonProperty(buf, Pname, toChars()); + JsonProperty(buf, Pkind, kind()); + if (comment) + JsonProperty(buf, Pcomment, comment); + + if (loc.linnum) + JsonProperty(buf, Pline, loc.linnum); + + if (memtype) + JsonProperty(buf, "base", memtype.toChars()); + + JsonString(buf, Pmembers); + buf.writestring(" : [\n"); + size_t offset = buf.offset; + foreach (Dsymbol s; members) + { + if (offset != buf.offset) + { + buf.writestring(","); + offset = buf.offset; + } + s.toJsonBuffer(buf); + } + buf.writestring("]\n"); + + buf.writestring("}\n"); + } + override void toDocBuffer(OutBuffer buf) { assert(false);
--- a/dmd/EnumMember.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/EnumMember.d Mon Aug 30 03:57:51 2010 +0200 @@ -5,6 +5,7 @@ import dmd.Type; import dmd.Loc; import dmd.Identifier; +import dmd.Json; import dmd.Scope; import dmd.OutBuffer; import dmd.HdrGenState; @@ -58,6 +59,24 @@ } } + override void toJsonBuffer(OutBuffer buf) + { + //writef("EnumMember.toJsonBuffer()\n"); + buf.writestring("{\n"); + + JsonProperty(buf, Pname, toChars()); + JsonProperty(buf, Pkind, kind()); + + if (comment) + JsonProperty(buf, Pcomment, comment); + + if (loc.linnum) + JsonProperty(buf, Pline, loc.linnum); + + JsonRemoveComma(buf); + buf.writestring("}\n"); + } + override string kind() { return "enum member";
--- a/dmd/EqualExp.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/EqualExp.d Mon Aug 30 03:57:51 2010 +0200 @@ -1,5 +1,6 @@ module dmd.EqualExp; +import dmd.ErrorExp; import dmd.Expression; import dmd.Id; import dmd.Identifier; @@ -42,8 +43,6 @@ override Expression semantic(Scope sc) { Expression e; - Type t1; - Type t2; //printf("EqualExp.semantic('%s')\n", toChars()); if (type) @@ -74,7 +73,9 @@ } } - if (e1.type.toBasetype().ty == TY.Tclass && e2.op == TOK.TOKnull || e2.type.toBasetype().ty == TY.Tclass && e1.op == TOK.TOKnull) + Type t1 = e1.type.toBasetype(); + Type t2 = e2.type.toBasetype(); + if (t1.ty == TY.Tclass && e2.op == TOK.TOKnull || t2.ty == TY.Tclass && e1.op == TOK.TOKnull) { error("use '%s' instead of '%s' when comparing with null", Token.toChars(op == TOK.TOKequal ? TOK.TOKidentity : TOK.TOKnotidentity), @@ -96,6 +97,14 @@ } } + // Disallow comparing T[]==T and T==T[] + if (e1.op == TOKslice && t1.ty == Tarray && e2.implicitConvTo(t1.nextOf()) || + e2.op == TOKslice && t2.ty == Tarray && e1.implicitConvTo(t2.nextOf())) + { + incompatibleTypes(); + return new ErrorExp(); + } + e = typeCombine(sc); type = Type.tboolean;
--- a/dmd/ExpStatement.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/ExpStatement.d Mon Aug 30 03:57:51 2010 +0200 @@ -68,7 +68,8 @@ override Expression interpret(InterState istate) { -version (LOG) { +version (LOG) +{ printf("ExpStatement.interpret(%s)\n", exp ? exp.toChars() : ""); } mixin(START!()); @@ -104,6 +105,11 @@ } return result; } + + override bool isEmpty() + { + return (exp is null); + } override int inlineCost(InlineCostState* ics) { @@ -112,8 +118,9 @@ override Expression doInline(InlineDoState ids) { - version (LOG) { - if (exp) printf("ExpStatement.doInline() '%s'\n", exp.toChars()); + version (LOG) + { + if (exp) writef("ExpStatement.doInline() '%s'\n", exp.toChars()); } return exp ? exp.doInline(ids) : null; }
--- a/dmd/ForStatement.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/ForStatement.d Mon Aug 30 03:57:51 2010 +0200 @@ -69,6 +69,7 @@ { increment = increment.semantic(sc); increment = resolveProperties(sc, increment); + increment = increment.optimize(0); } sc.sbreak = this;
--- a/dmd/FuncDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/FuncDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -278,7 +278,8 @@ InterfaceDeclaration id; Dsymbol pd; -static if (false) { +static if (false) +{ printf("FuncDeclaration.semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, this, toPrettyChars(), sc.linkage); if (isFuncLiteralDeclaration()) printf("\tFuncLiteralDeclaration()\n"); @@ -288,12 +289,12 @@ if (semanticRun && isFuncLiteralDeclaration()) { - /* Member functions that have return types that are - * forward references can have semantic() run more than - * once on them. - * See test\interface2.d, test20 - */ - return; + /* Member functions that have return types that are + * forward references can have semantic() run more than + * once on them. + * See test\interface2.d, test20 + */ + return; } assert(semanticRun <= 1); semanticRun = 1; @@ -302,52 +303,53 @@ //printf("function storage_class = x%x\n", storage_class); if (!originalType) - originalType = type; + originalType = type; if (!type.deco) { - /* Apply const and invariant storage class - * to the function type - */ - type = type.semantic(loc, sc); - STC stc = storage_class; - if (type.isInvariant()) - stc |= STC.STCimmutable; - if (type.isConst()) - stc |= STC.STCconst; - if (type.isShared() || storage_class & STC.STCsynchronized) - stc |= STC.STCshared; - switch (stc & STC.STC_TYPECTOR) - { - case STC.STCimmutable: - case STC.STCimmutable | STC.STCconst: - case STC.STCimmutable | STC.STCconst | STC.STCshared: - case STC.STCimmutable | STC.STCshared: - // Don't use toInvariant(), as that will do a merge() - type = type.makeInvariant(); - type.deco = type.merge().deco; - break; - - case STC.STCconst: - type = type.makeConst(); - type.deco = type.merge().deco; - break; - - case STC.STCshared | STC.STCconst: - type = type.makeSharedConst(); - type.deco = type.merge().deco; - break; - - case STC.STCshared: - type = type.makeShared(); - type.deco = type.merge().deco; - break; - - case STC.STCundefined: - break; - - default: - assert(0); - } + /* Apply const and invariant storage class + * to the function type + */ + type = type.semantic(loc, sc); + STC stc = storage_class; + if (type.isInvariant()) + stc |= STC.STCimmutable; + if (type.isConst()) + stc |= STC.STCconst; + if (type.isShared() || storage_class & STC.STCsynchronized) + stc |= STC.STCshared; + switch (stc & STC.STC_TYPECTOR) + { + case STC.STCimmutable: + case STC.STCimmutable | STC.STCconst: + case STC.STCimmutable | STC.STCconst | STC.STCshared: + case STC.STCimmutable | STC.STCshared: + // Don't use toInvariant(), as that will do a merge() + type = type.makeInvariant(); + goto Lmerge; + + case STC.STCconst: + type = type.makeConst(); + goto Lmerge; + + case STC.STCshared | STC.STCconst: + type = type.makeSharedConst(); + goto Lmerge; + + case STC.STCshared: + type = type.makeShared(); + Lmerge: + if (!(type.ty == Tfunction && !type.nextOf())) + /* Can't do merge if return type is not known yet + */ + type.deco = type.merge().deco; + break; + + case STC.STCundefined: + break; + + default: + assert(0); + } } //type.print(); if (type.ty != TY.Tfunction) @@ -742,7 +744,9 @@ goto Lmainerr; } - if (f.nextOf().ty != TY.Tint32 && f.nextOf().ty != TY.Tvoid) + if (!f.nextOf()) + error("must return int or void"); + else if (f.nextOf().ty != TY.Tint32 && f.nextOf().ty != TY.Tvoid) error("must return int or void, not %s", f.nextOf().toChars()); if (f.varargs) { @@ -1155,8 +1159,19 @@ } if (fensure || addPostInvariant()) - { /* fensure is composed of the [out] contracts + { + /* fensure is composed of the [out] contracts */ + if (!type.nextOf()) // if return type is inferred + { + /* This case: + * auto fp = function() out { } body { }; + * Can fix by doing semantic() onf fbody first. + */ + error("post conditions are not supported if the return type is inferred"); + return; + } + ScopeDsymbol sym = new ScopeDsymbol(); sym.parent = sc2.scopesym; sc2 = sc2.push(sym); @@ -1275,11 +1290,11 @@ */ if (isCtorDeclaration() && cd) { - for (int i = 0; i < cd.fields.dim; i++) - { VarDeclaration v = cast(VarDeclaration)cd.fields.data[i]; - - v.ctorinit = 0; - } + for (int i = 0; i < cd.fields.dim; i++) + { VarDeclaration v = cast(VarDeclaration)cd.fields[i]; + + v.ctorinit = 0; + } } if (inferRetType || f.retStyle() != RET.RETstack) @@ -1328,7 +1343,7 @@ if (!(sc2.callSuper & CSX.CSXthis_ctor)) { for (int i = 0; i < cd.fields.dim; i++) - { VarDeclaration v = cast(VarDeclaration)cd.fields.data[i]; + { VarDeclaration v = cast(VarDeclaration)cd.fields[i]; if (v.ctorinit == 0 && v.isCtorinit()) error("missing initializer for final field %s", v.toChars());
--- a/dmd/Global.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/Global.d Mon Aug 30 03:57:51 2010 +0200 @@ -25,8 +25,9 @@ } else { static assert (false); } - string doc_ext = "html";; // for Ddoc generated files - string ddoc_ext = "ddoc";; // for Ddoc macro include files + string doc_ext = "html"; // for Ddoc generated files + string ddoc_ext = "ddoc"; // for Ddoc macro include files + string json_ext = "json"; string hdr_ext = "di"; // for D 'header' import files string copyright= "Copyright (c) 1999-2009 by Digital Mars"; string written = "written by Walter Bright, ported to D by community"; @@ -37,7 +38,7 @@ string[] path; // Array of char*'s which form the import lookup path string[] filePath; // Array of char*'s which form the file import lookup path int structalign = 8; - string version_ = "v2.033"; + string version_ = "v2.035"; Param params; uint errors; // number of errors reported so far
--- a/dmd/Import.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/Import.d Mon Aug 30 03:57:51 2010 +0200 @@ -23,8 +23,8 @@ void escapePath(OutBuffer buf, string fname) { - foreach (char c; fname) - { + foreach (char c; fname) + { switch (c) { case '(': @@ -35,26 +35,26 @@ buf.writebyte(*fname); break; } - } + } } class Import : Dsymbol { - Array packages; // array of Identifier's representing packages - Identifier id; // module Identifier - Identifier aliasId; - int isstatic; // !=0 if static import + Array packages; // array of Identifier's representing packages + Identifier id; // module Identifier + Identifier aliasId; + int isstatic; // !=0 if static import - // Pairs of alias=name to bind into current namespace - Array names; - Array aliases; + // Pairs of alias=name to bind into current namespace + Array names; + Array aliases; - Array aliasdecls; // AliasDeclarations for names/aliases + Array aliasdecls; // AliasDeclarations for names/aliases - Module mod; - Package pkg; // leftmost package/module + Module mod; + Package pkg; // leftmost package/module - this(Loc loc, Array packages, Identifier id, Identifier aliasId, int isstatic) + this(Loc loc, Array packages, Identifier id, Identifier aliasId, int isstatic) { super(id); @@ -75,7 +75,7 @@ else if (packages && packages.dim) this.ident = cast(Identifier)packages.data[0]; } - + void addAlias(Identifier name, Identifier alias_) { if (isstatic) @@ -88,32 +88,32 @@ aliases.push(cast(void*)alias_); } - override string kind() + override string kind() { return isstatic ? "static import" : "import"; } - override Dsymbol syntaxCopy(Dsymbol s) // copy only syntax trees + override Dsymbol syntaxCopy(Dsymbol s) // copy only syntax trees { assert(false); } - void load(Scope sc) + void load(Scope sc) { - DsymbolTable dst; - Dsymbol s; - //writef("Import::load('%s')\n", toChars()); // See if existing module - dst = Package.resolve(packages, null, &pkg); + DsymbolTable dst = Package.resolve(packages, null, &pkg); - s = dst.lookup(id); + Dsymbol s = dst.lookup(id); if (s) { -version (TARGET_NET) { +version (TARGET_NET) +{ mod = cast(Module)s; -} else { +} +else +{ if (s.isModule()) mod = cast(Module)s; else @@ -125,7 +125,7 @@ { // Load module mod = Module.load(loc, packages, id); - dst.insert(id, mod); // id may be different from mod->ident, + dst.insert(id, mod); // id may be different from mod.ident, // if so then insert alias if (!mod.importedFrom) mod.importedFrom = sc ? sc.module_.importedFrom : Module.rootModule; @@ -137,15 +137,40 @@ //writef("-Import::load('%s'), pkg = %p\n", toChars(), pkg); } - override void semantic(Scope sc) + override void importAll(Scope sc) + { + if (!mod) + { + load(sc); + mod.importAll(null); + + if (!isstatic && !aliasId && !names.dim) + { + /* Default to private importing + */ + PROT prot = sc.protection; + if (!sc.explicitProtection) + prot = PROT.PROTprivate; + sc.scopesym.importScope(mod, prot); + } + } + } + + override void semantic(Scope sc) { //writef("Import.semantic('%s')\n", toChars()); - load(sc); + // Load if not already done so + if (!mod) + { + load(sc); + mod.importAll(null); + } if (mod) { -static if (false) { +static if (false) +{ if (mod.loc.linnum != 0) { /* If the line number is not 0, then this is not * a 'root' module, i.e. it was not specified on the command line. @@ -193,15 +218,15 @@ { /* The grammar of the file is: * ImportDeclaration - * .= BasicImportDeclaration [ " : " ImportBindList ] [ " . " + * .= BasicImportDeclaration [ " : " ImportBindList ] [ " . " * ModuleAliasIdentifier ] "\n" * * BasicImportDeclaration - * .= ModuleFullyQualifiedName " (" FilePath ") : " Protection + * .= ModuleFullyQualifiedName " (" FilePath ") : " Protection * " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")" * * FilePath - * - any string with '(', ')' and '\' escaped with the '\' character + * - any string with '(', ')' and '\' escaped with the '\' character */ OutBuffer ob = global.params.moduleDeps; @@ -261,7 +286,7 @@ //printf("-Import.semantic('%s'), pkg = %p\n", toChars(), pkg); } - override void semantic2(Scope sc) + override void semantic2(Scope sc) { //printf("Import::semantic2('%s')\n", toChars()); mod.semantic2(); @@ -269,7 +294,7 @@ sc.module_.needmoduleinfo = 1; } - override Dsymbol toAlias() + override Dsymbol toAlias() { if (aliasId) return mod; @@ -279,7 +304,7 @@ /***************************** * Add import to sd's symbol table. */ - override bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) + override bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) { bool result = false; @@ -310,7 +335,7 @@ return result; } - override Dsymbol search(Loc loc, Identifier ident, int flags) + override Dsymbol search(Loc loc, Identifier ident, int flags) { //printf("%s.Import.search(ident = '%s', flags = x%x)\n", toChars(), ident.toChars(), flags); @@ -324,16 +349,16 @@ return pkg.search(loc, ident, flags); } - override bool overloadInsert(Dsymbol s) + override bool overloadInsert(Dsymbol s) { // Allow multiple imports of the same name return s.isImport() !is null; } - override void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - override Import isImport() { return this; } + override Import isImport() { return this; } }
--- a/dmd/InExp.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/InExp.d Mon Aug 30 03:57:51 2010 +0200 @@ -97,6 +97,14 @@ key.Enumbytes = key.E1.Enumbytes; assert(key.Enumbytes); } + else if (tybasic(key.Ety) == TYarray && taa.index.ty == Tsarray) + { + // e2.elem() turns string literals into a TYarray, so the + // length is lost. Restore it. + key = el_una(OPstrpar, TYstruct, key); + assert(e1.type.size() == taa.index.size()); + key.Enumbytes = cast(size_t) taa.index.size(); + } Symbol* s = taa.aaGetSymbol("In", 0); keyti = taa.index.getInternalTypeInfo(null).toElem(irs);
--- a/dmd/IndexExp.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/IndexExp.d Mon Aug 30 03:57:51 2010 +0200 @@ -45,8 +45,6 @@ import core.stdc.string; import core.stdc.stdio; -extern (C) extern void exit(int); - class IndexExp : BinExp { VarDeclaration lengthVar; @@ -150,9 +148,6 @@ TupleExp te; TypeTuple tup; - printf("e1.op: %d\n", e1.op); - exit(-1); - if (e1.op == TOKtuple) { te = cast(TupleExp)e1; @@ -299,12 +294,10 @@ { elem* e; elem* n1 = e1.toElem(irs); - elem* n2; elem* eb = null; - Type t1; //printf("IndexExp.toElem() %s\n", toChars()); - t1 = e1.type.toBasetype(); + Type t1 = e1.type.toBasetype(); if (t1.ty == Taarray) { // set to: @@ -314,19 +307,23 @@ elem* keyti; elem* ep; int vsize = cast(int)taa.next.size(); - elem* valuesize; Symbol* s; // n2 becomes the index, also known as the key - n2 = e2.toElem(irs); + elem* n2 = e2.toElem(irs); if (tybasic(n2.Ety) == TYstruct || tybasic(n2.Ety) == TYarray) { n2 = el_una(OPstrpar, TYstruct, n2); n2.Enumbytes = n2.E1.Enumbytes; + if (taa.index.ty == Tsarray) + { + assert(e2.type.size() == taa.index.size()); + n2.Enumbytes = cast(size_t) taa.index.size(); + } //printf("numbytes = %d\n", n2.Enumbytes); assert(n2.Enumbytes); } - valuesize = el_long(TYuint, vsize); // BUG: should be TYsize_t + elem* valuesize = el_long(TYuint, vsize); // BUG: should be TYsize_t //printf("valuesize: "); elem_print(valuesize); if (modifiable) { @@ -344,17 +341,16 @@ //elem_print(keyti); ep = el_params(n2, valuesize, keyti, n1, null); e = el_bin(OPcall, TYnptr, el_var(s), ep); + if (global.params.useArrayBounds) { - elem* n; elem* ea; - n = el_same(&e); + elem* n = el_same(&e); // Construct: ((e || ModuleAssert(line)),n) - Symbol* sassert; - - sassert = irs.blx.module_.toModuleArray(); + Symbol* sassert = irs.blx.module_.toModuleArray(); + ea = el_bin(OPcall,TYvoid,el_var(sassert), el_long(TYint, loc.linnum)); e = el_bin(OPoror,TYvoid,e,ea); @@ -366,10 +362,8 @@ } else { - elem* einit; - - einit = resolveLengthVar(lengthVar, &n1, t1); - n2 = e2.toElem(irs); + elem* einit = resolveLengthVar(lengthVar, &n1, t1); + elem* n2 = e2.toElem(irs); if (global.params.useArrayBounds) {
--- a/dmd/Initializer.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/Initializer.d Mon Aug 30 03:57:51 2010 +0200 @@ -3,6 +3,7 @@ import dmd.Loc; import dmd.Scope; import dmd.Type; +import dmd.Util; import dmd.ArrayTypes; import dmd.Expression; import dmd.OutBuffer; @@ -25,39 +26,59 @@ Initializer syntaxCopy() { - assert(false); + return this; } Initializer semantic(Scope sc, Type t) { - assert(false); + return this; } Type inferType(Scope sc) { - assert(false); + error(loc, "cannot infer type from initializer"); + halt(); + return Type.terror; } - abstract Expression toExpression(); - + abstract Expression toExpression(); + abstract void toCBuffer(OutBuffer buf, HdrGenState* hgs); - + string toChars() { + OutBuffer buf; + HdrGenState hgs; + + buf = new OutBuffer(); + toCBuffer(buf, &hgs); + return buf.toChars(); + } + + static Initializers arraySyntaxCopy(Initializers ai) + { + Initializers a = null; + + if (ai) + { + a = new Initializers(); + a.setDim(ai.dim); + for (int i = 0; i < a.dim; i++) + { Initializer e = cast(Initializer)ai.data[i]; + + e = e.syntaxCopy(); + a.data[i] = cast(void*) e; + } + } + return a; + } + + dt_t* toDt() + { assert(false); } - static Initializers arraySyntaxCopy(Initializers *ai) - { - assert(false); - } - - dt_t* toDt() - { - assert(false); - } - - VoidInitializer isVoidInitializer() { return null; } + VoidInitializer isVoidInitializer() { return null; } StructInitializer isStructInitializer() { return null; }
--- a/dmd/InvariantDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/InvariantDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -86,5 +86,9 @@ bodyToCBuffer(buf, hgs); } - override InvariantDeclaration isInvariantDeclaration() { return this; } + override void toJsonBuffer(OutBuffer buf) + { + } + + override InvariantDeclaration isInvariantDeclaration() { return this; } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/Json.d Mon Aug 30 03:57:51 2010 +0200 @@ -0,0 +1,143 @@ +/** + * this implements the JSON capability + */ +module dmd.Json; + +import dmd.String; +import std.stdio : write, writef; + +import dmd.Array; +import dmd.File; +import dmd.FileName; +import dmd.Global; +import dmd.Module; +import dmd.OutBuffer; + +immutable Pname = "name"; +immutable Pkind = "kind"; +immutable Pfile = "file"; +immutable Pline = "line"; +immutable Ptype = "type"; +immutable Pcomment = "comment"; +immutable Pmembers = "members"; + +void json_generate(Array modules) +{ + OutBuffer buf; + + for (int i = 0; i < modules.dim; i++) + { + Module m = cast(Module)modules.data[i]; + if (global.params.verbose) + writef("json gen %s\n", m.toChars()); + m.toJsonBuffer(buf); + } + + // Write buf to file + string arg = global.params.xfilename; + if (arg is null || arg[0] == 0) + { // Generate lib file name from first obj name + String n2 = cast(String) global.params.objfiles.data[0]; + + string n = FileName.name(n2.toChars()); + FileName fn = FileName.forceExt(n, global.json_ext); + arg = fn.toChars(); + } + else if (arg[0] == '-' && arg[1] == 0) + { + // Write to stdout + write(buf.data[0..buf.offset]); + return; + } +// if (!FileName.absolute(arg)) +// arg = FileName.combine(dir, arg); + FileName jsonfilename = FileName.defaultExt(arg, global.json_ext); + File jsonfile = new File(jsonfilename); + assert(jsonfile); + jsonfile.setbuffer(buf.data, buf.offset); + jsonfile.ref_ = 1; + string pt = FileName.path(jsonfile.toChars()); + if (pt[0] != 0) + FileName.ensurePathExists(pt); +// mem.free(pt); + jsonfile.writev(); +} + + +/********************************* + * Encode string into buf, and wrap it in double quotes. + */ +void JsonString(OutBuffer buf, const(char)[] s) +{ + buf.writeByte('\"'); + foreach (c; s) + { + switch (c) + { + case '\n': + buf.writestring(`\n`); + break; + + case '\r': + buf.writestring(`\r`); + break; + + case '\t': + buf.writestring(`\t`); + break; + + case '\"': + buf.writestring(`\"`); + break; + + case '\\': + buf.writestring(`\\`); + break; + + case '/': + buf.writestring(`\/`); + break; + + case '\b': + buf.writestring(`\b`); + break; + + case '\f': + buf.writestring(`\f`); + break; + + default: + if (c < 0x20) + buf.printf("\\u%04x", c); + else + // Note that UTF-8 chars pass through here just fine + buf.writeByte(c); + break; + } + } + buf.writeByte('\"'); +} + +void JsonProperty(OutBuffer buf, const(char)[] name, const(char)[] value) +{ + JsonString(buf, name); + buf.writestring(" : "); + JsonString(buf, value); + buf.writestring(",\n"); +} + +void JsonProperty(OutBuffer buf, const(char)[] name, int value) +{ + JsonString(buf, name); + buf.writestring(" : "); + buf.printf("%d", value); + buf.writestring(",\n"); +} + +void JsonRemoveComma(OutBuffer buf) +{ + if (buf.offset >= 2 && + buf.data[buf.offset - 2] == ',' && + buf.data[buf.offset - 1] == '\n') + buf.offset -= 2; +} \ No newline at end of file
--- a/dmd/Lexer.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/Lexer.d Mon Aug 30 03:57:51 2010 +0200 @@ -2614,6 +2614,9 @@ case 8: // past end of exponent digits goto done; + + default: + assert(0, "inreal.dblstate has unexpected value"); } break; } @@ -2772,33 +2775,26 @@ return true; } - /// TODO: reimplement based on strings - static ubyte* combineComments(ubyte* c1, ubyte* c2) + /// TODO: use normal string append when GC works + static string combineComments(const(char)[] c1, const(char)[] c2) { - //printf("Lexer.combineComments('%s', '%s')\n", c1, c2); + //writef("Lexer.combineComments('%s', '%s')\n", c1, c2); - ubyte* c = c2; - - if (c1) + char[] c = cast(char[]) c2; + + if (c1 !is null) { - c = c1; - if (c2) + c = cast(char[]) c1; + if (c2 !is null) { - size_t len1 = strlen(cast(char*)c1); - size_t len2 = strlen(cast(char*)c2); - - c = cast(ubyte*)GC.malloc(len1 + 1 + len2 + 1); - memcpy(c, c1, len1); - if (len1 && c1[len1 - 1] != '\n') - { - c[len1] = '\n'; - len1++; - } - memcpy(c + len1, c2, len2); - c[len1 + len2] = 0; + c = cast(char[]) (GC.malloc(c1.length + 1 + c2.length)[0 .. c1.length + 1 + c2.length]); + size_t len1 = c1.length; + c[0..len1] = c1[]; + c[len1++] = '\n'; + c[len1 .. len1 + c2.length] = c2[]; } } - - return c; + + return cast(string)c; } } \ No newline at end of file
--- a/dmd/Module.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/Module.d Mon Aug 30 03:57:51 2010 +0200 @@ -12,6 +12,7 @@ import dmd.ModuleDeclaration; import dmd.File; import dmd.Identifier; +import dmd.Json; import dmd.Dsymbol; import dmd.ModuleInfoDeclaration; import dmd.FuncDeclaration; @@ -397,6 +398,38 @@ { assert(false); } + + override void toJsonBuffer(OutBuffer buf) + { + buf.writestring("{\n"); + + JsonProperty(buf, Pname, md.toChars()); + + JsonProperty(buf, Pkind, kind()); + + JsonProperty(buf, Pfile, srcfile.toChars()); + + if (comment) + JsonProperty(buf, Pcomment, comment); + + JsonString(buf, Pmembers); + buf.writestring(" : [\n"); + + size_t offset = buf.offset; + foreach (Dsymbol s; members) + { + if (offset != buf.offset) + { + buf.writestring(","); + offset = buf.offset; + } + s.toJsonBuffer(buf); + } + + buf.writestring("]\n"); + + buf.writestring("}\n"); + } override string kind() { @@ -612,7 +645,7 @@ */ if (buflen >= 4 && memcmp(buf, "Ddoc".ptr, 4) == 0) { - comment = buf + 4; + comment = cast(string) ((buf + 4)[0 .. buflen]); isDocFile = 1; if (!docfile) setDocfile(); @@ -627,7 +660,8 @@ ///buf = dbuf.data; ///buflen = dbuf.offset; -version (IN_GCC) { +version (IN_GCC) +{ // dump extracted source ///if (dump_source) /// d_gcc_dump_source(srcname, "d.utf-8", buf, buflen); @@ -673,10 +707,57 @@ } } + override void importAll(Scope prevsc) + { + //writef("+Module.importAll(this = %p, '%s'): parent = %p\n", this, toChars(), parent); + + if (scope_ !is null) + return; // already done + + /* Note that modules get their own scope, from scratch. + * This is so regardless of where in the syntax a module + * gets imported, it is unaffected by context. + * Ignore prevsc. + */ + Scope sc = Scope.createGlobal(this); // create root scope + + // Add import of "object" if this module isn't "object" + if (ident != Id.object) + { + if (members.dim == 0 || members[0].ident != Id.object) + { + Import im = new Import(Loc(), null, Id.object, null, 0); + members.shift(im); + } + } + + if (!symtab) + { + // Add all symbols into module's symbol table + symtab = new DsymbolTable(); + foreach (Dsymbol s; members) + s.addMember(null, sc.scopesym, 1); + } + // anything else should be run after addMember, so version/debug symbols are defined + + /* Set scope for the symbols so that if we forward reference + * a symbol, it can possibly be resolved on the spot. + * If this works out well, it can be extended to all modules + * before any semantic() on any of them. + */ + setScope(sc); // remember module scope for semantic + foreach (Dsymbol s; members) + s.setScope(sc); + + foreach (Dsymbol s; members) + s.importAll(sc); + + sc = sc.pop(); + sc.pop(); // 2 pops because Scope::createGlobal() created 2 + } + void semantic() // semantic analysis { - int i; - if (semanticstarted) return; @@ -686,10 +767,17 @@ // Note that modules get their own scope, from scratch. // This is so regardless of where in the syntax a module // gets imported, it is unaffected by context. - Scope sc = Scope.createGlobal(this); // create root scope + Scope sc = scope_; // // see if already got one from importAll() + if (!sc) + { + writef("test2\n"); + Scope.createGlobal(this); // create root scope + } - //printf("Module = %p, linkage = %d\n", sc.scopesym, sc.linkage); + //writef("Module = %p, linkage = %d\n", sc.scopesym, sc.linkage); +static if (false) +{ // Add import of "object" if this module isn't "object" if (ident !is Id.object) { @@ -711,6 +799,7 @@ */ foreach(Dsymbol s; members) s.setScope(sc); +} // Pass 1 semantic routines: do public side of the definition foreach (Dsymbol s; members) @@ -720,8 +809,11 @@ runDeferredSemantic(); } - sc = sc.pop(); - sc.pop(); // 2 pops because Scope.createGlobal() created 2 + if (!scope_) + { + sc = sc.pop(); + sc.pop(); // 2 pops because Scope.createGlobal() created 2 + } semanticRun = semanticstarted; //printf("-Module.semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent); } @@ -788,8 +880,6 @@ override void inlineScan() // scan for functions to inline { - int i; - if (semanticstarted >= 4) return; @@ -1144,13 +1234,14 @@ { /* Since modules can be circularly referenced, * need to stop infinite recursive searches. + * This is done with the cache. */ //printf("%s Module.search('%s', flags = %d) insearch = %d\n", toChars(), ident.toChars(), flags, insearch); Dsymbol s; if (insearch) s = null; - else if (searchCacheIdent == ident && searchCacheFlags == flags && searchCacheSymbol) + else if (searchCacheIdent == ident && searchCacheFlags == flags) { s = searchCacheSymbol; //printf("%s Module.search('%s', flags = %d) insearch = %d searchCacheSymbol = %s\n", toChars(), ident.toChars(), flags, insearch, searchCacheSymbol ? searchCacheSymbol.toChars() : "null"); @@ -1176,6 +1267,12 @@ docfile.remove(); } + override Dsymbol symtabInsert(Dsymbol s) + { + searchCacheIdent = null; // symbol is inserted, so invalidate cache + return Package.symtabInsert(s); + } + /******************************************* * Can't run semantic on s now, try again later. */ @@ -1190,7 +1287,7 @@ return; } - //printf("Module::addDeferredSemantic('%s')\n", s->toChars()); + //printf("Module::addDeferredSemantic('%s')\n", s.toChars()); deferred.push(cast(void*)s); }
--- a/dmd/ModuleInfoDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/ModuleInfoDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -2,6 +2,7 @@ import dmd.VarDeclaration; import dmd.Module; +import dmd.OutBuffer; import dmd.Dsymbol; import dmd.Scope; import dmd.Loc; @@ -33,6 +34,10 @@ assert(false); } + override void toJsonBuffer(OutBuffer buf) + { + } + override Symbol* toSymbol() { assert(false);
--- a/dmd/Param.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/Param.d Mon Aug 30 03:57:51 2010 +0200 @@ -60,6 +60,9 @@ string hdrdir; // write 'header' file to docdir directory string hdrname; // write 'header' file to docname + bool doXGeneration; // write JSON file + string xfilename; // write JSON file to xfilename + uint debuglevel; // debug level Array debugids; // debug identifiers @@ -71,8 +74,6 @@ const(char)* defaultlibname; // default library for non-debug builds const(char)* debuglibname; // default library for debug builds - const(char)* xmlname; // filename for XML output - string moduleDepsFile; // filename for deps output OutBuffer moduleDeps; // contents to be written to deps file
--- a/dmd/Parser.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/Parser.d Mon Aug 30 03:57:51 2010 +0200 @@ -139,6 +139,7 @@ import dmd.CompoundDeclarationStatement; import dmd.Argument; import dmd.ParseStatementFlags; +import dmd.TypeNewArray; import dmd.TypeNext; import dmd.TypeInstance; import dmd.TypePointer; @@ -229,7 +230,7 @@ // ModuleDeclation leads off if (token.value == TOK.TOKmodule) { - ubyte* comment = token.blockComment; + string comment = token.blockComment; bool safe = false; nextToken(); @@ -312,7 +313,7 @@ STC stc; STC storageClass; Condition condition; - ubyte* comment; + string comment; //printf("Parser.parseDeclDefs()\n"); decldefs = new Dsymbols(); @@ -747,8 +748,9 @@ * Starts with token on the first ident. * Ends with scanner past closing ';' */ -version (DMDV2) { - Dsymbols parseAutoDeclarations(STC storageClass, ubyte* comment) +version (DMDV2) +{ + Dsymbols parseAutoDeclarations(STC storageClass, const(char)[] comment) { auto a = new Dsymbols; @@ -1904,7 +1906,7 @@ //printf("enum definition\n"); e.members = new Dsymbols(); nextToken(); - ubyte* comment = token.blockComment; + string comment = token.blockComment; while (token.value != TOK.TOKrcurly) { /* Can take the following forms: @@ -2413,89 +2415,95 @@ Type parseBasicType2(Type t) { - //printf("parseBasicType2()\n"); + //writef("parseBasicType2()\n"); while (1) { - switch (token.value) - { - case TOK.TOKmul: - t = new TypePointer(t); - nextToken(); - continue; - - case TOK.TOKlbracket: - // Handle []. Make sure things like - // int[3][1] a; - // is (array[1] of array[3] of int) - nextToken(); - if (token.value == TOK.TOKrbracket) + switch (token.value) { - t = new TypeDArray(t); // [] + case TOK.TOKmul: + t = new TypePointer(t); + nextToken(); + continue; + + case TOK.TOKlbracket: + // Handle []. Make sure things like + // int[3][1] a; + // is (array[1] of array[3] of int) nextToken(); - } - else if (isDeclaration(&token, 0, TOK.TOKrbracket, null)) - { // It's an associative array declaration - - //printf("it's an associative array\n"); - Type index = parseType(); // [ type ] - t = new TypeAArray(t, index); - check(TOK.TOKrbracket); - } - else - { - //printf("it's type[expression]\n"); - inBrackets++; - Expression e = parseExpression(); // [ expression ] - if (token.value == TOK.TOKslice) + if (token.value == TOK.TOKrbracket) + { + t = new TypeDArray(t); // [] + nextToken(); + } + else if (token.value == TOKnew && peekNext() == TOKrbracket) { - nextToken(); - Expression e2 = parseExpression(); // [ exp .. exp ] - t = new TypeSlice(t, e, e2); + t = new TypeNewArray(t); // [new] + nextToken(); + nextToken(); + } + else if (isDeclaration(&token, 0, TOK.TOKrbracket, null)) + { // It's an associative array declaration + + //printf("it's an associative array\n"); + Type index = parseType(); // [ type ] + t = new TypeAArray(t, index); + check(TOK.TOKrbracket); } else - t = new TypeSArray(t,e); - inBrackets--; - check(TOK.TOKrbracket); - } - continue; - - case TOK.TOKdelegate: - case TOK.TOKfunction: - { // Handle delegate declaration: - // t delegate(parameter list) nothrow pure - // t function(parameter list) nothrow pure - Arguments arguments; - int varargs; - bool ispure = false; - bool isnothrow = false; - TOK save = token.value; - - nextToken(); - arguments = parseParameters(&varargs); - while (1) - { // Postfixes - if (token.value == TOK.TOKpure) - ispure = true; - else if (token.value == TOK.TOKnothrow) - isnothrow = true; + { + //printf("it's type[expression]\n"); + inBrackets++; + Expression e = parseExpression(); // [ expression ] + if (token.value == TOK.TOKslice) + { + nextToken(); + Expression e2 = parseExpression(); // [ exp .. exp ] + t = new TypeSlice(t, e, e2); + } + else + t = new TypeSArray(t,e); + inBrackets--; + check(TOK.TOKrbracket); + } + continue; + + case TOK.TOKdelegate: + case TOK.TOKfunction: + { // Handle delegate declaration: + // t delegate(parameter list) nothrow pure + // t function(parameter list) nothrow pure + Arguments arguments; + int varargs; + bool ispure = false; + bool isnothrow = false; + TOK save = token.value; + + nextToken(); + arguments = parseParameters(&varargs); + while (1) + { // Postfixes + if (token.value == TOK.TOKpure) + ispure = true; + else if (token.value == TOK.TOKnothrow) + isnothrow = true; + else + break; + nextToken(); + } + TypeFunction tf = new TypeFunction(arguments, t, varargs, linkage); + tf.ispure = ispure; + tf.isnothrow = isnothrow; + if (save == TOK.TOKdelegate) + t = new TypeDelegate(tf); else - break; - nextToken(); - } - TypeFunction tf = new TypeFunction(arguments, t, varargs, linkage); - tf.ispure = ispure; - tf.isnothrow = isnothrow; - if (save == TOK.TOKdelegate) - t = new TypeDelegate(tf); - else - t = new TypePointer(tf); // pointer to function - continue; - } - - default: - return t; - } - assert(0); + t = new TypePointer(tf); // pointer to function + continue; + } + + default: + return t; + } + assert(0); } assert(0); return null; @@ -2556,6 +2564,12 @@ ta = new TypeDArray(t); // [] nextToken(); } + else if (token.value == TOKnew && peekNext() == TOKrbracket) + { + t = new TypeNewArray(t); // [new] + nextToken(); + nextToken(); + } else if (isDeclaration(&token, 0, TOK.TOKrbracket, null)) { // It's an associative array @@ -2694,7 +2708,7 @@ Identifier ident; Dsymbols a; TOK tok = TOK.TOKreserved; - ubyte* comment = token.blockComment; + string comment = token.blockComment; LINK link = linkage; //printf("parseDeclarations() %s\n", token.toChars()); @@ -3289,11 +3303,10 @@ } case TOK.TOKlcurly: - { Statements statements; - - nextToken(); - statements = new Statements(); - while (token.value != TOK.TOKrcurly) + { + nextToken(); + Statements statements = new Statements(); + while (token.value != TOK.TOKrcurly && token.value != TOKeof) { statements.push(cast(void*)parseStatement(ParseStatementFlags.PSsemi | ParseStatementFlags.PScurlyscope)); } @@ -3644,6 +3657,7 @@ statements = new Statements(); while (token.value != TOK.TOKcase && token.value != TOK.TOKdefault && + token.value != TOKeof && token.value != TOK.TOKrcurly) { statements.push(cast(void*)parseStatement(ParseStatementFlags.PSsemi | ParseStatementFlags.PScurlyscope)); @@ -3679,6 +3693,7 @@ statements = new Statements(); while (token.value != TOK.TOKcase && token.value != TOK.TOKdefault && + token.value != TOKeof && token.value != TOK.TOKrcurly) { statements.push(cast(void*)parseStatement(ParseStatementFlags.PSsemi | ParseStatementFlags.PScurlyscope)); @@ -4464,6 +4479,11 @@ { t = peek(t); } + else if (t.value == TOKnew && peek(t).value == TOKrbracket) + { + t = peek(t); + t = peek(t); + } else if (isDeclaration(t, 0, TOK.TOKrbracket, &t)) { // It's an associative array declaration @@ -6101,7 +6121,7 @@ return e; } - void addComment(Dsymbol s, ubyte* blockComment) + void addComment(Dsymbol s, const(char)[] blockComment) { s.addComment(combineComments(blockComment, token.lineComment)); token.lineComment = null;
--- a/dmd/PostBlitDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/PostBlitDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -38,6 +38,11 @@ assert(false); } + version(DMDV2) + override void toJsonBuffer(OutBuffer buf) + { + } + override bool isVirtual() { assert(false);
--- a/dmd/ProtDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/ProtDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -29,6 +29,25 @@ return pd; } + override void importAll(Scope sc) + { + Scope newsc = sc; + if (sc.protection != protection || sc.explicitProtection != 1) + { + // create new one for changes + newsc = new Scope(sc); + newsc.flags &= ~SCOPE.SCOPEfree; + newsc.protection = protection; + newsc.explicitProtection = 1; + } + + foreach (Dsymbol s; decl) + s.importAll(newsc); + + if (newsc !is sc) + newsc.pop(); + } + override void setScope(Scope sc) { if (decl)
--- a/dmd/ReturnStatement.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/ReturnStatement.d Mon Aug 30 03:57:51 2010 +0200 @@ -336,16 +336,11 @@ * return exp; * with: * exp; return; - * or, if main(): - * exp; return 0; */ Statement s = new ExpStatement(loc, exp); - //s = s.semantic(sc); - loc = Loc(0); - if (fd.isMain()) - exp = new IntegerExp(0); - else - exp = null; + exp = null; + s = s.semantic(sc); + loc = Loc(); return new CompoundStatement(loc, s, this); }
--- a/dmd/Scope.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/Scope.d Mon Aug 30 03:57:51 2010 +0200 @@ -130,6 +130,8 @@ this.module_ = enclosing.module_; this.func = enclosing.func; this.parent = enclosing.parent; + this.scopesym = null; + this.sd = null; this.sw = enclosing.sw; this.tf = enclosing.tf; this.tinst = enclosing.tinst; @@ -299,7 +301,7 @@ if (!sc.scopesym.symtab) sc.scopesym.symtab = new DsymbolTable(); - return sc.scopesym.symtab.insert(s); + return sc.scopesym.symtabInsert(s); } }
--- a/dmd/ScopeDsymbol.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/ScopeDsymbol.d Mon Aug 30 03:57:51 2010 +0200 @@ -15,7 +15,8 @@ import dmd.Id; import dmd.expression.Util; -import core.stdc.stdlib; +import std.stdio : writef; +//core.stdc.stdlib; import core.memory; class ScopeDsymbol : Dsymbol @@ -56,7 +57,7 @@ // Look in symbols declared in this module Dsymbol s = symtab ? symtab.lookup(ident) : null; - + // writef("\ts = %p, imports = %p, %d\n", s, imports, imports ? imports->dim : 0); if (s) { //printf("\ts = '%s.%s'\n",toChars(),s.toChars()); @@ -159,10 +160,10 @@ void importScope(ScopeDsymbol s, PROT protection) { - //printf("%s.ScopeDsymbol.importScope(%s, %d)\n", toChars(), s.toChars(), protection); + //writef("%s.ScopeDsymbol.importScope(%s, %d)\n", toChars(), s.toChars(), protection); // No circular or redundant import's - if (s != this) + if (s !is this) { if (!imports) imports = new Array(); @@ -187,12 +188,14 @@ override int isforwardRef() { - assert(false); + return (members is null); } override void defineRef(Dsymbol s) { - assert(false); + ScopeDsymbol ss = s.isScopeDsymbol(); + members = ss.members; + ss.members = null; } static void multiplyDefined(Loc loc, Dsymbol s1, Dsymbol s2) @@ -226,6 +229,8 @@ assert(false); } +version(DMDV2) +{ /******************************************* * Look for member of the form: * const(MemberInfo)[] getMembers(string); @@ -259,21 +264,30 @@ return fdx; } +} + + Dsymbol symtabInsert(Dsymbol s) + { + return symtab.insert(s); + } void emitMemberComments(Scope sc) { assert(false); } +version(DMDV2) +{ static size_t dim(Dsymbols members) { assert(false); } - + + static Dsymbol getNth(Dsymbols members, size_t nth, size_t* pn = null) { assert(false); } - +} override ScopeDsymbol isScopeDsymbol() { return this; } }
--- a/dmd/StaticAssertStatement.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/StaticAssertStatement.d Mon Aug 30 03:57:51 2010 +0200 @@ -3,6 +3,7 @@ import dmd.Statement; import dmd.StaticAssert; import dmd.OutBuffer; +import dmd.BE; import dmd.HdrGenState; import dmd.Scope; import dmd.Loc; @@ -29,6 +30,11 @@ return null; } + override BE blockExit() + { + return BE.BEfallthru; + } + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false);
--- a/dmd/StaticCtorDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/StaticCtorDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -125,5 +125,9 @@ assert(false); } - override StaticCtorDeclaration isStaticCtorDeclaration() { return this; } + override void toJsonBuffer(OutBuffer buf) + { + } + + override StaticCtorDeclaration isStaticCtorDeclaration() { return this; } }
--- a/dmd/StaticDtorDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/StaticDtorDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -134,5 +134,9 @@ assert(false); } + override void toJsonBuffer(OutBuffer buf) + { + } + override StaticDtorDeclaration isStaticDtorDeclaration() { return this; } }
--- a/dmd/StaticIfDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/StaticIfDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -10,27 +10,27 @@ class StaticIfDeclaration : ConditionalDeclaration { - ScopeDsymbol sd; - int addisdone; + ScopeDsymbol sd; + int addisdone; - this(Condition condition, Dsymbols decl, Dsymbols elsedecl) + this(Condition condition, Dsymbols decl, Dsymbols elsedecl) { super(condition, decl, elsedecl); //printf("StaticIfDeclaration::StaticIfDeclaration()\n"); } - override Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { - StaticIfDeclaration dd; + StaticIfDeclaration dd; - assert(!s); - dd = new StaticIfDeclaration(condition.syntaxCopy(), + assert(!s); + dd = new StaticIfDeclaration(condition.syntaxCopy(), Dsymbol.arraySyntaxCopy(decl), Dsymbol.arraySyntaxCopy(elsedecl)); - return dd; + return dd; } - override bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) + override bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) { //printf("StaticIfDeclaration.addMember() '%s'\n",toChars()); /* This is deferred until semantic(), so that @@ -39,9 +39,9 @@ * * template Foo(int i) * { - * const int j = i + 1; - * static if (j == 3) - * const int k; + * const int j = i + 1; + * static if (j == 3) + * const int k; * } */ this.sd = sd; @@ -55,7 +55,17 @@ return m; } - override void semantic(Scope sc) + override void importAll(Scope sc) + { + // do not evaluate condition before semantic pass + } + + override void setScope(Scope sc) + { + // do not evaluate condition before semantic pass + } + + override void semantic(Scope sc) { auto d = include(sc, sd); @@ -73,7 +83,7 @@ } } - override string kind() + override string kind() { assert(false); }
--- a/dmd/StructDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/StructDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -322,28 +322,27 @@ // Determine if struct is all zeros or not zeroInit = true; - for (i = 0; i < fields.dim; i++) + foreach (Dsymbol s; fields) { - Dsymbol s = cast(Dsymbol)fields.data[i]; - VarDeclaration vd = s.isVarDeclaration(); - if (vd && !vd.isDataseg()) - { - if (vd.init) + VarDeclaration vd = s.isVarDeclaration(); + if (vd && !vd.isDataseg()) { - // Should examine init to see if it is really all 0's - zeroInit = false; - break; - } - else - { - if (!vd.type.isZeroInit(loc)) - { + if (vd.init) + { + // Should examine init to see if it is really all 0's zeroInit = false; break; - } + } + else + { + if (!vd.type.isZeroInit(loc)) + { + zeroInit = false; + break; + } + } } } - } /* Look for special member functions. */ @@ -396,9 +395,8 @@ /* If any of the fields need an opAssign, then we * need it too. */ - for (size_t i = 0; i < fields.dim; i++) + foreach (Dsymbol s; fields) { - Dsymbol s = cast(Dsymbol)fields.data[i]; VarDeclaration v = s.isVarDeclaration(); assert(v && v.storage_class & STC.STCfield); if (v.storage_class & STC.STCref) @@ -500,9 +498,8 @@ { /* Do memberwise copy */ //printf("\tmemberwise copy\n"); - for (size_t i = 0; i < fields.dim; i++) + foreach (Dsymbol s; fields) { - Dsymbol s = cast(Dsymbol)fields.data[i]; VarDeclaration v = s.isVarDeclaration(); assert(v && v.storage_class & STC.STCfield); // this.v = s.v; @@ -551,49 +548,48 @@ //printf("StructDeclaration.buildPostBlit() %s\n", toChars()); Expression e = null; - for (size_t i = 0; i < fields.dim; i++) + foreach (Dsymbol s; fields) { - Dsymbol s = cast(Dsymbol)fields.data[i]; - VarDeclaration v = s.isVarDeclaration(); - assert(v && v.storage_class & STC.STCfield); - if (v.storage_class & STC.STCref) - continue; - Type tv = v.type.toBasetype(); - size_t dim = 1; - while (tv.ty == TY.Tsarray) - { TypeSArray ta = cast(TypeSArray)tv; - dim *= (cast(TypeSArray)tv).dim.toInteger(); - tv = tv.nextOf().toBasetype(); - } - if (tv.ty == TY.Tstruct) - { TypeStruct ts = cast(TypeStruct)tv; - StructDeclaration sd = ts.sym; - if (sd.postblit) - { Expression ex; - - // this.v - ex = new ThisExp(Loc(0)); - ex = new DotVarExp(Loc(0), ex, v, 0); - - if (dim == 1) - { // this.v.postblit() - ex = new DotVarExp(Loc(0), ex, sd.postblit, 0); - ex = new CallExp(Loc(0), ex); + VarDeclaration v = s.isVarDeclaration(); + assert(v && v.storage_class & STC.STCfield); + if (v.storage_class & STC.STCref) + continue; + Type tv = v.type.toBasetype(); + size_t dim = 1; + while (tv.ty == TY.Tsarray) + { TypeSArray ta = cast(TypeSArray)tv; + dim *= (cast(TypeSArray)tv).dim.toInteger(); + tv = tv.nextOf().toBasetype(); } - else - { - // Typeinfo.postblit(cast(void*)&this.v); - Expression ea = new AddrExp(Loc(0), ex); - ea = new CastExp(Loc(0), ea, Type.tvoid.pointerTo()); - - Expression et = v.type.getTypeInfo(sc); - et = new DotIdExp(Loc(0), et, Id.postblit); - - ex = new CallExp(Loc(0), et, ea); + if (tv.ty == TY.Tstruct) + { TypeStruct ts = cast(TypeStruct)tv; + StructDeclaration sd = ts.sym; + if (sd.postblit) + { Expression ex; + + // this.v + ex = new ThisExp(Loc(0)); + ex = new DotVarExp(Loc(0), ex, v, 0); + + if (dim == 1) + { // this.v.postblit() + ex = new DotVarExp(Loc(0), ex, sd.postblit, 0); + ex = new CallExp(Loc(0), ex); + } + else + { + // Typeinfo.postblit(cast(void*)&this.v); + Expression ea = new AddrExp(Loc(0), ex); + ea = new CastExp(Loc(0), ea, Type.tvoid.pointerTo()); + + Expression et = v.type.getTypeInfo(sc); + et = new DotIdExp(Loc(0), et, Id.postblit); + + ex = new CallExp(Loc(0), et, ea); + } + e = Expression.combine(e, ex); // combine in forward order + } } - e = Expression.combine(e, ex); // combine in forward order - } - } } /* Build our own "postblit" which executes e @@ -787,16 +783,15 @@ void toDt(dt_t** pdt) { uint offset; - uint i; dt_t* dt; //printf("StructDeclaration.toDt(), this='%s'\n", toChars()); offset = 0; // Note equivalence of this loop to class's - for (i = 0; i < fields.dim; i++) + for (uint i = 0; i < fields.dim; i++) { - VarDeclaration v = cast(VarDeclaration)fields.data[i]; + VarDeclaration v = cast(VarDeclaration)fields[i]; //printf("\tfield '%s' voffset %d, offset = %d\n", v.toChars(), v.offset, offset); dt = null; int sz;
--- a/dmd/StructInitializer.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/StructInitializer.d Mon Aug 30 03:57:51 2010 +0200 @@ -108,7 +108,7 @@ } else { - s = cast(Dsymbol)ad.fields.data[fieldi]; + s = ad.fields[fieldi]; } } else @@ -129,7 +129,7 @@ s.error("is not a per-instance initializable field"); break; } - if (s == cast(Dsymbol)ad.fields.data[fieldi]) + if (s == ad.fields[fieldi]) break; } } @@ -243,8 +243,8 @@ for (j = 0; 1; j++) { assert(j < dts.dim); - //printf(" adfield[%d] = %s\n", j, ((VarDeclaration *)ad.fields.data[j]).toChars()); - if (cast(VarDeclaration)ad.fields.data[j] == v) + //printf(" adfield[%d] = %s\n", j, ((VarDeclaration *)ad.fields[j]).toChars()); + if (cast(VarDeclaration)ad.fields[j] == v) // TODO: check if 'is' needs to be used here { if (dts.data[j]) error(loc, "field %s of %s already initialized", v.toChars(), ad.toChars()); @@ -259,7 +259,7 @@ offset = 0; for (j = 0; j < dts.dim; j++) { - VarDeclaration v = cast(VarDeclaration)ad.fields.data[j]; + VarDeclaration v = cast(VarDeclaration)ad.fields[j]; d = cast(dt_t*)dts.data[j]; if (!d) @@ -284,7 +284,7 @@ v.type.toDt(&d); break; } - VarDeclaration v2 = cast(VarDeclaration)ad.fields.data[k]; + VarDeclaration v2 = cast(VarDeclaration)ad.fields[k]; if (v2.offset < offset2 && dts.data[k]) break; // overlap
--- a/dmd/StructLiteralExp.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/StructLiteralExp.d Mon Aug 30 03:57:51 2010 +0200 @@ -27,6 +27,7 @@ import dmd.HdrGenState; import dmd.backend.dt_t; import dmd.InlineScanState; +import dmd.ArrayLiteralExp; import dmd.ArrayTypes; import dmd.TOK; @@ -41,7 +42,7 @@ class StructLiteralExp : Expression { StructDeclaration sd; // which aggregate this is for - Expressions elements; // parallels sd->fields[] with + Expressions elements; // parallels sd.fields[] with // NULL entries for fields to skip Symbol* sym; // back end symbol to initialize with literal @@ -99,7 +100,7 @@ error("more initializers than fields of %s", sd.toChars()); return new ErrorExp(); } - Dsymbol s = cast(Dsymbol)sd.fields.data[i]; + Dsymbol s = sd.fields[i]; VarDeclaration v = s.isVarDeclaration(); assert(v); if (v.offset < offset) @@ -124,7 +125,7 @@ */ for (size_t i = elements.dim; i < nfields; i++) { - Dsymbol s = cast(Dsymbol)sd.fields.data[i]; + Dsymbol s = sd.fields[i]; VarDeclaration v = s.isVarDeclaration(); assert(v); assert(!v.isThisDeclaration()); @@ -158,12 +159,67 @@ Expression getField(Type type, uint offset) { - assert(false); + //printf("StructLiteralExp.getField(this = %s, type = %s, offset = %u)\n", +// /*toChars()*/"", type.toChars(), offset); + Expression e = null; + int i = getFieldIndex(type, offset); + + if (i != -1) + { + //printf("\ti = %d\n", i); + assert(i < elements.dim); + e = cast(Expression)elements.data[i]; + if (e) + { + //writef("e = %s, e.type = %s\n", e.toChars(), e.type.toChars()); + + /* If type is a static array, and e is an initializer for that array, + * then the field initializer should be an array literal of e. + */ + if (e.type != type && type.ty == Tsarray) + { + TypeSArray tsa = cast(TypeSArray)type; + size_t length = cast(size_t) tsa.dim.toInteger(); + Expressions z = new Expressions; + z.setDim(length); + for (int q = 0; q < length; ++q) + z.data[q] = cast(void*) e.copy(); + e = new ArrayLiteralExp(loc, z); + e.type = type; + } + else + { + e = e.copy(); + e.type = type; + } + } + } + return e; } int getFieldIndex(Type type, uint offset) { - assert(false); + /* Find which field offset is by looking at the field offsets + */ + if (elements.dim) + { + foreach (size_t i, Dsymbol s; sd.fields) + { + VarDeclaration v = s.isVarDeclaration(); + assert(v); + + if (offset == v.offset && type.size() == v.type.size()) + { + Expression e = cast(Expression)elements.data[i]; + if (e) + { + return i; + } + break; + } + } + } + return -1; } override elem* toElem(IRState* irs) @@ -185,9 +241,8 @@ * can spill over into the fields. */ size_t offset = 0; - for (size_t i = 0; i < sd.fields.dim; i++) + foreach (Dsymbol s; sd.fields) { - Dsymbol s = cast(Dsymbol)sd.fields.data[i]; VarDeclaration v = s.isVarDeclaration(); assert(v); @@ -209,7 +264,7 @@ if (!el) continue; - Dsymbol s = cast(Dsymbol)sd.fields.data[i]; + Dsymbol s = sd.fields[i]; VarDeclaration v = s.isVarDeclaration(); assert(v); assert(!v.isThisDeclaration()); @@ -299,11 +354,12 @@ } } -version (DMDV2) { +version (DMDV2) +{ if (sd.isnested) { // Initialize the hidden 'this' pointer assert(sd.fields.dim); - Dsymbol s = cast(Dsymbol)sd.fields.data[sd.fields.dim - 1]; + Dsymbol s = sd.fields[sd.fields.dim - 1]; ThisDeclaration v = s.isThisDeclaration(); assert(v); @@ -335,17 +391,41 @@ override bool checkSideEffect(int flag) { - assert(false); + bool f = 0; + + for (size_t i = 0; i < elements.dim; i++) + { + Expression e = cast(Expression)elements.data[i]; + if (!e) + continue; + + f |= e.checkSideEffect(2); + } + if (flag == 0 && f == 0) + Expression.checkSideEffect(0); + return f; } override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - assert(false); + buf.writestring(sd.toChars()); + buf.writeByte('('); + argsToCBuffer(buf, elements, hgs); + buf.writeByte(')'); } override void toMangleBuffer(OutBuffer buf) { - assert(false); + size_t dim = elements ? elements.dim : 0; + buf.printf("S%u", dim); + for (size_t i = 0; i < dim; i++) + { + Expression e = cast(Expression)elements.data[i]; + if (e) + e.toMangleBuffer(buf); + else + buf.writeByte('v'); // 'v' for void + } } override void scanForNestedRef(Scope sc) @@ -379,20 +459,26 @@ assert(false); } +version(DMDV2) +{ override int isLvalue() { - assert(false); + return 1; } +} override Expression toLvalue(Scope sc, Expression e) { - assert(false); + return this; } +version(DMDV2) +{ override bool canThrow() { return arrayExpressionCanThrow(elements); } +} override MATCH implicitConvTo(Type t) {
--- a/dmd/TemplateDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/TemplateDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -34,6 +34,7 @@ import dmd.Tuple; import dmd.TupleDeclaration; import dmd.Initializer; +import dmd.Json; import dmd.ExpInitializer; import dmd.TemplateValueParameter; import dmd.AliasDeclaration; @@ -327,6 +328,36 @@ assert(false); } + override void toJsonBuffer(OutBuffer buf) + { + //writef("TemplateDeclaration.toJsonBuffer()\n"); + + buf.writestring("{\n"); + + JsonProperty(buf, Pname, toChars()); + JsonProperty(buf, Pkind, kind()); + if (comment) + JsonProperty(buf, Pcomment, comment); + + if (loc.linnum) + JsonProperty(buf, Pline, loc.linnum); + + JsonString(buf, Pmembers); + buf.writestring(" : [\n"); + size_t offset = buf.offset; + foreach (Dsymbol s; members) + { + if (offset != buf.offset) + { buf.writestring(","); + offset = buf.offset; + } + s.toJsonBuffer(buf); + } + buf.writestring("]\n"); + + buf.writestring("}\n"); + } + override string kind() { return (onemember && onemember.isAggregateDeclaration()) @@ -624,7 +655,8 @@ int fvarargs; // function varargs scope Objects dedtypes = new Objects(); // for T:T*, the dedargs is the T*, dedtypes is the T - static if (false) { + static if (false) + { printf("\nTemplateDeclaration.deduceFunctionTemplateMatch() %s\n", toChars()); for (i = 0; i < fargs.dim; i++) { @@ -650,7 +682,8 @@ TemplateTupleParameter tp = isVariadic(); - static if (false) { + static if (false) + { for (i = 0; i < dedargs.dim; i++) { printf("\tdedarg[%d] = ", i); @@ -663,11 +696,10 @@ nargsi = 0; if (targsi) - { // Set initial template arguments - size_t n; - + { + // Set initial template arguments nargsi = targsi.dim; - n = parameters.dim; + size_t n = parameters.dim; if (tp) n--; if (nargsi > n) @@ -714,7 +746,8 @@ goto Lnomatch; } } - static if (false) { + static if (false) + { for (i = 0; i < dedargs.dim; i++) { printf("\tdedarg[%d] = ", i); @@ -750,7 +783,7 @@ */ if (tp) // if variadic { - if (nfparams == 0) // if no function parameters + if (nfparams == 0 && nfargs != 0) // if no function parameters { Tuple t = new Tuple(); //printf("t = %p\n", t);
--- a/dmd/TemplateInstance.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/TemplateInstance.d Mon Aug 30 03:57:51 2010 +0200 @@ -524,7 +524,7 @@ try { - static int nest; +// static int nest; //printf("%d\n", nest); if (++nest > 500) { @@ -578,7 +578,24 @@ if (sc.func || dosemantic3) { - semantic3(sc2); + try + { +// static int nest; // TODO: + if (++nest > 300) + { + global.gag = 0; // ensure error message gets printed + error("recursive expansion"); + fatal(); + } + semantic3(sc2); + --nest; + } + catch (Exception e) + { + global.gag = 0; // ensure error message gets printed + error("recursive expansion"); + fatal(); + } } Laftersemantic: @@ -703,12 +720,14 @@ override Dsymbol toAlias() // resolve real symbol { - version (LOG) { - printf("TemplateInstance.toAlias()\n"); + version (LOG) + { + writef("TemplateInstance.toAlias()\n"); } if (!inst) { error("cannot resolve forward reference"); + errors = 1; return this; }
--- a/dmd/TemplateMixin.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/TemplateMixin.d Mon Aug 30 03:57:51 2010 +0200 @@ -65,7 +65,8 @@ override void semantic(Scope sc) { - version (LOG) { + version (LOG) + { printf("+TemplateMixin.semantic('%s', this=%p)\n", toChars(), this); fflush(stdout); } @@ -177,6 +178,8 @@ // Run semantic on each argument, place results in tiargs[] semanticTiargs(sc); + if (errors) + return; tempdecl = findBestMatch(sc); if (!tempdecl)
--- a/dmd/Token.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/Token.d Mon Aug 30 03:57:51 2010 +0200 @@ -13,8 +13,8 @@ Token* next; ubyte* ptr; // pointer to first character of this token within buffer TOK value; - ubyte* blockComment; // doc comment string prior to this token - ubyte* lineComment; // doc comment for previous token + string blockComment; // doc comment string prior to this token + string lineComment; // doc comment for previous token union {
--- a/dmd/Type.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/Type.d Mon Aug 30 03:57:51 2010 +0200 @@ -405,7 +405,8 @@ */ int covariant(Type t) { -static if (false) { +static if (false) +{ printf("Type.covariant(t = %s) %s\n", t.toChars(), toChars()); printf("deco = %p, %p\n", deco, t.deco); // printf("ty = %d\n", next.ty); @@ -470,6 +471,9 @@ Type t1n = t1.next; Type t2n = t2.next; + if (t1n is null || t2n is null) // happens with return type inference + goto Lnotcovariant; + if (t1n.equals(t2n)) goto Lcovariant; if (t1n.ty == TY.Tclass && t2n.ty == TY.Tclass)
--- a/dmd/TypeClass.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/TypeClass.d Mon Aug 30 03:57:51 2010 +0200 @@ -162,7 +162,7 @@ exps.reserve(sym.fields.dim); for (size_t i = 0; i < sym.fields.dim; i++) { - VarDeclaration v2 = cast(VarDeclaration)sym.fields.data[i]; + VarDeclaration v2 = cast(VarDeclaration)sym.fields[i]; Expression fe = new DotVarExp(e.loc, e, v2); exps.push(cast(void*)fe); } @@ -677,7 +677,7 @@ if (global.params.symdebug) for (int i = 0; i < sym.fields.dim; i++) { - VarDeclaration v = cast(VarDeclaration)sym.fields.data[i]; + VarDeclaration v = cast(VarDeclaration)sym.fields[i]; Symbol* s2 = symbol_name(toStringz(v.ident.toChars()), SC.SCmember, v.type.toCtype()); s2.Smemoff = v.offset;
--- a/dmd/TypeEnum.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/TypeEnum.d Mon Aug 30 03:57:51 2010 +0200 @@ -137,27 +137,27 @@ return sym.memtype.isfloating(); } - bool isreal() + override bool isreal() { return sym.memtype.isreal(); } - bool isimaginary() + override bool isimaginary() { return sym.memtype.isimaginary(); } - bool iscomplex() + override bool iscomplex() { return sym.memtype.iscomplex(); } - bool checkBoolean() + override bool checkBoolean() { return sym.memtype.checkBoolean(); } - bool isAssignable() + override bool isAssignable() { return sym.memtype.isAssignable(); }
--- a/dmd/TypeFunction.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/TypeFunction.d Mon Aug 30 03:57:51 2010 +0200 @@ -275,6 +275,7 @@ Argument.argsToDecoBuffer(buf, parameters); //if (buf.data[buf.offset - 1] == '@') halt(); buf.writeByte('Z' - varargs); // mark end of arg list + assert(next); next.toDecoBuffer(buf); inuse--; }
--- a/dmd/TypeInfoDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/TypeInfoDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -7,6 +7,7 @@ import dmd.Scope; import dmd.Loc; import dmd.STC; +import dmd.OutBuffer; import dmd.PROT; import dmd.LINK; @@ -62,6 +63,10 @@ return VarDeclaration.toSymbol(); } + override void toJsonBuffer(OutBuffer buf) + { + } + override void toObjFile(int multiobj) // compile to .obj file { Symbol* s;
--- a/dmd/TypeInfoFunctionDeclaration.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/TypeInfoFunctionDeclaration.d Mon Aug 30 03:57:51 2010 +0200 @@ -12,7 +12,7 @@ type = Type.typeinfofunction.type; } - void toDt(dt_t** pdt) + override void toDt(dt_t** pdt) { assert(false); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/TypeNewArray.d Mon Aug 30 03:57:51 2010 +0200 @@ -0,0 +1,30 @@ +module dmd.TypeNewArray; + +import dmd.HdrGenState; +import dmd.MOD; +import dmd.OutBuffer; +import dmd.Type; +import dmd.TypeNext; +import dmd.TY; + +/** T[new] + */ +class TypeNewArray : TypeNext +{ + this(Type next) + { + super(Tnarray, next); + //writef("TypeNewArray\n"); + } + + void toCBuffer2(OutBuffer buf, HdrGenState *hgs, MOD mod) + { + if (mod != this.mod) + { + toCBuffer3(buf, hgs, mod); + return; + } + next.toCBuffer2(buf, hgs, this.mod); + buf.writestring("[new]"); + } +} \ No newline at end of file
--- a/dmd/TypeStruct.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/TypeStruct.d Mon Aug 30 03:57:51 2010 +0200 @@ -185,7 +185,7 @@ exps.reserve(sym.fields.dim); for (size_t i = 0; i < sym.fields.dim; i++) { - VarDeclaration v2 = cast(VarDeclaration)sym.fields.data[i]; + VarDeclaration v2 = cast(VarDeclaration)sym.fields[i]; Expression fe = new DotVarExp(e.loc, e, v2); exps.push(cast(void*)fe); } @@ -435,7 +435,7 @@ */ for (size_t i = 0; i < sym.fields.dim; i++) { - VarDeclaration v = cast(VarDeclaration)sym.fields.data[i]; + VarDeclaration v = cast(VarDeclaration)sym.fields[i]; if (v.isConst() || v.isInvariant()) return false; } @@ -516,9 +516,8 @@ StructDeclaration s = sym; sym.size(Loc(0)); // give error for forward references - for (size_t i = 0; i < s.fields.dim; i++) + foreach (Dsymbol sm; s.fields) { - Dsymbol sm = cast(Dsymbol)s.fields.data[i]; Declaration d = sm.isDeclaration(); if (d.storage_class & STC.STCref || d.hasPointers()) return true; @@ -543,9 +542,8 @@ { /* Check all the fields. If they can all be converted, * allow the conversion. */ - for (int i = 0; i < sym.fields.dim; i++) + foreach (Dsymbol s; sym.fields) { - Dsymbol s = cast(Dsymbol)sym.fields.data[i]; VarDeclaration v = s.isVarDeclaration(); assert(v && v.storage_class & STCfield); @@ -633,7 +631,7 @@ if (global.params.symdebug) { for (int i = 0; i < sym.fields.dim; i++) { - VarDeclaration v = cast(VarDeclaration)sym.fields.data[i]; + VarDeclaration v = cast(VarDeclaration)sym.fields[i]; Symbol* s2 = symbol_name(toStringz(v.ident.toChars()), SC.SCmember, v.type.toCtype()); s2.Smemoff = v.offset;
--- a/dmd/Util.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/Util.d Mon Aug 30 03:57:51 2010 +0200 @@ -408,11 +408,9 @@ string[] argv = args.dup; int argc = args.length; - int wildcard; // do wildcard expansion int instring; int slash; char c; - int j; string ienv = getenv(envvar); if (ienv is null) @@ -420,11 +418,11 @@ char[] env = ienv.dup; // create our own writable copy - j = 1; // leave argv[0] alone + int j = 1; // leave argv[0] alone char* e = env.ptr; while (1) { - wildcard = 1; + int wildcard = 1; // do wildcard expansion switch (*e) { case ' ': @@ -530,7 +528,7 @@ " -g add symbolic debug info\n" " -gc add symbolic debug info, pretend to be C\n" " -H generate 'header' file\n" -" -Hdhdrdir write 'header' file to hdrdir directory\n" +" -Hddirectory write 'header' file to directory\n" " -Hffilename write 'header' file to filename\n" " --help print help\n" " -Ipath where to look for imports\n" @@ -557,6 +555,8 @@ " -version=ident compile in version code identified by ident\n" " -vtls list all variables going into thread local storage\n" " -w enable warnings\n" +" -X generate JSON file\n" +" -Xffilename write JSON file to filename\n" ); }
--- a/dmd/backend/glue.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/backend/glue.d Mon Aug 30 03:57:51 2010 +0200 @@ -20,7 +20,8 @@ __gshared Array obj_symbols_towrite; -version (Windows) { +version (Windows) +{ extern (C++) extern { __gshared Outbuffer objbuf; @@ -28,8 +29,10 @@ void util_set64(); void util_set386(); } -} else { - extern (C++) /+extern+/ +} +else version (linux) +{ + extern (C++) { extern(C) extern __gshared Outbuffer objbuf; int go_flag(char* cp); @@ -37,6 +40,10 @@ void util_set386(); } } +else +{ + static assert(false, "fix this"); +} import std.exception; import std.string;
--- a/dmd/expression/Util.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/expression/Util.d Mon Aug 30 03:57:51 2010 +0200 @@ -946,7 +946,8 @@ Expression createTypeInfoArray(Scope sc, Expression* exps, int dim) { -static if (true) { +static if (true) +{ /* Get the corresponding TypeInfo_Tuple and * point at its elements[]. */ @@ -965,7 +966,8 @@ e = e.optimize(WANTvalue); assert(e.op == TOKsymoff); // should be SymOffExp -version (BREAKABI) { +version (BREAKABI) +{ /* * Should just pass a reference to TypeInfo_Tuple instead, * but that would require existing code to be recompiled. @@ -974,7 +976,9 @@ * TypeInfo_Tuple reference. */ -} else { +} +else +{ // Advance to elements[] member of TypeInfo_Tuple SymOffExp se = cast(SymOffExp)e; se.offset += PTRSIZE + PTRSIZE; @@ -987,7 +991,9 @@ e.type = se.type.next; } return e; -} else { +} // of static if (true) +else +{ /* Improvements: * 1) create an array literal instead, * as it would eliminate the extra dereference of loading the @@ -1036,7 +1042,7 @@ ai.type = t; v = new VarDeclaration(0, t, id, ai); m.members.push(v); - m.symtab.insert(v); + m.symtabInsert(v); sc = sc.push(); sc.linkage = LINKc; sc.stc = STCstatic | STCcomdat; @@ -1115,6 +1121,7 @@ e = e.copy(); e.type = e1.type; } + e.loc = e1.loc; } else {
--- a/dmd/interpret/Util.d Sun Aug 29 14:39:08 2010 +0100 +++ b/dmd/interpret/Util.d Mon Aug 30 03:57:51 2010 +0200 @@ -182,7 +182,7 @@ structelems.setDim(sym.fields.dim); for (size_t j = 0; j < structelems.dim; j++) { - structelems.data[j] = cast(void*)(cast(VarDeclaration)(sym.fields.data[j])).type.defaultInit(Loc(0)); + structelems.data[j] = cast(void*)(cast(VarDeclaration)(sym.fields[j])).type.defaultInit(Loc(0)); } StructLiteralExp structinit = new StructLiteralExp(loc, sym, structelems); // Why doesn't the StructLiteralExp constructor do this, when
--- a/linux_lib.mak Sun Aug 29 14:39:08 2010 +0100 +++ b/linux_lib.mak Mon Aug 30 03:57:51 2010 +0200 @@ -38,7 +38,7 @@ unialpha.o toobj.o toctype.o toelfdebug.o entity.o doc.o macro.o \ hdrgen.o delegatize.o aa.o ti_achar.o toir.o interpret.o traits.o \ builtin.o clone.o aliasthis.o \ - man.o arrayop.o port.o response.o async.o \ + man.o arrayop.o port.o response.o async.o json.o \ libelf.o elfobj.o SRC = win32.mak linux.mak osx.mak freebsd.mak solaris.mak \ @@ -57,7 +57,7 @@ doc.h doc.c macro.h macro.c hdrgen.h hdrgen.c arraytypes.h \ delegatize.c toir.h toir.c interpret.c traits.c cppmangle.c \ builtin.c clone.c lib.h libomf.c libelf.c libmach.c arrayop.c \ - aliasthis.h aliasthis.c \ + aliasthis.h aliasthis.c json.h json.c \ $C/cdef.h $C/cc.h $C/oper.h $C/ty.h $C/optabgen.c \ $C/global.h $C/parser.h $C/code.h $C/type.h $C/dt.h $C/cgcv.h \ $C/el.h $C/iasm.h $C/rtlsym.h $C/html.h \ @@ -344,6 +344,9 @@ interpret.o: interpret.c $(CC) -c $(CFLAGS) $< +json.o: json.c + $(CC) -c $(CFLAGS) $< + lexer.o: lexer.c $(CC) -c $(CFLAGS) $< @@ -531,6 +534,7 @@ gcov inline.c gcov interpret.c gcov irstate.c + gcov json.c gcov lexer.c gcov libelf.c gcov link.c
--- a/main.d Sun Aug 29 14:39:08 2010 +0100 +++ b/main.d Mon Aug 30 03:57:51 2010 +0200 @@ -13,6 +13,7 @@ import dmd.File; import dmd.Id; import dmd.Identifier; +import dmd.Json; import dmd.Library; import dmd.TOK; import dmd.String; @@ -438,6 +439,25 @@ } } ///} + else if (p[1] == 'X') + { + global.params.doXGeneration = 1; + switch (p[2]) + { + case 'f': + if (!p[3]) + goto Lnoarg; + global.params.xfilename = arg[(p - arg.ptr) + 3..$]; + break; + + case 0: + break; + + default: + goto Lerror; + } + } + else if (arg == "ignore") global.params.ignoreUnsupportedPragmas = 1; else if (arg == "inline") @@ -819,8 +839,16 @@ global.params.ddocfiles.push(files.data[i]); continue; } + + if (FileName.equals(ext, global.json_ext)) + { + global.params.doXGeneration = 1; + global.params.xfilename = (cast(immutable(char)*)files.data[i])[0..0]; + continue; + } -version (TARGET_WINDOS) { +version (TARGET_WINDOS) +{ if (FileName.equals(ext, "res")) { global.params.resfile = (cast(immutable(char)*)files.data[i])[0..0]; /// !!! @@ -967,7 +995,8 @@ } if (global.errors) fatal(); -version (_DH) { +version (_DH) +{ if (global.params.doHdrGeneration) { /* Generate 'header' import files. @@ -977,7 +1006,7 @@ */ for (i = 0; i < modules.dim; i++) { - m = cast(Module *)modules.data[i]; + m = cast(Module)modules.data[i]; if (global.params.verbose) writef("import %s\n", m.toChars()); m.genhdrfile(); @@ -986,6 +1015,16 @@ if (global.errors) fatal(); } + //load all unconditional imports for better symbol resolving + for (int i = 0; i < modules.dim; i++) + { + m = cast(Module)modules.data[i]; + if (global.params.verbose) + writef("importall %s\n", m.toChars()); + m.importAll(null); + } + if (global.errors) + fatal(); // Do semantic analysis for (int i = 0; i < modules.dim; i++) @@ -1081,6 +1120,9 @@ } // Generate output files + if (global.params.doXGeneration) + json_generate(modules); + if (global.params.oneobj) { for (int i = 0; i < modules.dim; i++)
--- a/win32_lib.mak Sun Aug 29 14:39:08 2010 +0100 +++ b/win32_lib.mak Mon Aug 30 03:57:51 2010 +0200 @@ -79,7 +79,8 @@ interpret.obj traits.obj aliasthis.obj \ builtin.obj clone.obj libomf.obj arrayop.obj irstate.obj \ glue.obj msc.obj ph.obj tk.obj s2ir.obj todt.obj e2ir.obj tocsym.obj \ - util.obj bit.obj eh.obj toobj.obj toctype.obj tocvdebug.obj toir.obj + util.obj bit.obj eh.obj toobj.obj toctype.obj tocvdebug.obj toir.obj \ + json.obj # from C/C++ compiler optimizer and back end @@ -113,7 +114,7 @@ macro.h macro.c hdrgen.h hdrgen.c arraytypes.h \ delegatize.c toir.h toir.c interpret.c traits.c builtin.c \ clone.c lib.h libomf.c libelf.c libmach.c arrayop.c \ - aliasthis.h aliasthis.c + aliasthis.h aliasthis.c json.h json.c # From C++ compiler @@ -447,6 +448,7 @@ init.obj : $(TOTALH) init.h init.c inline.obj : $(TOTALH) inline.c interpret.obj : $(TOTALH) interpret.c +json.obj : $(TOTALH) json.h json.c lexer.obj : $(TOTALH) lexer.c libomf.obj : $(TOTALH) lib.h libomf.c link.obj : $(TOTALH) link.c