Mercurial > projects > ddmd
changeset 110:12c0c84d13fd
merged in 2.036 changes
author | Trass3r |
---|---|
date | Tue, 31 Aug 2010 22:29:00 +0200 |
parents | ceda59b4d255 (diff) a1cf34da9ebe (current diff) |
children | 2f57c5ecd3b2 |
files | dmd/FuncDeclaration.d dmd/IsExp.d dmd/Parser.d dmd/StaticDtorDeclaration.d dmd/TemplateDeclaration.d dmd/TemplateInstance.d dmd/Type.d dmd/TypeSArray.d dmd/VarDeclaration.d |
diffstat | 74 files changed, 1438 insertions(+), 941 deletions(-) [+] |
line wrap: on
line diff
--- a/commands.linux.txt Tue Aug 31 16:35:41 2010 +0200 +++ b/commands.linux.txt Tue Aug 31 22:29:00 2010 +0200 @@ -17,6 +17,7 @@ -version=CARRAYDECL -version=BREAKABI -version=SNAN_DEFAULT_INIT +-version=SARRAYVALUE -ofbin/ddmd bridge.o
--- a/commands.txt Tue Aug 31 16:35:41 2010 +0200 +++ b/commands.txt Tue Aug 31 22:29:00 2010 +0200 @@ -14,6 +14,7 @@ -version=SEH -version=OMFOBJ -version=SNAN_DEFAULT_INIT +-version=SARRAYVALUE -ofbin\ddmd.exe bridge.obj ddmd.def
--- a/dmd/AddrExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/AddrExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -65,7 +65,6 @@ return new ErrorExp(); } - //printf("test3 deco = %p\n", e1.type.deco); type = e1.type.pointerTo(); // See if this should really be a delegate
--- a/dmd/AggregateDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/AggregateDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -468,11 +468,12 @@ BaseClass b = cd.interfaces[i]; if (offset != buf.offset) { - buf.writestring(","); + buf.writestring(",\n"); offset = buf.offset; } JsonString(buf, b.base.toChars()); } + JsonRemoveComma(buf); buf.writestring("],\n"); } } @@ -484,11 +485,12 @@ { if (offset != buf.offset) { - buf.writestring(","); + buf.writestring(",\n"); offset = buf.offset; } s.toJsonBuffer(buf); } + JsonRemoveComma(buf); buf.writestring("]\n"); buf.writestring("}\n");
--- a/dmd/AliasDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/AliasDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -126,17 +126,17 @@ if (s && ((s.getType() && type.equals(s.getType())) || s.isEnumMember())) goto L2; // it's a symbolic alias - ///version (DMDV2) { - if (storage_class & STC.STCref) +///version (DMDV2) { + if (storage_class & (STC.STCref | STCnothrow | STCpure)) { // For 'ref' to be attached to function types, and picked // up by Type.resolve(), it has to go into sc. sc = sc.push(); - sc.stc |= STC.STCref; + sc.stc |= storage_class & (STCref | STCnothrow | STCpure); type.resolve(loc, sc, &e, &t, &s); sc = sc.pop(); } else - /// #endif +/// #endif type.resolve(loc, sc, &e, &t, &s); if (s) {
--- a/dmd/AndExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/AndExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -49,11 +49,10 @@ else { typeCombine(sc); - if (e1.op != TOK.TOKslice && e2.op != TOK.TOKslice) - { + if (!e1.isArrayOperand()) e1.checkIntegral(); + if (!e2.isArrayOperand()) e2.checkIntegral(); - } } } return this;
--- a/dmd/AssocArrayLiteralExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/AssocArrayLiteralExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -57,6 +57,9 @@ printf("AssocArrayLiteralExp.semantic('%s')\n", toChars()); } + if (type) + return this; + // Run semantic() on each element for (size_t i = 0; i < keys.dim; i++) { auto key = keys[i]; @@ -147,6 +150,8 @@ assert(t.ty == Taarray); auto ta = cast(TypeAArray)t; +static if(false) +{ /* Unfortunately, the hash function for Aa (array of chars) is custom and * different from Axa and Aya, which get the generic hash function. * So, rewrite the type of the AArray so that if it's key type @@ -160,6 +165,7 @@ ta = new TypeAArray(ta.nextOf(), tkey); ta = cast(TypeAArray)ta.merge(); } +} e = el_param(e, ta.getTypeInfo(null).toElem(irs));
--- a/dmd/BinExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/BinExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -328,13 +328,13 @@ { assert(0); } - else if (e1.op == TOK.TOKslice && t1.ty == TY.Tarray && + else if (e1.isArrayOperand() && t1.ty == TY.Tarray && e2.implicitConvTo(t1.nextOf())) { // T[] op T e2 = e2.castTo(sc, t1.nextOf()); t = t1.nextOf().arrayOf(); } - else if (e2.op == TOK.TOKslice && t2.ty == TY.Tarray && + else if (e2.isArrayOperand() && t2.ty == TY.Tarray && e1.implicitConvTo(t2.nextOf())) { // T op T[] e1 = e1.castTo(sc, t2.nextOf());
--- a/dmd/CallExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/CallExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -94,7 +94,7 @@ super(loc, TOK.TOKcall, CallExp.sizeof, e); auto arguments = new Expressions(); - if (earg1) + if (earg1) { arguments.setDim(1); arguments[0] = earg1; @@ -184,7 +184,8 @@ return new RemoveExp(loc, dotid.e1, key); } - else if (e1ty == TY.Tarray || e1ty == TY.Tsarray || e1ty == TY.Taarray) + else if (e1ty == TY.Tarray || e1ty == TY.Tsarray || + (e1ty == Taarray && dotid.ident != Id.apply && dotid.ident != Id.applyReverse)) { if (!arguments) arguments = new Expressions(); @@ -778,7 +779,7 @@ override Expression optimize(int result) { - //printf("CallExp::optimize(result = %d) %s\n", result, toChars()); + // writef("CallExp::optimize(result = %d) %s\n", result, toChars()); Expression e = this; // Optimize parameters @@ -813,6 +814,19 @@ } } } + else if (e1.op == TOKdotvar && result & WANTinterpret) + { + DotVarExp dve = cast(DotVarExp) e1; + FuncDeclaration fd = dve.var.isFuncDeclaration(); + if (fd) + { + Expression eresult = fd.interpret(null, arguments, dve.e1); + if (eresult && eresult != EXP_VOID_INTERPRET) + e = eresult; + else + error("cannot evaluate %s at compile time", toChars()); + } + } return e; } @@ -833,7 +847,7 @@ { // Member function call if(pthis.op == TOKthis) - pthis = istate.localThis; + pthis = istate.localThis; Expression eresult = fd.interpret(istate, arguments, pthis); if (eresult) e = eresult; @@ -1034,7 +1048,7 @@ version (DMDV2) { override int isLvalue() { - // if (type.toBasetype().ty == Tstruct) + // if (type.toBasetype().ty == Tstruct) // return 1; Type tb = e1.type.toBasetype(); if (tb.ty == Tfunction && (cast(TypeFunction)tb).isref)
--- a/dmd/CastExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/CastExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -106,6 +106,12 @@ } } + if (e1.op == TOKtemplate) + { + error("cannot cast template %s to type %s", e1.toChars(), to.toChars()); + return new ErrorExp(); + } + Type t1b = e1.type.toBasetype(); Type tob = to.toBasetype(); if (tob.ty == TY.Tstruct &&
--- a/dmd/CatAssignExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/CatAssignExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -107,7 +107,7 @@ e1 = el_una(OPaddr, TYnptr, e1); e2 = this.e2.toElem(irs); - if (tybasic(e2.Ety) == TYstruct) + if (tybasic(e2.Ety) == TYstruct || tybasic(e2.Ety) == TYarray) { e2 = el_una(OPstrpar, TYstruct, e2); e2.Enumbytes = e2.E1.Enumbytes;
--- a/dmd/Declaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/Declaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -65,11 +65,12 @@ buf.writestring(sthis.type.deco); else { -debug { +debug +{ if (!fd.inferRetType) writef("%s\n", fd.toChars()); } - assert(fd.inferRetType); + assert(fd && fd.inferRetType); } id = buf.extractString();
--- a/dmd/DeleteExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/DeleteExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -188,7 +188,7 @@ elem* ep; elem* keyti; - if (tybasic(ekey.Ety) == TYstruct) + if (tybasic(ekey.Ety) == TYstruct || tybasic(ekey.Ety) == TYarray) { ekey = el_una(OPstrpar, TYstruct, ekey); ekey.Enumbytes = ekey.E1.Enumbytes;
--- a/dmd/DivExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/DivExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -41,11 +41,11 @@ return e; typeCombine(sc); - if (e1.op != TOK.TOKslice && e2.op != TOK.TOKslice) - { + if (!e1.isArrayOperand()) e1.checkArithmetic(); + if (!e2.isArrayOperand()) e2.checkArithmetic(); - } + if (type.isfloating()) { Type t1 = e1.type;
--- a/dmd/DotIdExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/DotIdExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -337,11 +337,13 @@ */ uint errors = global.errors; global.gag++; + Type t1 = e1.type; e = e1.type.dotExp(sc, e1, ident); global.gag--; if (errors != global.errors) // if failed to find the property { global.errors = errors; + e1.type = t1; // kludge to restore type e = new DotIdExp(loc, new IdentifierExp(loc, Id.empty), ident); e = new CallExp(loc, e, e1); }
--- a/dmd/DotVarExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/DotVarExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -126,9 +126,9 @@ return this; } - override int isLvalue() + override bool isLvalue() { - return 1; + return true; } override Expression toLvalue(Scope sc, Expression e) @@ -197,33 +197,24 @@ override Expression optimize(int result) { - //printf("DotVarExp.optimize(result = x%x) %s\n", result, toChars()); + //writef("DotVarExp.optimize(result = x%x) %s\n", result, toChars()); e1 = e1.optimize(result); + Expression e = e1; + if (e1.op == TOK.TOKvar) { VarExp ve = cast(VarExp)e1; VarDeclaration v = ve.var.isVarDeclaration(); - Expression e = expandVar(result, v); - if (e && e.op == TOK.TOKstructliteral) - { - StructLiteralExp sle = cast(StructLiteralExp)e; - VarDeclaration vf = var.isVarDeclaration(); - if (vf) - { - e = sle.getField(type, vf.offset); - if (e && e !is EXP_CANT_INTERPRET) - return e; - } - } + e = expandVar(result, v); } - else if (e1.op == TOK.TOKstructliteral) - { - StructLiteralExp sle = cast(StructLiteralExp)e1; + if (e && e.op == TOK.TOKstructliteral) + { + StructLiteralExp sle = cast(StructLiteralExp) e; VarDeclaration vf = var.isVarDeclaration(); if (vf) { - Expression e = sle.getField(type, vf.offset); + e = sle.getField(type, vf.offset); if (e && e !is EXP_CANT_INTERPRET) return e; }
--- a/dmd/Dsymbol.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/Dsymbol.d Tue Aug 31 22:29:00 2010 +0200 @@ -67,6 +67,7 @@ import dmd.backend.SC; import dmd.backend.FL; import dmd.backend.LIST; +public import dmd.PASS; import core.stdc.string : strcmp, memcpy, strlen; version (Bug4054) import core.memory;
--- a/dmd/DtorDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/DtorDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -17,23 +17,24 @@ class DtorDeclaration : FuncDeclaration { - this(Loc loc, Loc endloc) + this(Loc loc, Loc endloc) { super(loc, endloc, Id.dtor, STCundefined, null); } - this(Loc loc, Loc endloc, Identifier id) + this(Loc loc, Loc endloc, Identifier id) { - assert(false); - super(loc, endloc, null, STC.init, null); + super(loc, endloc, id, STCundefined, null); } - override Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol s) { - assert(false); + assert(!s); + DtorDeclaration dd = new DtorDeclaration(loc, endloc, ident); + return super.syntaxCopy(dd); } - override void semantic(Scope sc) + override void semantic(Scope sc) { //printf("DtorDeclaration::semantic() %s\n", toChars()); //printf("ident: %s, %s, %p, %p\n", ident.toChars(), Id::dtor.toChars(), ident, Id::dtor); @@ -53,31 +54,33 @@ sc.stc &= ~STCstatic; // not a static destructor sc.linkage = LINK.LINKd; - FuncDeclaration.semantic(sc); + super.semantic(sc); sc.pop(); } - override void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - assert(false); + buf.writestring("~this()"); + bodyToCBuffer(buf, hgs); } - + override void toJsonBuffer(OutBuffer buf) { + // intentionally empty } - override string kind() + override string kind() { - assert(false); + return "destructor"; } - override string toChars() + override string toChars() { return "~this"; } - override bool isVirtual() + override bool isVirtual() { /* This should be FALSE so that dtor's don't get put into the vtbl[], * but doing so will require recompiling everything. @@ -85,29 +88,29 @@ version (BREAKABI) { return false; } else { - return FuncDeclaration.isVirtual(); + return super.isVirtual(); } } - override bool addPreInvariant() + override bool addPreInvariant() { return (isThis() && vthis && global.params.useInvariants); } - override bool addPostInvariant() + override bool addPostInvariant() { return false; } - override bool overloadInsert(Dsymbol s) + override bool overloadInsert(Dsymbol s) { - assert(false); + return false; // cannot overload destructors } - override void emitComment(Scope sc) + override void emitComment(Scope sc) { - assert(false); + // intentionally empty } - override DtorDeclaration isDtorDeclaration() { return this; } + override DtorDeclaration isDtorDeclaration() { return this; } }
--- a/dmd/EnumDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/EnumDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -417,11 +417,12 @@ { if (offset != buf.offset) { - buf.writestring(","); + buf.writestring(",\n"); offset = buf.offset; } s.toJsonBuffer(buf); } + JsonRemoveComma(buf); buf.writestring("]\n"); buf.writestring("}\n");
--- a/dmd/Expression.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/Expression.d Tue Aug 31 22:29:00 2010 +0200 @@ -126,7 +126,6 @@ /*************************************** * Pull out any properties. */ - Expression resolveProperties(Scope sc, Expression e) { //printf("resolveProperties(%s)\n", e.toChars()); @@ -136,6 +135,11 @@ if (t.ty == TY.Tfunction || e.op == TOK.TOKoverloadset) { +static if(false) +{ + if (t.ty == Tfunction && !(cast(TypeFunction)t).isproperty) + error(e.loc, "not a property %s\n", e.toChars()); +} e = new CallExp(e.loc, e); e = e.semantic(sc); } @@ -166,6 +170,17 @@ return e; } +void indent(int indent) +{ + foreach (i; 0 .. indent) + writef(" "); +} + +string type_print(Type type) +{ + return type ? type.toChars() : "null"; +} + class Expression { Loc loc; // file location @@ -258,9 +273,10 @@ return buf.toChars(); } - void dump(int indent) + void dump(int i) { - assert(false); + indent(i); + writef("%p %s type=%s\n", this, Token.toChars(op), type_print(type)); } void error(T...)(string format, T t) @@ -726,14 +742,13 @@ Expression checkToPointer() { - Expression e; - Type tb; + //writef("Expression::checkToPointer()\n"); + Expression e = this; - //printf("Expression::checkToPointer()\n"); - e = this; - +version(SARRAYVALUE) {} else +{ // If C static array, convert to pointer - tb = type.toBasetype(); + Type tb = type.toBasetype(); if (tb.ty == Tsarray) { TypeSArray ts = cast(TypeSArray)tb; @@ -743,6 +758,7 @@ e = new AddrExp(loc, this); e.type = ts.next.pointerTo(); } +} return e; } @@ -978,7 +994,38 @@ Expression e = new IdentifierExp(Loc(0), id); return e; } - + + /*********************************************** + * Test if operand is a valid array op operand. + */ + int isArrayOperand() + { + //writef("Expression::isArrayOperand() %s\n", toChars()); + if (op == TOKslice) + return 1; + if (type.toBasetype().ty == TY.Tarray) + { + switch (op) + { + case TOKadd: + case TOKmin: + case TOKmul: + case TOKdiv: + case TOKmod: + case TOKxor: + case TOKand: + case TOKor: + case TOKneg: + case TOKtilde: + return 1; + + default: + break; + } + } + return 0; + } + // Back end elem* toElem(IRState* irs) {
--- a/dmd/ForeachStatement.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/ForeachStatement.d Tue Aug 31 22:29:00 2010 +0200 @@ -253,6 +253,7 @@ sc.noctor++; + Lagain: switch (tab.ty) { case TY.Tarray: @@ -318,13 +319,15 @@ var.storage_class |= STC.STCconst; } } -static if (false) { +static if (false) +{ DeclarationExp de = new DeclarationExp(loc, var); de.semantic(sc); } } -static if (true) { +static if (true) +{ { /* Convert to a ForStatement * foreach (key, value; a) body => @@ -423,12 +426,21 @@ error("only one or two arguments for associative array foreach"); break; } +version(SARRAYVALUE) +{ + /* This only works if Key or Value is a static array. + */ + tab = taa.getImpl().type; + goto Lagain; +} +else +{ if (op == TOK.TOKforeach_reverse) { error("no reverse iteration on associative arrays"); } goto Lapply; - +} case TY.Tclass: case TY.Tstruct: version (DMDV2) {
--- a/dmd/FuncDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/FuncDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -1473,6 +1473,7 @@ e = new AssignExp(Loc(0), e1, e); e.type = t; a.push(cast(void*)new ExpStatement(Loc(0), e)); + p.isargptr = true; } } @@ -2338,13 +2339,28 @@ } if (global.errors) return null; +version(DMDV1) +{ if (ident == Id.aaLen) return interpret_aaLen(istate, arguments); else if (ident == Id.aaKeys) return interpret_aaKeys(istate, arguments); else if (ident == Id.aaValues) return interpret_aaValues(istate, arguments); - +} +else version(DMDV2) +{ + if (thisarg && (!arguments || arguments.dim == 0)) + { + if (ident == Id.length) + return interpret_length(istate, thisarg); + else if (ident == Id.keys) + return interpret_keys(istate, thisarg, this); + else if (ident == Id.values) + return interpret_values(istate, thisarg, this); + } +} + if (cantInterpret || semanticRun == 3) return null; @@ -2962,7 +2978,7 @@ foreach(FuncDeclaration fdv; foverrides) //(int i = 0; i < foverrides.dim; i++) { sf = fdv.mergeFrequire(sf); - if (fdv.frequire) + if (fdv.fdrequire) { //printf("fdv.frequire: %s\n", fdv.frequire.toChars()); /* Make the call: @@ -3006,7 +3022,7 @@ foreach (FuncDeclaration fdv; foverrides) { sf = fdv.mergeFensure(sf); - if (fdv.fensure) + if (fdv.fdensure) { //printf("fdv.fensure: %s\n", fdv.fensure.toChars()); // Make the call: __ensure(result) @@ -3214,7 +3230,8 @@ int has_arguments; //printf("FuncDeclaration.toObjFile(%p, %s.%s)\n", func, parent.toChars(), func.toChars()); -static if (false) { +static if (false) +{ //printf("line = %d\n",func.getWhere() / LINEINC); EEcontext ee = env.getEEcontext(); if (ee.EEcompile == 2) @@ -3252,7 +3269,8 @@ s = func.toSymbol(); f = s.Sfunc; -version (TARGET_WINDOS) { +version (TARGET_WINDOS) +{ /* This is done so that the 'this' pointer on the stack is the same * distance away from the function parameters, so that an overriding * function can call the nested fdensure or fdrequire of its overridden function @@ -3407,11 +3425,12 @@ for ( ; i < parameters.dim; ++i) { auto v = cast(VarDeclaration)parameters[i]; -debug { + if (v.csym) - writef("parameter '%s'\n", v.toChars()); -} - assert(!v.csym); + { + error("compiler error, parameter '%s', bugzilla 2962?", v.toChars()); + assert(false); + } params[pi + i] = v.toSymbol(); } pi += i;
--- a/dmd/Global.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/Global.d Tue Aug 31 22:29:00 2010 +0200 @@ -38,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.035"; + string version_ = "v2.036"; Param params; uint errors; // number of errors reported so far
--- a/dmd/Id.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/Id.d Tue Aug 31 22:29:00 2010 +0200 @@ -3,458 +3,295 @@ import dmd.Identifier; import dmd.Lexer; -struct Id +private string idgen(T...)(T ts) +{ + string res = "struct Id\n{\n"; + + foreach(entry; ts) + res ~= "\tstatic Identifier " ~ entry.ident ~ ";\n"; + + res ~= "\tstatic void initialize()\n\t{\n"; + string tmp; + foreach (entry; ts) + { + if (entry.name_ is null) + tmp = entry.ident; + else + tmp = entry.name_; + res ~= "\t\t" ~ entry.ident ~ ` = Lexer.idPool("` ~ tmp ~ "\");\n"; + } + + res ~= "\t}\n}"; + return res; +} + +private struct ID { - static Identifier IUnknown; - static Identifier Object_; - static Identifier object; - static Identifier max; - static Identifier min; - static Identifier This; - static Identifier ctor; - static Identifier dtor; - static Identifier cpctor; - static Identifier _postblit; - static Identifier classInvariant; - static Identifier unitTest; - static Identifier require; - static Identifier ensure; - static Identifier init_; - static Identifier size; - static Identifier __sizeof; - static Identifier alignof_; - static Identifier mangleof_; - static Identifier stringof_; - static Identifier tupleof_; - static Identifier length; - static Identifier remove; - static Identifier ptr; - static Identifier funcptr; - static Identifier dollar; - static Identifier offset; - static Identifier offsetof; - static Identifier ModuleInfo; - static Identifier ClassInfo; - static Identifier classinfo_; - static Identifier typeinfo_; - static Identifier outer; - static Identifier Exception; - static Identifier Throwable; - static Identifier withSym; - static Identifier result; - static Identifier returnLabel; - static Identifier delegate_; - static Identifier line; - static Identifier empty; - static Identifier p; - static Identifier coverage; - static Identifier __vptr; - static Identifier __monitor; - static Identifier system; - static Identifier TypeInfo; - static Identifier TypeInfo_Class; - static Identifier TypeInfo_Interface; - static Identifier TypeInfo_Struct; - static Identifier TypeInfo_Enum; - static Identifier TypeInfo_Typedef; - static Identifier TypeInfo_Pointer; - static Identifier TypeInfo_Array; - static Identifier TypeInfo_StaticArray; - static Identifier TypeInfo_AssociativeArray; - static Identifier TypeInfo_Function; - static Identifier TypeInfo_Delegate; - static Identifier TypeInfo_Tuple; - static Identifier TypeInfo_Const; - static Identifier TypeInfo_Invariant; - static Identifier TypeInfo_Shared; - static Identifier elements; - static Identifier _arguments_typeinfo; - static Identifier _arguments; - static Identifier _argptr; - static Identifier _match; - static Identifier destroy; - static Identifier postblit; - static Identifier LINE; - static Identifier FILE; - static Identifier DATE; - static Identifier TIME; - static Identifier TIMESTAMP; - static Identifier VENDOR; - static Identifier VERSIONX; - static Identifier EOFX; - static Identifier nan; - static Identifier infinity; - static Identifier dig; - static Identifier epsilon; - static Identifier mant_dig; - static Identifier max_10_exp; - static Identifier max_exp; - static Identifier min_10_exp; - static Identifier min_exp; - static Identifier re; - static Identifier im; - static Identifier C; - static Identifier D; - static Identifier Windows; - static Identifier Pascal; - static Identifier System; - static Identifier exit; - static Identifier success; - static Identifier failure; - static Identifier keys; - static Identifier values; - static Identifier rehash; - static Identifier sort; - static Identifier reverse; - static Identifier dup; - static Identifier idup; - static Identifier property; - static Identifier ___out; - static Identifier ___in; - static Identifier __int; - static Identifier __dollar; - static Identifier __LOCAL_SIZE; - static Identifier uadd; - static Identifier neg; - static Identifier com; - static Identifier add; - static Identifier add_r; - static Identifier sub; - static Identifier sub_r; - static Identifier mul; - static Identifier mul_r; - static Identifier div; - static Identifier div_r; - static Identifier mod; - static Identifier mod_r; - static Identifier eq; - static Identifier cmp; - static Identifier iand; - static Identifier iand_r; - static Identifier ior; - static Identifier ior_r; - static Identifier ixor; - static Identifier ixor_r; - static Identifier shl; - static Identifier shl_r; - static Identifier shr; - static Identifier shr_r; - static Identifier ushr; - static Identifier ushr_r; - static Identifier cat; - static Identifier cat_r; - static Identifier assign; - static Identifier addass; - static Identifier subass; - static Identifier mulass; - static Identifier divass; - static Identifier modass; - static Identifier andass; - static Identifier orass; - static Identifier xorass; - static Identifier shlass; - static Identifier shrass; - static Identifier ushrass; - static Identifier catass; - static Identifier postinc; - static Identifier postdec; - static Identifier index; - static Identifier indexass; - static Identifier slice; - static Identifier sliceass; - static Identifier call; - static Identifier cast_; - static Identifier match; - static Identifier next; - static Identifier opIn; - static Identifier opIn_r; - static Identifier opStar; - static Identifier opDot; - static Identifier opImplicitCast; - static Identifier classNew; - static Identifier classDelete; - static Identifier apply; - static Identifier applyReverse; - static Identifier Fempty; - static Identifier Fhead; - static Identifier Ftoe; - static Identifier Fnext; - static Identifier Fretreat; - static Identifier adDup; - static Identifier adReverse; - static Identifier aaLen; - static Identifier aaKeys; - static Identifier aaValues; - static Identifier aaRehash; - static Identifier monitorenter; - static Identifier monitorexit; - static Identifier criticalenter; - static Identifier criticalexit; - static Identifier GNU_asm; - static Identifier lib; - static Identifier msg; - static Identifier startaddress; - static Identifier tohash; - static Identifier tostring; - static Identifier getmembers; - static Identifier alloca; - static Identifier main; - static Identifier WinMain; - static Identifier DllMain; - static Identifier tls_get_addr; - static Identifier std; - static Identifier math; - static Identifier sin; - static Identifier cos; - static Identifier tan; - static Identifier _sqrt; - static Identifier fabs; - static Identifier isAbstractClass; - static Identifier isArithmetic; - static Identifier isAssociativeArray; - static Identifier isFinalClass; - static Identifier isFloating; - static Identifier isIntegral; - static Identifier isScalar; - static Identifier isStaticArray; - static Identifier isUnsigned; - static Identifier isVirtualFunction; - static Identifier isAbstractFunction; - static Identifier isFinalFunction; - static Identifier hasMember; - static Identifier getMember; - static Identifier getVirtualFunctions; - static Identifier classInstanceSize; - static Identifier allMembers; - static Identifier derivedMembers; - static Identifier isSame; - static Identifier compiles; + string ident; // name to use in DMD source + string name_; // name in D executable +} + +mixin(idgen( + ID( "IUnknown" ), + ID( "Object_", "Object" ), + ID( "object" ), + ID( "max" ), + ID( "min" ), + ID( "This", "this" ), + ID( "ctor", "__ctor" ), + ID( "dtor", "__dtor" ), + ID( "cpctor", "__cpctor" ), + ID( "_postblit", "__postblit" ), + ID( "classInvariant", "__invariant" ), + ID( "unitTest", "__unitTest" ), + ID( "require", "__require" ), + ID( "ensure", "__ensure" ), + ID( "init_", "init" ), + ID( "size" ), + ID( "__sizeof", "sizeof" ), + ID( "alignof_", "alignof" ), + ID( "mangleof_", "mangleof" ), + ID( "stringof_", "stringof" ), + ID( "tupleof_", "tupleof" ), + ID( "length" ), + ID( "remove" ), + ID( "ptr" ), + ID( "funcptr" ), + ID( "dollar", "__dollar" ), + ID( "offset" ), + ID( "offsetof" ), + ID( "ModuleInfo" ), + ID( "ClassInfo" ), + ID( "classinfo_", "classinfo" ), + ID( "typeinfo_", "typeinfo" ), + ID( "outer" ), + ID( "Exception" ), + ID( "AssociativeArray" ), + ID( "Throwable" ), + ID( "withSym", "__withSym" ), + ID( "result", "__result" ), + ID( "returnLabel", "__returnLabel" ), + ID( "delegate_", "delegate" ), + ID( "line" ), + ID( "empty", "" ), + ID( "p" ), + ID( "coverage", "__coverage" ), + ID( "__vptr" ), + ID( "__monitor" ), + ID( "system" ), + + ID( "TypeInfo" ), + ID( "TypeInfo_Class" ), + ID( "TypeInfo_Interface" ), + ID( "TypeInfo_Struct" ), + ID( "TypeInfo_Enum" ), + ID( "TypeInfo_Typedef" ), + ID( "TypeInfo_Pointer" ), + ID( "TypeInfo_Array" ), + ID( "TypeInfo_StaticArray" ), + ID( "TypeInfo_AssociativeArray" ), + ID( "TypeInfo_Function" ), + ID( "TypeInfo_Delegate" ), + ID( "TypeInfo_Tuple" ), + ID( "TypeInfo_Const" ), + ID( "TypeInfo_Invariant" ), + ID( "TypeInfo_Shared" ), + ID( "elements" ), + ID( "_arguments_typeinfo" ), + ID( "_arguments" ), + ID( "_argptr" ), + ID( "_match" ), + ID( "destroy" ), + + ID( "LINE", "__LINE__" ), + ID( "FILE", "__FILE__" ), + ID( "DATE", "__DATE__" ), + ID( "TIME", "__TIME__" ), + ID( "TIMESTAMP", "__TIMESTAMP__" ), + ID( "VENDOR", "__VENDOR__" ), + ID( "VERSIONX", "__VERSION__" ), + ID( "EOFX", "__EOF__" ), + + ID( "nan" ), + ID( "infinity" ), + ID( "dig" ), + ID( "epsilon" ), + ID( "mant_dig" ), + ID( "max_10_exp" ), + ID( "max_exp" ), + ID( "min_10_exp" ), + ID( "min_exp" ), + ID( "min_normal" ), + ID( "re" ), + ID( "im" ), + + ID( "C" ), + ID( "D" ), + ID( "Windows" ), + ID( "Pascal" ), + ID( "System" ), + + ID( "exit" ), + ID( "success" ), + ID( "failure" ), + + ID( "keys" ), + ID( "values" ), + ID( "rehash" ), + + ID( "sort" ), + ID( "reverse" ), + ID( "dup" ), + ID( "idup" ), + + ID( "property" ), - static void initialize() - { - IUnknown = Lexer.idPool("IUnknown"); - Object_ = Lexer.idPool("Object"); - object = Lexer.idPool("object"); - max = Lexer.idPool("max"); - min = Lexer.idPool("min"); - This = Lexer.idPool("this"); - ctor = Lexer.idPool("__ctor"); - dtor = Lexer.idPool("__dtor"); - cpctor = Lexer.idPool("__cpctor"); - _postblit = Lexer.idPool("__postblit"); - classInvariant = Lexer.idPool("__invariant"); - unitTest = Lexer.idPool("__unitTest"); - require = Lexer.idPool("__require"); - ensure = Lexer.idPool("__ensure"); - init_ = Lexer.idPool("init"); - size = Lexer.idPool("size"); - __sizeof = Lexer.idPool("sizeof"); - alignof_ = Lexer.idPool("alignof"); - mangleof_ = Lexer.idPool("mangleof"); - stringof_ = Lexer.idPool("stringof"); - tupleof_ = Lexer.idPool("tupleof"); - length = Lexer.idPool("length"); - remove = Lexer.idPool("remove"); - ptr = Lexer.idPool("ptr"); - funcptr = Lexer.idPool("funcptr"); - dollar = Lexer.idPool("__dollar"); - offset = Lexer.idPool("offset"); - offsetof = Lexer.idPool("offsetof"); - ModuleInfo = Lexer.idPool("ModuleInfo"); - ClassInfo = Lexer.idPool("ClassInfo"); - classinfo_ = Lexer.idPool("classinfo"); - typeinfo_ = Lexer.idPool("typeinfo"); - outer = Lexer.idPool("outer"); - Exception = Lexer.idPool("Exception"); - Throwable = Lexer.idPool("Throwable"); - withSym = Lexer.idPool("__withSym"); - result = Lexer.idPool("__result"); - returnLabel = Lexer.idPool("__returnLabel"); - delegate_ = Lexer.idPool("delegate"); - line = Lexer.idPool("line"); - empty = Lexer.idPool(""); - p = Lexer.idPool("p"); - coverage = Lexer.idPool("__coverage"); - __vptr = Lexer.idPool("__vptr"); - __monitor = Lexer.idPool("__monitor"); - system = Lexer.idPool("system"); - TypeInfo = Lexer.idPool("TypeInfo"); - TypeInfo_Class = Lexer.idPool("TypeInfo_Class"); - TypeInfo_Interface = Lexer.idPool("TypeInfo_Interface"); - TypeInfo_Struct = Lexer.idPool("TypeInfo_Struct"); - TypeInfo_Enum = Lexer.idPool("TypeInfo_Enum"); - TypeInfo_Typedef = Lexer.idPool("TypeInfo_Typedef"); - TypeInfo_Pointer = Lexer.idPool("TypeInfo_Pointer"); - TypeInfo_Array = Lexer.idPool("TypeInfo_Array"); - TypeInfo_StaticArray = Lexer.idPool("TypeInfo_StaticArray"); - TypeInfo_AssociativeArray = Lexer.idPool("TypeInfo_AssociativeArray"); - TypeInfo_Function = Lexer.idPool("TypeInfo_Function"); - TypeInfo_Delegate = Lexer.idPool("TypeInfo_Delegate"); - TypeInfo_Tuple = Lexer.idPool("TypeInfo_Tuple"); - TypeInfo_Const = Lexer.idPool("TypeInfo_Const"); - TypeInfo_Invariant = Lexer.idPool("TypeInfo_Invariant"); - TypeInfo_Shared = Lexer.idPool("TypeInfo_Shared"); - elements = Lexer.idPool("elements"); - _arguments_typeinfo = Lexer.idPool("_arguments_typeinfo"); - _arguments = Lexer.idPool("_arguments"); - _argptr = Lexer.idPool("_argptr"); - _match = Lexer.idPool("_match"); - destroy = Lexer.idPool("destroy"); - postblit = Lexer.idPool("postblit"); - LINE = Lexer.idPool("__LINE__"); - FILE = Lexer.idPool("__FILE__"); - DATE = Lexer.idPool("__DATE__"); - TIME = Lexer.idPool("__TIME__"); - TIMESTAMP = Lexer.idPool("__TIMESTAMP__"); - VENDOR = Lexer.idPool("__VENDOR__"); - VERSIONX = Lexer.idPool("__VERSION__"); - EOFX = Lexer.idPool("__EOF__"); - nan = Lexer.idPool("nan"); - infinity = Lexer.idPool("infinity"); - dig = Lexer.idPool("dig"); - epsilon = Lexer.idPool("epsilon"); - mant_dig = Lexer.idPool("mant_dig"); - max_10_exp = Lexer.idPool("max_10_exp"); - max_exp = Lexer.idPool("max_exp"); - min_10_exp = Lexer.idPool("min_10_exp"); - min_exp = Lexer.idPool("min_exp"); - re = Lexer.idPool("re"); - im = Lexer.idPool("im"); - C = Lexer.idPool("C"); - D = Lexer.idPool("D"); - Windows = Lexer.idPool("Windows"); - Pascal = Lexer.idPool("Pascal"); - System = Lexer.idPool("System"); - exit = Lexer.idPool("exit"); - success = Lexer.idPool("success"); - failure = Lexer.idPool("failure"); - keys = Lexer.idPool("keys"); - values = Lexer.idPool("values"); - rehash = Lexer.idPool("rehash"); - sort = Lexer.idPool("sort"); - reverse = Lexer.idPool("reverse"); - dup = Lexer.idPool("dup"); - idup = Lexer.idPool("idup"); - property = Lexer.idPool("property"); - ___out = Lexer.idPool("out"); - ___in = Lexer.idPool("in"); - __int = Lexer.idPool("int"); - __dollar = Lexer.idPool("$"); - __LOCAL_SIZE = Lexer.idPool("__LOCAL_SIZE"); - uadd = Lexer.idPool("opPos"); - neg = Lexer.idPool("opNeg"); - com = Lexer.idPool("opCom"); - add = Lexer.idPool("opAdd"); - add_r = Lexer.idPool("opAdd_r"); - sub = Lexer.idPool("opSub"); - sub_r = Lexer.idPool("opSub_r"); - mul = Lexer.idPool("opMul"); - mul_r = Lexer.idPool("opMul_r"); - div = Lexer.idPool("opDiv"); - div_r = Lexer.idPool("opDiv_r"); - mod = Lexer.idPool("opMod"); - mod_r = Lexer.idPool("opMod_r"); - eq = Lexer.idPool("opEquals"); - cmp = Lexer.idPool("opCmp"); - iand = Lexer.idPool("opAnd"); - iand_r = Lexer.idPool("opAnd_r"); - ior = Lexer.idPool("opOr"); - ior_r = Lexer.idPool("opOr_r"); - ixor = Lexer.idPool("opXor"); - ixor_r = Lexer.idPool("opXor_r"); - shl = Lexer.idPool("opShl"); - shl_r = Lexer.idPool("opShl_r"); - shr = Lexer.idPool("opShr"); - shr_r = Lexer.idPool("opShr_r"); - ushr = Lexer.idPool("opUShr"); - ushr_r = Lexer.idPool("opUShr_r"); - cat = Lexer.idPool("opCat"); - cat_r = Lexer.idPool("opCat_r"); - assign = Lexer.idPool("opAssign"); - addass = Lexer.idPool("opAddAssign"); - subass = Lexer.idPool("opSubAssign"); - mulass = Lexer.idPool("opMulAssign"); - divass = Lexer.idPool("opDivAssign"); - modass = Lexer.idPool("opModAssign"); - andass = Lexer.idPool("opAndAssign"); - orass = Lexer.idPool("opOrAssign"); - xorass = Lexer.idPool("opXorAssign"); - shlass = Lexer.idPool("opShlAssign"); - shrass = Lexer.idPool("opShrAssign"); - ushrass = Lexer.idPool("opUShrAssign"); - catass = Lexer.idPool("opCatAssign"); - postinc = Lexer.idPool("opPostInc"); - postdec = Lexer.idPool("opPostDec"); - index = Lexer.idPool("opIndex"); - indexass = Lexer.idPool("opIndexAssign"); - slice = Lexer.idPool("opSlice"); - sliceass = Lexer.idPool("opSliceAssign"); - call = Lexer.idPool("opCall"); - cast_ = Lexer.idPool("opCast"); - match = Lexer.idPool("opMatch"); - next = Lexer.idPool("opNext"); - opIn = Lexer.idPool("opIn"); - opIn_r = Lexer.idPool("opIn_r"); - opStar = Lexer.idPool("opStar"); - opDot = Lexer.idPool("opDot"); - opImplicitCast = Lexer.idPool("opImplicitCast"); - classNew = Lexer.idPool("new"); - classDelete = Lexer.idPool("delete"); - apply = Lexer.idPool("opApply"); - applyReverse = Lexer.idPool("opApplyReverse"); - Fempty = Lexer.idPool("empty"); - Fhead = Lexer.idPool("front"); - Ftoe = Lexer.idPool("back"); - Fnext = Lexer.idPool("popFront"); - Fretreat = Lexer.idPool("popBack"); - adDup = Lexer.idPool("_adDupT"); - adReverse = Lexer.idPool("_adReverse"); - aaLen = Lexer.idPool("_aaLen"); - aaKeys = Lexer.idPool("_aaKeys"); - aaValues = Lexer.idPool("_aaValues"); - aaRehash = Lexer.idPool("_aaRehash"); - monitorenter = Lexer.idPool("_d_monitorenter"); - monitorexit = Lexer.idPool("_d_monitorexit"); - criticalenter = Lexer.idPool("_d_criticalenter"); - criticalexit = Lexer.idPool("_d_criticalexit"); - GNU_asm = Lexer.idPool("GNU_asm"); - lib = Lexer.idPool("lib"); - msg = Lexer.idPool("msg"); - startaddress = Lexer.idPool("startaddress"); - tohash = Lexer.idPool("toHash"); - tostring = Lexer.idPool("toString"); - getmembers = Lexer.idPool("getMembers"); - alloca = Lexer.idPool("alloca"); - main = Lexer.idPool("main"); - WinMain = Lexer.idPool("WinMain"); - DllMain = Lexer.idPool("DllMain"); - tls_get_addr = Lexer.idPool("___tls_get_addr"); - std = Lexer.idPool("std"); - math = Lexer.idPool("math"); - sin = Lexer.idPool("sin"); - cos = Lexer.idPool("cos"); - tan = Lexer.idPool("tan"); - _sqrt = Lexer.idPool("sqrt"); - fabs = Lexer.idPool("fabs"); - isAbstractClass = Lexer.idPool("isAbstractClass"); - isArithmetic = Lexer.idPool("isArithmetic"); - isAssociativeArray = Lexer.idPool("isAssociativeArray"); - isFinalClass = Lexer.idPool("isFinalClass"); - isFloating = Lexer.idPool("isFloating"); - isIntegral = Lexer.idPool("isIntegral"); - isScalar = Lexer.idPool("isScalar"); - isStaticArray = Lexer.idPool("isStaticArray"); - isUnsigned = Lexer.idPool("isUnsigned"); - isVirtualFunction = Lexer.idPool("isVirtualFunction"); - isAbstractFunction = Lexer.idPool("isAbstractFunction"); - isFinalFunction = Lexer.idPool("isFinalFunction"); - hasMember = Lexer.idPool("hasMember"); - getMember = Lexer.idPool("getMember"); - getVirtualFunctions = Lexer.idPool("getVirtualFunctions"); - classInstanceSize = Lexer.idPool("classInstanceSize"); - allMembers = Lexer.idPool("allMembers"); - derivedMembers = Lexer.idPool("derivedMembers"); - isSame = Lexer.idPool("isSame"); - compiles = Lexer.idPool("compiles"); - } -} \ No newline at end of file + // For inline assembler + ID( "___out", "out" ), + ID( "___in", "in" ), + ID( "__int", "int" ), + ID( "__dollar", "$" ), + ID( "__LOCAL_SIZE" ), + + // For operator overloads + ID( "uadd", "opPos" ), + ID( "neg", "opNeg" ), + ID( "com", "opCom" ), + ID( "add", "opAdd" ), + ID( "add_r", "opAdd_r" ), + ID( "sub", "opSub" ), + ID( "sub_r", "opSub_r" ), + ID( "mul", "opMul" ), + ID( "mul_r", "opMul_r" ), + ID( "div", "opDiv" ), + ID( "div_r", "opDiv_r" ), + ID( "mod", "opMod" ), + ID( "mod_r", "opMod_r" ), + ID( "eq", "opEquals" ), + ID( "cmp", "opCmp" ), + ID( "iand", "opAnd" ), + ID( "iand_r", "opAnd_r" ), + ID( "ior", "opOr" ), + ID( "ior_r", "opOr_r" ), + ID( "ixor", "opXor" ), + ID( "ixor_r", "opXor_r" ), + ID( "shl", "opShl" ), + ID( "shl_r", "opShl_r" ), + ID( "shr", "opShr" ), + ID( "shr_r", "opShr_r" ), + ID( "ushr", "opUShr" ), + ID( "ushr_r", "opUShr_r" ), + ID( "cat", "opCat" ), + ID( "cat_r", "opCat_r" ), + ID( "assign", "opAssign" ), + ID( "addass", "opAddAssign" ), + ID( "subass", "opSubAssign" ), + ID( "mulass", "opMulAssign" ), + ID( "divass", "opDivAssign" ), + ID( "modass", "opModAssign" ), + ID( "andass", "opAndAssign" ), + ID( "orass", "opOrAssign" ), + ID( "xorass", "opXorAssign" ), + ID( "shlass", "opShlAssign" ), + ID( "shrass", "opShrAssign" ), + ID( "ushrass", "opUShrAssign" ), + ID( "catass", "opCatAssign" ), + ID( "postinc", "opPostInc" ), + ID( "postdec", "opPostDec" ), + ID( "index", "opIndex" ), + ID( "indexass", "opIndexAssign" ), + ID( "slice", "opSlice" ), + ID( "sliceass", "opSliceAssign" ), + ID( "call", "opCall" ), + ID( "cast_", "opCast" ), + ID( "match", "opMatch" ), + ID( "next", "opNext" ), + ID( "opIn" ), + ID( "opIn_r" ), + ID( "opStar" ), + ID( "opDot" ), + ID( "opImplicitCast" ), + + ID( "classNew", "new" ), + ID( "classDelete", "delete" ), + + // For foreach + ID( "apply", "opApply" ), + ID( "applyReverse", "opApplyReverse" ), + +// #if 1 + ID( "Fempty", "empty" ), + ID( "Fhead", "front" ), + ID( "Ftoe", "back" ), + ID( "Fnext", "popFront" ), + ID( "Fretreat", "popBack" ), + /*#else + ID( "Fempty", "empty" ), + ID( "Fhead", "head" ), + ID( "Ftoe", "toe" ), + ID( "Fnext", "next" ), + ID( "Fretreat", "retreat" ), + #endif*/ + + ID( "adDup", "_adDupT" ), + ID( "adReverse", "_adReverse" ), + + // For internal functions + ID( "aaLen", "_aaLen" ), + ID( "aaKeys", "_aaKeys" ), + ID( "aaValues", "_aaValues" ), + ID( "aaRehash", "_aaRehash" ), + ID( "monitorenter", "_d_monitorenter" ), + ID( "monitorexit", "_d_monitorexit" ), + ID( "criticalenter", "_d_criticalenter" ), + ID( "criticalexit", "_d_criticalexit" ), + + // For pragma's + ID( "GNU_asm" ), + ID( "lib" ), + ID( "msg" ), + ID( "startaddress" ), + + // For special functions + ID( "tohash", "toHash" ), + ID( "tostring", "toString" ), + ID( "getmembers", "getMembers" ), + + // Special functions + ID( "alloca" ), + ID( "main" ), + ID( "WinMain" ), + ID( "DllMain" ), + ID( "tls_get_addr", "___tls_get_addr" ), + + // Builtin functions + ID( "std" ), + ID( "math" ), + ID( "sin" ), + ID( "cos" ), + ID( "tan" ), + ID( "_sqrt", "sqrt" ), + ID( "fabs" ), + + // Traits + ID( "isAbstractClass" ), + ID( "isArithmetic" ), + ID( "isAssociativeArray" ), + ID( "isFinalClass" ), + ID( "isFloating" ), + ID( "isIntegral" ), + ID( "isScalar" ), + ID( "isStaticArray" ), + ID( "isUnsigned" ), + ID( "isVirtualFunction" ), + ID( "isAbstractFunction" ), + ID( "isFinalFunction" ), + ID( "hasMember" ), + ID( "getMember" ), + ID( "getVirtualFunctions" ), + ID( "classInstanceSize" ), + ID( "allMembers" ), + ID( "derivedMembers" ), + ID( "isSame" ), + ID( "compiles" ) + )); \ No newline at end of file
--- a/dmd/Import.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/Import.d Tue Aug 31 22:29:00 2010 +0200 @@ -198,7 +198,10 @@ mod.semantic(); if (mod.needmoduleinfo) + { + // writef("module4 %s because of %s\n", sc.module.toChars(), mod.toChars()); sc.module_.needmoduleinfo = 1; + } sc = sc.push(mod); for (size_t i = 0; i < aliasdecls.dim; i++) @@ -291,7 +294,10 @@ //printf("Import::semantic2('%s')\n", toChars()); mod.semantic2(); if (mod.needmoduleinfo) + { + // writef("module5 %s because of %s\n", sc.module.toChars(), mod.toChars()); sc.module_.needmoduleinfo = 1; + } } override Dsymbol toAlias()
--- a/dmd/IntegerExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/IntegerExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -168,11 +168,7 @@ */ if (!global.errors) { - printf("ty = %d, %d\n", type.ty, t.ty); - if (type.ty == Tenum) { - printf("test1\n"); - } - ///type.print(); + writef("%s %p\n", type.toChars(), type); assert(0); } break;
--- a/dmd/IsExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/IsExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -83,6 +83,7 @@ Type tded; /* is(targ id tok tspec) + * is(targ id : tok2) * is(targ id == tok2) */ @@ -238,14 +239,13 @@ * If true, declare id as an alias for the specialized type. */ - MATCH m; assert(parameters && parameters.dim); scope dedtypes = new Objects(); dedtypes.setDim(parameters.dim); dedtypes.zero(); - m = targ.deduceType(null, tspec, parameters, dedtypes); + MATCH m = targ.deduceType(null, tspec, parameters, dedtypes); if (m == MATCHnomatch || (m != MATCHexact && tok == TOKequal)) {
--- a/dmd/Json.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/Json.d Tue Aug 31 22:29:00 2010 +0200 @@ -25,13 +25,17 @@ { OutBuffer buf; + buf.writestring("[\n"); 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); + buf.writestring(",\n"); } + JsonRemoveComma(buf); + buf.writestring("]\n"); // Write buf to file string arg = global.params.xfilename;
--- a/dmd/MOD.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/MOD.d Tue Aug 31 22:29:00 2010 +0200 @@ -5,7 +5,8 @@ MODundefined = 0, MODconst = 1, // type is const MODshared = 2, // type is shared - MODinvariant = 4, // type is invariant + MODinvariant = 4, // type is immutable + MODimmutable = 4, // type is immutable } import dmd.EnumUtils;
--- a/dmd/Macro.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/Macro.d Tue Aug 31 22:29:00 2010 +0200 @@ -2,4 +2,112 @@ struct Macro /// ??? { -} \ No newline at end of file +} + +/** +It is very important to use version control macros correctly - the +idea is that host and target are independent. If these are done +correctly, cross compilers can be built. +The host compiler and host operating system are also different, +and are predefined by the host compiler. The ones used in +dmd are: + +Macros defined by the compiler, not the code: + + Compiler: + __DMC__ Digital Mars compiler + _MSC_VER Microsoft compiler + __GNUC__ Gnu compiler + + Host operating system: + _WIN32 Microsoft NT, Windows 95, Windows 98, Win32s, + Windows 2000, Win XP, Vista + _WIN64 Windows for AMD64 + linux Linux + __APPLE__ Mac OSX + __FreeBSD__ FreeBSD + __sun&&__SVR4 Solaris, OpenSolaris (yes, both macros are necessary) + +For the target systems, there are the target operating system and +the target object file format: + + Target operating system: + TARGET_WINDOS Covers 32 bit windows and 64 bit windows + TARGET_LINUX Covers 32 and 64 bit linux + TARGET_OSX Covers 32 and 64 bit Mac OSX + TARGET_FREEBSD Covers 32 and 64 bit FreeBSD + TARGET_SOLARIS Covers 32 and 64 bit Solaris + TARGET_NET Covers .Net + + It is expected that the compiler for each platform will be able + to generate 32 and 64 bit code from the same compiler binary. + + Target object module format: + OMFOBJ Intel Object Module Format, used on Windows + ELFOBJ Elf Object Module Format, used on linux, FreeBSD and Solaris + MACHOBJ Mach-O Object Module Format, used on Mac OSX + + There are currently no macros for byte endianness order. + */ +//version definitions from mars.h + +version(IN_GCC) // Changes for the GDC compiler by David Friedman +{ + static assert(false, "GDC not supported"); +} + +// default to DMDV2 +version(DMDV1) {} else +version = DMDV2; // Version 2.0 features +version = BREAKABI; // 0 if not ready to break the ABI just yet +version(DMDV2) +{ + version = STRUCTTHISREF; // if 'this' for struct is a reference, not a pointer + version = SNAN_DEFAULT_INIT;// if floats are default initialized to signalling NaN + version = SARRAYVALUE; // static arrays are value types +} + +// Set if C++ mangling is done by the front end +version(DMDV2) +{ + version(POSIX) // TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS + version = CPP_MANGLE; +} + +/* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD and + * TARGET_SOLARIS, which are + * set on the command line via the compiler makefile. + */ + +version(_WIN32) +{ + version = TARGET_WINDOS; // Windows dmd generates Windows targets + version = OMFOBJ; +} + +version(TARGET_LINUX) + version = ELFOBJ; +version(TARGET_FREEBSD) + version = ELFOBJ; +version(TARGET_SOLARIS) + version = ELFOBJ; + + +version(TARGET_OSX) + version = MACHOBJ; + +/* TODO: +//Modify OutBuffer::writewchar to write the correct size of wchar +#if _WIN32 +#define writewchar writeword +#else +//This needs a configuration test... +#define writewchar write4 +#endif + +#define INTERFACE_OFFSET 0 // if 1, put classinfo as first entry +//in interface vtbl[]'s +#define INTERFACE_VIRTUAL 0 // 1 means if an interface appears +//in the inheritance graph multiple +//times, only one is used +*/ \ No newline at end of file
--- a/dmd/ModExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/ModExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -40,11 +40,11 @@ return e; typeCombine(sc); - if (e1.op != TOKslice && e2.op != TOKslice) - { + if (!e1.isArrayOperand()) e1.checkArithmetic(); + if (!e2.isArrayOperand()) e2.checkArithmetic(); - } + if (type.isfloating()) { type = e1.type;
--- a/dmd/Module.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/Module.d Tue Aug 31 22:29:00 2010 +0200 @@ -401,35 +401,37 @@ override void toJsonBuffer(OutBuffer buf) { - buf.writestring("{\n"); + buf.writestring("{\n"); - JsonProperty(buf, Pname, md.toChars()); + if (md) + JsonProperty(buf, Pname, md.toChars()); - JsonProperty(buf, Pkind, kind()); + JsonProperty(buf, Pkind, kind()); - JsonProperty(buf, Pfile, srcfile.toChars()); + JsonProperty(buf, Pfile, srcfile.toChars()); - if (comment) - JsonProperty(buf, Pcomment, comment); + if (comment) + JsonProperty(buf, Pcomment, comment); - JsonString(buf, Pmembers); - 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); - } + size_t offset = buf.offset; + foreach (Dsymbol s; members) + { + if (offset != buf.offset) + { + buf.writestring(",\n"); + offset = buf.offset; + } + s.toJsonBuffer(buf); + } - buf.writestring("]\n"); + JsonRemoveComma(buf); + buf.writestring("]\n"); - buf.writestring("}\n"); - } + buf.writestring("}\n"); + } override string kind() { @@ -1227,6 +1229,7 @@ */ bool needModuleInfo() { + // writef("needModuleInfo() %s, %d, %d\n", toChars(), needmoduleinfo, global.params.cov); return needmoduleinfo || global.params.cov; }
--- a/dmd/MulExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/MulExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -46,11 +46,11 @@ return e; typeCombine(sc); - if (e1.op != TOKslice && e2.op != TOKslice) - { + if (!e1.isArrayOperand()) e1.checkArithmetic(); + if (!e2.isArrayOperand()) e2.checkArithmetic(); - } + if (type.isfloating()) { Type t1 = e1.type;
--- a/dmd/NegExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/NegExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -41,7 +41,7 @@ return e; e1.checkNoBool(); - if (e1.op != TOKslice) + if (!e1.isArrayOperand()) e1.checkArithmetic(); type = e1.type;
--- a/dmd/OrExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/OrExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -48,11 +48,10 @@ else { typeCombine(sc); - if (e1.op != TOK.TOKslice && e2.op != TOK.TOKslice) - { + if (!e1.isArrayOperand()) e1.checkIntegral(); + if (!e2.isArrayOperand()) e2.checkIntegral(); - } } }
--- a/dmd/OverExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/OverExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -7,6 +7,8 @@ import dmd.TOK; import dmd.Type; +//! overload set +version(DMDV2) class OverExp : Expression { OverloadSet vars; @@ -21,12 +23,12 @@ override int isLvalue() { - assert(false); + return true; } override Expression toLvalue(Scope sc, Expression e) { - assert(false); + return this; } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/PASS.d Tue Aug 31 22:29:00 2010 +0200 @@ -0,0 +1,20 @@ +/** + * + */ +module dmd.PASS; + +/* State of symbol in winding its way through the passes of the compiler + */ +enum PASS +{ + PASSinit, // initial state + PASSsemantic, // semantic() started + PASSsemanticdone, // semantic() done + PASSsemantic2, // semantic2() run + PASSsemantic3, // semantic3() started + PASSsemantic3done, // semantic3() done + PASSobj, // toObjFile() run +} + +import dmd.EnumUtils; +mixin(BringToCurrentScope!(PASS)); \ No newline at end of file
--- a/dmd/Parser.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/Parser.d Tue Aug 31 22:29:00 2010 +0200 @@ -2666,9 +2666,9 @@ } Identifier id = token.ident; if (id is Id.property) - (cast(TypeFunction)tf).ispure = 1; + (cast(TypeFunction)tf).isproperty = 1; else - error("valid attribute identifiers are property, not %s", id.toChars()); + error("valid attribute identifiers are @property, not @%s", id.toChars()); nextToken(); continue; default:
--- a/dmd/PostBlitDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/PostBlitDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -1,72 +1,103 @@ module dmd.PostBlitDeclaration; import dmd.FuncDeclaration; +import dmd.Global; +import dmd.LINK; +import dmd.LinkDeclaration; import dmd.Loc; import dmd.Identifier; import dmd.Dsymbol; import dmd.Scope; +import dmd.StructDeclaration; import dmd.OutBuffer; import dmd.HdrGenState; import dmd.STC; +import dmd.Type; +import dmd.TypeFunction; import dmd.Id; +version(DMDV2) class PostBlitDeclaration : FuncDeclaration { - this(Loc loc, Loc endloc) + this(Loc loc, Loc endloc) { super(loc, endloc, Id._postblit, STCundefined, null); } - this(Loc loc, Loc endloc, Identifier id) + this(Loc loc, Loc endloc, Identifier id) { - assert(false); - super(loc, loc, null, STC.init, null); + super(loc, loc, id, STCundefined, null); } - override Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol s) { - assert(false); + assert(!s); + PostBlitDeclaration dd = new PostBlitDeclaration(loc, endloc, ident); + return super.syntaxCopy(dd); } - override void semantic(Scope sc) + override void semantic(Scope sc) { - assert(false); + //writef("PostBlitDeclaration.semantic() %s\n", toChars()); + //writef("ident: %s, %s, %p, %p\n", ident.toChars(), Id.dtor.toChars(), ident, Id.dtor); + //writef("stc = x%llx\n", sc.stc); + parent = sc.parent; + Dsymbol parent = toParent(); + StructDeclaration ad = parent.isStructDeclaration(); + if (!ad) + { + error("post blits are only for struct/union definitions, not %s %s", parent.kind(), parent.toChars()); + } + else if (ident == Id._postblit && semanticRun < PASSsemantic) + ad.postblits.push(this); + + if (!type) + type = new TypeFunction(null, Type.tvoid, false, LINKd); + + sc = sc.push(); + sc.stc &= ~STCstatic; // not static + sc.linkage = LINKd; + + FuncDeclaration.semantic(sc); + + sc.pop(); } - override void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - assert(false); + buf.writestring("this(this)"); + bodyToCBuffer(buf, hgs); } - version(DMDV2) override void toJsonBuffer(OutBuffer buf) { + // intentionally empty } - override bool isVirtual() + override bool isVirtual() { - assert(false); + return false; } - override bool addPreInvariant() + override bool addPreInvariant() { - assert(false); + return false; } - override bool addPostInvariant() + override bool addPostInvariant() { - assert(false); + return (isThis() && vthis && global.params.useInvariants); } - override bool overloadInsert(Dsymbol s) + override bool overloadInsert(Dsymbol s) { - assert(false); + return false; // cannot overload postblits } - override void emitComment(Scope sc) + override void emitComment(Scope sc) { - assert(false); + // intentionally empty } - override PostBlitDeclaration isPostBlitDeclaration() { return this; } -} + override PostBlitDeclaration isPostBlitDeclaration() { return this; } +} \ No newline at end of file
--- a/dmd/PragmaDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/PragmaDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -63,7 +63,7 @@ writef("%s", se.toChars()[1..$-3] /*se.len, cast(char*)se.string_*/); } else - error("string expected for message, not '%s'", e.toChars()); + writef(e.toChars()); } writef("\n"); }
--- a/dmd/RemoveExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/RemoveExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -38,7 +38,7 @@ elem* ep; elem* keyti; - if (tybasic(ekey.Ety) == TYstruct) + if (tybasic(ekey.Ety) == TYstruct || tybasic(ekey.Ety) == TYarray) { ekey = el_una(OPstrpar, TYstruct, ekey); ekey.Enumbytes = ekey.E1.Enumbytes;
--- a/dmd/StaticCtorDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/StaticCtorDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -30,17 +30,19 @@ class StaticCtorDeclaration : FuncDeclaration { - this(Loc loc, Loc endloc) + this(Loc loc, Loc endloc) { super(loc, endloc, Identifier.generateId("_staticCtor"), STCstatic, null); } - override Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol s) { - assert(false); + assert(!s); + StaticCtorDeclaration scd = new StaticCtorDeclaration(loc, endloc); + return FuncDeclaration.syntaxCopy(scd); } - override void semantic(Scope sc) + override void semantic(Scope sc) { //printf("StaticCtorDeclaration.semantic()\n"); @@ -84,45 +86,51 @@ if (m) { m.needmoduleinfo = 1; + // writef("module1 %s needs moduleinfo\n", m.toChars()); version (IN_GCC) { m.strictlyneedmoduleinfo = 1; } } } - override AggregateDeclaration isThis() + override AggregateDeclaration isThis() { return null; } - override bool isStaticConstructor() + override bool isStaticConstructor() { return true; } - override bool isVirtual() + override bool isVirtual() { return false; } - override bool addPreInvariant() + override bool addPreInvariant() + { + return false; + } + + override bool addPostInvariant() { return false; } - override bool addPostInvariant() + override void emitComment(Scope sc) { - return false; } - override void emitComment(Scope sc) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - assert(false); - } - - override void toCBuffer(OutBuffer buf, HdrGenState* hgs) - { - assert(false); + if (hgs.hdrgen) + { + buf.writestring("static this();\n"); + return; + } + buf.writestring("static this()"); + bodyToCBuffer(buf, hgs); } override void toJsonBuffer(OutBuffer buf)
--- a/dmd/StaticDtorDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/StaticDtorDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -95,6 +95,7 @@ if (m) { m.needmoduleinfo = 1; + // writef("module2 %s needs moduleinfo\n", m.toChars()); version (IN_GCC) { m.strictlyneedmoduleinfo = 1; }
--- a/dmd/StringExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/StringExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -344,8 +344,6 @@ * will result in a copy. * The this.string member is considered immutable. */ - StringExp se; - Type tb; int copied = 0; //printf("StringExp.castTo(t = %s), '%s' committed = %d\n", t.toChars(), toChars(), committed); @@ -355,7 +353,7 @@ error("cannot convert string literal to void*"); } - se = this; + StringExp se = this; if (!committed) { se = cast(StringExp)copy(); @@ -368,7 +366,7 @@ return se; } - tb = t.toBasetype(); + Type tb = t.toBasetype(); //printf("\ttype = %s\n", type.toChars()); if (tb.ty == TY.Tdelegate && type.toBasetype().ty != TY.Tdelegate) return Expression.castTo(sc, t); @@ -832,13 +830,12 @@ } else if (tb.ty == TY.Tsarray) { - Symbol *si; dt_t *dt = null; toDt(&dt); dtnzeros(&dt, sz); // leave terminating 0 - si = symbol_generate(SC.SCstatic,type_allocn(TYM.TYarray, tschar)); + Symbol* si = symbol_generate(SC.SCstatic,type_allocn(TYM.TYarray, tschar)); si.Sdt = dt; si.Sfl = FL.FLdata; @@ -848,6 +845,7 @@ outdata(si); e = el_var(si); + e.Enumbytes = len * sz; } else if (tb.ty == TY.Tpointer) {
--- a/dmd/StructDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/StructDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -578,7 +578,7 @@ ea = new CastExp(Loc(0), ea, Type.tvoid.pointerTo()); Expression et = v.type.getTypeInfo(sc); - et = new DotIdExp(Loc(0), et, Id.postblit); + et = new DotIdExp(Loc(0), et, Id._postblit); ex = new CallExp(Loc(0), et, ea); } @@ -740,7 +740,8 @@ toDt(&sinit.Sdt); -version (OMFOBJ) { +version (OMFOBJ) +{ /* For OMF, common blocks aren't pulled in from the library. */ /* ELF comdef's generate multiple @@ -749,7 +750,8 @@ */ // See if we can convert a comdat to a comdef, // which saves on exe file space. - if (sinit.Sclass == SCcomdat && + if (0 && // causes multiple def problems with COMMON in one file and COMDAT in library + sinit.Sclass == SCcomdat && sinit.Sdt && sinit.Sdt.dt == DT.DT_azeros && sinit.Sdt.DTnext == null &&
--- a/dmd/StructLiteralExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/StructLiteralExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -20,6 +20,7 @@ import dmd.OutBuffer; import dmd.Loc; import dmd.Scope; +import dmd.Initializer; import dmd.InlineCostState; import dmd.IRState; import dmd.InlineDoState; @@ -138,7 +139,18 @@ { e = v.init.toExpression(); if (!e) + { error("cannot make expression out of initializer for %s", v.toChars()); + e = new ErrorExp(); + } + else if (v.scope_) + { + // Do deferred semantic anaylsis + Initializer i2 = v.init.syntaxCopy(); + i2 = i2.semantic(v.scope_, v.type); + e = i2.toExpression(); + v.scope_ = null; + } } else { @@ -154,6 +166,10 @@ return this; } + /************************************** + * Gets expression at offset of type. + * Returns null if not found. + */ Expression getField(Type type, uint offset) { //printf("StructLiteralExp.getField(this = %s, type = %s, offset = %u)\n",
--- a/dmd/SymOffExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/SymOffExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -229,5 +229,13 @@ Symbol* s = var.toSymbol(); return dtxoff(pdt, s, offset, TYnptr); } + +static if (false) +{ + override elem* toElem(IRState* irs) + { + assert(false); // this function is #if 0'ed out in dmd + } +} }
--- a/dmd/SymbolExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/SymbolExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -19,6 +19,7 @@ import dmd.backend.Util; import dmd.codegen.Util; +version(DMDV2) class SymbolExp : Expression { Declaration var; @@ -97,7 +98,7 @@ if (op == TOK.TOKvar) e = el_una(OPER.OPind, TYM.TYnptr, e); - if ((var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef()) + if (ISREF(var, tb)) e = el_una(OPER.OPind, s.ty(), e); else if (op == TOK.TOKsymoff && nrvo) { @@ -122,7 +123,7 @@ e.Enumbytes = cast(uint)type.size(); el_setLoc(e, loc); } - if ((var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef()) + if (ISREF(var, tb)) { e.Ety = TYM.TYnptr; e = el_una(OPER.OPind, s.ty(), e); @@ -150,7 +151,7 @@ e = el_var(var.toImport()); e = el_una(OPER.OPind,s.ty(),e); } - else if ((var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef()) + else if (ISREF(var, tb)) { // Static arrays are really passed as pointers to the array // Out parameters are really references
--- a/dmd/TemplateDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TemplateDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -388,11 +388,12 @@ foreach (Dsymbol s; members) { if (offset != buf.offset) - { buf.writestring(","); + { buf.writestring(",\n"); offset = buf.offset; } s.toJsonBuffer(buf); } + JsonRemoveComma(buf); buf.writestring("]\n"); buf.writestring("}\n");
--- a/dmd/TemplateInstance.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TemplateInstance.d Tue Aug 31 22:29:00 2010 +0200 @@ -1255,21 +1255,18 @@ else if (sa) { Lsa: - Declaration d = null; TemplateDeclaration td = sa.isTemplateDeclaration(); - if (td && td.literal) - { - goto L2; - } - d = sa.isDeclaration(); - if (d && !d.isDataseg() && -/// version (DMDV2) { + Declaration d = sa.isDeclaration(); + if ((td && td.literal) || + (d && !d.isDataseg() && + +/// version (DMDV2) { // TODO: !(d.storage_class & STCmanifest) && /// } (!d.isFuncDeclaration() || d.isFuncDeclaration().isNested()) && - !isTemplateMixin()) + !isTemplateMixin() + )) { - L2: // if module level template if (tempdecl.toParent().isModule()) { @@ -1321,13 +1318,11 @@ Identifier genIdent() { scope OutBuffer buf = new OutBuffer(); - string id; - Objects args; //printf("TemplateInstance.genIdent('%s')\n", tempdecl.ident.toChars()); - id = tempdecl.ident.toChars(); + string id = tempdecl.ident.toChars(); buf.printf("__T%d%s", id.length, id); ///! - args = tiargs; + Objects args = tiargs; for (int i = 0; i < args.dim; i++) { Object o = cast(Object)args.data[i];
--- a/dmd/TemplateMixin.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TemplateMixin.d Tue Aug 31 22:29:00 2010 +0200 @@ -70,15 +70,20 @@ printf("+TemplateMixin.semantic('%s', this=%p)\n", toChars(), this); fflush(stdout); } - if (semanticRun && - // This for when a class/struct contains mixin members, and - // is done over because of forward references - (!parent || !toParent().isAggregateDeclaration())) + if (semanticRun) { - version (LOG) { - printf("\tsemantic done\n"); + // This for when a class/struct contains mixin members, and + // is done over because of forward references + if (parent && toParent().isAggregateDeclaration()) + semanticRun = 1; // do over + else + { +version (LOG) +{ + writef("\tsemantic done\n"); +} + return; } - return; } if (!semanticRun) semanticRun = 1;
--- a/dmd/TraitsExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TraitsExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -380,9 +380,11 @@ Dsymbol s1 = getDsymbol(o1); Dsymbol s2 = getDsymbol(o2); - static if (0) { - printf("o1: %p\n", o1); - printf("o2: %p\n", o2); + // writef("isSame: %s, %s\n", o1.toChars(), o2.toChars()); + static if (0) + { + writef("o1: %p\n", o1); + writef("o2: %p\n", o2); if (!s1) { Expression ea = isExpression(o1); if (ea)
--- a/dmd/TupleDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TupleDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -69,22 +69,28 @@ Arguments args = new Arguments(); args.setDim(objects.dim); OutBuffer buf = new OutBuffer(); + bool hasdeco = 1; for (size_t i = 0; i < objects.dim; i++) { Type t = cast(Type)objects.data[i]; //printf("type = %s\n", t->toChars()); - static if (0) { +static if (false) +{ buf.printf("_%s_%d", ident.toChars(), i); char *name = cast(char *)buf.extractData(); Identifier id = new Identifier(name, TOKidentifier); Argument arg = new Argument(STCin, t, id, null); - } else { +} else { Argument arg = new Argument(STCundefined, t, null, null); - } +} args.data[i] = cast(void *)arg; + if (!t.deco) + hasdeco = false; } tupletype = new TypeTuple(args); + if (hasdeco) + return tupletype.semantic(Loc(0), null); } return tupletype;
--- a/dmd/Type.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/Type.d Tue Aug 31 22:29:00 2010 +0200 @@ -128,7 +128,8 @@ /* pick this order of numbers so switch statements work better */ /// #define MODconst 1 // type is const -/// #define MODinvariant 4 // type is invariant +/// #define MODinvariant 4 // type is immutable +/// #define MODimmutable 4 // type is immutable /// #define MODshared 2 // type is shared string deco; @@ -396,6 +397,7 @@ DYNCAST dyncast() { return DYNCAST.DYNCAST_TYPE; } // kludge for template.isType() /******************************* + * Covariant means that 'this' can substitute for 't'. * Returns: * 0 types are distinct * 1 this is covariant with t @@ -445,6 +447,7 @@ { ///static if (false) { /// // turn on this for contravariant argument types, see bugzilla 3075 +/// // BUG: cannot convert ref to const to ref to immutable /// // We can add const, but not subtract it /// if (arg2.type.implicitConvTo(arg1.type) < MATCH.MATCHconst) ///} @@ -648,6 +651,7 @@ basic[TY.Terror] = basic[TY.Tint32]; tvoidptr = tvoid.pointerTo(); + tstring = tchar.invariantOf().arrayOf(); if (global.params.isX86_64) { PTRSIZE = 8; @@ -945,21 +949,6 @@ */ Type constOf() { -static if (false) { - //printf("Type.constOf() %p %s\n", this, toChars()); - if (isConst()) - return this; - if (cto) - return cto; - Type t = makeConst(); - t = t.merge(); - cto = t; - if (ito) - ito.cto = t; - //if (t.nextOf()) assert(t.nextOf().isConst()); - //printf("-Type.constOf() %p %s\n", t, toChars()); - return t; -} else { //printf("Type.constOf() %p %s\n", this, toChars()); if (mod == MOD.MODconst) return this; @@ -973,7 +962,6 @@ t.fixTo(this); //printf("-Type.constOf() %p %s\n", t, toChars()); return t; -} } /******************************** @@ -981,32 +969,6 @@ */ Type invariantOf() { -static if (false) { - //printf("Type.invariantOf() %p %s\n", this, toChars()); - if (isInvariant()) - { - return this; - } - if (ito) - { - //if (!ito.isInvariant()) printf("\tito is %p %s\n", ito, ito.toChars()); - assert(ito.isInvariant()); - return ito; - } - Type t = makeInvariant(); - t = t.merge(); - ito = t; - if (cto) - cto.ito = t; -static if (false) {// fails for function types - if (t.nextOf() && !t.nextOf().isInvariant()) - { - assert(0); - } -} - //printf("\t%p\n", t); - return t; -} else { //printf("Type.invariantOf() %p %s\n", this, toChars()); if (isInvariant()) { @@ -1022,60 +984,10 @@ t.fixTo(this); //printf("\t%p\n", t); return t; -} } Type mutableOf() { - static if (false) { - //printf("Type.mutableOf() %p, %s\n", this, toChars()); - Type t = this; - if (isConst()) - { - t = cto; - assert(!t || t.isMutable()); - } - else if (isInvariant()) - { - t = ito; - assert(!t || t.isMutable()); - } - if (!t) - { - uint sz = this.classinfo.init.length; - t = cast(Type)GC.malloc(sz); - memcpy(cast(void*)t, cast(void*)this, sz); - t.mod = 0; - t.deco = null; - t.arrayof = null; - t.pto = null; - t.rto = null; - t.cto = null; - t.ito = null; - t.sto = null; - t.scto = null; - t.vtinfo = null; - if (ty == Tsarray) - { - TypeSArray ta = cast(TypeSArray)t; - //ta.next = ta.next.mutableOf(); - } - t = t.merge(); - if (isConst()) - { cto = t; - t.cto = this; - if (ito) - ito.cto = this; - } - else if (isInvariant()) - { ito = t; - t.ito = this; - if (cto) - cto.ito = this; - } - } - return t; - } else { //printf("Type.mutableOf() %p, %s\n", this, toChars()); Type t = this; if (isConst()) @@ -1096,7 +1008,7 @@ uint sz = this.classinfo.init.length; t = cast(Type)GC.malloc(sz); memcpy(cast(void*)t, cast(void*)this, sz); - t.mod = MODundefined; + t.mod = mod & MODshared; t.deco = null; t.arrayof = null; t.pto = null; @@ -1120,10 +1032,6 @@ t.ito = this; break; - case MODshared: - t.sto = this; - break; - case MODshared | MODconst: t.scto = this; break; @@ -1134,7 +1042,6 @@ } return t; } - } Type sharedOf() { @@ -1177,7 +1084,61 @@ return t; } + + /******************************** + * Make type unshared. + */ + Type unSharedOf() + { + //writef("Type::unSharedOf() %p, %s\n", this, toChars()); + Type t = this; + + if (isShared()) + { + if (isConst()) + t = cto; // shared const => const + else + t = sto; + assert(!t || !t.isShared()); + } + + if (!t) + { + uint sz = this.classinfo.init.length; + t = cast(Type)GC.malloc(sz); + memcpy(cast(void*)t, cast(void*)this, sz); + t.mod = mod & ~MODshared; + t.deco = null; + t.arrayof = null; + t.pto = null; + t.rto = null; + t.cto = null; + t.ito = null; + t.sto = null; + t.scto = null; + t.vtinfo = null; + t = t.merge(); + t.fixTo(this); + + switch (mod) + { + case MODshared: + t.sto = this; + break; + + case MODshared | MODconst: + t.scto = this; + break; + + default: + assert(0); + } + } + assert(!t.isShared()); + return t; + } + static uint X(MOD m, MOD n) { return (((m) << 3) | (n)); @@ -1905,7 +1866,8 @@ */ MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { - static if (false) { + static if (false) + { printf("Type.deduceType()\n"); printf("\tthis = %d, ", ty); print(); printf("\ttparam = %d, ", tparam.ty); tparam.print(); @@ -1950,42 +1912,95 @@ Type tt = this; Type at = cast(Type)dedtypes.data[i]; - // 3*3 == 9 cases - if (tparam.isMutable()) - { // foo(U:U) T => T - // foo(U:U) const(T) => const(T) - // foo(U:U) invariant(T) => invariant(T) + // 5*5 == 25 cases + static pure int X(int U, int T) { return ((U << 3) | T); } + + switch (X(tparam.mod, mod)) + { + case X(0, 0): + case X(0, MODconst): + case X(0, MODinvariant): + case X(0, MODshared): + case X(0, MODconst | MODshared): + // foo(U:U) T => T + // foo(U:U) const(T) => const(T) + // foo(U:U) immutable(T) => immutable(T) + // foo(U:U) shared(T) => shared(T) + // foo(U:U) const(shared(T)) => const(shared(T)) if (!at) - { - dedtypes[i] = this; + { dedtypes[i] = tt; goto Lexact; } - } - else if (mod == tparam.mod) - { // foo(U:const(U)) const(T) => T - // foo(U:invariant(U)) invariant(T) => T - tt = mutableOf(); + break; + + case X(MODconst, MODconst): + case X(MODinvariant, MODinvariant): + case X(MODshared, MODshared): + case X(MODconst | MODshared, MODconst | MODshared): + // foo(U:const(U)) const(T) => T + // foo(U:immutable(U)) immutable(T) => T + // foo(U:shared(U)) shared(T) => T + // foo(U:const(shared(U)) const(shared(T))=> T + tt = mutableOf().unSharedOf(); if (!at) - { + { dedtypes[i] = tt; goto Lexact; } - } - else if (tparam.isConst()) - { // foo(U:const(U)) T => T - // foo(U:const(U)) invariant(T) => T + break; + + case X(MODconst, 0): + case X(MODconst, MODimmutable): + case X(MODconst, MODconst | MODshared): + case X(MODconst | MODshared, MODimmutable): + // foo(U:const(U)) T => T + // foo(U:const(U)) immutable(T) => T + // foo(U:const(U)) const(shared(T)) => shared(T) + // foo(U:const(shared(U)) immutable(T) => T tt = mutableOf(); if (!at) - { - dedtypes[i] = tt; + { dedtypes[i] = tt; + goto Lconst; + } + break; + + case X(MODshared, MODconst | MODshared): + case X(MODconst | MODshared, MODshared): + // foo(U:shared(U)) const(shared(T)) => const(T) + // foo(U:const(shared(U)) shared(T) => T + tt = unSharedOf(); + if (!at) + { dedtypes[i] = tt; goto Lconst; } - } - else - { // foo(U:invariant(U)) T => nomatch - // foo(U:invariant(U)) const(T) => nomatch - if (!at) + break; + + case X(MODimmutable, 0): + case X(MODimmutable, MODconst): + case X(MODimmutable, MODshared): + case X(MODimmutable, MODconst | MODshared): + case X(MODconst, MODshared): + case X(MODshared, 0): + case X(MODshared, MODconst): + case X(MODshared, MODimmutable): + case X(MODconst | MODshared, 0): + case X(MODconst | MODshared, MODconst): + // foo(U:immutable(U)) T => nomatch + // foo(U:immutable(U)) const(T) => nomatch + // foo(U:immutable(U)) shared(T) => nomatch + // foo(U:immutable(U)) const(shared(T)) => nomatch + // foo(U:const(U)) shared(T) => nomatch + // foo(U:shared(U)) T => nomatch + // foo(U:shared(U)) const(T) => nomatch + // foo(U:shared(U)) immutable(T) => nomatch + // foo(U:const(shared(U)) T => nomatch + // foo(U:const(shared(U)) const(T) => nomatch + //if (!at) goto Lnomatch; + break; + + default: + assert(0); } if (tt.equals(at)) @@ -2271,7 +2286,10 @@ case TY.Tpointer: t = TYM.TYnptr; break; case TY.Tdelegate: t = TYM.TYdelegate; break; case TY.Tarray: t = TYM.TYdarray; break; - case TY.Tsarray: t = TYM.TYarray; break; +version(SARRAYVALUE) +{ case TY.Tsarray: t = TYstruct; break;} +else +{ case TY.Tsarray: t = TYM.TYarray; break;} case TY.Tstruct: t = TYM.TYstruct; break; case TY.Tenum: @@ -2484,7 +2502,8 @@ } static Type tvoidptr; // void* - + static Type tstring; // immutable(char)[] + static Type terror() { return basic[TY.Terror]; // for error recovery
--- a/dmd/TypeAArray.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TypeAArray.d Tue Aug 31 22:29:00 2010 +0200 @@ -7,6 +7,7 @@ import dmd.TypeInfoAssociativeArrayDeclaration; import dmd.Expression; import dmd.Scope; +import dmd.StructDeclaration; import dmd.Loc; import dmd.Global; import dmd.Dsymbol; @@ -17,6 +18,7 @@ import dmd.Identifier; import dmd.MATCH; import dmd.TY; +import dmd.TemplateInstance; import dmd.Id; import dmd.CallExp; import dmd.IntegerExp; @@ -42,7 +44,10 @@ import core.memory; class TypeAArray : TypeArray { - Type index; // key type + Type index; // key type + Loc loc; + Scope sc; + StructDeclaration impl; // implementation this(Type t, Type index) { @@ -79,7 +84,11 @@ override Type semantic(Loc loc, Scope sc) { //printf("TypeAArray::semantic() %s index.ty = %d\n", toChars(), index.ty); - + this.loc = loc; + this.sc = sc; + if (sc) + sc.setNoFree(); + // Deal with the case where we thought the index was a type, but // in reality it was an expression. if (index.ty == Tident || index.ty == Tinstance || index.ty == Tsarray) @@ -98,7 +107,10 @@ else if (t) index = t; else + { index.error(loc, "index is not a type or an expression"); + return Type.terror; + } } else index = index.semantic(loc,sc); @@ -106,7 +118,8 @@ if (index.nextOf() && !index.nextOf().isInvariant()) { index = index.constOf().mutableOf(); -static if (false) { +static if (false) +{ printf("index is %p %s\n", index, index.toChars()); index.check(); printf("index.mod = x%x\n", index.mod); @@ -126,7 +139,7 @@ case Tnone: case Ttuple: error(loc, "can't have associative array key of %s", index.toBasetype().toChars()); - break; + return Type.terror; default: break; /// } @@ -138,16 +151,54 @@ case Tfunction: case Tnone: error(loc, "can't have associative array of %s", next.toChars()); - break; + return Type.terror; default: break; /// } if (next.isauto()) + { error(loc, "cannot have array of auto %s", next.toChars()); - + return Type.terror; + } return merge(); } + StructDeclaration getImpl() + { + // Do it lazily + if (!impl) + { + if (!index.reliesOnTident() && !next.reliesOnTident()) + { + /* This is really a proxy for the template instance AssocArray!(index, next) + * But the instantiation can fail if it is a template specialization field + * which has Tident's instead of real types. + */ + TemplateInstance ti = new TemplateInstance(loc, Id.AssociativeArray); + Objects tiargs = new Objects(); + tiargs.push(cast(void*)index); + tiargs.push(cast(void*)next); + ti.tiargs = tiargs; + + ti.semantic(sc); + ti.semantic2(sc); + ti.semantic3(sc); + impl = ti.toAlias().isStructDeclaration(); +debug +{ + if (!impl) + { + Dsymbol s = ti.toAlias(); + writef("%s %s\n", s.kind(), s.toChars()); + } +} + assert(impl); + } + } + return impl; + + } + override void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) { //printf("TypeAArray.resolve() %s\n", toChars()); @@ -201,6 +252,8 @@ version (LOGDOTEXP) { printf("TypeAArray.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars()); } +static if (false) +{ if (ident == Id.length) { Expression ec; @@ -261,9 +314,12 @@ e = new CallExp(e.loc, ec, arguments); e.type = this; } - else +// else +} // of static if (false) { - e = Type.dotExp(sc, e, ident); + e.type = getImpl().type; + e = e.type.dotExp(sc, e, ident); + //e = Type.dotExp(sc, e, ident); } return e; }
--- a/dmd/TypeBasic.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TypeBasic.d Tue Aug 31 22:29:00 2010 +0200 @@ -282,6 +282,24 @@ case TY.Tdchar: ivalue = dchar.min; goto Livalue; case TY.Tcomplex32: case TY.Timaginary32: + case Tfloat32: + case Tcomplex64: + case Timaginary64: + case Tfloat64: + case Tcomplex80: + case Timaginary80: + case Tfloat80: + // For backwards compatibility - eventually, deprecate + goto Lmin_normal; + } + } + else if (ident == Id.min_normal) + { + Lmin_normal: + switch (ty) + { + case Tcomplex32: + case Timaginary32: case TY.Tfloat32: fvalue = float.min; goto Lfvalue; case TY.Tcomplex64: case TY.Timaginary64: @@ -450,7 +468,7 @@ cvalue.im = fvalue; //for (int i = 0; i < 20; i++) - // printf("%02x ", ((unsigned char *)&cvalue)[i]); + // printf("%02x ", ((unsigned char *)&cvalue)[i]); //printf("\n"); e = new ComplexExp(loc, cvalue, this); }
--- a/dmd/TypeDArray.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TypeDArray.d Tue Aug 31 22:29:00 2010 +0200 @@ -119,15 +119,20 @@ next.toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); } - override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override 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("[]"); + if (equals(tstring)) + buf.writestring("string"); + else + { + next.toCBuffer2(buf, hgs, this.mod); + buf.writestring("[]"); + } } override Expression dotExp(Scope sc, Expression e, Identifier ident)
--- a/dmd/TypeDelegate.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TypeDelegate.d Tue Aug 31 22:29:00 2010 +0200 @@ -8,6 +8,7 @@ import dmd.AddExp; import dmd.PtrExp; import dmd.IntegerExp; +import dmd.MATCH; import dmd.NullExp; import dmd.TypeFunction; import dmd.HdrGenState; @@ -77,6 +78,21 @@ return PTRSIZE * 2; } + MATCH implicitConvTo(Type to) + { + //writef("TypeDelegate::implicitConvTo(this=%p, to=%p)\n", this, to); + //writef("from: %s\n", toChars()); + //writef("to : %s\n", to.toChars()); + if (this == to) + return MATCHexact; +static if (false) // not allowing covariant conversions because it interferes with overriding +{ + if (to.ty == Tdelegate && this.nextOf().covariant(to.nextOf()) == 1) + return MATCHconvert; +} + return MATCHnomatch; + } + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { if (mod != this.mod)
--- a/dmd/TypeFunction.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TypeFunction.d Tue Aug 31 22:29:00 2010 +0200 @@ -142,10 +142,13 @@ if (tf.next) { tf.next = tf.next.semantic(loc,sc); +version(SARRAYVALUE) {} else +{ if (tf.next.toBasetype().ty == TY.Tsarray) { error(loc, "functions cannot return static array %s", tf.next.toChars()); tf.next = Type.terror; } +} if (tf.next.toBasetype().ty == TY.Tfunction) { error(loc, "functions cannot return a function"); tf.next = Type.terror; @@ -187,10 +190,10 @@ if (arg.storageClass & (STC.STCout | STC.STCref | STC.STClazy)) { - if (t.ty == TY.Tsarray) - error(loc, "cannot have out or ref parameter of type %s", t.toChars()); - if (arg.storageClass & STC.STCout && arg.type.mod) - error(loc, "cannot have const/invariant out parameter of type %s", t.toChars()); + //if (t.ty == TY.Tsarray) + //error(loc, "cannot have out or ref parameter of type %s", t.toChars()); + if (arg.storageClass & STC.STCout && arg.type.mod & (STCconst | STCimmutable)) + error(loc, "cannot have const or immutabl out parameter of type %s", t.toChars()); } if (!(arg.storageClass & STC.STClazy) && t.ty == TY.Tvoid) error(loc, "cannot have parameter of type %s", arg.type.toChars()); @@ -511,10 +514,30 @@ arg = cast(Expression)args.data[u]; assert(arg); + // writef("arg: %s, type: %s\n", arg.toChars(), arg.type.toChars()); + // Non-lvalues do not match ref or out parameters - if (p.storageClass & (STC.STCref | STC.STCout) && !arg.isLvalue()) - goto Nomatch; + if (p.storageClass & (STC.STCref | STC.STCout)) + { + if (!arg.isLvalue()) + goto Nomatch; + } + + if (p.storageClass & STCref) + { + /* Don't allow static arrays to be passed to mutable refereces + * to static arrays if the argument cannot be modified. + */ + Type targb = arg.type.toBasetype(); + Type tparb = p.type.toBasetype(); + //writef("%s\n", targb.toChars()); + //writef("%s\n", tparb.toChars()); + if (targb.nextOf() && tparb.ty == Tsarray && + targb.nextOf().mod != tparb.nextOf().mod && + !tparb.nextOf().isConst()) + goto Nomatch; + } if (p.storageClass & STC.STClazy && p.type.ty == TY.Tvoid && arg.type.ty != TY.Tvoid) m = MATCH.MATCHconvert; @@ -605,7 +628,7 @@ return MATCH.MATCHnomatch; } - override type* toCtype() + override type* toCtype() { if (ctype) { return ctype; @@ -650,30 +673,62 @@ * Determine return style of function - whether in registers or * through a hidden pointer to the caller's stack. */ - RET retStyle() + RET retStyle() { //printf("TypeFunction.retStyle() %s\n", toChars()); -version (DMDV2) { +version (DMDV2) +{ if (isref) return RET.RETregs; // returns a pointer } Type tn = next.toBasetype(); + Type tns = tn; + ulong sz = tn.size(); - if (tn.ty == TY.Tstruct) +version(SARRAYVALUE) +{ + if (tn.ty == Tsarray) + { + do + { + tns = tns.nextOf().toBasetype(); + } while (tns.ty == Tsarray); + if (tns.ty != Tstruct) + { + if (global.params.isLinux && linkage != LINKd) + {} + else + { + switch (sz) + { case 1: + case 2: + case 4: + case 8: + return RET.RETregs; // return small structs in regs + // (not 3 byte structs!) + default: + break; + } + } + return RET.RETstack; + } + } +} + if (tns.ty == TY.Tstruct) { StructDeclaration sd = (cast(TypeStruct)tn).sym; if (global.params.isLinux && linkage != LINK.LINKd) { ; } -///version (DMDV2) { - else if (sd.dtor || sd.cpctor) { - ; +///version (DMDV2) { // TODO: + else if (sd.dtor || sd.cpctor) + { } ///} else { - switch (cast(int)tn.size()) + switch (sz) { case 1: case 2:
--- a/dmd/TypeInfoAssociativeArrayDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TypeInfoAssociativeArrayDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -31,6 +31,9 @@ tc.index.getTypeInfo(null); dtxoff(pdt, tc.index.vtinfo.toSymbol(), 0, TYnptr); // TypeInfo for array of type + + tc.getImpl().type.getTypeInfo(null); + dtxoff(pdt, tc.getImpl().type.vtinfo.toSymbol(), 0, TYnptr); // impl } }
--- a/dmd/TypeInfoSharedDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TypeInfoSharedDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -3,18 +3,26 @@ import dmd.Type; import dmd.TypeInfoDeclaration; import dmd.backend.dt_t; +import dmd.backend.Util; +import dmd.backend.TYM; +version(DMDV2) class TypeInfoSharedDeclaration : TypeInfoDeclaration { this(Type tinfo) { super(tinfo, 0); - type = Type.typeinfoshared.type; + type = Type.typeinfoshared.type; } override void toDt(dt_t** pdt) { - assert(false); + // writef("TypeInfoSharedDeclaration::toDt() %s\n", toChars()); + dtxoff(pdt, Type.typeinfoshared.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Shared + dtdword(pdt, 0); // monitor + Type tm = tinfo.unSharedOf(); + tm = tm.merge(); + tm.getTypeInfo(null); + dtxoff(pdt, tm.vtinfo.toSymbol(), 0, TYnptr); } -} - +} \ No newline at end of file
--- a/dmd/TypeNext.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TypeNext.d Tue Aug 31 22:29:00 2010 +0200 @@ -1,6 +1,7 @@ module dmd.TypeNext; import dmd.Type; +import dmd.TypeAArray; import dmd.TY; import dmd.OutBuffer; import dmd.Loc; @@ -75,7 +76,11 @@ else t.next = next.constOf(); } - //printf("TypeNext::makeConst() returns %p, %s\n", t, t.toChars()); + if (ty == Taarray) + { + (cast(TypeAArray)t).impl = null; // lazily recompute it + } + //writef("TypeNext::makeConst() returns %p, %s\n", t, t.toChars()); return t; } @@ -92,6 +97,10 @@ { t.next = next.invariantOf(); } + if (ty == Taarray) + { + (cast(TypeAArray)t).impl = null; // lazily recompute it + } return t; } @@ -113,17 +122,38 @@ else t.next = next.sharedOf(); } - - //printf("TypeNext::makeShared() returns %p, %s\n", t, t.toChars()); + if (ty == Taarray) + { + (cast(TypeAArray)t).impl = null; // lazily recompute it + } + //writef("TypeNext::makeShared() returns %p, %s\n", t, t.toChars()); return t; } - override Type makeSharedConst() + override Type makeSharedConst() { - assert(false); + //printf("TypeNext::makeSharedConst() %s\n", toChars()); + if (scto) + { + assert(scto.mod == (MODshared | MODconst)); + return scto; + } + TypeNext t = cast(TypeNext) Type.makeSharedConst(); + if (ty != Tfunction && ty != Tdelegate && + (next.deco || next.ty == Tfunction) && + !next.isInvariant() && !next.isSharedConst()) + { + t.next = next.sharedConstOf(); + } + if (ty == Taarray) + { + (cast(TypeAArray)t).impl = null; // lazily recompute it + } +// writef("TypeNext::makeSharedConst() returns %p, %s\n", t, t.toChars()); + return t; } - override MATCH constConv(Type to) + override MATCH constConv(Type to) { MATCH m = Type.constConv(to); @@ -132,7 +162,7 @@ return m; } - void transitive() + void transitive() { /* Invoke transitivity of type attributes */
--- a/dmd/TypeSArray.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TypeSArray.d Tue Aug 31 22:29:00 2010 +0200 @@ -617,7 +617,14 @@ override type* toCParamtype() { +version(SARRAYVALUE) +{ + return toCtype(); +} +else +{ // arrays are passed as pointers return next.pointerTo().toCtype(); +} } }
--- a/dmd/TypeTuple.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TypeTuple.d Tue Aug 31 22:29:00 2010 +0200 @@ -81,7 +81,7 @@ override Type semantic(Loc loc, Scope sc) { //printf("TypeTuple::semantic(this = %p)\n", this); - //printf("TypeTuple::semantic() %s\n", toChars()); + //printf("TypeTuple::semantic() %p, %s\n", this, toChars()); if (!deco) deco = merge().deco;
--- a/dmd/TypeTypeof.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/TypeTypeof.d Tue Aug 31 22:29:00 2010 +0200 @@ -1,5 +1,6 @@ module dmd.TypeTypeof; +import dmd.TypeFunction; import dmd.TypeQualified; import dmd.Expression; import dmd.Identifier; @@ -123,6 +124,9 @@ { sc.intypeof++; exp = exp.semantic(sc); + if (exp.type && exp.type.ty == Tfunction && + (cast(TypeFunction)exp.type).isproperty) + exp = resolveProperties(sc, exp); sc.intypeof--; if (exp.op == TOK.TOKtype) {
--- a/dmd/UnitTestDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/UnitTestDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -53,14 +53,21 @@ sc2.pop(); } +static if (false) +{ // We're going to need ModuleInfo even if the unit tests are not // compiled in, because other modules may import this module and refer // to this ModuleInfo. + // (This doesn't make sense to me?) Module m = getModule(); if (!m) m = sc.module_; if (m) + { + // writef("module3 %s needs moduleinfo\n", m.toChars()); m.needmoduleinfo = 1; + } +} } override AggregateDeclaration isThis()
--- a/dmd/VarDeclaration.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/VarDeclaration.d Tue Aug 31 22:29:00 2010 +0200 @@ -74,7 +74,8 @@ uint offset; bool noauto; // no auto semantics version (DMDV2) { - FuncDeclarations nestedrefs; // referenced by these lexically nested functions + FuncDeclarations nestedrefs; // referenced by these lexically nested functions + bool isargptr = false; // if parameter that _argptr points to } else { int nestedref; // referenced by a lexically nested function } @@ -95,7 +96,8 @@ { super(id); -debug { +debug +{ if (!type && !init) { writef("VarDeclaration('%s')\n", id.toChars()); @@ -105,8 +107,24 @@ assert(type || init); this.type = type; this.init = init; +version(_DH) +{ + this.htype = null; + this.hinit = null; +} this.loc = loc; + /* TODO: + #if DMDV1 + nestedref = 0; + #endif + ctorinit = 0; + aliassym = NULL; + onstack = 0; + canassign = 0; + value = NULL; + rundtor = NULL; + */ nestedrefs = new FuncDeclarations(); } @@ -521,10 +539,12 @@ else if (t.ty == TY.Tstruct) { ei.exp = ei.exp.semantic(sc); -version (DMDV2) { + ei.exp = resolveProperties(sc, ei.exp); + StructDeclaration sd = (cast(TypeStruct)t).sym; +version (DMDV2) +{ /* Look to see if initializer is a call to the constructor */ - StructDeclaration sd = (cast(TypeStruct)t).sym; if (sd.ctor && // there are constructors ei.exp.type.ty == TY.Tstruct && // rvalue is the same struct (cast(TypeStruct)ei.exp.type).sym == sd && @@ -562,10 +582,22 @@ } if (!ei.exp.implicitConvTo(type)) { + Type ti = ei.exp.type.toBasetype(); + // Look for constructor first + if (sd.ctor && + /* Initializing with the same type is done differently + */ + !(ti.ty == Tstruct && t.toDsymbol(sc) == ti.toDsymbol(sc))) + { + // Rewrite as e1.ctor(arguments) + Expression ector = new DotIdExp(loc, e1, Id.ctor); + ei.exp = new CallExp(loc, ector, ei.exp); + } + else /* Look for opCall * See bugzilla 2702 for more discussion */ - Type ti = ei.exp.type.toBasetype(); + // Don't cast away invariant or mutability in initializer if (search_function(sd, Id.call) && /* Initializing with the same type is done differently @@ -590,7 +622,8 @@ } } else if (storage_class & (STC.STCconst | STC.STCimmutable | STC.STCmanifest) || - type.isConst() || type.isInvariant()) + type.isConst() || type.isInvariant() || + parent.isAggregateDeclaration()) { /* Because we may need the results of a const declaration in a * subsequent type, such as an array dimension, before semantic2()
--- a/dmd/VarExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/VarExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -22,8 +22,7 @@ import dmd.backend.dt_t; import dmd.expression.Util; -// Variable - +//! Variable class VarExp : SymbolExp { this(Loc loc, Declaration var, bool hasOverloads = false) @@ -188,7 +187,8 @@ } } -version (DMDV2) { +version (DMDV2) +{ override int isLvalue() { if (var.storage_class & STClazy) @@ -216,8 +216,8 @@ override Expression modifiableLvalue(Scope sc, Expression e) { //printf("VarExp::modifiableLvalue('%s')\n", var.toChars()); - if (type && type.toBasetype().ty == TY.Tsarray) - error("cannot change reference to static array '%s'", var.toChars()); + //if (type && type.toBasetype().ty == TY.Tsarray) + // error("cannot change reference to static array '%s'", var.toChars()); var.checkModify(loc, sc, type); @@ -230,6 +230,12 @@ assert(false); } + version(DMDV1) + override elem* toElem(IRState* irs) + { + assert(false); + } + override void scanForNestedRef(Scope sc) { //printf("VarExp.scanForNestedRef(%s)\n", toChars());
--- a/dmd/VersionCondition.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/VersionCondition.d Tue Aug 31 22:29:00 2010 +0200 @@ -44,7 +44,8 @@ static void checkPredefined(Loc loc, string ident) { -version (DMDV2) { +version (DMDV2) +{ static string[] reserved = [ "DigitalMars", "X86", "X86_64", "Windows", "Win32", "Win64",
--- a/dmd/XorExp.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/XorExp.d Tue Aug 31 22:29:00 2010 +0200 @@ -47,11 +47,10 @@ else { typeCombine(sc); - if (e1.op != TOKslice && e2.op != TOKslice) - { + if (!e1.isArrayOperand()) e1.checkIntegral(); + if (!e2.isArrayOperand()) e2.checkIntegral(); - } } } return this;
--- a/dmd/codegen/Util.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/codegen/Util.d Tue Aug 31 22:29:00 2010 +0200 @@ -5,6 +5,7 @@ import dmd.IRState; import dmd.Type; import dmd.Array; +import dmd.Declaration; import dmd.Dsymbol; import dmd.FuncDeclaration; import dmd.Identifier; @@ -60,10 +61,21 @@ import core.memory; + +/* If variable var of type typ is a reference + */ +version(SARRAYVALUE) +{ + bool ISREF(Declaration var, Type tb) {return var.isOut() || var.isRef();} +} +else + bool ISREF(Declaration var, Type tb) {return (var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef();} + + + /************************************ * Call a function. */ - elem* callfunc(Loc loc, IRState* irs, int directcall, // 1: don't do virtual call @@ -126,13 +138,11 @@ // j=1 if _arguments[] is first argument int j = (tf.linkage == LINK.LINKd && tf.varargs == 1); - for (i = 0; i < arguments.dim ; i++) + foreach (size_t i, Expression arg; arguments) { - Expression arg; elem* ea; - arg = cast(Expression)arguments.data[i]; - //printf("\targ[%d]: %s\n", i, arg.toChars()); + //writef("\targ[%d]: %s\n", i, arg.toChars()); size_t nparams = Argument.dim(tf.parameters); if (i - j < nparams && i >= j) @@ -150,11 +160,11 @@ } ea = arg.toElem(irs); L1: - if (tybasic(ea.Ety) == TYM.TYstruct) + if (tybasic(ea.Ety) == TYM.TYstruct || tybasic(ea.Ety) == TYarray) { ea = el_una(OPER.OPstrpar, TYM.TYstruct, ea); ea.Enumbytes = ea.E1.Enumbytes; - assert(ea.Enumbytes); + //assert(ea.Enumbytes); } if (reverse) ep = el_param(ep,ea); @@ -170,10 +180,12 @@ // Don't have one, so create one type* tt; - if (tf.next.toBasetype().ty == TY.Tstruct) - tt = tf.next.toCtype(); + Type tret2 = tf.next; // in dmd tret is shadowed here, so -> tret2 + if (tret2.toBasetype().ty == Tstruct || + tret2.toBasetype().ty == Tsarray) + tt = tret2.toCtype(); else - tt = type_fake(tf.next.totym()); + tt = type_fake(tret2.totym()); Symbol* stmp = symbol_genauto(tt); ehidden = el_ptr(stmp); @@ -284,9 +296,9 @@ e = el_una(op,tyret,ep); } else if (ep) - e = el_bin(tf.ispure ? OPER.OPcallns : OPER.OPcall, tyret, ec, ep); + e = el_bin((tf.ispure && tf.isnothrow) ? OPER.OPcallns : OPER.OPcall, tyret, ec, ep); else - e = el_una(tf.ispure ? OPER.OPucallns : OPER.OPucall, tyret, ec); + e = el_una((tf.ispure && tf.isnothrow) ? OPER.OPucallns : OPER.OPucall, tyret, ec); if (retmethod == RET.RETstack) { @@ -792,7 +804,6 @@ * edim number of times to write evalue to eptr[] * tb type of evalue */ - elem* setArray(elem* eptr, elem* edim, Type tb, elem* evalue, IRState* irs, int op) { int r; @@ -852,7 +863,7 @@ edim = el_bin(OPER.OPmul, TYM.TYuint, edim, el_long(TYM.TYuint, sz)); } - if (tybasic(evalue.Ety) == TYM.TYstruct) + if (tybasic(evalue.Ety) == TYM.TYstruct || tybasic(evalue.Ety) == TYarray) { evalue = el_una(OPER.OPstrpar, TYM.TYstruct, evalue); evalue.Enumbytes = evalue.E1.Enumbytes; @@ -987,7 +998,7 @@ break; case TY.Tsarray: - e = el_una(OPER.OPaddr, TYM.TYnptr, e); + e = addressElem(e, t); dim = cast(uint)(cast(TypeSArray)t).dim.toInteger(); e = el_pair(TYM.TYullong, el_long(TYM.TYint, dim), e); break; @@ -1062,12 +1073,13 @@ return el_combine(ef, e); } +/************************************ + */ elem* sarray_toDarray(Loc loc, Type tfrom, Type tto, elem* e) { //printf("sarray_toDarray()\n"); //elem_print(e); - elem* elen; uint dim = cast(uint)(cast(TypeSArray)tfrom).dim.toInteger(); if (tto) @@ -1084,8 +1096,8 @@ } L1: - elen = el_long(TYM.TYint, dim); - e = el_una(OPER.OPaddr, TYM.TYnptr, e); + elem* elen = el_long(TYM.TYint, dim); + e = addressElem(e, tfrom); e = el_pair(TYM.TYullong, elen, e); return e; }
--- a/dmd/expression/Util.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/expression/Util.d Tue Aug 31 22:29:00 2010 +0200 @@ -196,7 +196,7 @@ m.anyf = f; TypeFunction tf = cast(TypeFunction)f.type; match = tf.callMatch(f.needThis() ? ethis : null, arguments); - //printf("match = %d\n", match); + //printf("test: match = %d\n", match); if (match != MATCH.MATCHnomatch) { if (match > m.last) @@ -631,6 +631,8 @@ if (p.type != arg.type) { //printf("arg.type = %s, p.type = %s\n", arg.type.toChars(), p.type.toChars()); + if (arg.op == TOKtype) + arg.error("cannot pass type %s as function argument", arg.toChars()); arg = arg.implicitCastTo(sc, p.type); arg = arg.optimize(WANT.WANTvalue); } @@ -644,12 +646,15 @@ arg = arg.modifiableLvalue(sc, arg); } + tb = arg.type.toBasetype(); +version(SARRAYVALUE) {} else +{ // Convert static arrays to pointers - tb = arg.type.toBasetype(); if (tb.ty == TY.Tsarray) { arg = arg.checkToPointer(); } +} version (DMDV2) { if (tb.ty == TY.Tstruct && !(p.storageClass & (STC.STCref | STC.STCout))) {
--- a/dmd/interpret/Util.d Tue Aug 31 16:35:41 2010 +0200 +++ b/dmd/interpret/Util.d Tue Aug 31 22:29:00 2010 +0200 @@ -2,6 +2,7 @@ import dmd.StructDeclaration; import dmd.Expression; +import dmd.FuncDeclaration; import dmd.InterState; import dmd.ArrayTypes; import dmd.GlobalExpressions; @@ -13,74 +14,130 @@ import dmd.Loc; import dmd.ArrayLiteralExp; import dmd.TypeAArray; +import dmd.TypeFunction; import dmd.TypeSArray; +import dmd.TY; import dmd.STC; import dmd.SymbolDeclaration; import dmd.StructLiteralExp; import dmd.VarDeclaration; import dmd.Util; +version(DMDV1) +{ Expression interpret_aaLen(InterState istate, Expressions arguments) { - if (!arguments || arguments.dim != 1) + if (!arguments || arguments.dim != 1) return null; - auto earg = arguments[0]; - earg = earg.interpret(istate); - if (earg is EXP_CANT_INTERPRET) + auto earg = arguments[0]; + earg = earg.interpret(istate); + if (earg is EXP_CANT_INTERPRET) return null; - if (earg.op != TOKassocarrayliteral) + if (earg.op != TOKassocarrayliteral) return null; - auto aae = cast(AssocArrayLiteralExp)earg; - auto e = new IntegerExp(aae.loc, aae.keys.dim, Type.tsize_t); - return e; + auto aae = cast(AssocArrayLiteralExp)earg; + auto e = new IntegerExp(aae.loc, aae.keys.dim, Type.tsize_t); + return e; } Expression interpret_aaKeys(InterState istate, Expressions arguments) { version (LOG) { - printf("interpret_aaKeys()\n"); + writef("interpret_aaKeys()\n"); } - if (!arguments || arguments.dim != 2) + if (!arguments || arguments.dim != 2) return null; - auto earg = arguments[0]; - earg = earg.interpret(istate); - if (earg is EXP_CANT_INTERPRET) + auto earg = arguments[0]; + earg = earg.interpret(istate); + if (earg is EXP_CANT_INTERPRET) return null; - if (earg.op != TOKassocarrayliteral) + if (earg.op != TOKassocarrayliteral) return null; - auto aae = cast(AssocArrayLiteralExp)earg; - auto e = new ArrayLiteralExp(aae.loc, aae.keys); - Type elemType = (cast(TypeAArray)aae.type).index; - e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0)); - return e; + auto aae = cast(AssocArrayLiteralExp)earg; + auto e = new ArrayLiteralExp(aae.loc, aae.keys); + Type elemType = (cast(TypeAArray)aae.type).index; + e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0)); + return e; } Expression interpret_aaValues(InterState istate, Expressions arguments) { - //printf("interpret_aaValues()\n"); - if (!arguments || arguments.dim != 3) + //writef("interpret_aaValues()\n"); + if (!arguments || arguments.dim != 3) + return null; + auto earg = arguments[0]; + earg = earg.interpret(istate); + if (earg is EXP_CANT_INTERPRET) + return null; + if (earg.op != TOKassocarrayliteral) return null; - auto earg = arguments[0]; - earg = earg.interpret(istate); - if (earg is EXP_CANT_INTERPRET) + auto aae = cast(AssocArrayLiteralExp)earg; + auto e = new ArrayLiteralExp(aae.loc, aae.values); + Type elemType = (cast(TypeAArray)aae.type).next; + e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0)); + //writef("result is %s\n", e.toChars()); + return e; +} +} +else version(DMDV2) +{ +Expression interpret_length(InterState istate, Expression earg) +{ +// writef("interpret_length()\n"); + earg = earg.interpret(istate); + if (earg == EXP_CANT_INTERPRET) + return null; + if (earg.op != TOKassocarrayliteral) return null; - if (earg.op != TOKassocarrayliteral) + AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg; + Expression e = new IntegerExp(aae.loc, aae.keys.dim, Type.tsize_t); + return e; +} + +Expression interpret_keys(InterState istate, Expression earg, FuncDeclaration fd) +{ +version(LOG) + writef("interpret_keys()\n"); + + earg = earg.interpret(istate); + if (earg == EXP_CANT_INTERPRET) + return null; + if (earg.op != TOKassocarrayliteral) + return null; + AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg; + Expression e = new ArrayLiteralExp(aae.loc, aae.keys); + assert(fd.type.ty == Tfunction); + assert(fd.type.nextOf().ty == Tarray); + Type elemType = (cast(TypeFunction)fd.type).nextOf().nextOf(); + e.type = new TypeSArray(elemType, new IntegerExp(aae.keys.dim)); + return e; +} +Expression interpret_values(InterState istate, Expression earg, FuncDeclaration fd) +{ + //writef("interpret_values()\n"); + earg = earg.interpret(istate); + if (earg == EXP_CANT_INTERPRET) return null; - auto aae = cast(AssocArrayLiteralExp)earg; - auto e = new ArrayLiteralExp(aae.loc, aae.values); - Type elemType = (cast(TypeAArray)aae.type).next; - e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0)); - //printf("result is %s\n", e.toChars()); - return e; + if (earg.op != TOKassocarrayliteral) + return null; + AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg; + Expression e = new ArrayLiteralExp(aae.loc, aae.values); + assert(fd.type.ty == Tfunction); + assert(fd.type.nextOf().ty == Tarray); + Type elemType = (cast(TypeFunction)fd.type).nextOf().nextOf(); + e.type = new TypeSArray(elemType, new IntegerExp(aae.values.dim)); + //writef("result is %s\n", e.toChars()); + return e; +} } Expression getVarExp(Loc loc, InterState istate, Declaration d) { - Expression e = EXP_CANT_INTERPRET; - VarDeclaration v = d.isVarDeclaration(); - SymbolDeclaration s = d.isSymbolDeclaration(); - if (v) - { + Expression e = EXP_CANT_INTERPRET; + VarDeclaration v = d.isVarDeclaration(); + SymbolDeclaration s = d.isSymbolDeclaration(); + if (v) + { ///version (DMDV2) { if ((v.isConst() || v.isInvariant() || v.storage_class & STCmanifest) && v.init && !v.value) ///} else { @@ -106,17 +163,17 @@ } if (!e) e = EXP_CANT_INTERPRET; - } - else if (s) - { + } + else if (s) + { if (s.dsym.toInitializer() == s.sym) { Expressions exps = new Expressions(); e = new StructLiteralExp(Loc(0), s.dsym, exps); e = e.semantic(null); } - } - return e; + } + return e; } /* Helper functions for BinExp.interpretAssignCommon @@ -127,16 +184,16 @@ */ Expressions changeOneElement(Expressions oldelems, size_t indexToChange, Expression newelem) { - auto expsx = new Expressions(); - expsx.setDim(oldelems.dim); - for (size_t j = 0; j < expsx.dim; j++) - { + auto expsx = new Expressions(); + expsx.setDim(oldelems.dim); + for (size_t j = 0; j < expsx.dim; j++) + { if (j == indexToChange) expsx[j] = newelem; else expsx[j] = oldelems[j]; - } - return expsx; + } + return expsx; } /*************************************** @@ -144,16 +201,16 @@ */ Expressions spliceElements(Expressions oldelems, Expressions newelems, size_t insertpoint) { - auto expsx = new Expressions(); - expsx.setDim(oldelems.dim); - for (size_t j = 0; j < expsx.dim; j++) - { + auto expsx = new Expressions(); + expsx.setDim(oldelems.dim); + for (size_t j = 0; j < expsx.dim; j++) + { if (j >= insertpoint && j < insertpoint + newelems.dim) expsx[j] = newelems[j - insertpoint]; else expsx[j] = oldelems[j]; - } - return expsx; + } + return expsx; } /****************************** @@ -161,15 +218,15 @@ */ ArrayLiteralExp createBlockDuplicatedArrayLiteral(Type type, Expression elem, size_t dim) { - auto elements = new Expressions(); - elements.setDim(dim); - for (size_t i = 0; i < dim; i++) { + auto elements = new Expressions(); + elements.setDim(dim); + for (size_t i = 0; i < dim; i++) { elements[i] = elem; } - auto ae = new ArrayLiteralExp(Loc(0), elements); - ae.type = type; - return ae; + auto ae = new ArrayLiteralExp(Loc(0), elements); + ae.type = type; + return ae; } @@ -178,17 +235,17 @@ */ StructLiteralExp createDefaultInitStructLiteral(Loc loc, StructDeclaration sym) { - Expressions structelems = new Expressions(); - structelems.setDim(sym.fields.dim); - for (size_t j = 0; j < structelems.dim; j++) - { + Expressions structelems = new Expressions(); + structelems.setDim(sym.fields.dim); + for (size_t j = 0; j < structelems.dim; j++) + { structelems[j] = sym.fields[j].type.defaultInit(Loc(0)); - } - StructLiteralExp structinit = new StructLiteralExp(loc, sym, structelems); - // Why doesn't the StructLiteralExp constructor do this, when - // sym.type != null ? - structinit.type = sym.type; - return structinit; + } + StructLiteralExp structinit = new StructLiteralExp(loc, sym, structelems); + // Why doesn't the StructLiteralExp constructor do this, when + // sym.type != null ? + structinit.type = sym.type; + return structinit; } /******************************** @@ -196,18 +253,18 @@ */ void addVarToInterstate(InterState istate, VarDeclaration v) { - if (!v.isParameter()) - { + if (!v.isParameter()) + { for (size_t i = 0; 1; i++) { if (i == istate.vars.dim) { istate.vars.push(v); - //printf("\tadding %s to istate\n", v.toChars()); + //writef("\tadding %s to istate\n", v.toChars()); break; } if (v == cast(VarDeclaration)istate.vars[i]) break; } - } + } } \ No newline at end of file