# HG changeset patch # User Trass3r # Date 1283005188 -7200 # Node ID 2e2a5c3f943a94c067208bfbb8216cbc9a775fe9 # Parent 8e24ef1dd13946dc3cdad5ee405640bd5bdf5520 reduced warnings by adding override to the methods think this also normalizes different line endings used all over the place diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AddAssignExp.d --- a/dmd/AddAssignExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AddAssignExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -30,7 +30,7 @@ super(loc, TOK.TOKaddass, AddAssignExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -138,17 +138,17 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { AssignExp_buildArrayIdent(buf, arguments, "Add"); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { /* Evaluate assign expressions right to left */ @@ -160,12 +160,12 @@ return e; } - Identifier opId() /* For operator overloading */ + override Identifier opId() /* For operator overloading */ { return Id.addass; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { //printf("AddAssignExp::toElem() %s\n", toChars()); elem *e; @@ -181,4 +181,4 @@ return e; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AddExp.d --- a/dmd/AddExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AddExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,24 +1,24 @@ -module dmd.AddExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.backend.elem; -import dmd.InterState; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Id; -import dmd.Scope; -import dmd.IRState; -import dmd.ArrayTypes; -import dmd.BinExp; -import dmd.Type; -import dmd.TOK; -import dmd.TY; - -import dmd.expression.Add; -import dmd.backend.Util; -import dmd.backend.OPER; - +module dmd.AddExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.backend.elem; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Id; +import dmd.Scope; +import dmd.IRState; +import dmd.ArrayTypes; +import dmd.BinExp; +import dmd.Type; +import dmd.TOK; +import dmd.TY; + +import dmd.expression.Add; +import dmd.backend.Util; +import dmd.backend.OPER; + class AddExp : BinExp { this(Loc loc, Expression e1, Expression e2) @@ -26,140 +26,140 @@ super(loc, TOK.TOKadd, AddExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { - Expression e; - -version (LOGSEMANTIC) { - printf("AddExp.semantic('%s')\n", toChars()); -} - if (!type) - { - BinExp.semanticp(sc); - - e = op_overload(sc); - if (e) - return e; - - Type tb1 = e1.type.toBasetype(); - Type tb2 = e2.type.toBasetype(); - - if ((tb1.ty == TY.Tarray || tb1.ty == TY.Tsarray) && - (tb2.ty == TY.Tarray || tb2.ty == TY.Tsarray) && - tb1.nextOf().equals(tb2.nextOf()) - ) - { - type = e1.type; - e = this; - } - else if (tb1.ty == TY.Tpointer && e2.type.isintegral() || - tb2.ty == TY.Tpointer && e1.type.isintegral()) - e = scaleFactor(sc); - else if (tb1.ty == TY.Tpointer && tb2.ty == TY.Tpointer) - { - incompatibleTypes(); - type = e1.type; - e = this; - } - else - { - typeCombine(sc); - if ((e1.type.isreal() && e2.type.isimaginary()) || - (e1.type.isimaginary() && e2.type.isreal())) - { - switch (type.toBasetype().ty) - { - case TY.Tfloat32: - case TY.Timaginary32: - type = Type.tcomplex32; - break; - - case TY.Tfloat64: - case TY.Timaginary64: - type = Type.tcomplex64; - break; - - case TY.Tfloat80: - case TY.Timaginary80: - type = Type.tcomplex80; - break; - } - } - e = this; - } - return e; - } + Expression e; + +version (LOGSEMANTIC) { + printf("AddExp.semantic('%s')\n", toChars()); +} + if (!type) + { + BinExp.semanticp(sc); + + e = op_overload(sc); + if (e) + return e; + + Type tb1 = e1.type.toBasetype(); + Type tb2 = e2.type.toBasetype(); + + if ((tb1.ty == TY.Tarray || tb1.ty == TY.Tsarray) && + (tb2.ty == TY.Tarray || tb2.ty == TY.Tsarray) && + tb1.nextOf().equals(tb2.nextOf()) + ) + { + type = e1.type; + e = this; + } + else if (tb1.ty == TY.Tpointer && e2.type.isintegral() || + tb2.ty == TY.Tpointer && e1.type.isintegral()) + e = scaleFactor(sc); + else if (tb1.ty == TY.Tpointer && tb2.ty == TY.Tpointer) + { + incompatibleTypes(); + type = e1.type; + e = this; + } + else + { + typeCombine(sc); + if ((e1.type.isreal() && e2.type.isimaginary()) || + (e1.type.isimaginary() && e2.type.isreal())) + { + switch (type.toBasetype().ty) + { + case TY.Tfloat32: + case TY.Timaginary32: + type = Type.tcomplex32; + break; + + case TY.Tfloat64: + case TY.Timaginary64: + type = Type.tcomplex64; + break; + + case TY.Tfloat80: + case TY.Timaginary80: + type = Type.tcomplex80; + break; + } + } + e = this; + } + return e; + } return this; } - Expression optimize(int result) + override Expression optimize(int result) { - Expression e; - - //printf("AddExp::optimize(%s)\n", toChars()); - e1 = e1.optimize(result); - e2 = e2.optimize(result); - if (e1.isConst() && e2.isConst()) - { - if (e1.op == TOK.TOKsymoff && e2.op == TOK.TOKsymoff) - return this; - e = Add(type, e1, e2); - } - else - e = this; - + Expression e; + + //printf("AddExp::optimize(%s)\n", toChars()); + e1 = e1.optimize(result); + e2 = e2.optimize(result); + if (e1.isConst() && e2.isConst()) + { + if (e1.op == TOK.TOKsymoff && e2.op == TOK.TOKsymoff) + return this; + e = Add(type, e1, e2); + } + else + e = this; + return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { Exp_buildArrayIdent(buf, arguments, "Add"); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { - /* Evaluate assign expressions left to right - */ - Expression ex1 = e1.buildArrayLoop(fparams); - Expression ex2 = e2.buildArrayLoop(fparams); - Expression e = new AddExp(Loc(0), ex1, ex2); + /* Evaluate assign expressions left to right + */ + Expression ex1 = e1.buildArrayLoop(fparams); + Expression ex2 = e2.buildArrayLoop(fparams); + Expression e = new AddExp(Loc(0), ex1, ex2); return e; } - bool isCommutative() + override bool isCommutative() { return true; } - Identifier opId() + override Identifier opId() { return Id.add; } - Identifier opId_r() + override Identifier opId_r() { return Id.add_r; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { - elem *e; - Type tb1 = e1.type.toBasetype(); - Type tb2 = e2.type.toBasetype(); - - if ((tb1.ty == TY.Tarray || tb1.ty == TY.Tsarray) && (tb2.ty == TY.Tarray || tb2.ty == TY.Tsarray)) - { - error("Array operation %s not implemented", toChars()); - e = el_long(type.totym(), 0); // error recovery - } - else - e = toElemBin(irs, OPER.OPadd); - + elem *e; + Type tb1 = e1.type.toBasetype(); + Type tb2 = e2.type.toBasetype(); + + if ((tb1.ty == TY.Tarray || tb1.ty == TY.Tsarray) && (tb2.ty == TY.Tarray || tb2.ty == TY.Tsarray)) + { + error("Array operation %s not implemented", toChars()); + e = el_long(type.totym(), 0); // error recovery + } + else + e = toElemBin(irs, OPER.OPadd); + return e; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AddrExp.d --- a/dmd/AddrExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AddrExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,11 +1,11 @@ -module dmd.AddrExp; - -import dmd.Expression; -import dmd.UnaExp; -import dmd.MATCH; -import dmd.Type; -import dmd.Loc; -import dmd.Scope; +module dmd.AddrExp; + +import dmd.Expression; +import dmd.UnaExp; +import dmd.MATCH; +import dmd.Type; +import dmd.Loc; +import dmd.Scope; import dmd.IRState; import dmd.ErrorExp; import dmd.DotVarExp; @@ -13,7 +13,7 @@ import dmd.DelegateExp; import dmd.VarExp; import dmd.VarDeclaration; -import dmd.ThisExp; +import dmd.ThisExp; import dmd.TOK; import dmd.WANT; import dmd.CommaExp; @@ -25,12 +25,12 @@ import dmd.Dsymbol; import dmd.ScopeDsymbol; import dmd.TY; -import dmd.TypeSArray; - +import dmd.TypeSArray; + import dmd.backend.elem; import dmd.backend.Util; -import dmd.codegen.Util; - +import dmd.codegen.Util; + class AddrExp : UnaExp { this(Loc loc, Expression e) @@ -38,7 +38,7 @@ super(loc, TOK.TOKaddress, AddrExp.sizeof, e); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { version (LOGSEMANTIC) { printf("AddrExp.semantic('%s')\n", toChars()); @@ -126,7 +126,7 @@ return this; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e; @@ -140,7 +140,7 @@ return e; } - MATCH implicitConvTo(Type t) + override MATCH implicitConvTo(Type t) { static if (false) { printf("AddrExp.implicitConvTo(this=%s, type=%s, t=%s)\n", @@ -201,7 +201,7 @@ return result; } - Expression castTo(Scope sc, Type t) + override Expression castTo(Scope sc, Type t) { Type tb; @@ -274,7 +274,7 @@ return e; } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AggregateDeclaration.d --- a/dmd/AggregateDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AggregateDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -187,7 +187,7 @@ dtors = new FuncDeclarations(); } - void semantic2(Scope sc) + override void semantic2(Scope sc) { //printf("AggregateDeclaration.semantic2(%s)\n", toChars()); if (scope_ && members) @@ -207,7 +207,7 @@ } } - void semantic3(Scope sc) + override void semantic3(Scope sc) { int i; @@ -224,7 +224,7 @@ } } - void inlineScan() + override void inlineScan() { int i; @@ -240,7 +240,7 @@ } } - uint size(Loc loc) + override uint size(Loc loc) { //printf("AggregateDeclaration.size() = %d\n", structsize); if (!members) @@ -273,7 +273,7 @@ //printf("result = %d\n",offset); } - Type getType() + override Type getType() { return type; } @@ -333,7 +333,7 @@ fields.push(cast(void*)v); } - bool isDeprecated() // is aggregate deprecated? + override bool isDeprecated() // is aggregate deprecated? { return isdeprecated; } @@ -446,12 +446,12 @@ return isnested; } - void emitComment(Scope sc) + override void emitComment(Scope sc) { assert(false); } - void toDocBuffer(OutBuffer buf) + override void toDocBuffer(OutBuffer buf) { assert(false); } @@ -612,7 +612,7 @@ } } - PROT prot() + override PROT prot() { assert(false); } @@ -639,5 +639,5 @@ return sinit; } - AggregateDeclaration isAggregateDeclaration() { return this; } + override AggregateDeclaration isAggregateDeclaration() { return this; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AliasDeclaration.d --- a/dmd/AliasDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AliasDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -57,7 +57,7 @@ assert(s); } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { //printf("AliasDeclaration::syntaxCopy()\n"); assert(!s); @@ -88,7 +88,7 @@ return sa; } - void semantic(Scope sc) + override void semantic(Scope sc) { //printf("AliasDeclaration.semantic() %s\n", toChars()); if (aliassym) @@ -198,7 +198,7 @@ this.inSemantic = 0; } - bool overloadInsert(Dsymbol s) + override bool overloadInsert(Dsymbol s) { /* Don't know yet what the aliased symbol is, so assume it can * be overloaded and check later for correctness. @@ -216,17 +216,17 @@ } } - string kind() + override string kind() { return "alias"; } - Type getType() + override Type getType() { return type; } - Dsymbol toAlias() + override Dsymbol toAlias() { //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : ""); assert(this !is aliassym); @@ -241,7 +241,7 @@ return s; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } @@ -250,10 +250,10 @@ Type htype; Dsymbol haliassym; } - void toDocBuffer(OutBuffer buf) + override void toDocBuffer(OutBuffer buf) { assert(false); } - AliasDeclaration isAliasDeclaration() { return this; } + override AliasDeclaration isAliasDeclaration() { return this; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AliasThis.d --- a/dmd/AliasThis.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AliasThis.d Sat Aug 28 16:19:48 2010 +0200 @@ -20,7 +20,7 @@ this.ident = ident; } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { assert(!s); /* Since there is no semantic information stored here, @@ -29,7 +29,7 @@ return this; } - void semantic(Scope sc) + override void semantic(Scope sc) { Dsymbol parent = sc.parent; if (parent) @@ -49,15 +49,15 @@ error("alias this can only appear in struct or class declaration, not %s", parent ? parent.toChars() : "nowhere"); } - string kind() + override string kind() { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } AliasThis isAliasThis() { return this; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AlignDeclaration.d --- a/dmd/AlignDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AlignDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -17,12 +17,12 @@ salign = sa; } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { assert(false); } - void setScope(Scope sc) + override void setScope(Scope sc) { //printf("\tAlignDeclaration::setScope '%s'\n",toChars()); if (decl) @@ -31,7 +31,7 @@ } } - void semantic(Scope sc) + override void semantic(Scope sc) { //printf("\tAlignDeclaration::semantic '%s'\n",toChars()); if (decl) @@ -40,8 +40,8 @@ } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AndAndExp.d --- a/dmd/AndAndExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AndAndExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,24 +1,24 @@ -module dmd.AndAndExp; - -import dmd.Expression; -import dmd.InterState; -import dmd.Loc; -import dmd.Scope; +module dmd.AndAndExp; + +import dmd.Expression; +import dmd.InterState; +import dmd.Loc; +import dmd.Scope; import dmd.IRState; import dmd.CommaExp; import dmd.Global; -import dmd.BoolExp; -import dmd.BinExp; +import dmd.BoolExp; +import dmd.BinExp; import dmd.TOK; import dmd.WANT; import dmd.IntegerExp; import dmd.Type; -import dmd.TY; - +import dmd.TY; + import dmd.backend.elem; import dmd.backend.OPER; -import dmd.backend.Util; - +import dmd.backend.Util; + class AndAndExp : BinExp { this(Loc loc, Expression e1, Expression e2) @@ -26,7 +26,7 @@ super(loc, TOK.TOKandand, AndAndExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { uint cs1; @@ -61,18 +61,18 @@ return this; } - Expression checkToBoolean() + override Expression checkToBoolean() { e2 = e2.checkToBoolean(); return this; } - int isBit() + override int isBit() { assert(false); } - Expression optimize(int result) + override Expression optimize(int result) { //printf("AndAndExp::optimize(%d) %s\n", result, toChars()); e1 = e1.optimize(WANTflags | (result & WANTinterpret)); @@ -105,17 +105,17 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - bool checkSideEffect(int flag) + override bool checkSideEffect(int flag) { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e = toElemBin(irs, OPandand); if (global.params.cov && e2.loc.linnum) diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AndAssignExp.d --- a/dmd/AndAssignExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AndAssignExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -22,33 +22,33 @@ super(loc, TOK.TOKandass, AndAssignExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { return commonSemanticAssignIntegral(sc); } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { AssignExp_buildArrayIdent(buf, arguments, "And"); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { assert(false); } - Identifier opId() /* For operator overloading */ + override Identifier opId() /* For operator overloading */ { return Id.andass; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs, OPER.OPandass); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AndExp.d --- a/dmd/AndExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AndExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,27 +1,27 @@ -module dmd.AndExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.InterState; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IntRange; -import dmd.IRState; -import dmd.BinExp; -import dmd.TOK; +module dmd.AndExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IntRange; +import dmd.IRState; +import dmd.BinExp; +import dmd.TOK; import dmd.ArrayTypes; import dmd.TY; import dmd.Type; import dmd.Id; -import dmd.Global; - +import dmd.Global; + import dmd.backend.elem; import dmd.backend.Util; import dmd.backend.OPER; import dmd.expression.Util; -import dmd.expression.And; - +import dmd.expression.And; + class AndExp : BinExp { this(Loc loc, Expression e1, Expression e2) @@ -29,7 +29,7 @@ super(loc, TOK.TOKand, AndExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -59,7 +59,7 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -73,75 +73,75 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { Exp_buildArrayIdent(buf, arguments, "And"); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { - /* Evaluate assign expressions left to right - */ - Expression ex1 = e1.buildArrayLoop(fparams); - Expression ex2 = e2.buildArrayLoop(fparams); - Expression e = new AndExp(Loc(0), ex1, ex2); + /* Evaluate assign expressions left to right + */ + Expression ex1 = e1.buildArrayLoop(fparams); + Expression ex2 = e2.buildArrayLoop(fparams); + Expression e = new AndExp(Loc(0), ex1, ex2); return e; } - IntRange getIntRange() + override IntRange getIntRange() { - IntRange ir; - IntRange ir1 = e1.getIntRange(); - IntRange ir2 = e2.getIntRange(); - - ir.imin = ir1.imin; - if (ir2.imin < ir.imin) - ir.imin = ir2.imin; - - ir.imax = ir1.imax; - if (ir2.imax > ir.imax) - ir.imax = ir2.imax; - - ulong u; - - u = getMask(ir1.imax); - ir.imin &= u; - ir.imax &= u; - - u = getMask(ir2.imax); - ir.imin &= u; - ir.imax &= u; - - ir.imin &= type.sizemask(); - ir.imax &= type.sizemask(); - - //printf("AndExp: imin = x%llx, imax = x%llx\n", ir.imin, ir.imax); - //e1.dump(0); - + IntRange ir; + IntRange ir1 = e1.getIntRange(); + IntRange ir2 = e2.getIntRange(); + + ir.imin = ir1.imin; + if (ir2.imin < ir.imin) + ir.imin = ir2.imin; + + ir.imax = ir1.imax; + if (ir2.imax > ir.imax) + ir.imax = ir2.imax; + + ulong u; + + u = getMask(ir1.imax); + ir.imin &= u; + ir.imax &= u; + + u = getMask(ir2.imax); + ir.imin &= u; + ir.imax &= u; + + ir.imin &= type.sizemask(); + ir.imax &= type.sizemask(); + + //printf("AndExp: imin = x%llx, imax = x%llx\n", ir.imin, ir.imax); + //e1.dump(0); + return ir; } - bool isCommutative() + override bool isCommutative() { return true; } - Identifier opId() + override Identifier opId() { return Id.iand; } - Identifier opId_r() + override Identifier opId_r() { return Id.iand_r; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs, OPER.OPand); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AnonDeclaration.d --- a/dmd/AnonDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AnonDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,18 +1,18 @@ -module dmd.AnonDeclaration; - -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.Array; -import dmd.AttribDeclaration; -import dmd.HdrGenState; +module dmd.AnonDeclaration; + +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.Array; +import dmd.AttribDeclaration; +import dmd.HdrGenState; import dmd.Dsymbol; import dmd.AggregateDeclaration; import dmd.AnonymousAggregateDeclaration; import dmd.STC; import dmd.Module; -import dmd.VarDeclaration; - +import dmd.VarDeclaration; + class AnonDeclaration : AttribDeclaration { int isunion; @@ -25,16 +25,16 @@ this.isunion = isunion; } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { - AnonDeclaration ad; - - assert(!s); - ad = new AnonDeclaration(loc, isunion, Dsymbol.arraySyntaxCopy(decl)); + AnonDeclaration ad; + + assert(!s); + ad = new AnonDeclaration(loc, isunion, Dsymbol.arraySyntaxCopy(decl)); return ad; } - void semantic(Scope sc) + override void semantic(Scope sc) { //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this); @@ -160,12 +160,12 @@ } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - string kind() + override string kind() { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/Array.d --- a/dmd/Array.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/Array.d Sat Aug 28 16:19:48 2010 +0200 @@ -25,7 +25,7 @@ ///mem.mark(data[u]); // BUG: what if arrays of Object's? } - string toString() + override string toString() { char *p; @@ -179,4 +179,4 @@ { return copyTo(new Array()); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ArrayExp.d --- a/dmd/ArrayExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ArrayExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,24 +1,24 @@ -module dmd.ArrayExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.UnaExp; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.InlineCostState; -import dmd.InlineDoState; -import dmd.HdrGenState; -import dmd.InlineScanState; -import dmd.ArrayTypes; +module dmd.ArrayExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.UnaExp; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.InlineCostState; +import dmd.InlineDoState; +import dmd.HdrGenState; +import dmd.InlineScanState; +import dmd.ArrayTypes; import dmd.TOK; import dmd.Type; import dmd.TY; import dmd.Id; import dmd.IndexExp; -import dmd.expression.Util; - +import dmd.expression.Util; + class ArrayExp : UnaExp { Expressions arguments; @@ -29,12 +29,12 @@ arguments = args; } - Expression syntaxCopy() + override Expression syntaxCopy() { - return new ArrayExp(loc, e1.syntaxCopy(), arraySyntaxCopy(arguments)); + return new ArrayExp(loc, e1.syntaxCopy(), arraySyntaxCopy(arguments)); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; Type t1; @@ -78,37 +78,37 @@ return e; } - int isLvalue() + override int isLvalue() { assert(false); } - Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression e) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - void scanForNestedRef(Scope sc) + override void scanForNestedRef(Scope sc) { assert(false); } - Identifier opId() + override Identifier opId() { return Id.index; } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { return 1 + e1.inlineCost(ics) + arrayInlineCost(ics, arguments); } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { ArrayExp ce; @@ -118,7 +118,7 @@ return ce; } - Expression inlineScan(InlineScanState* iss) + override Expression inlineScan(InlineScanState* iss) { Expression e = this; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ArrayInitializer.d --- a/dmd/ArrayInitializer.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ArrayInitializer.d Sat Aug 28 16:19:48 2010 +0200 @@ -39,7 +39,7 @@ value = new Initializers(); } - Initializer syntaxCopy() + override Initializer syntaxCopy() { //printf("ArrayInitializer.syntaxCopy()\n"); @@ -70,7 +70,7 @@ type = null; } - Initializer semantic(Scope sc, Type t) + override Initializer semantic(Scope sc, Type t) { uint i; uint length; @@ -125,7 +125,7 @@ return this; } - Type inferType(Scope sc) + override Type inferType(Scope sc) { //printf("ArrayInitializer.inferType() %s\n", toChars()); type = Type.terror; @@ -159,7 +159,7 @@ /******************************** * If possible, convert array initializer to array literal. */ - Expression toExpression() + override Expression toExpression() { Expression e; @@ -248,12 +248,12 @@ assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - dt_t* toDt() + override dt_t* toDt() { //printf("ArrayInitializer.toDt('%s')\n", toChars()); Type tb = type.toBasetype(); @@ -369,5 +369,5 @@ assert(false); } - ArrayInitializer isArrayInitializer() { return this; } -} \ No newline at end of file + override ArrayInitializer isArrayInitializer() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ArrayLengthExp.d --- a/dmd/ArrayLengthExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ArrayLengthExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,14 +1,14 @@ -module dmd.ArrayLengthExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.UnaExp; -import dmd.InterState; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.HdrGenState; +module dmd.ArrayLengthExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.UnaExp; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.HdrGenState; import dmd.TOK; import dmd.Type; import dmd.WANT; @@ -16,8 +16,8 @@ import dmd.expression.ArrayLength; import dmd.backend.Util; -import dmd.backend.OPER; - +import dmd.backend.OPER; + class ArrayLengthExp : UnaExp { this(Loc loc, Expression e1) @@ -25,7 +25,7 @@ super(loc, TOK.TOKarraylength, ArrayLengthExp.sizeof, e1); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -42,7 +42,7 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { //printf("ArrayLengthExp::optimize(result = %d) %s\n", result, toChars()); e1 = e1.optimize(WANTvalue | (result & WANTinterpret)); @@ -54,17 +54,17 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem *e = e1.toElem(irs); e = el_una(OP64_32, type.totym(), e); diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ArrayLiteralExp.d --- a/dmd/ArrayLiteralExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ArrayLiteralExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,21 +1,21 @@ -module dmd.ArrayLiteralExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.InterState; -import dmd.MATCH; -import dmd.Type; -import dmd.OutBuffer; -import dmd.Loc; +module dmd.ArrayLiteralExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.InterState; +import dmd.MATCH; +import dmd.Type; +import dmd.OutBuffer; +import dmd.Loc; import dmd.WANT; -import dmd.Scope; -import dmd.InlineCostState; -import dmd.IRState; -import dmd.InlineDoState; -import dmd.HdrGenState; -import dmd.backend.dt_t; -import dmd.InlineScanState; -import dmd.ArrayTypes; +import dmd.Scope; +import dmd.InlineCostState; +import dmd.IRState; +import dmd.InlineDoState; +import dmd.HdrGenState; +import dmd.backend.dt_t; +import dmd.InlineScanState; +import dmd.ArrayTypes; import dmd.TOK; import dmd.IntegerExp; import dmd.TypeSArray; @@ -25,18 +25,18 @@ import dmd.expression.Util; import dmd.backend.Util; import dmd.backend.RTLSYM; -import dmd.backend.OPER; +import dmd.backend.OPER; import dmd.backend.Symbol; import dmd.backend.TYM; -import dmd.backend.mTY; -import dmd.codegen.Util; - +import dmd.backend.mTY; +import dmd.codegen.Util; + class ArrayLiteralExp : Expression { Expressions elements; this(Loc loc, Expressions elements) - { + { super(loc, TOK.TOKarrayliteral, ArrayLiteralExp.sizeof); this.elements = elements; } @@ -48,12 +48,12 @@ elements.push(cast(void*)e); } - Expression syntaxCopy() + override Expression syntaxCopy() { return new ArrayLiteralExp(loc, arraySyntaxCopy(elements)); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; Type t0 = null; @@ -116,13 +116,13 @@ return this; } - bool isBool(bool result) + override bool isBool(bool result) { size_t dim = elements ? elements.dim : 0; return result ? (dim != 0) : (dim == 0); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e; size_t dim; @@ -188,7 +188,7 @@ return e; } - bool checkSideEffect(int flag) + override bool checkSideEffect(int flag) { bool f = false; @@ -203,14 +203,14 @@ return f; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writeByte('['); argsToCBuffer(buf, elements, hgs); buf.writeByte(']'); } - void toMangleBuffer(OutBuffer buf) + override void toMangleBuffer(OutBuffer buf) { size_t dim = elements ? elements.dim : 0; buf.printf("A%u", dim); @@ -221,12 +221,12 @@ } } - void scanForNestedRef(Scope sc) + override void scanForNestedRef(Scope sc) { assert(false); } - Expression optimize(int result) + override Expression optimize(int result) { if (elements) { @@ -242,12 +242,12 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - MATCH implicitConvTo(Type t) + override MATCH implicitConvTo(Type t) { MATCH result = MATCHexact; @@ -282,7 +282,7 @@ return Expression.implicitConvTo(t); } - Expression castTo(Scope sc, Type t) + override Expression castTo(Scope sc, Type t) { static if (false) { printf("ArrayLiteralExp.castTo(this=%s, type=%s, => %s)\n", @@ -329,73 +329,73 @@ return e.Expression.castTo(sc, t); } - dt_t** toDt(dt_t** pdt) + override dt_t** toDt(dt_t** pdt) { - //printf("ArrayLiteralExp.toDt() '%s', type = %s\n", toChars(), type.toChars()); - - dt_t *d; - dt_t **pdtend; - - d = null; - pdtend = &d; - for (int i = 0; i < elements.dim; i++) - { - Expression e = cast(Expression)elements.data[i]; - - pdtend = e.toDt(pdtend); - } - Type t = type.toBasetype(); - - switch (t.ty) - { - case Tsarray: - pdt = dtcat(pdt, d); - break; - - case Tpointer: - case Tarray: - if (t.ty == Tarray) - dtdword(pdt, elements.dim); - if (d) - { - // Create symbol, and then refer to it - Symbol* s; - s = static_sym(); - s.Sdt = d; - outdata(s); - - dtxoff(pdt, s, 0, TYnptr); - } - else - dtdword(pdt, 0); - - break; - - default: - assert(0); - } + //printf("ArrayLiteralExp.toDt() '%s', type = %s\n", toChars(), type.toChars()); + + dt_t *d; + dt_t **pdtend; + + d = null; + pdtend = &d; + for (int i = 0; i < elements.dim; i++) + { + Expression e = cast(Expression)elements.data[i]; + + pdtend = e.toDt(pdtend); + } + Type t = type.toBasetype(); + + switch (t.ty) + { + case Tsarray: + pdt = dtcat(pdt, d); + break; + + case Tpointer: + case Tarray: + if (t.ty == Tarray) + dtdword(pdt, elements.dim); + if (d) + { + // Create symbol, and then refer to it + Symbol* s; + s = static_sym(); + s.Sdt = d; + outdata(s); + + dtxoff(pdt, s, 0, TYnptr); + } + else + dtdword(pdt, 0); + + break; + + default: + assert(0); + } return pdt; } version (DMDV2) { - bool canThrow() + override bool canThrow() { return 1; // because it can fail allocating memory } } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { return 1 + arrayInlineCost(ics, elements); } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { ArrayLiteralExp ce = cast(ArrayLiteralExp)copy(); ce.elements = arrayExpressiondoInline(elements, ids); return ce; } - Expression inlineScan(InlineScanState* iss) + override Expression inlineScan(InlineScanState* iss) { Expression e = this; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ArrayScopeSymbol.d --- a/dmd/ArrayScopeSymbol.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ArrayScopeSymbol.d Sat Aug 28 16:19:48 2010 +0200 @@ -56,7 +56,7 @@ this.sc = sc; } - Dsymbol search(Loc loc, Identifier ident, int flags) + override Dsymbol search(Loc loc, Identifier ident, int flags) { //printf("ArrayScopeSymbol.search('%s', flags = %d)\n", ident.toChars(), flags); if (ident == Id.length || ident == Id.dollar) @@ -168,5 +168,5 @@ return null; } - ArrayScopeSymbol isArrayScopeSymbol() { return this; } -} \ No newline at end of file + override ArrayScopeSymbol isArrayScopeSymbol() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AsmStatement.d --- a/dmd/AsmStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AsmStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -50,12 +50,12 @@ this.tokens = tokens; } - Statement syntaxCopy() + override Statement syntaxCopy() { assert(false); } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { //printf("AsmStatement.semantic()\n"); @@ -259,24 +259,24 @@ return this; } - BE blockExit() + override BE blockExit() { assert(false); } - bool comeFrom() + override bool comeFrom() { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - AsmStatement isAsmStatement() { return this; } + override AsmStatement isAsmStatement() { return this; } - void toIR(IRState *irs) + override void toIR(IRState *irs) { block* bpre; block* basm; @@ -370,4 +370,4 @@ blx.funcsym.Stype.Tty |= mTYnaked; } } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AssertExp.d --- a/dmd/AssertExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AssertExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,20 +1,20 @@ -module dmd.AssertExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.UnaExp; -import dmd.InterState; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.InlineCostState; -import dmd.InlineDoState; -import dmd.IRState; -import dmd.HdrGenState; +module dmd.AssertExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.UnaExp; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.InlineCostState; +import dmd.InlineDoState; +import dmd.IRState; +import dmd.HdrGenState; import dmd.InlineScanState; import dmd.Type; import dmd.Global; -import dmd.InvariantDeclaration; +import dmd.InvariantDeclaration; import dmd.TOK; import dmd.TY; import dmd.TypeClass; @@ -31,7 +31,7 @@ import dmd.backend.Symbol; import dmd.backend.dt_t; import dmd.backend.SC; -import dmd.backend.FL; +import dmd.backend.FL; import core.stdc.string; import std.string : toStringz; @@ -39,7 +39,7 @@ static __gshared Symbol* assertexp_sfilename = null; static __gshared string assertexp_name = null; static __gshared Module assertexp_mn = null; - + class AssertExp : UnaExp { Expression msg; @@ -50,14 +50,14 @@ this.msg = msg; } - Expression syntaxCopy() + override Expression syntaxCopy() { - AssertExp ae = new AssertExp(loc, e1.syntaxCopy(), - msg ? msg.syntaxCopy() : null); + AssertExp ae = new AssertExp(loc, e1.syntaxCopy(), + msg ? msg.syntaxCopy() : null); return ae; } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { version (LOGSEMANTIC) { printf("AssertExp.semantic('%s')\n", toChars()); @@ -90,18 +90,18 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - bool checkSideEffect(int flag) + override bool checkSideEffect(int flag) { return true; } version (DMDV2) { - bool canThrow() + override bool canThrow() { /* assert()s are non-recoverable errors, so functions that * use them can be considered "nothrow" @@ -109,17 +109,17 @@ return 0; //(global.params.useAssert != 0); } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { return 1 + e1.inlineCost(ics) + (msg ? msg.inlineCost(ics) : 0); } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { AssertExp ae = cast(AssertExp)copy(); @@ -129,7 +129,7 @@ return ae; } - Expression inlineScan(InlineScanState* iss) + override Expression inlineScan(InlineScanState* iss) { e1 = e1.inlineScan(iss); if (msg) @@ -142,7 +142,7 @@ return cast(void*)i; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e; elem* ea; @@ -223,7 +223,7 @@ efilename = el_var(assertexp_sfilename); if (msg) - { + { elem* emsg = msg.toElem(irs); ea = el_var(rtlsym[RTLSYM_DASSERT_MSG]); ea = el_bin(OPcall, TYvoid, ea, el_params(el_long(TYint, loc.linnum), efilename, emsg, null)); diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AssignExp.d --- a/dmd/AssignExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AssignExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,55 +1,55 @@ -module dmd.AssignExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.backend.elem; -import dmd.InterState; -import dmd.Argument; -import dmd.IndexExp; -import dmd.CallExp; -import dmd.CastExp; -import dmd.TypeSArray; -import dmd.StructLiteralExp; -import dmd.ArrayLengthExp; -import dmd.TypeStruct; -import dmd.StructDeclaration; -import dmd.VarExp; -import dmd.TY; -import dmd.SliceExp; -import dmd.CommaExp; -import dmd.ArrayExp; -import dmd.AggregateDeclaration; -import dmd.CondExp; -import dmd.DotVarExp; -import dmd.WANT; -import dmd.Id; -import dmd.TypeClass; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.TypeNext; -import dmd.TupleExp; -import dmd.VarDeclaration; -import dmd.Scope; -import dmd.IRState; -import dmd.ArrayTypes; -import dmd.BinExp; -import dmd.TOK; -import dmd.Global; -import dmd.Declaration; -import dmd.TypeFunction; -import dmd.Type; -import dmd.RET; -import dmd.STC; -import dmd.DotIdExp; - -import dmd.backend.Util; -import dmd.backend.Symbol; -import dmd.backend.OPER; -import dmd.backend.TYM; -import dmd.backend.RTLSYM; -import dmd.codegen.Util; -import dmd.expression.Util; - +module dmd.AssignExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.backend.elem; +import dmd.InterState; +import dmd.Argument; +import dmd.IndexExp; +import dmd.CallExp; +import dmd.CastExp; +import dmd.TypeSArray; +import dmd.StructLiteralExp; +import dmd.ArrayLengthExp; +import dmd.TypeStruct; +import dmd.StructDeclaration; +import dmd.VarExp; +import dmd.TY; +import dmd.SliceExp; +import dmd.CommaExp; +import dmd.ArrayExp; +import dmd.AggregateDeclaration; +import dmd.CondExp; +import dmd.DotVarExp; +import dmd.WANT; +import dmd.Id; +import dmd.TypeClass; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.TypeNext; +import dmd.TupleExp; +import dmd.VarDeclaration; +import dmd.Scope; +import dmd.IRState; +import dmd.ArrayTypes; +import dmd.BinExp; +import dmd.TOK; +import dmd.Global; +import dmd.Declaration; +import dmd.TypeFunction; +import dmd.Type; +import dmd.RET; +import dmd.STC; +import dmd.DotIdExp; + +import dmd.backend.Util; +import dmd.backend.Symbol; +import dmd.backend.OPER; +import dmd.backend.TYM; +import dmd.backend.RTLSYM; +import dmd.codegen.Util; +import dmd.expression.Util; + class AssignExp : BinExp { int ismemset = 0; @@ -59,823 +59,823 @@ super(loc, TOK.TOKassign, AssignExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { - Expression e1old = e1; - -version (LOGSEMANTIC) { - printf("AssignExp.semantic('%s')\n", toChars()); -} - //printf("e1.op = %d, '%s'\n", e1.op, Token.toChars(e1.op)); - //printf("e2.op = %d, '%s'\n", e2.op, Token.toChars(e2.op)); - - if (type) - return this; - - if (e2.op == TOK.TOKcomma) - { - /* Rewrite to get rid of the comma from rvalue - */ - AssignExp ea = new AssignExp(loc, e1, (cast(CommaExp)e2).e2); - ea.op = op; - Expression e = new CommaExp(loc, (cast(CommaExp)e2).e1, ea); - return e.semantic(sc); - } - - /* Look for operator overloading of a[i]=value. - * Do it before semantic() otherwise the a[i] will have been - * converted to a.opIndex() already. - */ - if (e1.op == TOK.TOKarray) - { - ArrayExp ae = cast(ArrayExp)e1; - AggregateDeclaration ad; - Identifier id = Id.index; - - ae.e1 = ae.e1.semantic(sc); - Type t1 = ae.e1.type.toBasetype(); - if (t1.ty == TY.Tstruct) - { - ad = (cast(TypeStruct)t1).sym; - goto L1; - } - else if (t1.ty == TY.Tclass) - { - ad = (cast(TypeClass)t1).sym; - L1: - // Rewrite (a[i] = value) to (a.opIndexAssign(value, i)) - if (search_function(ad, Id.indexass)) - { - Expression e = new DotIdExp(loc, ae.e1, Id.indexass); - Expressions a = cast(Expressions)ae.arguments.copy(); - - a.insert(0, cast(void*)e2); - e = new CallExp(loc, e, a); - e = e.semantic(sc); - return e; - } - else - { - // Rewrite (a[i] = value) to (a.opIndex(i, value)) - if (search_function(ad, id)) - { - Expression e = new DotIdExp(loc, ae.e1, id); - - if (1 || !global.params.useDeprecated) - error("operator [] assignment overload with opIndex(i, value) illegal, use opIndexAssign(value, i)"); - - e = new CallExp(loc, e, cast(Expression)ae.arguments.data[0], e2); - e = e.semantic(sc); - return e; - } - } - } - } - /* Look for operator overloading of a[i..j]=value. - * Do it before semantic() otherwise the a[i..j] will have been - * converted to a.opSlice() already. - */ - if (e1.op == TOK.TOKslice) - { - Type t1; - SliceExp ae = cast(SliceExp)e1; - AggregateDeclaration ad; - Identifier id = Id.index; - - ae.e1 = ae.e1.semantic(sc); - ae.e1 = resolveProperties(sc, ae.e1); - t1 = ae.e1.type.toBasetype(); - if (t1.ty == TY.Tstruct) - { - ad = (cast(TypeStruct)t1).sym; - goto L2; - } - else if (t1.ty == TY.Tclass) - { - ad = (cast(TypeClass)t1).sym; - L2: - // Rewrite (a[i..j] = value) to (a.opIndexAssign(value, i, j)) - if (search_function(ad, Id.sliceass)) - { - Expression e = new DotIdExp(loc, ae.e1, Id.sliceass); - Expressions a = new Expressions(); - - a.push(cast(void*)e2); - if (ae.lwr) - { - a.push(cast(void*)ae.lwr); - assert(ae.upr); - a.push(cast(void*)ae.upr); - } - else - assert(!ae.upr); - - e = new CallExp(loc, e, a); - e = e.semantic(sc); - return e; - } - } - } - - BinExp.semantic(sc); - - if (e1.op == TOK.TOKdottd) - { - // Rewrite a.b=e2, when b is a template, as a.b(e2) - Expression e = new CallExp(loc, e1, e2); - e = e.semantic(sc); - return e; - } - - e2 = resolveProperties(sc, e2); - assert(e1.type); - - /* Rewrite tuple assignment as a tuple of assignments. - */ - if (e1.op == TOK.TOKtuple && e2.op == TOK.TOKtuple) - { - TupleExp tup1 = cast(TupleExp)e1; - TupleExp tup2 = cast(TupleExp)e2; - size_t dim = tup1.exps.dim; - if (dim != tup2.exps.dim) - { - error("mismatched tuple lengths, %d and %d", cast(int)dim, cast(int)tup2.exps.dim); - } - else - { - Expressions exps = new Expressions; - exps.setDim(dim); - - for (int i = 0; i < dim; i++) - { - Expression ex1 = cast(Expression)tup1.exps.data[i]; - Expression ex2 = cast(Expression)tup2.exps.data[i]; - exps.data[i] = cast(void*) new AssignExp(loc, ex1, ex2); - } - Expression e = new TupleExp(loc, exps); - e = e.semantic(sc); - return e; - } - } - - // Determine if this is an initialization of a reference - int refinit = 0; - if (op == TOK.TOKconstruct && e1.op == TOK.TOKvar) - { - VarExp ve = cast(VarExp)e1; - VarDeclaration v = ve.var.isVarDeclaration(); - if (v.storage_class & (STC.STCout | STC.STCref)) - refinit = 1; - } - - Type t1 = e1.type.toBasetype(); - - if (t1.ty == TY.Tfunction) - { - // Rewrite f=value to f(value) - Expression e = new CallExp(loc, e1, e2); - e = e.semantic(sc); - return e; - } - - /* If it is an assignment from a 'foreign' type, - * check for operator overloading. - */ - if (t1.ty == TY.Tstruct) - { - StructDeclaration sd = (cast(TypeStruct)t1).sym; - if (op == TOK.TOKassign) - { - Expression e = op_overload(sc); - if (e) - return e; - } - else if (op == TOK.TOKconstruct && !refinit) - { - Type t2 = e2.type.toBasetype(); - if (t2.ty == TY.Tstruct && sd == (cast(TypeStruct)t2).sym && sd.cpctor) - { - /* We have a copy constructor for this - */ - if (e2.op == TOK.TOKquestion) - { /* Write as: - * a ? e1 = b : e1 = c; - */ - CondExp ec = cast(CondExp)e2; - AssignExp ea1 = new AssignExp(ec.e1.loc, e1, ec.e1); - ea1.op = op; - AssignExp ea2 = new AssignExp(ec.e1.loc, e1, ec.e2); - ea2.op = op; - Expression e = new CondExp(loc, ec.econd, ea1, ea2); - return e.semantic(sc); - } - else if (e2.op == TOK.TOKvar || e2.op == TOK.TOKdotvar || e2.op == TOK.TOKstar || e2.op == TOK.TOKindex) - { /* Write as: - * e1.cpctor(e2); - */ - Expression e = new DotVarExp(loc, e1, sd.cpctor, 0); - e = new CallExp(loc, e, e2); - return e.semantic(sc); - } - } - } - } - else if (t1.ty == TY.Tclass) - { - // Disallow assignment operator overloads for same type - if (!e2.type.implicitConvTo(e1.type)) - { - Expression e = op_overload(sc); - if (e) - return e; - } - } - - if (t1.ty == TY.Tsarray && !refinit) - { - // Convert e1 to e1[] - Expression e = new SliceExp(e1.loc, e1, null, null); - e1 = e.semantic(sc); - t1 = e1.type.toBasetype(); - } - - e2.rvalue(); - - if (e1.op == TOK.TOKarraylength) - { - // e1 is not an lvalue, but we let code generator handle it - ArrayLengthExp ale = cast(ArrayLengthExp)e1; - ale.e1 = ale.e1.modifiableLvalue(sc, e1); - } - else if (e1.op == TOK.TOKslice) - { - Type tn = e1.type.nextOf(); - if (tn && !tn.isMutable() && op != TOK.TOKconstruct) - error("slice %s is not mutable", e1.toChars()); - } - else - { - // Try to do a decent error message with the expression - // before it got constant folded - if (e1.op != TOK.TOKvar) - e1 = e1.optimize(WANT.WANTvalue); - - if (op != TOK.TOKconstruct) - e1 = e1.modifiableLvalue(sc, e1old); - } - - Type t2 = e2.type; - if (e1.op == TOK.TOKslice && t1.nextOf() && e2.implicitConvTo(t1.nextOf())) - { - // memset - ismemset = 1; // make it easy for back end to tell what this is - e2 = e2.implicitCastTo(sc, t1.nextOf()); - } - else if (t1.ty == TY.Tsarray) - { - /* Should have already converted e1 => e1[] - */ - assert(op == TOK.TOKconstruct); - //error("cannot assign to static array %s", e1.toChars()); - } - else if (e1.op == TOK.TOKslice) - { - e2 = e2.implicitCastTo(sc, e1.type.constOf()); - } - else - { - e2 = e2.implicitCastTo(sc, e1.type); - } - - /* Look for array operations - */ - if (e1.op == TOK.TOKslice && !ismemset && - (e2.op == TOK.TOKadd || e2.op == TOK.TOKmin || - e2.op == TOK.TOKmul || e2.op == TOK.TOKdiv || - e2.op == TOK.TOKmod || e2.op == TOK.TOKxor || - e2.op == TOK.TOKand || e2.op == TOK.TOKor || - e2.op == TOK.TOKtilde || e2.op == TOK.TOKneg)) - { - type = e1.type; - return arrayOp(sc); - } - - type = e1.type; - assert(type); + Expression e1old = e1; + +version (LOGSEMANTIC) { + printf("AssignExp.semantic('%s')\n", toChars()); +} + //printf("e1.op = %d, '%s'\n", e1.op, Token.toChars(e1.op)); + //printf("e2.op = %d, '%s'\n", e2.op, Token.toChars(e2.op)); + + if (type) + return this; + + if (e2.op == TOK.TOKcomma) + { + /* Rewrite to get rid of the comma from rvalue + */ + AssignExp ea = new AssignExp(loc, e1, (cast(CommaExp)e2).e2); + ea.op = op; + Expression e = new CommaExp(loc, (cast(CommaExp)e2).e1, ea); + return e.semantic(sc); + } + + /* Look for operator overloading of a[i]=value. + * Do it before semantic() otherwise the a[i] will have been + * converted to a.opIndex() already. + */ + if (e1.op == TOK.TOKarray) + { + ArrayExp ae = cast(ArrayExp)e1; + AggregateDeclaration ad; + Identifier id = Id.index; + + ae.e1 = ae.e1.semantic(sc); + Type t1 = ae.e1.type.toBasetype(); + if (t1.ty == TY.Tstruct) + { + ad = (cast(TypeStruct)t1).sym; + goto L1; + } + else if (t1.ty == TY.Tclass) + { + ad = (cast(TypeClass)t1).sym; + L1: + // Rewrite (a[i] = value) to (a.opIndexAssign(value, i)) + if (search_function(ad, Id.indexass)) + { + Expression e = new DotIdExp(loc, ae.e1, Id.indexass); + Expressions a = cast(Expressions)ae.arguments.copy(); + + a.insert(0, cast(void*)e2); + e = new CallExp(loc, e, a); + e = e.semantic(sc); + return e; + } + else + { + // Rewrite (a[i] = value) to (a.opIndex(i, value)) + if (search_function(ad, id)) + { + Expression e = new DotIdExp(loc, ae.e1, id); + + if (1 || !global.params.useDeprecated) + error("operator [] assignment overload with opIndex(i, value) illegal, use opIndexAssign(value, i)"); + + e = new CallExp(loc, e, cast(Expression)ae.arguments.data[0], e2); + e = e.semantic(sc); + return e; + } + } + } + } + /* Look for operator overloading of a[i..j]=value. + * Do it before semantic() otherwise the a[i..j] will have been + * converted to a.opSlice() already. + */ + if (e1.op == TOK.TOKslice) + { + Type t1; + SliceExp ae = cast(SliceExp)e1; + AggregateDeclaration ad; + Identifier id = Id.index; + + ae.e1 = ae.e1.semantic(sc); + ae.e1 = resolveProperties(sc, ae.e1); + t1 = ae.e1.type.toBasetype(); + if (t1.ty == TY.Tstruct) + { + ad = (cast(TypeStruct)t1).sym; + goto L2; + } + else if (t1.ty == TY.Tclass) + { + ad = (cast(TypeClass)t1).sym; + L2: + // Rewrite (a[i..j] = value) to (a.opIndexAssign(value, i, j)) + if (search_function(ad, Id.sliceass)) + { + Expression e = new DotIdExp(loc, ae.e1, Id.sliceass); + Expressions a = new Expressions(); + + a.push(cast(void*)e2); + if (ae.lwr) + { + a.push(cast(void*)ae.lwr); + assert(ae.upr); + a.push(cast(void*)ae.upr); + } + else + assert(!ae.upr); + + e = new CallExp(loc, e, a); + e = e.semantic(sc); + return e; + } + } + } + + BinExp.semantic(sc); + + if (e1.op == TOK.TOKdottd) + { + // Rewrite a.b=e2, when b is a template, as a.b(e2) + Expression e = new CallExp(loc, e1, e2); + e = e.semantic(sc); + return e; + } + + e2 = resolveProperties(sc, e2); + assert(e1.type); + + /* Rewrite tuple assignment as a tuple of assignments. + */ + if (e1.op == TOK.TOKtuple && e2.op == TOK.TOKtuple) + { + TupleExp tup1 = cast(TupleExp)e1; + TupleExp tup2 = cast(TupleExp)e2; + size_t dim = tup1.exps.dim; + if (dim != tup2.exps.dim) + { + error("mismatched tuple lengths, %d and %d", cast(int)dim, cast(int)tup2.exps.dim); + } + else + { + Expressions exps = new Expressions; + exps.setDim(dim); + + for (int i = 0; i < dim; i++) + { + Expression ex1 = cast(Expression)tup1.exps.data[i]; + Expression ex2 = cast(Expression)tup2.exps.data[i]; + exps.data[i] = cast(void*) new AssignExp(loc, ex1, ex2); + } + Expression e = new TupleExp(loc, exps); + e = e.semantic(sc); + return e; + } + } + + // Determine if this is an initialization of a reference + int refinit = 0; + if (op == TOK.TOKconstruct && e1.op == TOK.TOKvar) + { + VarExp ve = cast(VarExp)e1; + VarDeclaration v = ve.var.isVarDeclaration(); + if (v.storage_class & (STC.STCout | STC.STCref)) + refinit = 1; + } + + Type t1 = e1.type.toBasetype(); + + if (t1.ty == TY.Tfunction) + { + // Rewrite f=value to f(value) + Expression e = new CallExp(loc, e1, e2); + e = e.semantic(sc); + return e; + } + + /* If it is an assignment from a 'foreign' type, + * check for operator overloading. + */ + if (t1.ty == TY.Tstruct) + { + StructDeclaration sd = (cast(TypeStruct)t1).sym; + if (op == TOK.TOKassign) + { + Expression e = op_overload(sc); + if (e) + return e; + } + else if (op == TOK.TOKconstruct && !refinit) + { + Type t2 = e2.type.toBasetype(); + if (t2.ty == TY.Tstruct && sd == (cast(TypeStruct)t2).sym && sd.cpctor) + { + /* We have a copy constructor for this + */ + if (e2.op == TOK.TOKquestion) + { /* Write as: + * a ? e1 = b : e1 = c; + */ + CondExp ec = cast(CondExp)e2; + AssignExp ea1 = new AssignExp(ec.e1.loc, e1, ec.e1); + ea1.op = op; + AssignExp ea2 = new AssignExp(ec.e1.loc, e1, ec.e2); + ea2.op = op; + Expression e = new CondExp(loc, ec.econd, ea1, ea2); + return e.semantic(sc); + } + else if (e2.op == TOK.TOKvar || e2.op == TOK.TOKdotvar || e2.op == TOK.TOKstar || e2.op == TOK.TOKindex) + { /* Write as: + * e1.cpctor(e2); + */ + Expression e = new DotVarExp(loc, e1, sd.cpctor, 0); + e = new CallExp(loc, e, e2); + return e.semantic(sc); + } + } + } + } + else if (t1.ty == TY.Tclass) + { + // Disallow assignment operator overloads for same type + if (!e2.type.implicitConvTo(e1.type)) + { + Expression e = op_overload(sc); + if (e) + return e; + } + } + + if (t1.ty == TY.Tsarray && !refinit) + { + // Convert e1 to e1[] + Expression e = new SliceExp(e1.loc, e1, null, null); + e1 = e.semantic(sc); + t1 = e1.type.toBasetype(); + } + + e2.rvalue(); + + if (e1.op == TOK.TOKarraylength) + { + // e1 is not an lvalue, but we let code generator handle it + ArrayLengthExp ale = cast(ArrayLengthExp)e1; + ale.e1 = ale.e1.modifiableLvalue(sc, e1); + } + else if (e1.op == TOK.TOKslice) + { + Type tn = e1.type.nextOf(); + if (tn && !tn.isMutable() && op != TOK.TOKconstruct) + error("slice %s is not mutable", e1.toChars()); + } + else + { + // Try to do a decent error message with the expression + // before it got constant folded + if (e1.op != TOK.TOKvar) + e1 = e1.optimize(WANT.WANTvalue); + + if (op != TOK.TOKconstruct) + e1 = e1.modifiableLvalue(sc, e1old); + } + + Type t2 = e2.type; + if (e1.op == TOK.TOKslice && t1.nextOf() && e2.implicitConvTo(t1.nextOf())) + { + // memset + ismemset = 1; // make it easy for back end to tell what this is + e2 = e2.implicitCastTo(sc, t1.nextOf()); + } + else if (t1.ty == TY.Tsarray) + { + /* Should have already converted e1 => e1[] + */ + assert(op == TOK.TOKconstruct); + //error("cannot assign to static array %s", e1.toChars()); + } + else if (e1.op == TOK.TOKslice) + { + e2 = e2.implicitCastTo(sc, e1.type.constOf()); + } + else + { + e2 = e2.implicitCastTo(sc, e1.type); + } + + /* Look for array operations + */ + if (e1.op == TOK.TOKslice && !ismemset && + (e2.op == TOK.TOKadd || e2.op == TOK.TOKmin || + e2.op == TOK.TOKmul || e2.op == TOK.TOKdiv || + e2.op == TOK.TOKmod || e2.op == TOK.TOKxor || + e2.op == TOK.TOKand || e2.op == TOK.TOKor || + e2.op == TOK.TOKtilde || e2.op == TOK.TOKneg)) + { + type = e1.type; + return arrayOp(sc); + } + + type = e1.type; + assert(type); return this; } - Expression checkToBoolean() + override Expression checkToBoolean() { assert(false); } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { return interpretAssignCommon(istate, null); } - Identifier opId() + override Identifier opId() { return Id.assign; } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { - /* Evaluate assign expressions right to left - */ - e2.buildArrayIdent(buf, arguments); - e1.buildArrayIdent(buf, arguments); + /* Evaluate assign expressions right to left + */ + e2.buildArrayIdent(buf, arguments); + e1.buildArrayIdent(buf, arguments); buf.writestring("Assign"); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { - /* Evaluate assign expressions right to left - */ - Expression ex2 = e2.buildArrayLoop(fparams); - version (DMDV2) { - /* Need the cast because: - * b = c + p[i]; - * where b is a byte fails because (c + p[i]) is an int - * which cannot be implicitly cast to byte. - */ - ex2 = new CastExp(Loc(0), ex2, e1.type.nextOf()); - } - Expression ex1 = e1.buildArrayLoop(fparams); - Argument param = cast(Argument)fparams.data[0]; - param.storageClass = STCundefined; - Expression e = new AssignExp(Loc(0), ex1, ex2); + /* Evaluate assign expressions right to left + */ + Expression ex2 = e2.buildArrayLoop(fparams); + version (DMDV2) { + /* Need the cast because: + * b = c + p[i]; + * where b is a byte fails because (c + p[i]) is an int + * which cannot be implicitly cast to byte. + */ + ex2 = new CastExp(Loc(0), ex2, e1.type.nextOf()); + } + Expression ex1 = e1.buildArrayLoop(fparams); + Argument param = cast(Argument)fparams.data[0]; + param.storageClass = STCundefined; + Expression e = new AssignExp(Loc(0), ex1, ex2); return e; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { - elem* e; - IndexExp ae; - int r; - Type t1b; - - //printf("AssignExp.toElem('%s')\n", toChars()); - t1b = e1.type.toBasetype(); - - // Look for array.length = n - if (e1.op == TOK.TOKarraylength) - { - // Generate: - // _d_arraysetlength(e2, sizeelem, &ale.e1); - - ArrayLengthExp ale = cast(ArrayLengthExp)e1; - elem* p1; - elem* p2; - elem* p3; - elem* ep; - Type t1; - - p1 = e2.toElem(irs); - p3 = ale.e1.toElem(irs); - p3 = addressElem(p3, null); - t1 = ale.e1.type.toBasetype(); - -static if (true) { - // call _d_arraysetlengthT(ti, e2, &ale.e1); - p2 = t1.getTypeInfo(null).toElem(irs); - ep = el_params(p3, p1, p2, null); // c function - r = t1.nextOf().isZeroInit(Loc(0)) ? RTLSYM.RTLSYM_ARRAYSETLENGTHT : RTLSYM.RTLSYM_ARRAYSETLENGTHIT; -} else { - if (t1.next.isZeroInit()) - { - p2 = t1.getTypeInfo(null).toElem(irs); - ep = el_params(p3, p1, p2, null); // c function - r = RTLSYM.RTLSYM_ARRAYSETLENGTHT; - } - else - { - p2 = el_long(TYM.TYint, t1.next.size()); - ep = el_params(p3, p2, p1, null); // c function - Expression init = t1.next.defaultInit(); - ep = el_param(el_long(TYM.TYint, init.type.size()), ep); - elem* ei = init.toElem(irs); - ep = el_param(ei, ep); - r = RTLSYM.RTLSYM_ARRAYSETLENGTH3; - } -} - e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[r]), ep); - el_setLoc(e, loc); - return e; - } - - // Look for array[]=n - if (e1.op == TOK.TOKslice) - { - Type t1 = t1b; - Type t2 = e2.type.toBasetype(); - - // which we do if the 'next' types match - if (ismemset) - { - // Do a memset for array[]=v - //printf("Lpair %s\n", toChars()); - SliceExp are = cast(SliceExp)e1; - elem* elwr; - elem* eupr; - elem* n1; - elem* evalue; - elem* enbytes; - elem* elength; - elem* einit; - long value; - Type ta = are.e1.type.toBasetype(); - Type tb = ta.nextOf().toBasetype(); - int sz = cast(uint)tb.size(); - tym_t tym = type.totym(); - - n1 = are.e1.toElem(irs); - elwr = are.lwr ? are.lwr.toElem(irs) : null; - eupr = are.upr ? are.upr.toElem(irs) : null; - - elem* n1x = n1; - - // Look for array[]=n - if (ta.ty == TY.Tsarray) - { - TypeSArray ts = cast(TypeSArray)ta; - n1 = array_toPtr(ta, n1); - enbytes = ts.dim.toElem(irs); - n1x = n1; - n1 = el_same(&n1x); - einit = resolveLengthVar(are.lengthVar, &n1, ta); - } - else if (ta.ty == TY.Tarray) - { - n1 = el_same(&n1x); - einit = resolveLengthVar(are.lengthVar, &n1, ta); - enbytes = el_copytree(n1); - n1 = array_toPtr(ta, n1); - enbytes = el_una(OPER.OP64_32, TYM.TYint, enbytes); - } - else if (ta.ty == TY.Tpointer) - { - n1 = el_same(&n1x); - enbytes = el_long(TYM.TYint, -1); // largest possible index - einit = null; - } - - // Enforce order of evaluation of n1[elwr..eupr] as n1,elwr,eupr - elem* elwrx = elwr; - if (elwr) elwr = el_same(&elwrx); - elem* euprx = eupr; - if (eupr) eupr = el_same(&euprx); - - static if (false) { - printf("sz = %d\n", sz); - printf("n1x\n"); - elem_print(n1x); - printf("einit\n"); - elem_print(einit); - printf("elwrx\n"); - elem_print(elwrx); - printf("euprx\n"); - elem_print(euprx); - printf("n1\n"); - elem_print(n1); - printf("elwr\n"); - elem_print(elwr); - printf("eupr\n"); - elem_print(eupr); - printf("enbytes\n"); - elem_print(enbytes); - } - einit = el_combine(n1x, einit); - einit = el_combine(einit, elwrx); - einit = el_combine(einit, euprx); - - evalue = this.e2.toElem(irs); - - static if (false) { - printf("n1\n"); - elem_print(n1); - printf("enbytes\n"); - elem_print(enbytes); - } - - if (global.params.useArrayBounds && eupr && ta.ty != TY.Tpointer) - { - elem *c1; - elem *c2; - elem *ea; - elem *eb; - elem *enbytesx; - - assert(elwr); - enbytesx = enbytes; - enbytes = el_same(&enbytesx); - c1 = el_bin(OPER.OPle, TYM.TYint, el_copytree(eupr), enbytesx); - c2 = el_bin(OPER.OPle, TYM.TYint, el_copytree(elwr), el_copytree(eupr)); - c1 = el_bin(OPER.OPandand, TYM.TYint, c1, c2); - - // Construct: (c1 || ModuleArray(line)) - Symbol *sassert; - - sassert = irs.blx.module_.toModuleArray(); - ea = el_bin(OPER.OPcall,TYM.TYvoid,el_var(sassert), el_long(TYM.TYint, loc.linnum)); - eb = el_bin(OPER.OPoror,TYM.TYvoid,c1,ea); - einit = el_combine(einit, eb); - } - - if (elwr) - { - elem *elwr2; - - el_free(enbytes); - elwr2 = el_copytree(elwr); - elwr2 = el_bin(OPER.OPmul, TYM.TYint, elwr2, el_long(TYM.TYint, sz)); - n1 = el_bin(OPER.OPadd, TYM.TYnptr, n1, elwr2); - enbytes = el_bin(OPER.OPmin, TYM.TYint, eupr, elwr); - elength = el_copytree(enbytes); - } - else - elength = el_copytree(enbytes); - - e = setArray(n1, enbytes, tb, evalue, irs, op); - Lpair: - e = el_pair(TYM.TYullong, elength, e); - Lret2: - e = el_combine(einit, e); - //elem_print(e); - goto Lret; - } -///static if (false) { -/// else if (e2.op == TOK.TOKadd || e2.op == TOK.TOKmin) -/// { -/// /* It's ea[] = eb[] +- ec[] -/// */ -/// BinExp e2a = cast(BinExp)e2; -/// Type t = e2.type.toBasetype().nextOf().toBasetype(); -/// if (t.ty != TY.Tfloat32 && t.ty != TY.Tfloat64 && t.ty != TY.Tfloat80) -/// { -/// e2.error("array add/min for %s not supported", t.toChars()); -/// return el_long(TYM.TYint, 0); -/// } -/// elem* ea = e1.toElem(irs); -/// ea = array_toDarray(e1.type, ea); -/// elem* eb = e2a.e1.toElem(irs); -/// eb = array_toDarray(e2a.e1.type, eb); -/// elem* ec = e2a.e2.toElem(irs); -/// ec = array_toDarray(e2a.e2.type, ec); -/// -/// int rtl = RTLSYM.RTLSYM_ARRAYASSADDFLOAT; -/// if (t.ty == Tfloat64) -/// rtl = RTLSYM.RTLSYM_ARRAYASSADDDOUBLE; -/// else if (t.ty == Tfloat80) -/// rtl = RTLSYM.RTLSYM_ARRAYASSADDREAL; -/// if (e2.op == TOK.TOKmin) -/// { -/// rtl = RTLSYM.RTLSYM_ARRAYASSMINFLOAT; -/// if (t.ty == Tfloat64) -/// rtl = RTLSYM.RTLSYM_ARRAYASSMINDOUBLE; -/// else if (t.ty == Tfloat80) -/// rtl = RTLSYM.RTLSYM_ARRAYASSMINREAL; -/// } -/// -/// /* Set parameters so the order of evaluation is eb, ec, ea -/// */ -/// elem* ep = el_params(eb, ec, ea, null); -/// e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[rtl]), ep); -/// goto Lret; -/// } -///} - else - { - /* It's array1[]=array2[] - * which is a memcpy - */ - elem* eto; - elem* efrom; - elem* esize; - elem* ep; - - eto = e1.toElem(irs); - efrom = e2.toElem(irs); - - uint size = cast(uint)t1.nextOf().size(); - esize = el_long(TYM.TYint, size); - - /* Determine if we need to do postblit - */ - int postblit = 0; - if (needsPostblit(t1)) - postblit = 1; - - assert(e2.type.ty != TY.Tpointer); - - if (!postblit && !global.params.useArrayBounds) - { - elem* epto; - elem* epfr; - elem* elen; - elem* ex; - - ex = el_same(&eto); - - // Determine if elen is a constant - if (eto.Eoper == OPER.OPpair && eto.E1.Eoper == OPER.OPconst) - { - elen = el_copytree(eto.E1); - } - else - { - // It's not a constant, so pull it from the dynamic array - elen = el_una(OPER.OP64_32, TYM.TYint, el_copytree(ex)); - } - - esize = el_bin(OPER.OPmul, TYM.TYint, elen, esize); - epto = array_toPtr(e1.type, ex); - epfr = array_toPtr(e2.type, efrom); - static if (true) { - // memcpy() is faster, so if we can't beat 'em, join 'em - e = el_params(esize, epfr, epto, null); - e = el_bin(OPER.OPcall, TYM.TYnptr, el_var(rtlsym[RTLSYM.RTLSYM_MEMCPY]), e); - } else { - e = el_bin(OPER.OPmemcpy, TYM.TYnptr, epto, el_param(epfr, esize)); - } - e = el_pair(eto.Ety, el_copytree(elen), e); - e = el_combine(eto, e); - } -///version (DMDV2) { - else if (postblit && op != TOK.TOKblit) - { - /* Generate: - * _d_arrayassign(ti, efrom, eto) - * or: - * _d_arrayctor(ti, efrom, eto) - */ - el_free(esize); - Expression ti = t1.nextOf().toBasetype().getTypeInfo(null); - ep = el_params(eto, efrom, ti.toElem(irs), null); - int rtl = (op == TOK.TOKconstruct) ? RTLSYM.RTLSYM_ARRAYCTOR : RTLSYM.RTLSYM_ARRAYASSIGN; - e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[rtl]), ep); - } -///} - else - { - // Generate: - // _d_arraycopy(eto, efrom, esize) - - ep = el_params(eto, efrom, esize, null); - e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[RTLSYM.RTLSYM_ARRAYCOPY]), ep); - } - el_setLoc(e, loc); - return e; - } - } - - if (e1.op == TOK.TOKindex) - { - elem* eb; - elem* ei; - elem* ev; - TY ty; - Type ta; - - ae = cast(IndexExp)e1; - ta = ae.e1.type.toBasetype(); - ty = ta.ty; - } - -version (DMDV2) { - /* Look for reference initializations - */ - if (op == TOK.TOKconstruct && e1.op == TOK.TOKvar) - { - VarExp ve = cast(VarExp)e1; - Declaration s = ve.var; - if (s.storage_class & STC.STCref) - { -static if (false) { - Expression ae = e2.addressOf(null); - e = ae.toElem(irs); -} else { - e = e2.toElem(irs); - e = addressElem(e, e2.type); -} - elem* es = el_var(s.toSymbol()); - es.Ety = TYM.TYnptr; - e = el_bin(OPER.OPeq, TYM.TYnptr, es, e); - // BUG: type is struct, and e2 is TOKint64 - goto Lret; - } - } -} - -static if (true) { - /* This will work if we can distinguish an assignment from - * an initialization of the lvalue. It'll work if the latter. - * If the former, because of aliasing of the return value with - * function arguments, it'll fail. - */ - if (op == TOK.TOKconstruct && e2.op == TOK.TOKcall) - { - CallExp ce = cast(CallExp)e2; - - Type t = ce.e1.type.toBasetype(); - if (t.ty == TY.Tfunction) { - TypeFunction tf = cast(TypeFunction)t; - if (tf.retStyle() == RET.RETstack) - { - elem* ehidden = e1.toElem(irs); - ehidden = el_una(OPER.OPaddr, TYM.TYnptr, ehidden); - assert(!irs.ehidden); - irs.ehidden = ehidden; - e = e2.toElem(irs); - goto Lret; - } - } - } -} - //printf("test2 %d\n", op); - //if (op == TOK.TOKconstruct) printf("construct\n"); - if (t1b.ty == TY.Tstruct) - { - elem* eleft = e1.toElem(irs); - - if (e2.op == TOK.TOKint64) - { - /* Implement: - * (struct = 0) - * with: - * memset(&struct, 0, struct.sizeof) - */ - elem* ey = null; - int sz = cast(int)e1.type.size(); - StructDeclaration sd = (cast(TypeStruct)t1b).sym; - if (sd.isnested && op == TOK.TOKconstruct) - { - ey = el_una(OPER.OPaddr, TYM.TYnptr, eleft); - eleft = el_same(&ey); - ey = setEthis(loc, irs, ey, sd); - sz = sd.vthis.offset; - } - - elem *el = eleft; - elem *enbytes = el_long(TYM.TYint, sz); - elem *evalue = el_long(TYM.TYint, 0); - - if (!(sd.isnested && op == TOK.TOKconstruct)) - el = el_una(OPER.OPaddr, TYM.TYnptr, el); - - e = el_param(enbytes, evalue); - e = el_bin(OPER.OPmemset, TYM.TYnptr,el,e); - e = el_combine(ey, e); - el_setLoc(e, loc); - //e = el_una(OPER.OPind, TYM.TYstruct, e); - } - else - { - //printf("toElemBin() '%s'\n", toChars()); - - tym_t tym = type.totym(); - - elem* e1 = eleft; - elem* ex = e1; - if (e1.Eoper == OPER.OPind) - ex = e1.E1; - - if (this.e2.op == TOK.TOKstructliteral && ex.Eoper == OPER.OPvar && ex.EV.sp.Voffset == 0) - { - StructLiteralExp se = cast(StructLiteralExp)this.e2; - - Symbol* symSave = se.sym; - size_t soffsetSave = se.soffset; - int fillHolesSave = se.fillHoles; - - se.sym = ex.EV.sp.Vsym; - se.soffset = 0; - se.fillHoles = (op == TOK.TOKconstruct || op == TOK.TOKblit) ? 1 : 0; - - el_free(e1); - e = this.e2.toElem(irs); - - se.sym = symSave; - se.soffset = soffsetSave; - se.fillHoles = fillHolesSave; - } - else - { - elem* e2 = this.e2.toElem(irs); - e = el_bin(OPER.OPstreq,tym,e1,e2); - e.Enumbytes = cast(uint)this.e1.type.size(); - } - goto Lret; - } - } - else - e = toElemBin(irs,OPER.OPeq); - - return e; - - Lret: - el_setLoc(e,loc); + elem* e; + IndexExp ae; + int r; + Type t1b; + + //printf("AssignExp.toElem('%s')\n", toChars()); + t1b = e1.type.toBasetype(); + + // Look for array.length = n + if (e1.op == TOK.TOKarraylength) + { + // Generate: + // _d_arraysetlength(e2, sizeelem, &ale.e1); + + ArrayLengthExp ale = cast(ArrayLengthExp)e1; + elem* p1; + elem* p2; + elem* p3; + elem* ep; + Type t1; + + p1 = e2.toElem(irs); + p3 = ale.e1.toElem(irs); + p3 = addressElem(p3, null); + t1 = ale.e1.type.toBasetype(); + +static if (true) { + // call _d_arraysetlengthT(ti, e2, &ale.e1); + p2 = t1.getTypeInfo(null).toElem(irs); + ep = el_params(p3, p1, p2, null); // c function + r = t1.nextOf().isZeroInit(Loc(0)) ? RTLSYM.RTLSYM_ARRAYSETLENGTHT : RTLSYM.RTLSYM_ARRAYSETLENGTHIT; +} else { + if (t1.next.isZeroInit()) + { + p2 = t1.getTypeInfo(null).toElem(irs); + ep = el_params(p3, p1, p2, null); // c function + r = RTLSYM.RTLSYM_ARRAYSETLENGTHT; + } + else + { + p2 = el_long(TYM.TYint, t1.next.size()); + ep = el_params(p3, p2, p1, null); // c function + Expression init = t1.next.defaultInit(); + ep = el_param(el_long(TYM.TYint, init.type.size()), ep); + elem* ei = init.toElem(irs); + ep = el_param(ei, ep); + r = RTLSYM.RTLSYM_ARRAYSETLENGTH3; + } +} + e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[r]), ep); + el_setLoc(e, loc); + return e; + } + + // Look for array[]=n + if (e1.op == TOK.TOKslice) + { + Type t1 = t1b; + Type t2 = e2.type.toBasetype(); + + // which we do if the 'next' types match + if (ismemset) + { + // Do a memset for array[]=v + //printf("Lpair %s\n", toChars()); + SliceExp are = cast(SliceExp)e1; + elem* elwr; + elem* eupr; + elem* n1; + elem* evalue; + elem* enbytes; + elem* elength; + elem* einit; + long value; + Type ta = are.e1.type.toBasetype(); + Type tb = ta.nextOf().toBasetype(); + int sz = cast(uint)tb.size(); + tym_t tym = type.totym(); + + n1 = are.e1.toElem(irs); + elwr = are.lwr ? are.lwr.toElem(irs) : null; + eupr = are.upr ? are.upr.toElem(irs) : null; + + elem* n1x = n1; + + // Look for array[]=n + if (ta.ty == TY.Tsarray) + { + TypeSArray ts = cast(TypeSArray)ta; + n1 = array_toPtr(ta, n1); + enbytes = ts.dim.toElem(irs); + n1x = n1; + n1 = el_same(&n1x); + einit = resolveLengthVar(are.lengthVar, &n1, ta); + } + else if (ta.ty == TY.Tarray) + { + n1 = el_same(&n1x); + einit = resolveLengthVar(are.lengthVar, &n1, ta); + enbytes = el_copytree(n1); + n1 = array_toPtr(ta, n1); + enbytes = el_una(OPER.OP64_32, TYM.TYint, enbytes); + } + else if (ta.ty == TY.Tpointer) + { + n1 = el_same(&n1x); + enbytes = el_long(TYM.TYint, -1); // largest possible index + einit = null; + } + + // Enforce order of evaluation of n1[elwr..eupr] as n1,elwr,eupr + elem* elwrx = elwr; + if (elwr) elwr = el_same(&elwrx); + elem* euprx = eupr; + if (eupr) eupr = el_same(&euprx); + + static if (false) { + printf("sz = %d\n", sz); + printf("n1x\n"); + elem_print(n1x); + printf("einit\n"); + elem_print(einit); + printf("elwrx\n"); + elem_print(elwrx); + printf("euprx\n"); + elem_print(euprx); + printf("n1\n"); + elem_print(n1); + printf("elwr\n"); + elem_print(elwr); + printf("eupr\n"); + elem_print(eupr); + printf("enbytes\n"); + elem_print(enbytes); + } + einit = el_combine(n1x, einit); + einit = el_combine(einit, elwrx); + einit = el_combine(einit, euprx); + + evalue = this.e2.toElem(irs); + + static if (false) { + printf("n1\n"); + elem_print(n1); + printf("enbytes\n"); + elem_print(enbytes); + } + + if (global.params.useArrayBounds && eupr && ta.ty != TY.Tpointer) + { + elem *c1; + elem *c2; + elem *ea; + elem *eb; + elem *enbytesx; + + assert(elwr); + enbytesx = enbytes; + enbytes = el_same(&enbytesx); + c1 = el_bin(OPER.OPle, TYM.TYint, el_copytree(eupr), enbytesx); + c2 = el_bin(OPER.OPle, TYM.TYint, el_copytree(elwr), el_copytree(eupr)); + c1 = el_bin(OPER.OPandand, TYM.TYint, c1, c2); + + // Construct: (c1 || ModuleArray(line)) + Symbol *sassert; + + sassert = irs.blx.module_.toModuleArray(); + ea = el_bin(OPER.OPcall,TYM.TYvoid,el_var(sassert), el_long(TYM.TYint, loc.linnum)); + eb = el_bin(OPER.OPoror,TYM.TYvoid,c1,ea); + einit = el_combine(einit, eb); + } + + if (elwr) + { + elem *elwr2; + + el_free(enbytes); + elwr2 = el_copytree(elwr); + elwr2 = el_bin(OPER.OPmul, TYM.TYint, elwr2, el_long(TYM.TYint, sz)); + n1 = el_bin(OPER.OPadd, TYM.TYnptr, n1, elwr2); + enbytes = el_bin(OPER.OPmin, TYM.TYint, eupr, elwr); + elength = el_copytree(enbytes); + } + else + elength = el_copytree(enbytes); + + e = setArray(n1, enbytes, tb, evalue, irs, op); + Lpair: + e = el_pair(TYM.TYullong, elength, e); + Lret2: + e = el_combine(einit, e); + //elem_print(e); + goto Lret; + } +///static if (false) { +/// else if (e2.op == TOK.TOKadd || e2.op == TOK.TOKmin) +/// { +/// /* It's ea[] = eb[] +- ec[] +/// */ +/// BinExp e2a = cast(BinExp)e2; +/// Type t = e2.type.toBasetype().nextOf().toBasetype(); +/// if (t.ty != TY.Tfloat32 && t.ty != TY.Tfloat64 && t.ty != TY.Tfloat80) +/// { +/// e2.error("array add/min for %s not supported", t.toChars()); +/// return el_long(TYM.TYint, 0); +/// } +/// elem* ea = e1.toElem(irs); +/// ea = array_toDarray(e1.type, ea); +/// elem* eb = e2a.e1.toElem(irs); +/// eb = array_toDarray(e2a.e1.type, eb); +/// elem* ec = e2a.e2.toElem(irs); +/// ec = array_toDarray(e2a.e2.type, ec); +/// +/// int rtl = RTLSYM.RTLSYM_ARRAYASSADDFLOAT; +/// if (t.ty == Tfloat64) +/// rtl = RTLSYM.RTLSYM_ARRAYASSADDDOUBLE; +/// else if (t.ty == Tfloat80) +/// rtl = RTLSYM.RTLSYM_ARRAYASSADDREAL; +/// if (e2.op == TOK.TOKmin) +/// { +/// rtl = RTLSYM.RTLSYM_ARRAYASSMINFLOAT; +/// if (t.ty == Tfloat64) +/// rtl = RTLSYM.RTLSYM_ARRAYASSMINDOUBLE; +/// else if (t.ty == Tfloat80) +/// rtl = RTLSYM.RTLSYM_ARRAYASSMINREAL; +/// } +/// +/// /* Set parameters so the order of evaluation is eb, ec, ea +/// */ +/// elem* ep = el_params(eb, ec, ea, null); +/// e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[rtl]), ep); +/// goto Lret; +/// } +///} + else + { + /* It's array1[]=array2[] + * which is a memcpy + */ + elem* eto; + elem* efrom; + elem* esize; + elem* ep; + + eto = e1.toElem(irs); + efrom = e2.toElem(irs); + + uint size = cast(uint)t1.nextOf().size(); + esize = el_long(TYM.TYint, size); + + /* Determine if we need to do postblit + */ + int postblit = 0; + if (needsPostblit(t1)) + postblit = 1; + + assert(e2.type.ty != TY.Tpointer); + + if (!postblit && !global.params.useArrayBounds) + { + elem* epto; + elem* epfr; + elem* elen; + elem* ex; + + ex = el_same(&eto); + + // Determine if elen is a constant + if (eto.Eoper == OPER.OPpair && eto.E1.Eoper == OPER.OPconst) + { + elen = el_copytree(eto.E1); + } + else + { + // It's not a constant, so pull it from the dynamic array + elen = el_una(OPER.OP64_32, TYM.TYint, el_copytree(ex)); + } + + esize = el_bin(OPER.OPmul, TYM.TYint, elen, esize); + epto = array_toPtr(e1.type, ex); + epfr = array_toPtr(e2.type, efrom); + static if (true) { + // memcpy() is faster, so if we can't beat 'em, join 'em + e = el_params(esize, epfr, epto, null); + e = el_bin(OPER.OPcall, TYM.TYnptr, el_var(rtlsym[RTLSYM.RTLSYM_MEMCPY]), e); + } else { + e = el_bin(OPER.OPmemcpy, TYM.TYnptr, epto, el_param(epfr, esize)); + } + e = el_pair(eto.Ety, el_copytree(elen), e); + e = el_combine(eto, e); + } +///version (DMDV2) { + else if (postblit && op != TOK.TOKblit) + { + /* Generate: + * _d_arrayassign(ti, efrom, eto) + * or: + * _d_arrayctor(ti, efrom, eto) + */ + el_free(esize); + Expression ti = t1.nextOf().toBasetype().getTypeInfo(null); + ep = el_params(eto, efrom, ti.toElem(irs), null); + int rtl = (op == TOK.TOKconstruct) ? RTLSYM.RTLSYM_ARRAYCTOR : RTLSYM.RTLSYM_ARRAYASSIGN; + e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[rtl]), ep); + } +///} + else + { + // Generate: + // _d_arraycopy(eto, efrom, esize) + + ep = el_params(eto, efrom, esize, null); + e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[RTLSYM.RTLSYM_ARRAYCOPY]), ep); + } + el_setLoc(e, loc); + return e; + } + } + + if (e1.op == TOK.TOKindex) + { + elem* eb; + elem* ei; + elem* ev; + TY ty; + Type ta; + + ae = cast(IndexExp)e1; + ta = ae.e1.type.toBasetype(); + ty = ta.ty; + } + +version (DMDV2) { + /* Look for reference initializations + */ + if (op == TOK.TOKconstruct && e1.op == TOK.TOKvar) + { + VarExp ve = cast(VarExp)e1; + Declaration s = ve.var; + if (s.storage_class & STC.STCref) + { +static if (false) { + Expression ae = e2.addressOf(null); + e = ae.toElem(irs); +} else { + e = e2.toElem(irs); + e = addressElem(e, e2.type); +} + elem* es = el_var(s.toSymbol()); + es.Ety = TYM.TYnptr; + e = el_bin(OPER.OPeq, TYM.TYnptr, es, e); + // BUG: type is struct, and e2 is TOKint64 + goto Lret; + } + } +} + +static if (true) { + /* This will work if we can distinguish an assignment from + * an initialization of the lvalue. It'll work if the latter. + * If the former, because of aliasing of the return value with + * function arguments, it'll fail. + */ + if (op == TOK.TOKconstruct && e2.op == TOK.TOKcall) + { + CallExp ce = cast(CallExp)e2; + + Type t = ce.e1.type.toBasetype(); + if (t.ty == TY.Tfunction) { + TypeFunction tf = cast(TypeFunction)t; + if (tf.retStyle() == RET.RETstack) + { + elem* ehidden = e1.toElem(irs); + ehidden = el_una(OPER.OPaddr, TYM.TYnptr, ehidden); + assert(!irs.ehidden); + irs.ehidden = ehidden; + e = e2.toElem(irs); + goto Lret; + } + } + } +} + //printf("test2 %d\n", op); + //if (op == TOK.TOKconstruct) printf("construct\n"); + if (t1b.ty == TY.Tstruct) + { + elem* eleft = e1.toElem(irs); + + if (e2.op == TOK.TOKint64) + { + /* Implement: + * (struct = 0) + * with: + * memset(&struct, 0, struct.sizeof) + */ + elem* ey = null; + int sz = cast(int)e1.type.size(); + StructDeclaration sd = (cast(TypeStruct)t1b).sym; + if (sd.isnested && op == TOK.TOKconstruct) + { + ey = el_una(OPER.OPaddr, TYM.TYnptr, eleft); + eleft = el_same(&ey); + ey = setEthis(loc, irs, ey, sd); + sz = sd.vthis.offset; + } + + elem *el = eleft; + elem *enbytes = el_long(TYM.TYint, sz); + elem *evalue = el_long(TYM.TYint, 0); + + if (!(sd.isnested && op == TOK.TOKconstruct)) + el = el_una(OPER.OPaddr, TYM.TYnptr, el); + + e = el_param(enbytes, evalue); + e = el_bin(OPER.OPmemset, TYM.TYnptr,el,e); + e = el_combine(ey, e); + el_setLoc(e, loc); + //e = el_una(OPER.OPind, TYM.TYstruct, e); + } + else + { + //printf("toElemBin() '%s'\n", toChars()); + + tym_t tym = type.totym(); + + elem* e1 = eleft; + elem* ex = e1; + if (e1.Eoper == OPER.OPind) + ex = e1.E1; + + if (this.e2.op == TOK.TOKstructliteral && ex.Eoper == OPER.OPvar && ex.EV.sp.Voffset == 0) + { + StructLiteralExp se = cast(StructLiteralExp)this.e2; + + Symbol* symSave = se.sym; + size_t soffsetSave = se.soffset; + int fillHolesSave = se.fillHoles; + + se.sym = ex.EV.sp.Vsym; + se.soffset = 0; + se.fillHoles = (op == TOK.TOKconstruct || op == TOK.TOKblit) ? 1 : 0; + + el_free(e1); + e = this.e2.toElem(irs); + + se.sym = symSave; + se.soffset = soffsetSave; + se.fillHoles = fillHolesSave; + } + else + { + elem* e2 = this.e2.toElem(irs); + e = el_bin(OPER.OPstreq,tym,e1,e2); + e.Enumbytes = cast(uint)this.e1.type.size(); + } + goto Lret; + } + } + else + e = toElemBin(irs,OPER.OPeq); + + return e; + + Lret: + el_setLoc(e,loc); return e; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AssocArrayLiteralExp.d --- a/dmd/AssocArrayLiteralExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AssocArrayLiteralExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,410 +1,410 @@ -module dmd.AssocArrayLiteralExp; - -import dmd.Expression; -import dmd.GlobalExpressions; -import dmd.WANT; -import dmd.expression.Equal; -import dmd.backend.elem; -import dmd.InterState; -import dmd.MATCH; -import dmd.Type; -import dmd.TypeAArray; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.InlineCostState; -import dmd.IRState; -import dmd.TY; -import dmd.InlineDoState; -import dmd.HdrGenState; -import dmd.InlineScanState; -import dmd.ArrayTypes; -import dmd.TOK; -import dmd.PREC; -import dmd.expression.Util; -import dmd.backend.Util; -import dmd.backend.TYM; -import dmd.backend.mTY; -import dmd.backend.OPER; -import dmd.backend.RTLSYM; - -class AssocArrayLiteralExp : Expression -{ - Expressions keys; - Expressions values; - - this(Loc loc, Expressions keys, Expressions values) - { - super(loc, TOK.TOKassocarrayliteral, this.sizeof); - assert(keys.dim == values.dim); - this.keys = keys; - this.values = values; - } - - Expression syntaxCopy() - { - return new AssocArrayLiteralExp(loc, - arraySyntaxCopy(keys), arraySyntaxCopy(values)); - } - - Expression semantic(Scope sc) - { - Expression e; - Type tkey = null; - Type tvalue = null; - - version (LOGSEMANTIC) { - printf("AssocArrayLiteralExp.semantic('%s')\n", toChars()); - } - - // Run semantic() on each element - for (size_t i = 0; i < keys.dim; i++) - { Expression key = cast(Expression)keys.data[i]; - Expression value = cast(Expression)values.data[i]; - - key = key.semantic(sc); - value = value.semantic(sc); - - keys.data[i] = cast(void *)key; - values.data[i] = cast(void *)value; - } - expandTuples(keys); - expandTuples(values); - if (keys.dim != values.dim) - { - error("number of keys is %u, must match number of values %u", keys.dim, values.dim); - keys.setDim(0); - values.setDim(0); - } - for (size_t i = 0; i < keys.dim; i++) - { Expression key = cast(Expression)keys.data[i]; - Expression value = cast(Expression)values.data[i]; - - if (!key.type) - error("%s has no value", key.toChars()); - if (!value.type) - error("%s has no value", value.toChars()); - key = resolveProperties(sc, key); - value = resolveProperties(sc, value); - - if (!tkey) - tkey = key.type; - else - key = key.implicitCastTo(sc, tkey); - keys.data[i] = cast(void *)key; - - if (!tvalue) - tvalue = value.type; - else - value = value.implicitCastTo(sc, tvalue); - values.data[i] = cast(void *)value; - } - - if (!tkey) - tkey = Type.tvoid; - if (!tvalue) - tvalue = Type.tvoid; - type = new TypeAArray(tvalue, tkey); - type = type.semantic(loc, sc); - return this; - } - - bool isBool(bool result) - { - size_t dim = keys.dim; - return result ? (dim != 0) : (dim == 0); - } - - elem* toElem(IRState* irs) - { - elem* e; - size_t dim; - - //printf("AssocArrayLiteralExp.toElem() %s\n", toChars()); - dim = keys.dim; - e = el_long(TYint, dim); - for (size_t i = 0; i < dim; i++) - { - Expression el = cast(Expression)keys.data[i]; - - for (int j = 0; j < 2; j++) - { - elem* ep = el.toElem(irs); - - if (tybasic(ep.Ety) == TYstruct || tybasic(ep.Ety) == TYarray) - { - ep = el_una(OPstrpar, TYstruct, ep); - ep.Enumbytes = cast(uint)el.type.size(); - } - //printf("[%d] %s\n", i, el.toChars()); - //elem_print(ep); - e = el_param(ep, e); - el = cast(Expression)values.data[i]; - } - } - - Type t = type.toBasetype().mutableOf(); - assert(t.ty == Taarray); - TypeAArray ta = cast(TypeAArray)t; - - /* 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 - * is an array of const or invariant, make it an array of mutable. - */ - Type tkey = ta.index.toBasetype(); - if (tkey.ty == Tarray) - { - tkey = tkey.nextOf().mutableOf().arrayOf(); - tkey = tkey.semantic(Loc(0), null); - ta = new TypeAArray(ta.nextOf(), tkey); - ta = cast(TypeAArray)ta.merge(); - } - - e = el_param(e, ta.getTypeInfo(null).toElem(irs)); - - // call _d_assocarrayliteralT(ti, dim, ...) - e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALT]),e); - - el_setLoc(e,loc); - return e; - } - - bool checkSideEffect(int flag) - { - bool f = false; - - for (size_t i = 0; i < keys.dim; i++) - { Expression key = cast(Expression)keys.data[i]; - Expression value = cast(Expression)values.data[i]; - - f |= key.checkSideEffect(2); - f |= value.checkSideEffect(2); - } - if (flag == 0 && f == 0) - Expression.checkSideEffect(0); - return f; - } - - void toCBuffer(OutBuffer buf, HdrGenState* hgs) - { - buf.writeByte('['); - for (size_t i = 0; i < keys.dim; i++) - { Expression key = cast(Expression)keys.data[i]; - Expression value = cast(Expression)values.data[i]; - - if (i) - buf.writeByte(','); - expToCBuffer(buf, hgs, key, PREC.PREC_assign); - buf.writeByte(':'); - expToCBuffer(buf, hgs, value, PREC.PREC_assign); - } - buf.writeByte(']'); - } - - void toMangleBuffer(OutBuffer buf) - { - size_t dim = keys.dim; - buf.printf("A%u", dim); - for (size_t i = 0; i < dim; i++) - { Expression key = cast(Expression)keys.data[i]; - Expression value = cast(Expression)values.data[i]; - - key.toMangleBuffer(buf); - value.toMangleBuffer(buf); - } - } - - void scanForNestedRef(Scope sc) - { - assert(false); - } - - Expression optimize(int result) - { - assert(keys.dim == values.dim); - for (size_t i = 0; i < keys.dim; i++) - { - Expression e = cast(Expression)keys.data[i]; - - e = e.optimize(WANTvalue | (result & WANTinterpret)); - keys.data[i] = cast(void*)e; - - e = cast(Expression)values.data[i]; - e = e.optimize(WANTvalue | (result & WANTinterpret)); - values.data[i] = cast(void*)e; - } - return this; - } - - Expression interpret(InterState istate) - { - Expressions keysx = keys; - Expressions valuesx = values; - -version (LOG) { - printf("AssocArrayLiteralExp.interpret() %s\n", toChars()); -} - for (size_t i = 0; i < keys.dim; i++) - { - Expression ekey = cast(Expression)keys.data[i]; - Expression evalue = cast(Expression)values.data[i]; - Expression ex; - - ex = ekey.interpret(istate); - if (ex is EXP_CANT_INTERPRET) - goto Lerr; - - /* If any changes, do Copy On Write - */ - if (ex != ekey) - { - if (keysx == keys) - keysx = cast(Expressions)keys.copy(); - keysx.data[i] = cast(void*)ex; - } - - ex = evalue.interpret(istate); - if (ex is EXP_CANT_INTERPRET) - goto Lerr; - - /* If any changes, do Copy On Write - */ - if (ex != evalue) - { - if (valuesx == values) - valuesx = cast(Expressions)values.copy(); - valuesx.data[i] = cast(void*)ex; - } - } - - if (keysx != keys) - expandTuples(keysx); - if (valuesx != values) - expandTuples(valuesx); - if (keysx.dim != valuesx.dim) - goto Lerr; - - /* Remove duplicate keys - */ - for (size_t i = 1; i < keysx.dim; i++) - { - Expression ekey = cast(Expression)keysx.data[i - 1]; - - for (size_t j = i; j < keysx.dim; j++) - { - Expression ekey2 = cast(Expression)keysx.data[j]; - Expression ex = Equal(TOKequal, Type.tbool, ekey, ekey2); - if (ex is EXP_CANT_INTERPRET) - goto Lerr; - if (ex.isBool(true)) // if a match - { - // Remove ekey - if (keysx == keys) - keysx = cast(Expressions)keys.copy(); - if (valuesx == values) - valuesx = cast(Expressions)values.copy(); - keysx.remove(i - 1); - valuesx.remove(i - 1); - i -= 1; // redo the i'th iteration - break; - } - } - } - - if (keysx != keys || valuesx != values) - { - AssocArrayLiteralExp ae; - ae = new AssocArrayLiteralExp(loc, keysx, valuesx); - ae.type = type; - return ae; - } - return this; - - Lerr: - if (keysx != keys) - delete keysx; - if (valuesx != values) - delete values; - return EXP_CANT_INTERPRET; - } - - MATCH implicitConvTo(Type t) - { - MATCH result = MATCHexact; - - Type typeb = type.toBasetype(); - Type tb = t.toBasetype(); - if (tb.ty == Taarray && typeb.ty == Taarray) - { - for (size_t i = 0; i < keys.dim; i++) - { - Expression e = cast(Expression)keys.data[i]; - MATCH m = cast(MATCH)e.implicitConvTo((cast(TypeAArray)tb).index); - if (m < result) - result = m; // remember worst match - if (result == MATCHnomatch) - break; // no need to check for worse - e = cast(Expression)values.data[i]; - m = cast(MATCH)e.implicitConvTo(tb.nextOf()); - if (m < result) - result = m; // remember worst match - if (result == MATCHnomatch) - break; // no need to check for worse - } - return result; - } - else - return Expression.implicitConvTo(t); - } - - Expression castTo(Scope sc, Type t) - { - if (type == t) - return this; - AssocArrayLiteralExp e = this; - Type typeb = type.toBasetype(); - Type tb = t.toBasetype(); - if (tb.ty == Taarray && typeb.ty == Taarray && tb.nextOf().toBasetype().ty != Tvoid) - { - e = cast(AssocArrayLiteralExp)copy(); - e.keys = cast(Expressions)keys.copy(); - e.values = cast(Expressions)values.copy(); - assert(keys.dim == values.dim); - for (size_t i = 0; i < keys.dim; i++) - { - Expression ex = cast(Expression)values.data[i]; - ex = ex.castTo(sc, tb.nextOf()); - e.values.data[i] = cast(void*)ex; - - ex = cast(Expression)keys.data[i]; - ex = ex.castTo(sc, (cast(TypeAArray)tb).index); - e.keys.data[i] = cast(void*)ex; - } - e.type = t; - return e; - } - L1: - return e.Expression.castTo(sc, t); - } - - bool canThrow() - { - return true; - } - - int inlineCost(InlineCostState* ics) - { - assert(false); - } - - Expression doInline(InlineDoState ids) - { - assert(false); - } - - Expression inlineScan(InlineScanState* iss) - { - assert(false); - } -} +module dmd.AssocArrayLiteralExp; + +import dmd.Expression; +import dmd.GlobalExpressions; +import dmd.WANT; +import dmd.expression.Equal; +import dmd.backend.elem; +import dmd.InterState; +import dmd.MATCH; +import dmd.Type; +import dmd.TypeAArray; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.InlineCostState; +import dmd.IRState; +import dmd.TY; +import dmd.InlineDoState; +import dmd.HdrGenState; +import dmd.InlineScanState; +import dmd.ArrayTypes; +import dmd.TOK; +import dmd.PREC; +import dmd.expression.Util; +import dmd.backend.Util; +import dmd.backend.TYM; +import dmd.backend.mTY; +import dmd.backend.OPER; +import dmd.backend.RTLSYM; + +class AssocArrayLiteralExp : Expression +{ + Expressions keys; + Expressions values; + + this(Loc loc, Expressions keys, Expressions values) + { + super(loc, TOK.TOKassocarrayliteral, this.sizeof); + assert(keys.dim == values.dim); + this.keys = keys; + this.values = values; + } + + override Expression syntaxCopy() + { + return new AssocArrayLiteralExp(loc, + arraySyntaxCopy(keys), arraySyntaxCopy(values)); + } + + override Expression semantic(Scope sc) + { + Expression e; + Type tkey = null; + Type tvalue = null; + + version (LOGSEMANTIC) { + printf("AssocArrayLiteralExp.semantic('%s')\n", toChars()); + } + + // Run semantic() on each element + for (size_t i = 0; i < keys.dim; i++) + { Expression key = cast(Expression)keys.data[i]; + Expression value = cast(Expression)values.data[i]; + + key = key.semantic(sc); + value = value.semantic(sc); + + keys.data[i] = cast(void *)key; + values.data[i] = cast(void *)value; + } + expandTuples(keys); + expandTuples(values); + if (keys.dim != values.dim) + { + error("number of keys is %u, must match number of values %u", keys.dim, values.dim); + keys.setDim(0); + values.setDim(0); + } + for (size_t i = 0; i < keys.dim; i++) + { Expression key = cast(Expression)keys.data[i]; + Expression value = cast(Expression)values.data[i]; + + if (!key.type) + error("%s has no value", key.toChars()); + if (!value.type) + error("%s has no value", value.toChars()); + key = resolveProperties(sc, key); + value = resolveProperties(sc, value); + + if (!tkey) + tkey = key.type; + else + key = key.implicitCastTo(sc, tkey); + keys.data[i] = cast(void *)key; + + if (!tvalue) + tvalue = value.type; + else + value = value.implicitCastTo(sc, tvalue); + values.data[i] = cast(void *)value; + } + + if (!tkey) + tkey = Type.tvoid; + if (!tvalue) + tvalue = Type.tvoid; + type = new TypeAArray(tvalue, tkey); + type = type.semantic(loc, sc); + return this; + } + + override bool isBool(bool result) + { + size_t dim = keys.dim; + return result ? (dim != 0) : (dim == 0); + } + + override elem* toElem(IRState* irs) + { + elem* e; + size_t dim; + + //printf("AssocArrayLiteralExp.toElem() %s\n", toChars()); + dim = keys.dim; + e = el_long(TYint, dim); + for (size_t i = 0; i < dim; i++) + { + Expression el = cast(Expression)keys.data[i]; + + for (int j = 0; j < 2; j++) + { + elem* ep = el.toElem(irs); + + if (tybasic(ep.Ety) == TYstruct || tybasic(ep.Ety) == TYarray) + { + ep = el_una(OPstrpar, TYstruct, ep); + ep.Enumbytes = cast(uint)el.type.size(); + } + //printf("[%d] %s\n", i, el.toChars()); + //elem_print(ep); + e = el_param(ep, e); + el = cast(Expression)values.data[i]; + } + } + + Type t = type.toBasetype().mutableOf(); + assert(t.ty == Taarray); + TypeAArray ta = cast(TypeAArray)t; + + /* 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 + * is an array of const or invariant, make it an array of mutable. + */ + Type tkey = ta.index.toBasetype(); + if (tkey.ty == Tarray) + { + tkey = tkey.nextOf().mutableOf().arrayOf(); + tkey = tkey.semantic(Loc(0), null); + ta = new TypeAArray(ta.nextOf(), tkey); + ta = cast(TypeAArray)ta.merge(); + } + + e = el_param(e, ta.getTypeInfo(null).toElem(irs)); + + // call _d_assocarrayliteralT(ti, dim, ...) + e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALT]),e); + + el_setLoc(e,loc); + return e; + } + + override bool checkSideEffect(int flag) + { + bool f = false; + + for (size_t i = 0; i < keys.dim; i++) + { Expression key = cast(Expression)keys.data[i]; + Expression value = cast(Expression)values.data[i]; + + f |= key.checkSideEffect(2); + f |= value.checkSideEffect(2); + } + if (flag == 0 && f == 0) + Expression.checkSideEffect(0); + return f; + } + + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) + { + buf.writeByte('['); + for (size_t i = 0; i < keys.dim; i++) + { Expression key = cast(Expression)keys.data[i]; + Expression value = cast(Expression)values.data[i]; + + if (i) + buf.writeByte(','); + expToCBuffer(buf, hgs, key, PREC.PREC_assign); + buf.writeByte(':'); + expToCBuffer(buf, hgs, value, PREC.PREC_assign); + } + buf.writeByte(']'); + } + + override void toMangleBuffer(OutBuffer buf) + { + size_t dim = keys.dim; + buf.printf("A%u", dim); + for (size_t i = 0; i < dim; i++) + { Expression key = cast(Expression)keys.data[i]; + Expression value = cast(Expression)values.data[i]; + + key.toMangleBuffer(buf); + value.toMangleBuffer(buf); + } + } + + override void scanForNestedRef(Scope sc) + { + assert(false); + } + + override Expression optimize(int result) + { + assert(keys.dim == values.dim); + for (size_t i = 0; i < keys.dim; i++) + { + Expression e = cast(Expression)keys.data[i]; + + e = e.optimize(WANTvalue | (result & WANTinterpret)); + keys.data[i] = cast(void*)e; + + e = cast(Expression)values.data[i]; + e = e.optimize(WANTvalue | (result & WANTinterpret)); + values.data[i] = cast(void*)e; + } + return this; + } + + override Expression interpret(InterState istate) + { + Expressions keysx = keys; + Expressions valuesx = values; + +version (LOG) { + printf("AssocArrayLiteralExp.interpret() %s\n", toChars()); +} + for (size_t i = 0; i < keys.dim; i++) + { + Expression ekey = cast(Expression)keys.data[i]; + Expression evalue = cast(Expression)values.data[i]; + Expression ex; + + ex = ekey.interpret(istate); + if (ex is EXP_CANT_INTERPRET) + goto Lerr; + + /* If any changes, do Copy On Write + */ + if (ex != ekey) + { + if (keysx == keys) + keysx = cast(Expressions)keys.copy(); + keysx.data[i] = cast(void*)ex; + } + + ex = evalue.interpret(istate); + if (ex is EXP_CANT_INTERPRET) + goto Lerr; + + /* If any changes, do Copy On Write + */ + if (ex != evalue) + { + if (valuesx == values) + valuesx = cast(Expressions)values.copy(); + valuesx.data[i] = cast(void*)ex; + } + } + + if (keysx != keys) + expandTuples(keysx); + if (valuesx != values) + expandTuples(valuesx); + if (keysx.dim != valuesx.dim) + goto Lerr; + + /* Remove duplicate keys + */ + for (size_t i = 1; i < keysx.dim; i++) + { + Expression ekey = cast(Expression)keysx.data[i - 1]; + + for (size_t j = i; j < keysx.dim; j++) + { + Expression ekey2 = cast(Expression)keysx.data[j]; + Expression ex = Equal(TOKequal, Type.tbool, ekey, ekey2); + if (ex is EXP_CANT_INTERPRET) + goto Lerr; + if (ex.isBool(true)) // if a match + { + // Remove ekey + if (keysx == keys) + keysx = cast(Expressions)keys.copy(); + if (valuesx == values) + valuesx = cast(Expressions)values.copy(); + keysx.remove(i - 1); + valuesx.remove(i - 1); + i -= 1; // redo the i'th iteration + break; + } + } + } + + if (keysx != keys || valuesx != values) + { + AssocArrayLiteralExp ae; + ae = new AssocArrayLiteralExp(loc, keysx, valuesx); + ae.type = type; + return ae; + } + return this; + + Lerr: + if (keysx != keys) + delete keysx; + if (valuesx != values) + delete values; + return EXP_CANT_INTERPRET; + } + + override MATCH implicitConvTo(Type t) + { + MATCH result = MATCHexact; + + Type typeb = type.toBasetype(); + Type tb = t.toBasetype(); + if (tb.ty == Taarray && typeb.ty == Taarray) + { + for (size_t i = 0; i < keys.dim; i++) + { + Expression e = cast(Expression)keys.data[i]; + MATCH m = cast(MATCH)e.implicitConvTo((cast(TypeAArray)tb).index); + if (m < result) + result = m; // remember worst match + if (result == MATCHnomatch) + break; // no need to check for worse + e = cast(Expression)values.data[i]; + m = cast(MATCH)e.implicitConvTo(tb.nextOf()); + if (m < result) + result = m; // remember worst match + if (result == MATCHnomatch) + break; // no need to check for worse + } + return result; + } + else + return Expression.implicitConvTo(t); + } + + override Expression castTo(Scope sc, Type t) + { + if (type == t) + return this; + AssocArrayLiteralExp e = this; + Type typeb = type.toBasetype(); + Type tb = t.toBasetype(); + if (tb.ty == Taarray && typeb.ty == Taarray && tb.nextOf().toBasetype().ty != Tvoid) + { + e = cast(AssocArrayLiteralExp)copy(); + e.keys = cast(Expressions)keys.copy(); + e.values = cast(Expressions)values.copy(); + assert(keys.dim == values.dim); + for (size_t i = 0; i < keys.dim; i++) + { + Expression ex = cast(Expression)values.data[i]; + ex = ex.castTo(sc, tb.nextOf()); + e.values.data[i] = cast(void*)ex; + + ex = cast(Expression)keys.data[i]; + ex = ex.castTo(sc, (cast(TypeAArray)tb).index); + e.keys.data[i] = cast(void*)ex; + } + e.type = t; + return e; + } + L1: + return e.Expression.castTo(sc, t); + } + + override bool canThrow() + { + return true; + } + + override int inlineCost(InlineCostState* ics) + { + assert(false); + } + + override Expression doInline(InlineDoState ids) + { + assert(false); + } + + override Expression inlineScan(InlineScanState* iss) + { + assert(false); + } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/AttribDeclaration.d --- a/dmd/AttribDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/AttribDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -25,7 +25,7 @@ return decl; } - bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) + override bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) { bool m = false; Array d = include(sc, sd); @@ -104,7 +104,7 @@ } } - void semantic(Scope sc) + override void semantic(Scope sc) { Array d = include(sc, null); @@ -120,7 +120,7 @@ } } - void semantic2(Scope sc) + override void semantic2(Scope sc) { Array d = include(sc, null); @@ -133,7 +133,7 @@ } } - void semantic3(Scope sc) + override void semantic3(Scope sc) { Array d = include(sc, null); @@ -147,7 +147,7 @@ } } - void inlineScan() + override void inlineScan() { Array d = include(null, null); @@ -162,7 +162,7 @@ } } - void addComment(ubyte* comment) + override void addComment(ubyte* comment) { if (comment !is null) { @@ -179,24 +179,24 @@ } } - void emitComment(Scope sc) + override void emitComment(Scope sc) { assert(false); } - string kind() + override string kind() { assert(false); } - bool oneMember(Dsymbol* ps) + override bool oneMember(Dsymbol* ps) { Array d = include(null, null); return Dsymbol.oneMembers(d, ps); } - bool hasPointers() + override bool hasPointers() { Array d = include(null, null); @@ -213,7 +213,7 @@ return 0; } - void checkCtorConstInit() + override void checkCtorConstInit() { Array d = include(null, null); if (d) @@ -226,7 +226,7 @@ } } - void addLocalClass(ClassDeclarations aclasses) + override void addLocalClass(ClassDeclarations aclasses) { Array d = include(null, null); if (d) @@ -239,14 +239,14 @@ } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - AttribDeclaration isAttribDeclaration() { return this; } + override AttribDeclaration isAttribDeclaration() { return this; } - void toObjFile(int multiobj) // compile to .obj file + override void toObjFile(int multiobj) // compile to .obj file { Array d = include(null, null); @@ -260,8 +260,8 @@ } } - int cvMember(ubyte* p) + override int cvMember(ubyte* p) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/BinExp.d --- a/dmd/BinExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/BinExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -394,7 +394,7 @@ this.e2 = e2; } - Expression syntaxCopy() + override Expression syntaxCopy() { BinExp e = cast(BinExp)copy(); e.type = null; @@ -404,7 +404,7 @@ return e; } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { version (LOGSEMANTIC) { printf("BinExp.semantic('%.*s')\n", toChars()); @@ -512,7 +512,7 @@ return this; } - bool checkSideEffect(int flag) + override bool checkSideEffect(int flag) { switch (op) { case TOK.TOKplusplus: @@ -541,7 +541,7 @@ } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { expToCBuffer(buf, hgs, e1, precedence[op]); buf.writeByte(' '); @@ -627,7 +627,7 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { //printf("BinExp.optimize(result = %d) %s\n", result, toChars()); if (op != TOK.TOKconstruct && op != TOK.TOKblit) // don't replace const variable with its initializer @@ -664,7 +664,7 @@ e1.type.toChars(), e2.type.toChars()); } - void dump(int indent) + override void dump(int indent) { assert(false); } @@ -1324,7 +1324,7 @@ return e; } - bool canThrow() + override bool canThrow() { return e1.canThrow() || e2.canThrow(); } @@ -1608,12 +1608,12 @@ return e; } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { return 1 + e1.inlineCost(ics) + e2.inlineCost(ics); } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { BinExp be = cast(BinExp)copy(); @@ -1622,7 +1622,7 @@ return be; } - Expression inlineScan(InlineScanState* iss) + override Expression inlineScan(InlineScanState* iss) { e1 = e1.inlineScan(iss); e2 = e2.inlineScan(iss); @@ -1919,4 +1919,4 @@ buf.writestring(Str); buf.writestring("ass"); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/BoolExp.d --- a/dmd/BoolExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/BoolExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,18 +1,18 @@ -module dmd.BoolExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.UnaExp; -import dmd.InterState; -import dmd.Type; -import dmd.Loc; -import dmd.Scope; +module dmd.BoolExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.UnaExp; +import dmd.InterState; +import dmd.Type; +import dmd.Loc; +import dmd.Scope; import dmd.IRState; -import dmd.TOK; +import dmd.TOK; import dmd.backend.OPER; import dmd.backend.Util; - + class BoolExp : UnaExp { this(Loc loc, Expression e, Type t) @@ -21,7 +21,7 @@ type = t; } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { UnaExp.semantic(sc); e1 = resolveProperties(sc, e1); @@ -30,22 +30,22 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { assert(false); } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - int isBit() + override int isBit() { return true; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e1 = this.e1.toElem(irs); return el_una(OPbool,type.totym(),e1); diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/BreakStatement.d --- a/dmd/BreakStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/BreakStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -30,13 +30,13 @@ this.ident = ident; } - Statement syntaxCopy() + override Statement syntaxCopy() { BreakStatement s = new BreakStatement(loc, ident); return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { //printf("BreakStatement::semantic()\n"); // If: @@ -98,23 +98,23 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - BE blockExit() + override BE blockExit() { //printf("BreakStatement::blockExit(%p) = x%x\n", this, ident ? BEgoto : BEbreak); return ident ? BE.BEgoto : BE.BEbreak; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - void toIR(IRState* irs) + override void toIR(IRState* irs) { block* bbreak; block* b; @@ -136,4 +136,4 @@ list_append(&b.Bsucc, bbreak); block_next(blx, BCgoto, null); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/CallExp.d --- a/dmd/CallExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/CallExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,85 +1,85 @@ -module dmd.CallExp; - -import dmd.Expression; -import dmd.Cast; -import dmd.WANT; -import dmd.BUILTIN; -import dmd.TypeFunction; -import dmd.ScopeDsymbol; -import dmd.CastExp; -import dmd.GlobalExpressions; -import dmd.TypePointer; -import dmd.ThisExp; -import dmd.OverExp; -import dmd.Dsymbol; -import dmd.CSX; -import dmd.AggregateDeclaration; -import dmd.TypeDelegate; -import dmd.ClassDeclaration; -import dmd.DsymbolExp; -import dmd.DotExp; -import dmd.TemplateExp; -import dmd.TypeStruct; -import dmd.TypeClass; -import dmd.Identifier; -import dmd.Lexer; -import dmd.VarDeclaration; -import dmd.DeclarationExp; -import dmd.CtorDeclaration; -import dmd.PtrExp; -import dmd.TemplateDeclaration; -import dmd.StructLiteralExp; -import dmd.StructDeclaration; -import dmd.DotTemplateExp; -import dmd.CommaExp; -import dmd.AggregateDeclaration; -import dmd.FuncDeclaration; -import dmd.Type; -import dmd.ScopeExp; -import dmd.VarExp; -import dmd.STC; -import dmd.LINK; -import dmd.Global; -import dmd.DotTemplateInstanceExp; -import dmd.TemplateInstance; -import dmd.DelegateExp; -import dmd.IdentifierExp; -import dmd.DotVarExp; -import dmd.DotIdExp; -import dmd.TY; -import dmd.Id; -import dmd.TypeAArray; -import dmd.RemoveExp; -import dmd.backend.elem; -import dmd.UnaExp; -import dmd.InterState; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.InlineCostState; -import dmd.IRState; -import dmd.InlineDoState; -import dmd.HdrGenState; -import dmd.InlineScanState; -import dmd.ArrayTypes; -import dmd.TOK; -import dmd.PREC; -import dmd.expression.Util; -import dmd.backend.Symbol; -import dmd.backend.TYPE; -import dmd.backend.Util; -import dmd.backend.TYM; -import dmd.codegen.Util; - -import std.stdio; - +module dmd.CallExp; + +import dmd.Expression; +import dmd.Cast; +import dmd.WANT; +import dmd.BUILTIN; +import dmd.TypeFunction; +import dmd.ScopeDsymbol; +import dmd.CastExp; +import dmd.GlobalExpressions; +import dmd.TypePointer; +import dmd.ThisExp; +import dmd.OverExp; +import dmd.Dsymbol; +import dmd.CSX; +import dmd.AggregateDeclaration; +import dmd.TypeDelegate; +import dmd.ClassDeclaration; +import dmd.DsymbolExp; +import dmd.DotExp; +import dmd.TemplateExp; +import dmd.TypeStruct; +import dmd.TypeClass; +import dmd.Identifier; +import dmd.Lexer; +import dmd.VarDeclaration; +import dmd.DeclarationExp; +import dmd.CtorDeclaration; +import dmd.PtrExp; +import dmd.TemplateDeclaration; +import dmd.StructLiteralExp; +import dmd.StructDeclaration; +import dmd.DotTemplateExp; +import dmd.CommaExp; +import dmd.AggregateDeclaration; +import dmd.FuncDeclaration; +import dmd.Type; +import dmd.ScopeExp; +import dmd.VarExp; +import dmd.STC; +import dmd.LINK; +import dmd.Global; +import dmd.DotTemplateInstanceExp; +import dmd.TemplateInstance; +import dmd.DelegateExp; +import dmd.IdentifierExp; +import dmd.DotVarExp; +import dmd.DotIdExp; +import dmd.TY; +import dmd.Id; +import dmd.TypeAArray; +import dmd.RemoveExp; +import dmd.backend.elem; +import dmd.UnaExp; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.InlineCostState; +import dmd.IRState; +import dmd.InlineDoState; +import dmd.HdrGenState; +import dmd.InlineScanState; +import dmd.ArrayTypes; +import dmd.TOK; +import dmd.PREC; +import dmd.expression.Util; +import dmd.backend.Symbol; +import dmd.backend.TYPE; +import dmd.backend.Util; +import dmd.backend.TYM; +import dmd.codegen.Util; + +import std.stdio; + class CallExp : UnaExp { Expressions arguments; this(Loc loc, Expression e, Expressions exps) { - super(loc, TOK.TOKcall, CallExp.sizeof, e); + super(loc, TOK.TOKcall, CallExp.sizeof, e); this.arguments = exps; } @@ -90,1051 +90,1051 @@ this(Loc loc, Expression e, Expression earg1) { - super(loc, TOK.TOKcall, CallExp.sizeof, e); - - Expressions arguments = new Expressions(); - arguments.setDim(1); - arguments.data[0] = cast(void*)earg1; - + super(loc, TOK.TOKcall, CallExp.sizeof, e); + + Expressions arguments = new Expressions(); + arguments.setDim(1); + arguments.data[0] = cast(void*)earg1; + this.arguments = arguments; } this(Loc loc, Expression e, Expression earg1, Expression earg2) - { - super(loc, TOK.TOKcall, CallExp.sizeof, e); + { + super(loc, TOK.TOKcall, CallExp.sizeof, e); - Expressions arguments = new Expressions(); - arguments.setDim(2); - arguments.data[0] = cast(void*)earg1; - arguments.data[1] = cast(void*)earg2; - + Expressions arguments = new Expressions(); + arguments.setDim(2); + arguments.data[0] = cast(void*)earg1; + arguments.data[1] = cast(void*)earg2; + this.arguments = arguments; } - Expression syntaxCopy() + override Expression syntaxCopy() { return new CallExp(loc, e1.syntaxCopy(), arraySyntaxCopy(arguments)); } - Expression semantic(Scope sc) - { - TypeFunction tf; - FuncDeclaration f; - int i; - Type t1; - int istemp; - Objects targsi; // initial list of template arguments - TemplateInstance tierror; - -version (LOGSEMANTIC) { - printf("CallExp.semantic() %s\n", toChars()); -} - if (type) - return this; // semantic() already run - -static if (false) { - if (arguments && arguments.dim) - { - Expression earg = cast(Expression)arguments.data[0]; - earg.print(); - if (earg.type) earg.type.print(); - } -} - - if (e1.op == TOK.TOKdelegate) - { - DelegateExp de = cast(DelegateExp)e1; - - e1 = new DotVarExp(de.loc, de.e1, de.func); - return semantic(sc); - } - - /* Transform: - * array.id(args) into .id(array,args) - * aa.remove(arg) into delete aa[arg] - */ - if (e1.op == TOK.TOKdot) - { - // BUG: we should handle array.a.b.c.e(args) too - - DotIdExp dotid = cast(DotIdExp)(e1); - dotid.e1 = dotid.e1.semantic(sc); - assert(dotid.e1); - if (dotid.e1.type) - { - TY e1ty = dotid.e1.type.toBasetype().ty; - if (e1ty == TY.Taarray && dotid.ident == Id.remove) - { - if (!arguments || arguments.dim != 1) - { - error("expected key as argument to aa.remove()"); - goto Lagain; - } - Expression key = cast(Expression)arguments.data[0]; - key = key.semantic(sc); - key = resolveProperties(sc, key); - key.rvalue(); - - TypeAArray taa = cast(TypeAArray)dotid.e1.type.toBasetype(); - key = key.implicitCastTo(sc, taa.index); - - return new RemoveExp(loc, dotid.e1, key); - } - else if (e1ty == TY.Tarray || e1ty == TY.Tsarray || e1ty == TY.Taarray) - { - if (!arguments) - arguments = new Expressions(); - arguments.shift(cast(void*)dotid.e1); -version (DMDV2) { - e1 = new DotIdExp(dotid.loc, new IdentifierExp(dotid.loc, Id.empty), dotid.ident); -} else { - e1 = new IdentifierExp(dotid.loc, dotid.ident); -} - } - } - } - -static if (true) { - /* This recognizes: - * foo!(tiargs)(funcargs) - */ - if (e1.op == TOK.TOKimport && !e1.type) - { - ScopeExp se = cast(ScopeExp)e1; - TemplateInstance ti = se.sds.isTemplateInstance(); - if (ti && !ti.semanticRun) - { - /* Attempt to instantiate ti. If that works, go with it. - * If not, go with partial explicit specialization. - */ - ti.semanticTiargs(sc); - uint errors = global.errors; - global.gag++; - ti.semantic(sc); - global.gag--; - if (errors != global.errors) - { - /* Didn't work, go with partial explicit specialization - */ - global.errors = errors; - targsi = ti.tiargs; - tierror = ti; // for error reporting - e1 = new IdentifierExp(loc, ti.name); - } - } - } - - /* This recognizes: - * expr.foo!(tiargs)(funcargs) - */ - if (e1.op == TOK.TOKdotti && !e1.type) - { - DotTemplateInstanceExp se = cast(DotTemplateInstanceExp)e1; - TemplateInstance ti = se.ti; - if (!ti.semanticRun) - { - /* Attempt to instantiate ti. If that works, go with it. - * If not, go with partial explicit specialization. - */ - ti.semanticTiargs(sc); - Expression etmp = e1.trySemantic(sc); - if (etmp) - e1 = etmp; // it worked - else // didn't work - { - targsi = ti.tiargs; - tierror = ti; // for error reporting - e1 = new DotIdExp(loc, se.e1, ti.name); - } - } - } -} - - istemp = 0; - Lagain: - //printf("Lagain: %s\n", toChars()); - f = null; - if (e1.op == TOK.TOKthis || e1.op == TOK.TOKsuper) - { - // semantic() run later for these - } - else - { - UnaExp.semantic(sc); - - /* Look for e1 being a lazy parameter - */ - if (e1.op == TOK.TOKvar) - { - VarExp ve = cast(VarExp)e1; - - if (ve.var.storage_class & STC.STClazy) - { - TypeFunction tff = new TypeFunction(null, ve.var.type, 0, LINK.LINKd); - TypeDelegate t = new TypeDelegate(tff); - ve.type = t.semantic(loc, sc); - } - } - - if (e1.op == TOK.TOKimport) - { - // Perhaps this should be moved to ScopeExp.semantic() - ScopeExp se = cast(ScopeExp)e1; - e1 = new DsymbolExp(loc, se.sds); - e1 = e1.semantic(sc); - } -///static if (true) { // patch for #540 by Oskar Linde - else if (e1.op == TOK.TOKdotexp) - { - DotExp de = cast(DotExp)e1; - - if (de.e2.op == TOK.TOKimport) - { - // This should *really* be moved to ScopeExp.semantic() - ScopeExp se = cast(ScopeExp)de.e2; - de.e2 = new DsymbolExp(loc, se.sds); - de.e2 = de.e2.semantic(sc); - } - - if (de.e2.op == TOK.TOKtemplate) - { - TemplateExp te = cast(TemplateExp)de.e2; - e1 = new DotTemplateExp(loc,de.e1,te.td); - } - } -///} - } - - if (e1.op == TOK.TOKcomma) - { - CommaExp ce = cast(CommaExp)e1; - - e1 = ce.e2; - e1.type = ce.type; - ce.e2 = this; - ce.type = null; - return ce.semantic(sc); - } - - t1 = null; - if (e1.type) - t1 = e1.type.toBasetype(); - - // Check for call operator overload - if (t1) - { - AggregateDeclaration ad; - - if (t1.ty == TY.Tstruct) - { - ad = (cast(TypeStruct)t1).sym; -version (DMDV2) { - // First look for constructor - if (ad.ctor && arguments && arguments.dim) - { - // Create variable that will get constructed - Identifier idtmp = Lexer.uniqueId("__ctmp"); - VarDeclaration tmp = new VarDeclaration(loc, t1, idtmp, null); - Expression av = new DeclarationExp(loc, tmp); - av = new CommaExp(loc, av, new VarExp(loc, tmp)); - - Expression e; - CtorDeclaration cf = ad.ctor.isCtorDeclaration(); - if (cf) - e = new DotVarExp(loc, av, cf, 1); - else - { - TemplateDeclaration td = ad.ctor.isTemplateDeclaration(); - assert(td); - e = new DotTemplateExp(loc, av, td); - } - e = new CallExp(loc, e, arguments); - version (STRUCTTHISREF) { - } else { - /* Constructors return a pointer to the instance - */ - e = new PtrExp(loc, e); - } - e = e.semantic(sc); - return e; - } -} - // No constructor, look for overload of opCall - if (search_function(ad, Id.call)) - goto L1; // overload of opCall, therefore it's a call - - if (e1.op != TOK.TOKtype) - error("%s %s does not overload ()", ad.kind(), ad.toChars()); - - /* It's a struct literal - */ - Expression e = new StructLiteralExp(loc, cast(StructDeclaration)ad, arguments); - e = e.semantic(sc); - e.type = e1.type; // in case e1.type was a typedef - return e; - } - else if (t1.ty == TY.Tclass) - { - ad = (cast(TypeClass)t1).sym; - goto L1; - L1: - // Rewrite as e1.call(arguments) - Expression e = new DotIdExp(loc, e1, Id.call); - e = new CallExp(loc, e, arguments); - e = e.semantic(sc); - return e; - } - } - - arrayExpressionSemantic(arguments, sc); - preFunctionArguments(loc, sc, arguments); - - if (e1.op == TOK.TOKdotvar && t1.ty == TY.Tfunction || - e1.op == TOK.TOKdottd) - { - DotVarExp dve; - DotTemplateExp dte; - AggregateDeclaration ad; - UnaExp ue = cast(UnaExp)e1; - - if (e1.op == TOK.TOKdotvar) - { - // Do overload resolution - dve = cast(DotVarExp)e1; - - f = dve.var.isFuncDeclaration(); - assert(f); - f = f.overloadResolve(loc, ue.e1, arguments); - - ad = f.toParent().isAggregateDeclaration(); - } - else - { - dte = cast(DotTemplateExp)e1; - TemplateDeclaration td = dte.td; - assert(td); - - if (!arguments) - // Should fix deduceFunctionTemplate() so it works on null argument - arguments = new Expressions(); - - f = td.deduceFunctionTemplate(sc, loc, targsi, ue.e1, arguments); - if (!f) - { - type = Type.terror; - return this; - } - ad = td.toParent().isAggregateDeclaration(); - } - - if (f.needThis()) - { - ue.e1 = getRightThis(loc, sc, ad, ue.e1, f); - } - - /* Cannot call public functions from inside invariant - * (because then the invariant would have infinite recursion) - */ - if (sc.func && sc.func.isInvariantDeclaration() && - ue.e1.op == TOK.TOKthis && f.addPostInvariant()) - { - error("cannot call public/export function %s from invariant", f.toChars()); - } - - checkDeprecated(sc, f); - version (DMDV2) { - checkPurity(sc, f); - } - accessCheck(loc, sc, ue.e1, f); - if (!f.needThis()) - { - VarExp ve = new VarExp(loc, f); - e1 = new CommaExp(loc, ue.e1, ve); - e1.type = f.type; - } - else - { - if (e1.op == TOK.TOKdotvar) - dve.var = f; - else - e1 = new DotVarExp(loc, dte.e1, f); - - e1.type = f.type; -static if (false) { - printf("ue.e1 = %s\n", ue.e1.toChars()); - printf("f = %s\n", f.toChars()); - printf("t = %s\n", t.toChars()); - printf("e1 = %s\n", e1.toChars()); - printf("e1.type = %s\n", e1.type.toChars()); -} - // Const member function can take const/immutable/mutable this - if (!(f.type.isConst())) - { - // Check for const/immutable compatibility - Type tthis = ue.e1.type.toBasetype(); - if (tthis.ty == TY.Tpointer) - tthis = tthis.nextOf().toBasetype(); - - static if (false) { // this checking should have been already done - if (f.type.isInvariant()) - { - if (tthis.mod != MOD.MODinvariant) - error("%s can only be called with an immutable object", e1.toChars()); - } - else if (f.type.isShared()) - { - if (tthis.mod != MOD.MODinvariant && tthis.mod != MOD.MODshared && tthis.mod != (MOD.MODshared | MOD.MODconst)) - error("shared %s can only be called with a shared or immutable object", e1.toChars()); - } - else - { - if (tthis.mod != MOD.MODundefined) - { - //printf("mod = %x\n", tthis.mod); - error("%s can only be called with a mutable object, not %s", e1.toChars(), tthis.toChars()); - } - } - } - /* Cannot call mutable method on a final struct - */ - if (tthis.ty == TY.Tstruct && - ue.e1.op == TOK.TOKvar) - { - VarExp v = cast(VarExp)ue.e1; - if (v.var.storage_class & STC.STCfinal) - error("cannot call mutable method on final struct"); - } - } - - // See if we need to adjust the 'this' pointer - AggregateDeclaration add = f.isThis(); - ClassDeclaration cd = ue.e1.type.isClassHandle(); - if (add && cd && add.isClassDeclaration() && add != cd && ue.e1.op != TOK.TOKsuper) - { - ue.e1 = ue.e1.castTo(sc, add.type); //new CastExp(loc, ue.e1, add.type); - ue.e1 = ue.e1.semantic(sc); - } - } - t1 = e1.type; - } - else if (e1.op == TOK.TOKsuper) - { - // Base class constructor call - ClassDeclaration cd = null; - - if (sc.func) - cd = sc.func.toParent().isClassDeclaration(); - if (!cd || !cd.baseClass || !sc.func.isCtorDeclaration()) - { - error("super class constructor call must be in a constructor"); - type = Type.terror; - return this; - } - else - { - if (!cd.baseClass.ctor) - { - error("no super class constructor for %s", cd.baseClass.toChars()); - type = Type.terror; - return this; - } - else - { - if (!sc.intypeof) - { -static if (false) { - if (sc.callSuper & (CSX.CSXthis | CSX.CSXsuper)) - error("reference to this before super()"); -} - if (sc.noctor || sc.callSuper & CSX.CSXlabel) - error("constructor calls not allowed in loops or after labels"); - if (sc.callSuper & (CSX.CSXsuper_ctor | CSX.CSXthis_ctor)) - error("multiple constructor calls"); - sc.callSuper |= CSX.CSXany_ctor | CSX.CSXsuper_ctor; - } - - f = resolveFuncCall(sc, loc, cd.baseClass.ctor, null, null, arguments, 0); - checkDeprecated(sc, f); -version (DMDV2) { - checkPurity(sc, f); -} - e1 = new DotVarExp(e1.loc, e1, f); - e1 = e1.semantic(sc); - t1 = e1.type; - } - } - } - else if (e1.op == TOK.TOKthis) - { - // same class constructor call - AggregateDeclaration cd = null; - - if (sc.func) - cd = sc.func.toParent().isAggregateDeclaration(); - if (!cd || !sc.func.isCtorDeclaration()) - { - error("constructor call must be in a constructor"); - type = Type.terror; - return this; - } - else - { - if (!sc.intypeof) - { -static if (false) { - if (sc.callSuper & (CSXthis | CSXsuper)) - error("reference to this before super()"); -} - if (sc.noctor || sc.callSuper & CSX.CSXlabel) - error("constructor calls not allowed in loops or after labels"); - if (sc.callSuper & (CSX.CSXsuper_ctor | CSX.CSXthis_ctor)) - error("multiple constructor calls"); - sc.callSuper |= CSX.CSXany_ctor | CSX.CSXthis_ctor; - } - - f = resolveFuncCall(sc, loc, cd.ctor, null, null, arguments, 0); - checkDeprecated(sc, f); -version (DMDV2) { - checkPurity(sc, f); -} - e1 = new DotVarExp(e1.loc, e1, f); - e1 = e1.semantic(sc); - t1 = e1.type; - - // BUG: this should really be done by checking the static - // call graph - if (f == sc.func) - error("cyclic constructor call"); - } - } - else if (e1.op == TOK.TOKoverloadset) - { - OverExp eo = cast(OverExp)e1; - FuncDeclaration ff = null; - for (int j = 0; j < eo.vars.a.dim; j++) - { - Dsymbol s = cast(Dsymbol)eo.vars.a.data[j]; - FuncDeclaration f2 = s.isFuncDeclaration(); - if (f2) - { - f2 = f2.overloadResolve(loc, null, arguments, 1); - } - else - { - TemplateDeclaration td = s.isTemplateDeclaration(); - assert(td); - f2 = td.deduceFunctionTemplate(sc, loc, targsi, null, arguments, 1); - } - if (f2) - { - if (ff) - /* Error if match in more than one overload set, - * even if one is a 'better' match than the other. - */ - ScopeDsymbol.multiplyDefined(loc, ff, f2); - else - ff = f2; - } - } - if (!ff) - { - /* No overload matches, just set ff and rely on error - * message being generated later. - */ - ff = cast(FuncDeclaration)eo.vars.a.data[0]; - } - e1 = new VarExp(loc, ff); - goto Lagain; - } - else if (!t1) - { - error("function expected before (), not '%s'", e1.toChars()); - type = Type.terror; - return this; - } - else if (t1.ty != TY.Tfunction) - { - if (t1.ty == TY.Tdelegate) - { - TypeDelegate td = cast(TypeDelegate)t1; - assert(td.next.ty == TY.Tfunction); - tf = cast(TypeFunction)(td.next); - if (sc.func && sc.func.isPure() && !tf.ispure) - { - error("pure function '%s' cannot call impure delegate '%s'", sc.func.toChars(), e1.toChars()); - } - goto Lcheckargs; - } - else if (t1.ty == TY.Tpointer && (cast(TypePointer)t1).next.ty == TY.Tfunction) - { - Expression e = new PtrExp(loc, e1); - t1 = (cast(TypePointer)t1).next; - if (sc.func && sc.func.isPure() && !(cast(TypeFunction)t1).ispure) - { - error("pure function '%s' cannot call impure function pointer '%s'", sc.func.toChars(), e1.toChars()); - } - e.type = t1; - e1 = e; - } - else if (e1.op == TOK.TOKtemplate) - { - TemplateExp te = cast(TemplateExp)e1; - f = te.td.deduceFunctionTemplate(sc, loc, targsi, null, arguments); - if (!f) - { - if (tierror) - tierror.error("errors instantiating template"); // give better error message - type = Type.terror; - return this; - } - if (f.needThis() && hasThis(sc)) - { - // Supply an implicit 'this', as in - // this.ident - - e1 = new DotTemplateExp(loc, (new ThisExp(loc)).semantic(sc), te.td); - goto Lagain; - } - - e1 = new VarExp(loc, f); - goto Lagain; - } - else - { - error("function expected before (), not %s of type %s", e1.toChars(), e1.type.toChars()); - type = Type.terror; - return this; - } - } - else if (e1.op == TOK.TOKvar) - { - // Do overload resolution - VarExp ve = cast(VarExp)e1; - - f = ve.var.isFuncDeclaration(); - assert(f); - - if (ve.hasOverloads) - f = f.overloadResolve(loc, null, arguments); - - checkDeprecated(sc, f); -version (DMDV2) { - checkPurity(sc, f); -} - - if (f.needThis() && hasThis(sc)) - { - // Supply an implicit 'this', as in - // this.ident - - e1 = new DotVarExp(loc, new ThisExp(loc), f); - goto Lagain; - } - - accessCheck(loc, sc, null, f); - - ve.var = f; - // ve.hasOverloads = 0; - ve.type = f.type; - t1 = f.type; - } - assert(t1.ty == TY.Tfunction); - tf = cast(TypeFunction)t1; - - Lcheckargs: - assert(tf.ty == TY.Tfunction); - type = tf.next; - - if (!arguments) - arguments = new Expressions(); - - functionArguments(loc, sc, tf, arguments); - - if (!type) - { - error("forward reference to inferred return type of function call %s", toChars()); - type = Type.terror; - } - - if (f && f.tintro) - { - Type t = type; - int offset = 0; - TypeFunction tff = cast(TypeFunction)f.tintro; - - if (tff.next.isBaseOf(t, &offset) && offset) - { - type = tff.next; - return castTo(sc, t); - } - } - - return this; + override Expression semantic(Scope sc) + { + TypeFunction tf; + FuncDeclaration f; + int i; + Type t1; + int istemp; + Objects targsi; // initial list of template arguments + TemplateInstance tierror; + +version (LOGSEMANTIC) { + printf("CallExp.semantic() %s\n", toChars()); +} + if (type) + return this; // semantic() already run + +static if (false) { + if (arguments && arguments.dim) + { + Expression earg = cast(Expression)arguments.data[0]; + earg.print(); + if (earg.type) earg.type.print(); + } +} + + if (e1.op == TOK.TOKdelegate) + { + DelegateExp de = cast(DelegateExp)e1; + + e1 = new DotVarExp(de.loc, de.e1, de.func); + return semantic(sc); + } + + /* Transform: + * array.id(args) into .id(array,args) + * aa.remove(arg) into delete aa[arg] + */ + if (e1.op == TOK.TOKdot) + { + // BUG: we should handle array.a.b.c.e(args) too + + DotIdExp dotid = cast(DotIdExp)(e1); + dotid.e1 = dotid.e1.semantic(sc); + assert(dotid.e1); + if (dotid.e1.type) + { + TY e1ty = dotid.e1.type.toBasetype().ty; + if (e1ty == TY.Taarray && dotid.ident == Id.remove) + { + if (!arguments || arguments.dim != 1) + { + error("expected key as argument to aa.remove()"); + goto Lagain; + } + Expression key = cast(Expression)arguments.data[0]; + key = key.semantic(sc); + key = resolveProperties(sc, key); + key.rvalue(); + + TypeAArray taa = cast(TypeAArray)dotid.e1.type.toBasetype(); + key = key.implicitCastTo(sc, taa.index); + + return new RemoveExp(loc, dotid.e1, key); + } + else if (e1ty == TY.Tarray || e1ty == TY.Tsarray || e1ty == TY.Taarray) + { + if (!arguments) + arguments = new Expressions(); + arguments.shift(cast(void*)dotid.e1); +version (DMDV2) { + e1 = new DotIdExp(dotid.loc, new IdentifierExp(dotid.loc, Id.empty), dotid.ident); +} else { + e1 = new IdentifierExp(dotid.loc, dotid.ident); +} + } + } + } + +static if (true) { + /* This recognizes: + * foo!(tiargs)(funcargs) + */ + if (e1.op == TOK.TOKimport && !e1.type) + { + ScopeExp se = cast(ScopeExp)e1; + TemplateInstance ti = se.sds.isTemplateInstance(); + if (ti && !ti.semanticRun) + { + /* Attempt to instantiate ti. If that works, go with it. + * If not, go with partial explicit specialization. + */ + ti.semanticTiargs(sc); + uint errors = global.errors; + global.gag++; + ti.semantic(sc); + global.gag--; + if (errors != global.errors) + { + /* Didn't work, go with partial explicit specialization + */ + global.errors = errors; + targsi = ti.tiargs; + tierror = ti; // for error reporting + e1 = new IdentifierExp(loc, ti.name); + } + } + } + + /* This recognizes: + * expr.foo!(tiargs)(funcargs) + */ + if (e1.op == TOK.TOKdotti && !e1.type) + { + DotTemplateInstanceExp se = cast(DotTemplateInstanceExp)e1; + TemplateInstance ti = se.ti; + if (!ti.semanticRun) + { + /* Attempt to instantiate ti. If that works, go with it. + * If not, go with partial explicit specialization. + */ + ti.semanticTiargs(sc); + Expression etmp = e1.trySemantic(sc); + if (etmp) + e1 = etmp; // it worked + else // didn't work + { + targsi = ti.tiargs; + tierror = ti; // for error reporting + e1 = new DotIdExp(loc, se.e1, ti.name); + } + } + } +} + + istemp = 0; + Lagain: + //printf("Lagain: %s\n", toChars()); + f = null; + if (e1.op == TOK.TOKthis || e1.op == TOK.TOKsuper) + { + // semantic() run later for these + } + else + { + UnaExp.semantic(sc); + + /* Look for e1 being a lazy parameter + */ + if (e1.op == TOK.TOKvar) + { + VarExp ve = cast(VarExp)e1; + + if (ve.var.storage_class & STC.STClazy) + { + TypeFunction tff = new TypeFunction(null, ve.var.type, 0, LINK.LINKd); + TypeDelegate t = new TypeDelegate(tff); + ve.type = t.semantic(loc, sc); + } + } + + if (e1.op == TOK.TOKimport) + { + // Perhaps this should be moved to ScopeExp.semantic() + ScopeExp se = cast(ScopeExp)e1; + e1 = new DsymbolExp(loc, se.sds); + e1 = e1.semantic(sc); + } +///static if (true) { // patch for #540 by Oskar Linde + else if (e1.op == TOK.TOKdotexp) + { + DotExp de = cast(DotExp)e1; + + if (de.e2.op == TOK.TOKimport) + { + // This should *really* be moved to ScopeExp.semantic() + ScopeExp se = cast(ScopeExp)de.e2; + de.e2 = new DsymbolExp(loc, se.sds); + de.e2 = de.e2.semantic(sc); + } + + if (de.e2.op == TOK.TOKtemplate) + { + TemplateExp te = cast(TemplateExp)de.e2; + e1 = new DotTemplateExp(loc,de.e1,te.td); + } + } +///} + } + + if (e1.op == TOK.TOKcomma) + { + CommaExp ce = cast(CommaExp)e1; + + e1 = ce.e2; + e1.type = ce.type; + ce.e2 = this; + ce.type = null; + return ce.semantic(sc); + } + + t1 = null; + if (e1.type) + t1 = e1.type.toBasetype(); + + // Check for call operator overload + if (t1) + { + AggregateDeclaration ad; + + if (t1.ty == TY.Tstruct) + { + ad = (cast(TypeStruct)t1).sym; +version (DMDV2) { + // First look for constructor + if (ad.ctor && arguments && arguments.dim) + { + // Create variable that will get constructed + Identifier idtmp = Lexer.uniqueId("__ctmp"); + VarDeclaration tmp = new VarDeclaration(loc, t1, idtmp, null); + Expression av = new DeclarationExp(loc, tmp); + av = new CommaExp(loc, av, new VarExp(loc, tmp)); + + Expression e; + CtorDeclaration cf = ad.ctor.isCtorDeclaration(); + if (cf) + e = new DotVarExp(loc, av, cf, 1); + else + { + TemplateDeclaration td = ad.ctor.isTemplateDeclaration(); + assert(td); + e = new DotTemplateExp(loc, av, td); + } + e = new CallExp(loc, e, arguments); + version (STRUCTTHISREF) { + } else { + /* Constructors return a pointer to the instance + */ + e = new PtrExp(loc, e); + } + e = e.semantic(sc); + return e; + } +} + // No constructor, look for overload of opCall + if (search_function(ad, Id.call)) + goto L1; // overload of opCall, therefore it's a call + + if (e1.op != TOK.TOKtype) + error("%s %s does not overload ()", ad.kind(), ad.toChars()); + + /* It's a struct literal + */ + Expression e = new StructLiteralExp(loc, cast(StructDeclaration)ad, arguments); + e = e.semantic(sc); + e.type = e1.type; // in case e1.type was a typedef + return e; + } + else if (t1.ty == TY.Tclass) + { + ad = (cast(TypeClass)t1).sym; + goto L1; + L1: + // Rewrite as e1.call(arguments) + Expression e = new DotIdExp(loc, e1, Id.call); + e = new CallExp(loc, e, arguments); + e = e.semantic(sc); + return e; + } + } + + arrayExpressionSemantic(arguments, sc); + preFunctionArguments(loc, sc, arguments); + + if (e1.op == TOK.TOKdotvar && t1.ty == TY.Tfunction || + e1.op == TOK.TOKdottd) + { + DotVarExp dve; + DotTemplateExp dte; + AggregateDeclaration ad; + UnaExp ue = cast(UnaExp)e1; + + if (e1.op == TOK.TOKdotvar) + { + // Do overload resolution + dve = cast(DotVarExp)e1; + + f = dve.var.isFuncDeclaration(); + assert(f); + f = f.overloadResolve(loc, ue.e1, arguments); + + ad = f.toParent().isAggregateDeclaration(); + } + else + { + dte = cast(DotTemplateExp)e1; + TemplateDeclaration td = dte.td; + assert(td); + + if (!arguments) + // Should fix deduceFunctionTemplate() so it works on null argument + arguments = new Expressions(); + + f = td.deduceFunctionTemplate(sc, loc, targsi, ue.e1, arguments); + if (!f) + { + type = Type.terror; + return this; + } + ad = td.toParent().isAggregateDeclaration(); + } + + if (f.needThis()) + { + ue.e1 = getRightThis(loc, sc, ad, ue.e1, f); + } + + /* Cannot call public functions from inside invariant + * (because then the invariant would have infinite recursion) + */ + if (sc.func && sc.func.isInvariantDeclaration() && + ue.e1.op == TOK.TOKthis && f.addPostInvariant()) + { + error("cannot call public/export function %s from invariant", f.toChars()); + } + + checkDeprecated(sc, f); + version (DMDV2) { + checkPurity(sc, f); + } + accessCheck(loc, sc, ue.e1, f); + if (!f.needThis()) + { + VarExp ve = new VarExp(loc, f); + e1 = new CommaExp(loc, ue.e1, ve); + e1.type = f.type; + } + else + { + if (e1.op == TOK.TOKdotvar) + dve.var = f; + else + e1 = new DotVarExp(loc, dte.e1, f); + + e1.type = f.type; +static if (false) { + printf("ue.e1 = %s\n", ue.e1.toChars()); + printf("f = %s\n", f.toChars()); + printf("t = %s\n", t.toChars()); + printf("e1 = %s\n", e1.toChars()); + printf("e1.type = %s\n", e1.type.toChars()); +} + // Const member function can take const/immutable/mutable this + if (!(f.type.isConst())) + { + // Check for const/immutable compatibility + Type tthis = ue.e1.type.toBasetype(); + if (tthis.ty == TY.Tpointer) + tthis = tthis.nextOf().toBasetype(); + + static if (false) { // this checking should have been already done + if (f.type.isInvariant()) + { + if (tthis.mod != MOD.MODinvariant) + error("%s can only be called with an immutable object", e1.toChars()); + } + else if (f.type.isShared()) + { + if (tthis.mod != MOD.MODinvariant && tthis.mod != MOD.MODshared && tthis.mod != (MOD.MODshared | MOD.MODconst)) + error("shared %s can only be called with a shared or immutable object", e1.toChars()); + } + else + { + if (tthis.mod != MOD.MODundefined) + { + //printf("mod = %x\n", tthis.mod); + error("%s can only be called with a mutable object, not %s", e1.toChars(), tthis.toChars()); + } + } + } + /* Cannot call mutable method on a final struct + */ + if (tthis.ty == TY.Tstruct && + ue.e1.op == TOK.TOKvar) + { + VarExp v = cast(VarExp)ue.e1; + if (v.var.storage_class & STC.STCfinal) + error("cannot call mutable method on final struct"); + } + } + + // See if we need to adjust the 'this' pointer + AggregateDeclaration add = f.isThis(); + ClassDeclaration cd = ue.e1.type.isClassHandle(); + if (add && cd && add.isClassDeclaration() && add != cd && ue.e1.op != TOK.TOKsuper) + { + ue.e1 = ue.e1.castTo(sc, add.type); //new CastExp(loc, ue.e1, add.type); + ue.e1 = ue.e1.semantic(sc); + } + } + t1 = e1.type; + } + else if (e1.op == TOK.TOKsuper) + { + // Base class constructor call + ClassDeclaration cd = null; + + if (sc.func) + cd = sc.func.toParent().isClassDeclaration(); + if (!cd || !cd.baseClass || !sc.func.isCtorDeclaration()) + { + error("super class constructor call must be in a constructor"); + type = Type.terror; + return this; + } + else + { + if (!cd.baseClass.ctor) + { + error("no super class constructor for %s", cd.baseClass.toChars()); + type = Type.terror; + return this; + } + else + { + if (!sc.intypeof) + { +static if (false) { + if (sc.callSuper & (CSX.CSXthis | CSX.CSXsuper)) + error("reference to this before super()"); +} + if (sc.noctor || sc.callSuper & CSX.CSXlabel) + error("constructor calls not allowed in loops or after labels"); + if (sc.callSuper & (CSX.CSXsuper_ctor | CSX.CSXthis_ctor)) + error("multiple constructor calls"); + sc.callSuper |= CSX.CSXany_ctor | CSX.CSXsuper_ctor; + } + + f = resolveFuncCall(sc, loc, cd.baseClass.ctor, null, null, arguments, 0); + checkDeprecated(sc, f); +version (DMDV2) { + checkPurity(sc, f); +} + e1 = new DotVarExp(e1.loc, e1, f); + e1 = e1.semantic(sc); + t1 = e1.type; + } + } + } + else if (e1.op == TOK.TOKthis) + { + // same class constructor call + AggregateDeclaration cd = null; + + if (sc.func) + cd = sc.func.toParent().isAggregateDeclaration(); + if (!cd || !sc.func.isCtorDeclaration()) + { + error("constructor call must be in a constructor"); + type = Type.terror; + return this; + } + else + { + if (!sc.intypeof) + { +static if (false) { + if (sc.callSuper & (CSXthis | CSXsuper)) + error("reference to this before super()"); +} + if (sc.noctor || sc.callSuper & CSX.CSXlabel) + error("constructor calls not allowed in loops or after labels"); + if (sc.callSuper & (CSX.CSXsuper_ctor | CSX.CSXthis_ctor)) + error("multiple constructor calls"); + sc.callSuper |= CSX.CSXany_ctor | CSX.CSXthis_ctor; + } + + f = resolveFuncCall(sc, loc, cd.ctor, null, null, arguments, 0); + checkDeprecated(sc, f); +version (DMDV2) { + checkPurity(sc, f); +} + e1 = new DotVarExp(e1.loc, e1, f); + e1 = e1.semantic(sc); + t1 = e1.type; + + // BUG: this should really be done by checking the static + // call graph + if (f == sc.func) + error("cyclic constructor call"); + } + } + else if (e1.op == TOK.TOKoverloadset) + { + OverExp eo = cast(OverExp)e1; + FuncDeclaration ff = null; + for (int j = 0; j < eo.vars.a.dim; j++) + { + Dsymbol s = cast(Dsymbol)eo.vars.a.data[j]; + FuncDeclaration f2 = s.isFuncDeclaration(); + if (f2) + { + f2 = f2.overloadResolve(loc, null, arguments, 1); + } + else + { + TemplateDeclaration td = s.isTemplateDeclaration(); + assert(td); + f2 = td.deduceFunctionTemplate(sc, loc, targsi, null, arguments, 1); + } + if (f2) + { + if (ff) + /* Error if match in more than one overload set, + * even if one is a 'better' match than the other. + */ + ScopeDsymbol.multiplyDefined(loc, ff, f2); + else + ff = f2; + } + } + if (!ff) + { + /* No overload matches, just set ff and rely on error + * message being generated later. + */ + ff = cast(FuncDeclaration)eo.vars.a.data[0]; + } + e1 = new VarExp(loc, ff); + goto Lagain; + } + else if (!t1) + { + error("function expected before (), not '%s'", e1.toChars()); + type = Type.terror; + return this; + } + else if (t1.ty != TY.Tfunction) + { + if (t1.ty == TY.Tdelegate) + { + TypeDelegate td = cast(TypeDelegate)t1; + assert(td.next.ty == TY.Tfunction); + tf = cast(TypeFunction)(td.next); + if (sc.func && sc.func.isPure() && !tf.ispure) + { + error("pure function '%s' cannot call impure delegate '%s'", sc.func.toChars(), e1.toChars()); + } + goto Lcheckargs; + } + else if (t1.ty == TY.Tpointer && (cast(TypePointer)t1).next.ty == TY.Tfunction) + { + Expression e = new PtrExp(loc, e1); + t1 = (cast(TypePointer)t1).next; + if (sc.func && sc.func.isPure() && !(cast(TypeFunction)t1).ispure) + { + error("pure function '%s' cannot call impure function pointer '%s'", sc.func.toChars(), e1.toChars()); + } + e.type = t1; + e1 = e; + } + else if (e1.op == TOK.TOKtemplate) + { + TemplateExp te = cast(TemplateExp)e1; + f = te.td.deduceFunctionTemplate(sc, loc, targsi, null, arguments); + if (!f) + { + if (tierror) + tierror.error("errors instantiating template"); // give better error message + type = Type.terror; + return this; + } + if (f.needThis() && hasThis(sc)) + { + // Supply an implicit 'this', as in + // this.ident + + e1 = new DotTemplateExp(loc, (new ThisExp(loc)).semantic(sc), te.td); + goto Lagain; + } + + e1 = new VarExp(loc, f); + goto Lagain; + } + else + { + error("function expected before (), not %s of type %s", e1.toChars(), e1.type.toChars()); + type = Type.terror; + return this; + } + } + else if (e1.op == TOK.TOKvar) + { + // Do overload resolution + VarExp ve = cast(VarExp)e1; + + f = ve.var.isFuncDeclaration(); + assert(f); + + if (ve.hasOverloads) + f = f.overloadResolve(loc, null, arguments); + + checkDeprecated(sc, f); +version (DMDV2) { + checkPurity(sc, f); +} + + if (f.needThis() && hasThis(sc)) + { + // Supply an implicit 'this', as in + // this.ident + + e1 = new DotVarExp(loc, new ThisExp(loc), f); + goto Lagain; + } + + accessCheck(loc, sc, null, f); + + ve.var = f; + // ve.hasOverloads = 0; + ve.type = f.type; + t1 = f.type; + } + assert(t1.ty == TY.Tfunction); + tf = cast(TypeFunction)t1; + + Lcheckargs: + assert(tf.ty == TY.Tfunction); + type = tf.next; + + if (!arguments) + arguments = new Expressions(); + + functionArguments(loc, sc, tf, arguments); + + if (!type) + { + error("forward reference to inferred return type of function call %s", toChars()); + type = Type.terror; + } + + if (f && f.tintro) + { + Type t = type; + int offset = 0; + TypeFunction tff = cast(TypeFunction)f.tintro; + + if (tff.next.isBaseOf(t, &offset) && offset) + { + type = tff.next; + return castTo(sc, t); + } + } + + return this; } - Expression optimize(int result) + override Expression optimize(int result) { - //printf("CallExp::optimize(result = %d) %s\n", result, toChars()); - Expression e = this; - - // Optimize parameters - if (arguments) - { - for (size_t i = 0; i < arguments.dim; i++) - { - Expression ee = cast(Expression)arguments.data[i]; - - ee = ee.optimize(WANT.WANTvalue); - arguments.data[i] = cast(void*)ee; - } - } - - e1 = e1.optimize(result); - if (e1.op == TOK.TOKvar) - { - FuncDeclaration fd = (cast(VarExp)e1).var.isFuncDeclaration(); - if (fd) - { - BUILTIN b = fd.isBuiltin(); - if (b) - { - e = eval_builtin(b, arguments); - if (!e) // failed - e = this; // evaluate at runtime - } - else if (result & WANT.WANTinterpret) - { - Expression eresult = fd.interpret(null, arguments); - if (eresult && eresult !is EXP_VOID_INTERPRET) - e = eresult; - else - error("cannot evaluate %s at compile time", toChars()); - } - } - } - + //printf("CallExp::optimize(result = %d) %s\n", result, toChars()); + Expression e = this; + + // Optimize parameters + if (arguments) + { + for (size_t i = 0; i < arguments.dim; i++) + { + Expression ee = cast(Expression)arguments.data[i]; + + ee = ee.optimize(WANT.WANTvalue); + arguments.data[i] = cast(void*)ee; + } + } + + e1 = e1.optimize(result); + if (e1.op == TOK.TOKvar) + { + FuncDeclaration fd = (cast(VarExp)e1).var.isFuncDeclaration(); + if (fd) + { + BUILTIN b = fd.isBuiltin(); + if (b) + { + e = eval_builtin(b, arguments); + if (!e) // failed + e = this; // evaluate at runtime + } + else if (result & WANT.WANTinterpret) + { + Expression eresult = fd.interpret(null, arguments); + if (eresult && eresult !is EXP_VOID_INTERPRET) + e = eresult; + else + error("cannot evaluate %s at compile time", toChars()); + } + } + } + return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { - Expression e = EXP_CANT_INTERPRET; - -version (LOG) { - printf("CallExp.interpret() %.*s\n", toChars()); -} - if (e1.op == TOKdotvar) - { - Expression pthis = (cast(DotVarExp)e1).e1; - FuncDeclaration fd = (cast(DotVarExp)e1).var.isFuncDeclaration(); - TypeFunction tf = fd ? cast(TypeFunction)fd.type : null; - if (tf) - { - // Member function call - if(pthis.op == TOKthis) - pthis = istate.localThis; - Expression eresult = fd.interpret(istate, arguments, pthis); - if (eresult) - e = eresult; - else if (fd.type.toBasetype().nextOf().ty == Tvoid && !global.errors) - e = EXP_VOID_INTERPRET; - else - error("cannot evaluate %s at compile time", toChars()); - return e; - } - error("cannot evaluate %s at compile time", toChars()); - return EXP_CANT_INTERPRET; - } - if (e1.op == TOKvar) - { - FuncDeclaration fd = (cast(VarExp)e1).var.isFuncDeclaration(); - if (fd) - { -///version (DMDV2) { - BUILTIN b = fd.isBuiltin(); - if (b) - { - scope Expressions args = new Expressions(); - args.setDim(arguments.dim); - for (size_t i = 0; i < args.dim; i++) - { - Expression earg = cast(Expression)arguments.data[i]; - earg = earg.interpret(istate); - if (earg == EXP_CANT_INTERPRET) - return earg; - args.data[i] = cast(void*)earg; - } - e = eval_builtin(b, args); - if (!e) - e = EXP_CANT_INTERPRET; - } - else -///} - // Inline .dup - if (fd.ident == Id.adDup && arguments && arguments.dim == 2) - { - e = cast(Expression)arguments.data[1]; - e = e.interpret(istate); - if (e !is EXP_CANT_INTERPRET) - { - e = expType(type, e); - } - } - else - { - Expression eresult = fd.interpret(istate, arguments); - if (eresult) - e = eresult; - else if (fd.type.toBasetype().nextOf().ty == Tvoid && !global.errors) - e = EXP_VOID_INTERPRET; - else - error("cannot evaluate %s at compile time", toChars()); - } - } - } + Expression e = EXP_CANT_INTERPRET; + +version (LOG) { + printf("CallExp.interpret() %.*s\n", toChars()); +} + if (e1.op == TOKdotvar) + { + Expression pthis = (cast(DotVarExp)e1).e1; + FuncDeclaration fd = (cast(DotVarExp)e1).var.isFuncDeclaration(); + TypeFunction tf = fd ? cast(TypeFunction)fd.type : null; + if (tf) + { + // Member function call + if(pthis.op == TOKthis) + pthis = istate.localThis; + Expression eresult = fd.interpret(istate, arguments, pthis); + if (eresult) + e = eresult; + else if (fd.type.toBasetype().nextOf().ty == Tvoid && !global.errors) + e = EXP_VOID_INTERPRET; + else + error("cannot evaluate %s at compile time", toChars()); + return e; + } + error("cannot evaluate %s at compile time", toChars()); + return EXP_CANT_INTERPRET; + } + if (e1.op == TOKvar) + { + FuncDeclaration fd = (cast(VarExp)e1).var.isFuncDeclaration(); + if (fd) + { +///version (DMDV2) { + BUILTIN b = fd.isBuiltin(); + if (b) + { + scope Expressions args = new Expressions(); + args.setDim(arguments.dim); + for (size_t i = 0; i < args.dim; i++) + { + Expression earg = cast(Expression)arguments.data[i]; + earg = earg.interpret(istate); + if (earg == EXP_CANT_INTERPRET) + return earg; + args.data[i] = cast(void*)earg; + } + e = eval_builtin(b, args); + if (!e) + e = EXP_CANT_INTERPRET; + } + else +///} + // Inline .dup + if (fd.ident == Id.adDup && arguments && arguments.dim == 2) + { + e = cast(Expression)arguments.data[1]; + e = e.interpret(istate); + if (e !is EXP_CANT_INTERPRET) + { + e = expType(type, e); + } + } + else + { + Expression eresult = fd.interpret(istate, arguments); + if (eresult) + e = eresult; + else if (fd.type.toBasetype().nextOf().ty == Tvoid && !global.errors) + e = EXP_VOID_INTERPRET; + else + error("cannot evaluate %s at compile time", toChars()); + } + } + } return e; } - bool checkSideEffect(int flag) + override bool checkSideEffect(int flag) { -version (DMDV2) { - if (flag != 2) - return true; - - if (e1.checkSideEffect(2)) - return true; - - /* If any of the arguments have side effects, this expression does - */ - for (size_t i = 0; i < arguments.dim; i++) - { - Expression e = cast(Expression)arguments.data[i]; - - if (e.checkSideEffect(2)) - return true; - } - - /* If calling a function or delegate that is typed as pure, - * then this expression has no side effects. - */ - Type t = e1.type.toBasetype(); - if (t.ty == TY.Tfunction && (cast(TypeFunction)t).ispure) - return false; - if (t.ty == TY.Tdelegate && (cast(TypeFunction)(cast(TypeDelegate)t).next).ispure) - return false; -} +version (DMDV2) { + if (flag != 2) + return true; + + if (e1.checkSideEffect(2)) + return true; + + /* If any of the arguments have side effects, this expression does + */ + for (size_t i = 0; i < arguments.dim; i++) + { + Expression e = cast(Expression)arguments.data[i]; + + if (e.checkSideEffect(2)) + return true; + } + + /* If calling a function or delegate that is typed as pure, + * then this expression has no side effects. + */ + Type t = e1.type.toBasetype(); + if (t.ty == TY.Tfunction && (cast(TypeFunction)t).ispure) + return false; + if (t.ty == TY.Tdelegate && (cast(TypeFunction)(cast(TypeDelegate)t).next).ispure) + return false; +} return true; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - int i; - expToCBuffer(buf, hgs, e1, precedence[op]); - buf.writeByte('('); - argsToCBuffer(buf, arguments, hgs); + int i; + expToCBuffer(buf, hgs, e1, precedence[op]); + buf.writeByte('('); + argsToCBuffer(buf, arguments, hgs); buf.writeByte(')'); } - void dump(int indent) + override void dump(int indent) { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { - //printf("CallExp::toElem('%s')\n", toChars()); - assert(e1.type); - elem* ec; - int directcall; - FuncDeclaration fd; - Type t1 = e1.type.toBasetype(); - Type ectype = t1; - - elem* ehidden = irs.ehidden; - irs.ehidden = null; - - directcall = 0; - fd = null; - if (e1.op == TOK.TOKdotvar && t1.ty != TY.Tdelegate) - { - DotVarExp dve = cast(DotVarExp)e1; - - fd = dve.var.isFuncDeclaration(); - Expression ex = dve.e1; - while (1) - { - switch (ex.op) - { - case TOK.TOKsuper: // super.member() calls directly - case TOK.TOKdottype: // type.member() calls directly - directcall = 1; - break; - - case TOK.TOKcast: - ex = (cast(CastExp)ex).e1; - continue; - - default: - //ex.dump(0); - break; - } - break; - } - ec = dve.e1.toElem(irs); - ectype = dve.e1.type.toBasetype(); - } - else if (e1.op == TOK.TOKvar) - { - fd = (cast(VarExp)e1).var.isFuncDeclaration(); - - if (fd && fd.ident == Id.alloca && !fd.fbody && fd.linkage == LINK.LINKc && arguments && arguments.dim == 1) - { - Expression arg = cast(Expression)arguments.data[0]; - arg = arg.optimize(WANT.WANTvalue); - if (arg.isConst() && arg.type.isintegral()) - { - long sz = arg.toInteger(); - if (sz > 0 && sz < 0x40000) - { - // It's an alloca(sz) of a fixed amount. - // Replace with an array allocated on the stack - // of the same size: char[sz] tmp; - - Symbol* stmp; - .type* t; - - assert(!ehidden); - t = type_allocn(TYM.TYarray, tschar); - t.Tdim = cast(uint)sz; - stmp = symbol_genauto(t); - ec = el_ptr(stmp); - el_setLoc(ec,loc); - return ec; - } - } - } - - ec = e1.toElem(irs); - } - else - { - ec = e1.toElem(irs); - } - ec = callfunc(loc, irs, directcall, type, ec, ectype, fd, t1, ehidden, arguments); - el_setLoc(ec,loc); + //printf("CallExp::toElem('%s')\n", toChars()); + assert(e1.type); + elem* ec; + int directcall; + FuncDeclaration fd; + Type t1 = e1.type.toBasetype(); + Type ectype = t1; + + elem* ehidden = irs.ehidden; + irs.ehidden = null; + + directcall = 0; + fd = null; + if (e1.op == TOK.TOKdotvar && t1.ty != TY.Tdelegate) + { + DotVarExp dve = cast(DotVarExp)e1; + + fd = dve.var.isFuncDeclaration(); + Expression ex = dve.e1; + while (1) + { + switch (ex.op) + { + case TOK.TOKsuper: // super.member() calls directly + case TOK.TOKdottype: // type.member() calls directly + directcall = 1; + break; + + case TOK.TOKcast: + ex = (cast(CastExp)ex).e1; + continue; + + default: + //ex.dump(0); + break; + } + break; + } + ec = dve.e1.toElem(irs); + ectype = dve.e1.type.toBasetype(); + } + else if (e1.op == TOK.TOKvar) + { + fd = (cast(VarExp)e1).var.isFuncDeclaration(); + + if (fd && fd.ident == Id.alloca && !fd.fbody && fd.linkage == LINK.LINKc && arguments && arguments.dim == 1) + { + Expression arg = cast(Expression)arguments.data[0]; + arg = arg.optimize(WANT.WANTvalue); + if (arg.isConst() && arg.type.isintegral()) + { + long sz = arg.toInteger(); + if (sz > 0 && sz < 0x40000) + { + // It's an alloca(sz) of a fixed amount. + // Replace with an array allocated on the stack + // of the same size: char[sz] tmp; + + Symbol* stmp; + .type* t; + + assert(!ehidden); + t = type_allocn(TYM.TYarray, tschar); + t.Tdim = cast(uint)sz; + stmp = symbol_genauto(t); + ec = el_ptr(stmp); + el_setLoc(ec,loc); + return ec; + } + } + } + + ec = e1.toElem(irs); + } + else + { + ec = e1.toElem(irs); + } + ec = callfunc(loc, irs, directcall, type, ec, ectype, fd, t1, ehidden, arguments); + el_setLoc(ec,loc); return ec; } - void scanForNestedRef(Scope sc) + override void scanForNestedRef(Scope sc) { - //printf("CallExp.scanForNestedRef(Scope *sc): %s\n", toChars()); - e1.scanForNestedRef(sc); + //printf("CallExp.scanForNestedRef(Scope *sc): %s\n", toChars()); + e1.scanForNestedRef(sc); arrayExpressionScanForNestedRef(sc, arguments); - } + } version (DMDV2) { - int isLvalue() + override int isLvalue() { - // if (type.toBasetype().ty == Tstruct) - // return 1; - Type tb = e1.type.toBasetype(); - if (tb.ty == Tfunction && (cast(TypeFunction)tb).isref) - return 1; // function returns a reference + // if (type.toBasetype().ty == Tstruct) + // return 1; + Type tb = e1.type.toBasetype(); + if (tb.ty == Tfunction && (cast(TypeFunction)tb).isref) + return 1; // function returns a reference return 0; } } - Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression e) { - if (isLvalue()) - return this; + if (isLvalue()) + return this; return Expression.toLvalue(sc, e); - } + } version (DMDV2) { - bool canThrow() + override bool canThrow() { - //printf("CallExp::canThrow() %s\n", toChars()); - if (e1.canThrow()) - return true; - - /* If any of the arguments can throw, then this expression can throw - */ - for (size_t i = 0; i < arguments.dim; i++) - { - Expression e = cast(Expression)arguments.data[i]; - - if (e && e.canThrow()) - return true; - } - - if (global.errors && !e1.type) - return false; // error recovery - - /* If calling a function or delegate that is typed as nothrow, - * then this expression cannot throw. - * Note that pure functions can throw. - */ - Type t = e1.type.toBasetype(); - if (t.ty == TY.Tfunction && (cast(TypeFunction)t).isnothrow) - return false; - if (t.ty == TY.Tdelegate && (cast(TypeFunction)(cast(TypeDelegate)t).next).isnothrow) - return false; - + //printf("CallExp::canThrow() %s\n", toChars()); + if (e1.canThrow()) + return true; + + /* If any of the arguments can throw, then this expression can throw + */ + for (size_t i = 0; i < arguments.dim; i++) + { + Expression e = cast(Expression)arguments.data[i]; + + if (e && e.canThrow()) + return true; + } + + if (global.errors && !e1.type) + return false; // error recovery + + /* If calling a function or delegate that is typed as nothrow, + * then this expression cannot throw. + * Note that pure functions can throw. + */ + Type t = e1.type.toBasetype(); + if (t.ty == TY.Tfunction && (cast(TypeFunction)t).isnothrow) + return false; + if (t.ty == TY.Tdelegate && (cast(TypeFunction)(cast(TypeDelegate)t).next).isnothrow) + return false; + return true; } } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { return 1 + e1.inlineCost(ics) + arrayInlineCost(ics, arguments); } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { - CallExp ce = cast(CallExp)copy(); - ce.e1 = e1.doInline(ids); - ce.arguments = arrayExpressiondoInline(arguments, ids); + CallExp ce = cast(CallExp)copy(); + ce.e1 = e1.doInline(ids); + ce.arguments = arrayExpressiondoInline(arguments, ids); return ce; } - Expression inlineScan(InlineScanState* iss) + override Expression inlineScan(InlineScanState* iss) { - Expression e = this; - - //printf("CallExp.inlineScan()\n"); - e1 = e1.inlineScan(iss); - arrayInlineScan(iss, arguments); - - if (e1.op == TOKvar) - { - VarExp ve = cast(VarExp)e1; - FuncDeclaration fd = ve.var.isFuncDeclaration(); - - if (fd && fd != iss.fd && fd.canInline(0)) - { - e = fd.doInline(iss, null, arguments); - } - } - else if (e1.op == TOKdotvar) - { - DotVarExp dve = cast(DotVarExp)e1; - FuncDeclaration fd = dve.var.isFuncDeclaration(); - - if (fd && fd != iss.fd && fd.canInline(1)) - { - if (dve.e1.op == TOKcall && - dve.e1.type.toBasetype().ty == Tstruct) - { - /* To create ethis, we'll need to take the address - * of dve.e1, but this won't work if dve.e1 is - * a function call. - */ - ; - } - else - e = fd.doInline(iss, dve.e1, arguments); - } - } - + Expression e = this; + + //printf("CallExp.inlineScan()\n"); + e1 = e1.inlineScan(iss); + arrayInlineScan(iss, arguments); + + if (e1.op == TOKvar) + { + VarExp ve = cast(VarExp)e1; + FuncDeclaration fd = ve.var.isFuncDeclaration(); + + if (fd && fd != iss.fd && fd.canInline(0)) + { + e = fd.doInline(iss, null, arguments); + } + } + else if (e1.op == TOKdotvar) + { + DotVarExp dve = cast(DotVarExp)e1; + FuncDeclaration fd = dve.var.isFuncDeclaration(); + + if (fd && fd != iss.fd && fd.canInline(1)) + { + if (dve.e1.op == TOKcall && + dve.e1.type.toBasetype().ty == Tstruct) + { + /* To create ethis, we'll need to take the address + * of dve.e1, but this won't work if dve.e1 is + * a function call. + */ + ; + } + else + e = fd.doInline(iss, dve.e1, arguments); + } + } + return e; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/CaseRangeStatement.d --- a/dmd/CaseRangeStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/CaseRangeStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -29,12 +29,12 @@ this.statement = s; } - Statement syntaxCopy() + override Statement syntaxCopy() { assert(false); } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { SwitchStatement sw = sc.sw; @@ -83,7 +83,7 @@ return s; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("case "); first.toCBuffer(buf, hgs); @@ -92,4 +92,4 @@ buf.writenl(); statement.toCBuffer(buf, hgs); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/CaseStatement.d --- a/dmd/CaseStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/CaseStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -42,13 +42,13 @@ this.statement = s; } - Statement syntaxCopy() + override Statement syntaxCopy() { CaseStatement s = new CaseStatement(loc, exp.syntaxCopy(), statement.syntaxCopy()); return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { SwitchStatement sw = sc.sw; @@ -119,7 +119,7 @@ return this; } - int opCmp(Object obj) + override int opCmp(Object obj) { // Sort cases so we can do an efficient lookup CaseStatement cs2 = cast(CaseStatement)obj; @@ -127,32 +127,32 @@ return exp.opCmp(cs2.exp); } - bool usesEH() + override bool usesEH() { assert(false); } - BE blockExit() + override BE blockExit() { return statement.blockExit(); } - bool comeFrom() + override bool comeFrom() { return true; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { //printf("CaseStatement.inlineScan()\n"); exp = exp.inlineScan(iss); @@ -161,7 +161,7 @@ return this; } - void toIR(IRState *irs) + override void toIR(IRState *irs) { Blockx* blx = irs.blx; block* bcase = blx.curblock; @@ -178,4 +178,4 @@ if (statement) statement.toIR(irs); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/CastExp.d --- a/dmd/CastExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/CastExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,1233 +1,1233 @@ -module dmd.CastExp; - -import dmd.Expression; -import dmd.TY; -import dmd.TypeStruct; -import dmd.TypeExp; -import dmd.DotIdExp; -import dmd.CallExp; -import dmd.Global; -import dmd.Id; -import dmd.Identifier; -import dmd.BinExp; -import dmd.backend.elem; -import dmd.UnaExp; -import dmd.VarExp; -import dmd.Token; -import dmd.VarDeclaration; -import dmd.InterState; -import dmd.MATCH; -import dmd.Type; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IntRange; -import dmd.IRState; -import dmd.ArrayTypes; -import dmd.HdrGenState; -import dmd.MOD; -import dmd.TOK; -import dmd.WANT; -import dmd.ClassDeclaration; - -import dmd.Optimize; -import dmd.PREC; -import dmd.Cast; - -import dmd.backend.Util; -import dmd.expression.Util; -import dmd.backend.TYM; -import dmd.backend.OPER; -import dmd.codegen.Util; -import dmd.backend.RTLSYM; - +module dmd.CastExp; + +import dmd.Expression; +import dmd.TY; +import dmd.TypeStruct; +import dmd.TypeExp; +import dmd.DotIdExp; +import dmd.CallExp; +import dmd.Global; +import dmd.Id; +import dmd.Identifier; +import dmd.BinExp; +import dmd.backend.elem; +import dmd.UnaExp; +import dmd.VarExp; +import dmd.Token; +import dmd.VarDeclaration; +import dmd.InterState; +import dmd.MATCH; +import dmd.Type; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IntRange; +import dmd.IRState; +import dmd.ArrayTypes; +import dmd.HdrGenState; +import dmd.MOD; +import dmd.TOK; +import dmd.WANT; +import dmd.ClassDeclaration; + +import dmd.Optimize; +import dmd.PREC; +import dmd.Cast; + +import dmd.backend.Util; +import dmd.expression.Util; +import dmd.backend.TYM; +import dmd.backend.OPER; +import dmd.codegen.Util; +import dmd.backend.RTLSYM; + class CastExp : UnaExp { - // Possible to cast to one type while painting to another type + // Possible to cast to one type while painting to another type Type to; // type to cast to MOD mod; // MODxxxxx this(Loc loc, Expression e, Type t) { - super(loc, TOK.TOKcast, CastExp.sizeof, e); - to = t; + super(loc, TOK.TOKcast, CastExp.sizeof, e); + to = t; this.mod = cast(MOD)~0; } this(Loc loc, Expression e, MOD mod) - { - super(loc, TOK.TOKcast, CastExp.sizeof, e); - to = null; + { + super(loc, TOK.TOKcast, CastExp.sizeof, e); + to = null; this.mod = mod; } - Expression syntaxCopy() + override Expression syntaxCopy() { - return to ? new CastExp(loc, e1.syntaxCopy(), to.syntaxCopy()) + return to ? new CastExp(loc, e1.syntaxCopy(), to.syntaxCopy()) : new CastExp(loc, e1.syntaxCopy(), mod); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { - Expression e; - BinExp b; - UnaExp u; - -version (LOGSEMANTIC) { - printf("CastExp.semantic('%s')\n", toChars()); -} - - //static int x; assert(++x < 10); - - if (type) - return this; - super.semantic(sc); - if (e1.type) // if not a tuple - { - e1 = resolveProperties(sc, e1); - - if (!to) - { - /* Handle cast(const) and cast(immutable), etc. - */ - to = e1.type.castMod(mod); - } - else - to = to.semantic(loc, sc); - - if (!to.equals(e1.type)) - { - e = op_overload(sc); - if (e) - { - return e.implicitCastTo(sc, to); - } - } - - Type t1b = e1.type.toBasetype(); - Type tob = to.toBasetype(); - if (tob.ty == TY.Tstruct && - !tob.equals(t1b) && - (cast(TypeStruct)tob).sym.search(Loc(0), Id.call, 0) - ) - { - /* Look to replace: - * cast(S)t - * with: - * S(t) - */ - - // Rewrite as to.call(e1) - e = new TypeExp(loc, to); - e = new DotIdExp(loc, e, Id.call); - e = new CallExp(loc, e, e1); - e = e.semantic(sc); - return e; - } - } - else if (!to) - { error("cannot cast tuple"); - to = Type.terror; - } - - if (global.params.safe && !sc.module_.safe && !sc.intypeof) - { // Disallow unsafe casts - Type tob = to.toBasetype(); - Type t1b = e1.type.toBasetype(); - if (!t1b.isMutable() && tob.isMutable()) - { // Cast not mutable to mutable - Lunsafe: - error("cast from %s to %s not allowed in safe mode", e1.type.toChars(), to.toChars()); - } - else if (t1b.isShared() && !tob.isShared()) - // Cast away shared - goto Lunsafe; - else if (tob.ty == TY.Tpointer) - { if (t1b.ty != TY.Tpointer) - goto Lunsafe; - Type tobn = tob.nextOf().toBasetype(); - Type t1bn = t1b.nextOf().toBasetype(); - - if (!t1bn.isMutable() && tobn.isMutable()) - // Cast away pointer to not mutable - goto Lunsafe; - - if (t1bn.isShared() && !tobn.isShared()) - // Cast away pointer to shared - goto Lunsafe; - - if (tobn.isTypeBasic() && tobn.size() < t1bn.size()) { - // Allow things like casting a long* to an int* - ; - } else if (tobn.ty != TY.Tvoid) { - // Cast to a pointer other than void* - goto Lunsafe; - } - } - - // BUG: Check for casting array types, such as void[] to int*[] - } - - e = e1.castTo(sc, to); + Expression e; + BinExp b; + UnaExp u; + +version (LOGSEMANTIC) { + printf("CastExp.semantic('%s')\n", toChars()); +} + + //static int x; assert(++x < 10); + + if (type) + return this; + super.semantic(sc); + if (e1.type) // if not a tuple + { + e1 = resolveProperties(sc, e1); + + if (!to) + { + /* Handle cast(const) and cast(immutable), etc. + */ + to = e1.type.castMod(mod); + } + else + to = to.semantic(loc, sc); + + if (!to.equals(e1.type)) + { + e = op_overload(sc); + if (e) + { + return e.implicitCastTo(sc, to); + } + } + + Type t1b = e1.type.toBasetype(); + Type tob = to.toBasetype(); + if (tob.ty == TY.Tstruct && + !tob.equals(t1b) && + (cast(TypeStruct)tob).sym.search(Loc(0), Id.call, 0) + ) + { + /* Look to replace: + * cast(S)t + * with: + * S(t) + */ + + // Rewrite as to.call(e1) + e = new TypeExp(loc, to); + e = new DotIdExp(loc, e, Id.call); + e = new CallExp(loc, e, e1); + e = e.semantic(sc); + return e; + } + } + else if (!to) + { error("cannot cast tuple"); + to = Type.terror; + } + + if (global.params.safe && !sc.module_.safe && !sc.intypeof) + { // Disallow unsafe casts + Type tob = to.toBasetype(); + Type t1b = e1.type.toBasetype(); + if (!t1b.isMutable() && tob.isMutable()) + { // Cast not mutable to mutable + Lunsafe: + error("cast from %s to %s not allowed in safe mode", e1.type.toChars(), to.toChars()); + } + else if (t1b.isShared() && !tob.isShared()) + // Cast away shared + goto Lunsafe; + else if (tob.ty == TY.Tpointer) + { if (t1b.ty != TY.Tpointer) + goto Lunsafe; + Type tobn = tob.nextOf().toBasetype(); + Type t1bn = t1b.nextOf().toBasetype(); + + if (!t1bn.isMutable() && tobn.isMutable()) + // Cast away pointer to not mutable + goto Lunsafe; + + if (t1bn.isShared() && !tobn.isShared()) + // Cast away pointer to shared + goto Lunsafe; + + if (tobn.isTypeBasic() && tobn.size() < t1bn.size()) { + // Allow things like casting a long* to an int* + ; + } else if (tobn.ty != TY.Tvoid) { + // Cast to a pointer other than void* + goto Lunsafe; + } + } + + // BUG: Check for casting array types, such as void[] to int*[] + } + + e = e1.castTo(sc, to); return e; } - MATCH implicitConvTo(Type t) + override MATCH implicitConvTo(Type t) { - static if (false) { - printf("CastExp::implicitConvTo(this=%s, type=%s, t=%s)\n", toChars(), type.toChars(), t.toChars()); - } - MATCH result = type.implicitConvTo(t); - - if (result == MATCHnomatch) - { - if (t.isintegral() && - e1.type.isintegral() && - e1.implicitConvTo(t) != MATCHnomatch) - result = MATCHconvert; - else - result = Expression.implicitConvTo(t); - } + static if (false) { + printf("CastExp::implicitConvTo(this=%s, type=%s, t=%s)\n", toChars(), type.toChars(), t.toChars()); + } + MATCH result = type.implicitConvTo(t); + + if (result == MATCHnomatch) + { + if (t.isintegral() && + e1.type.isintegral() && + e1.implicitConvTo(t) != MATCHnomatch) + result = MATCHconvert; + else + result = Expression.implicitConvTo(t); + } return result; } - IntRange getIntRange() + override IntRange getIntRange() { - IntRange ir; - ir = e1.getIntRange(); - // Do sign extension - switch (e1.type.toBasetype().ty) - { - case Tint8: - if (ir.imax & 0x80) - ir.imax |= 0xFFFFFFFFFFFFFF00UL; - break; - case Tint16: - if (ir.imax & 0x8000) - ir.imax |= 0xFFFFFFFFFFFF0000UL; - break; - case Tint32: - if (ir.imax & 0x80000000) - ir.imax |= 0xFFFFFFFF00000000UL; - break; - default: - } - ir.imin &= type.sizemask(); - ir.imax &= type.sizemask(); - //printf("CastExp: imin = x%llx, imax = x%llx\n", ir.imin, ir.imax); + IntRange ir; + ir = e1.getIntRange(); + // Do sign extension + switch (e1.type.toBasetype().ty) + { + case Tint8: + if (ir.imax & 0x80) + ir.imax |= 0xFFFFFFFFFFFFFF00UL; + break; + case Tint16: + if (ir.imax & 0x8000) + ir.imax |= 0xFFFFFFFFFFFF0000UL; + break; + case Tint32: + if (ir.imax & 0x80000000) + ir.imax |= 0xFFFFFFFF00000000UL; + break; + default: + } + ir.imin &= type.sizemask(); + ir.imax &= type.sizemask(); + //printf("CastExp: imin = x%llx, imax = x%llx\n", ir.imin, ir.imax); return ir; } - Expression optimize(int result) - { - //printf("CastExp.optimize(result = %d) %s\n", result, toChars()); - //printf("from %s to %s\n", type.toChars(), to.toChars()); - //printf("from %s\n", type.toChars()); - //printf("e1.type %s\n", e1.type.toChars()); - //printf("type = %p\n", type); - assert(type); - TOK op1 = e1.op; - - Expression e1old = e1; - e1 = e1.optimize(result); - e1 = fromConstInitializer(result, e1); - - if (e1 == e1old && - e1.op == TOK.TOKarrayliteral && - type.toBasetype().ty == TY.Tpointer && - e1.type.toBasetype().ty != TY.Tsarray) - { - // Casting this will result in the same expression, and - // infinite loop because of Expression.implicitCastTo() - return this; // no change - } - - if ((e1.op == TOK.TOKstring || e1.op == TOK.TOKarrayliteral) && - (type.ty == TY.Tpointer || type.ty == TY.Tarray) && - e1.type.nextOf().size() == type.nextOf().size() - ) - { - Expression e = e1.castTo(null, type); - -static if (false) { - printf(" returning1 %s\n", e.toChars()); -} - return e; - } - - if (e1.op == TOK.TOKstructliteral && - e1.type.implicitConvTo(type) >= MATCH.MATCHconst) - { - e1.type = type; -static if (false) { - printf(" returning2 %s\n", e1.toChars()); -} - return e1; - } - - /* The first test here is to prevent infinite loops - */ - if (op1 != TOK.TOKarrayliteral && e1.op == TOK.TOKarrayliteral) - return e1.castTo(null, to); - if (e1.op == TOK.TOKnull && - (type.ty == TY.Tpointer || type.ty == TY.Tclass || type.ty == TY.Tarray)) - { - e1.type = type; -static if (false) { - printf(" returning3 %s\n", e1.toChars()); -} - return e1; - } - - if (result & WANT.WANTflags && type.ty == TY.Tclass && e1.type.ty == TY.Tclass) - { - // See if we can remove an unnecessary cast - ClassDeclaration cdfrom; - ClassDeclaration cdto; - int offset; - - cdfrom = e1.type.isClassHandle(); - cdto = type.isClassHandle(); - if (cdto.isBaseOf(cdfrom, &offset) && offset == 0) - { - e1.type = type; -static if (false) { - printf(" returning4 %s\n", e1.toChars()); -} - return e1; - } - } - - // We can convert 'head const' to mutable - if (to.constOf().equals(e1.type.constOf())) - // if (to.constConv(e1.type) >= MATCHconst) - { - e1.type = type; -static if (false) { - printf(" returning5 %s\n", e1.toChars()); -} - return e1; - } - - Expression e; - - if (e1.isConst()) - { - if (e1.op == TOK.TOKsymoff) - { - if (type.size() == e1.type.size() && - type.toBasetype().ty != TY.Tsarray) - { - e1.type = type; - return e1; - } - return this; - } - if (to.toBasetype().ty == TY.Tvoid) - e = this; - else - e = Cast(type, to, e1); - } - else - e = this; -static if (false) { - printf(" returning6 %s\n", e.toChars()); -} + override Expression optimize(int result) + { + //printf("CastExp.optimize(result = %d) %s\n", result, toChars()); + //printf("from %s to %s\n", type.toChars(), to.toChars()); + //printf("from %s\n", type.toChars()); + //printf("e1.type %s\n", e1.type.toChars()); + //printf("type = %p\n", type); + assert(type); + TOK op1 = e1.op; + + Expression e1old = e1; + e1 = e1.optimize(result); + e1 = fromConstInitializer(result, e1); + + if (e1 == e1old && + e1.op == TOK.TOKarrayliteral && + type.toBasetype().ty == TY.Tpointer && + e1.type.toBasetype().ty != TY.Tsarray) + { + // Casting this will result in the same expression, and + // infinite loop because of Expression.implicitCastTo() + return this; // no change + } + + if ((e1.op == TOK.TOKstring || e1.op == TOK.TOKarrayliteral) && + (type.ty == TY.Tpointer || type.ty == TY.Tarray) && + e1.type.nextOf().size() == type.nextOf().size() + ) + { + Expression e = e1.castTo(null, type); + +static if (false) { + printf(" returning1 %s\n", e.toChars()); +} + return e; + } + + if (e1.op == TOK.TOKstructliteral && + e1.type.implicitConvTo(type) >= MATCH.MATCHconst) + { + e1.type = type; +static if (false) { + printf(" returning2 %s\n", e1.toChars()); +} + return e1; + } + + /* The first test here is to prevent infinite loops + */ + if (op1 != TOK.TOKarrayliteral && e1.op == TOK.TOKarrayliteral) + return e1.castTo(null, to); + if (e1.op == TOK.TOKnull && + (type.ty == TY.Tpointer || type.ty == TY.Tclass || type.ty == TY.Tarray)) + { + e1.type = type; +static if (false) { + printf(" returning3 %s\n", e1.toChars()); +} + return e1; + } + + if (result & WANT.WANTflags && type.ty == TY.Tclass && e1.type.ty == TY.Tclass) + { + // See if we can remove an unnecessary cast + ClassDeclaration cdfrom; + ClassDeclaration cdto; + int offset; + + cdfrom = e1.type.isClassHandle(); + cdto = type.isClassHandle(); + if (cdto.isBaseOf(cdfrom, &offset) && offset == 0) + { + e1.type = type; +static if (false) { + printf(" returning4 %s\n", e1.toChars()); +} + return e1; + } + } + + // We can convert 'head const' to mutable + if (to.constOf().equals(e1.type.constOf())) + // if (to.constConv(e1.type) >= MATCHconst) + { + e1.type = type; +static if (false) { + printf(" returning5 %s\n", e1.toChars()); +} + return e1; + } + + Expression e; + + if (e1.isConst()) + { + if (e1.op == TOK.TOKsymoff) + { + if (type.size() == e1.type.size() && + type.toBasetype().ty != TY.Tsarray) + { + e1.type = type; + return e1; + } + return this; + } + if (to.toBasetype().ty == TY.Tvoid) + e = this; + else + e = Cast(type, to, e1); + } + else + e = this; +static if (false) { + printf(" returning6 %s\n", e.toChars()); +} return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - bool checkSideEffect(int flag) + override bool checkSideEffect(int flag) { assert(false); } - void checkEscape() + override void checkEscape() { - Type tb = type.toBasetype(); - if (tb.ty == TY.Tarray && e1.op == TOK.TOKvar && e1.type.toBasetype().ty ==TY.Tsarray) - { - VarExp ve = cast(VarExp)e1; - VarDeclaration v = ve.var.isVarDeclaration(); - if (v) - { - if (!v.isDataseg() && !v.isParameter()) - error("escaping reference to local %s", v.toChars()); - } + Type tb = type.toBasetype(); + if (tb.ty == TY.Tarray && e1.op == TOK.TOKvar && e1.type.toBasetype().ty ==TY.Tsarray) + { + VarExp ve = cast(VarExp)e1; + VarDeclaration v = ve.var.isVarDeclaration(); + if (v) + { + if (!v.isDataseg() && !v.isParameter()) + error("escaping reference to local %s", v.toChars()); + } } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - buf.writestring("cast("); - version (DMDV1) { - to.toCBuffer(buf, null, hgs); - } else { - if (to) - to.toCBuffer(buf, null, hgs); - else - { - switch (mod) - { - case MODundefined: - break; - case MODconst: - buf.writestring(Token.tochars[TOKconst]); - break; - case MODinvariant: - buf.writestring(Token.tochars[TOKimmutable]); - break; - case MODshared: - buf.writestring(Token.tochars[TOKshared]); - break; - case MODshared | MODconst: - buf.writestring(Token.tochars[TOKshared]); - buf.writeByte(' '); - buf.writestring(Token.tochars[TOKconst]); - break; - default: - assert(0); - } - } - } - buf.writeByte(')'); + buf.writestring("cast("); + version (DMDV1) { + to.toCBuffer(buf, null, hgs); + } else { + if (to) + to.toCBuffer(buf, null, hgs); + else + { + switch (mod) + { + case MODundefined: + break; + case MODconst: + buf.writestring(Token.tochars[TOKconst]); + break; + case MODinvariant: + buf.writestring(Token.tochars[TOKimmutable]); + break; + case MODshared: + buf.writestring(Token.tochars[TOKshared]); + break; + case MODshared | MODconst: + buf.writestring(Token.tochars[TOKshared]); + buf.writeByte(' '); + buf.writestring(Token.tochars[TOKconst]); + break; + default: + assert(0); + } + } + } + buf.writeByte(')'); expToCBuffer(buf, hgs, e1, precedence[op]); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { - Type tb = type.toBasetype(); - if (tb.ty == Tarray || tb.ty == Tsarray) - { - e1.buildArrayIdent(buf, arguments); - } - else + Type tb = type.toBasetype(); + if (tb.ty == Tarray || tb.ty == Tsarray) + { + e1.buildArrayIdent(buf, arguments); + } + else Expression.buildArrayIdent(buf, arguments); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { - Type tb = type.toBasetype(); - if (tb.ty == Tarray || tb.ty == Tsarray) - { - return e1.buildArrayLoop(fparams); - } - else + Type tb = type.toBasetype(); + if (tb.ty == Tarray || tb.ty == Tsarray) + { + return e1.buildArrayLoop(fparams); + } + else return Expression.buildArrayLoop(fparams); - } - - static int X(int fty, int tty) { - return ((fty) * TY.TMAX + (tty)); + } + + static int X(int fty, int tty) { + return ((fty) * TY.TMAX + (tty)); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { - elem* e; - TY fty; - TY tty; - tym_t ftym; - tym_t ttym; - OPER eop; - Type t; - Type tfrom; - -static if (false) { - printf("CastExp::toElem()\n"); - print(); - printf("\tfrom: %s\n", e1.type.toChars()); - printf("\tto : %s\n", to.toChars()); -} - - e = e1.toElem(irs); - tfrom = e1.type.toBasetype(); - t = to.toBasetype(); // skip over typedef's - if (t.equals(tfrom)) - goto Lret; - - fty = tfrom.ty; - //printf("fty = %d\n", fty); - tty = t.ty; - - if (tty == TY.Tpointer && fty == TY.Tarray -///static if (false) { -/// && (t.next.ty == Tvoid || t.next.equals(e1.type.next)) -///} - ) - { - if (e.Eoper == OPER.OPvar) - { - // e1 . *(&e1 + 4) - e = el_una(OPER.OPaddr, TYM.TYnptr, e); - e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, 4)); - e = el_una(OPER.OPind, t.totym(),e); - } - else - { - // e1 . (unsigned)(e1 >> 32) - e = el_bin(OPER.OPshr, TYM.TYullong, e, el_long(TYM.TYint, 32)); - e = el_una(OPER.OP64_32, t.totym(), e); - } - goto Lret; - } - - if (tty == TY.Tpointer && fty == TY.Tsarray -///static if (false) { -/// && (t.next.ty == Tvoid || t.next.equals(e1.type.next)) -///} - ) - { - // e1 . &e1 - e = el_una(OPER.OPaddr, TYM.TYnptr, e); - goto Lret; - } - - // Convert from static array to dynamic array - if (tty == TY.Tarray && fty == TY.Tsarray) - { - e = sarray_toDarray(loc, tfrom, t, e); - goto Lret; - } - - // Convert from dynamic array to dynamic array - if (tty == TY.Tarray && fty == TY.Tarray) - { - uint fsize = cast(uint)tfrom.nextOf().size(); - uint tsize = cast(uint)t.nextOf().size(); - - if (fsize != tsize) - { - elem* ep = el_params(e, el_long(TYM.TYint, fsize), el_long(TYM.TYint, tsize), null); - e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[RTLSYM.RTLSYM_ARRAYCAST]), ep); - } - goto Lret; - } - -static if (false) { - // Convert from dynamic array string literal to static array - if (tty == TY.Tsarray && fty == TY.Tarray && e1.op == TOK.TOKstring) - { - goto Lret; // treat as a 'paint' - } -} - - // Casting from base class to derived class requires a runtime check - if (fty == TY.Tclass && tty == TY.Tclass) - { - // Casting from derived class to base class is a no-op - ClassDeclaration cdfrom; - ClassDeclaration cdto; - int offset; - int rtl = RTLSYM.RTLSYM_DYNAMIC_CAST; - - cdfrom = tfrom.isClassHandle(); - cdto = t.isClassHandle(); - if (cdfrom.isInterfaceDeclaration()) - { - rtl = RTLSYM.RTLSYM_INTERFACE_CAST; - if (cdfrom.isCPPinterface()) - { - if (cdto.isCPPinterface()) - { - /* Casting from a C++ interface to a C++ interface - * is always a 'paint' operation - */ - goto Lret; // no-op - } - - /* Casting from a C++ interface to a class - * always results in null because there is no runtime - * information available to do it. - * - * Casting from a C++ interface to a non-C++ interface - * always results in null because there's no way one - * can be derived from the other. - */ - e = el_bin(OPER.OPcomma, TYM.TYnptr, e, el_long(TYM.TYnptr, 0)); - goto Lret; - } - } - if (cdto.isBaseOf(cdfrom, &offset) && offset != OFFSET_RUNTIME) - { - /* The offset from cdfrom=>cdto is known at compile time. - */ - - //printf("offset = %d\n", offset); - if (offset) - { - /* Rewrite cast as (e ? e + offset : null) - */ - elem* etmp; - elem* ex; - - if (e1.op == TOK.TOKthis) - { - // Assume 'this' is never null, so skip null check - e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, offset)); - } - else - { - etmp = el_same(&e); - ex = el_bin(OPER.OPadd, TYM.TYnptr, etmp, el_long(TYM.TYint, offset)); - ex = el_bin(OPER.OPcolon, TYM.TYnptr, ex, el_long(TYM.TYnptr, 0)); - e = el_bin(OPER.OPcond, TYM.TYnptr, e, ex); - } - } - goto Lret; // no-op - } - - /* The offset from cdfrom=>cdto can only be determined at runtime. - */ - elem* ep; - - ep = el_param(el_ptr(cdto.toSymbol()), e); - e = el_bin(OPER.OPcall, TYM.TYnptr, el_var(rtlsym[rtl]), ep); - goto Lret; - } - - ftym = e.Ety; - ttym = t.totym(); - if (ftym == ttym) - goto Lret; - - switch (tty) - { - case TY.Tpointer: - if (fty == TY.Tdelegate) - goto Lpaint; - tty = TY.Tuns32; - break; - - case TY.Tchar: - tty = TY.Tuns8; - break; - case TY.Twchar: - tty = TY.Tuns16; - break; - case TY.Tdchar: - tty = TY.Tuns32; - break; - case TY.Tvoid: - goto Lpaint; - - case TY.Tbool: - { - // Construct e?true:false - elem* eq; - - e = el_una(OPER.OPbool, ttym, e); - goto Lret; - } - - default: - break; /// - } - - switch (fty) - { - case TY.Tpointer: fty = TY.Tuns32; break; - case TY.Tchar: fty = TY.Tuns8; break; - case TY.Twchar: fty = TY.Tuns16; break; - case TY.Tdchar: fty = TY.Tuns32; break; - default: break; /// - } - - Lagain: - switch (X(fty,tty)) - { -static if (false) { - case X(TY.Tbit,TY.Tint8): - case X(TY.Tbit,TY.Tuns8): - goto Lpaint; - case X(TY.Tbit,TY.Tint16): - case X(TY.Tbit,TY.Tuns16): - case X(TY.Tbit,TY.Tint32): - case X(TY.Tbit,TY.Tuns32): - eop = OPu8_16; - goto Leop; - case X(TY.Tbit,TY.Tint64): - case X(TY.Tbit,TY.Tuns64): - case X(TY.Tbit,TY.Tfloat32): - case X(TY.Tbit,TY.Tfloat64): - case X(TY.Tbit,TY.Tfloat80): - case X(TY.Tbit,TY.Tcomplex32): - case X(TY.Tbit,TY.Tcomplex64): - case X(TY.Tbit,TY.Tcomplex80): - e = el_una(OPER.OPu8_16, TYM.TYuint, e); - fty = TY.Tuns32; - goto Lagain; - case X(Tbit,Timaginary32): - case X(Tbit,Timaginary64): - case X(Tbit,Timaginary80): - goto Lzero; -} - /* ============================= */ - - case X(TY.Tbool,TY.Tint8): - case X(TY.Tbool,TY.Tuns8): - goto Lpaint; - case X(TY.Tbool,TY.Tint16): - case X(TY.Tbool,TY.Tuns16): - case X(TY.Tbool,TY.Tint32): - case X(TY.Tbool,TY.Tuns32): - eop = OPER.OPu8_16; - goto Leop; - case X(TY.Tbool,TY.Tint64): - case X(TY.Tbool,TY.Tuns64): - case X(TY.Tbool,TY.Tfloat32): - case X(TY.Tbool,TY.Tfloat64): - case X(TY.Tbool,TY.Tfloat80): - case X(TY.Tbool,TY.Tcomplex32): - case X(TY.Tbool,TY.Tcomplex64): - case X(TY.Tbool,TY.Tcomplex80): - e = el_una(OPER.OPu8_16, TYM.TYuint, e); - fty = TY.Tuns32; - goto Lagain; - case X(TY.Tbool,TY.Timaginary32): - case X(TY.Tbool,TY.Timaginary64): - case X(TY.Tbool,TY.Timaginary80): - goto Lzero; - - /* ============================= */ - - case X(TY.Tint8,TY.Tuns8): - goto Lpaint; - case X(TY.Tint8,TY.Tint16): - case X(TY.Tint8,TY.Tuns16): - case X(TY.Tint8,TY.Tint32): - case X(TY.Tint8,TY.Tuns32): - eop = OPER.OPs8_16; - goto Leop; - case X(TY.Tint8,TY.Tint64): - case X(TY.Tint8,TY.Tuns64): - case X(TY.Tint8,TY.Tfloat32): - case X(TY.Tint8,TY.Tfloat64): - case X(TY.Tint8,TY.Tfloat80): - case X(TY.Tint8,TY.Tcomplex32): - case X(TY.Tint8,TY.Tcomplex64): - case X(TY.Tint8,TY.Tcomplex80): - e = el_una(OPER.OPs8_16, TYM.TYint, e); - fty = TY.Tint32; - goto Lagain; - case X(TY.Tint8,TY.Timaginary32): - case X(TY.Tint8,TY.Timaginary64): - case X(TY.Tint8,TY.Timaginary80): - goto Lzero; - - /* ============================= */ - - case X(TY.Tuns8,TY.Tint8): - goto Lpaint; - case X(TY.Tuns8,TY.Tint16): - case X(TY.Tuns8,TY.Tuns16): - case X(TY.Tuns8,TY.Tint32): - case X(TY.Tuns8,TY.Tuns32): - eop = OPER.OPu8_16; - goto Leop; - case X(TY.Tuns8,TY.Tint64): - case X(TY.Tuns8,TY.Tuns64): - case X(TY.Tuns8,TY.Tfloat32): - case X(TY.Tuns8,TY.Tfloat64): - case X(TY.Tuns8,TY.Tfloat80): - case X(TY.Tuns8,TY.Tcomplex32): - case X(TY.Tuns8,TY.Tcomplex64): - case X(TY.Tuns8,TY.Tcomplex80): - e = el_una(OPER.OPu8_16, TYM.TYuint, e); - fty = TY.Tuns32; - goto Lagain; - case X(TY.Tuns8,TY.Timaginary32): - case X(TY.Tuns8,TY.Timaginary64): - case X(TY.Tuns8,TY.Timaginary80): - goto Lzero; - - /* ============================= */ - - case X(TY.Tint16,TY.Tint8): - case X(TY.Tint16,TY.Tuns8): - eop = OPER.OP16_8; - goto Leop; - case X(TY.Tint16,TY.Tuns16): - goto Lpaint; - case X(TY.Tint16,TY.Tint32): - case X(TY.Tint16,TY.Tuns32): - eop = OPER.OPs16_32; - goto Leop; - case X(TY.Tint16,TY.Tint64): - case X(TY.Tint16,TY.Tuns64): - e = el_una(OPER.OPs16_32, TYM.TYint, e); - fty = TY.Tint32; - goto Lagain; - case X(TY.Tint16,TY.Tfloat32): - case X(TY.Tint16,TY.Tfloat64): - case X(TY.Tint16,TY.Tfloat80): - case X(TY.Tint16,TY.Tcomplex32): - case X(TY.Tint16,TY.Tcomplex64): - case X(TY.Tint16,TY.Tcomplex80): - e = el_una(OPER.OPs16_d, TYM.TYdouble, e); - fty = TY.Tfloat64; - goto Lagain; - case X(TY.Tint16,TY.Timaginary32): - case X(TY.Tint16,TY.Timaginary64): - case X(TY.Tint16,TY.Timaginary80): - goto Lzero; - - /* ============================= */ - - case X(TY.Tuns16,TY.Tint8): - case X(TY.Tuns16,TY.Tuns8): - eop = OPER.OP16_8; - goto Leop; - case X(TY.Tuns16,TY.Tint16): - goto Lpaint; - case X(TY.Tuns16,TY.Tint32): - case X(TY.Tuns16,TY.Tuns32): - eop = OPER.OPu16_32; - goto Leop; - case X(TY.Tuns16,TY.Tint64): - case X(TY.Tuns16,TY.Tuns64): - case X(TY.Tuns16,TY.Tfloat64): - case X(TY.Tuns16,TY.Tfloat32): - case X(TY.Tuns16,TY.Tfloat80): - case X(TY.Tuns16,TY.Tcomplex32): - case X(TY.Tuns16,TY.Tcomplex64): - case X(TY.Tuns16,TY.Tcomplex80): - e = el_una(OPER.OPu16_32, TYM.TYuint, e); - fty = TY.Tuns32; - goto Lagain; - case X(TY.Tuns16,TY.Timaginary32): - case X(TY.Tuns16,TY.Timaginary64): - case X(TY.Tuns16,TY.Timaginary80): - goto Lzero; - - /* ============================= */ - - case X(TY.Tint32,TY.Tint8): - case X(TY.Tint32,TY.Tuns8): - e = el_una(OPER.OP32_16, TYM.TYshort, e); - fty = TY.Tint16; - goto Lagain; - case X(TY.Tint32,TY.Tint16): - case X(TY.Tint32,TY.Tuns16): - eop = OPER.OP32_16; - goto Leop; - case X(TY.Tint32,TY.Tuns32): - goto Lpaint; - case X(TY.Tint32,TY.Tint64): - case X(TY.Tint32,TY.Tuns64): - eop = OPER.OPs32_64; - goto Leop; - case X(TY.Tint32,TY.Tfloat32): - case X(TY.Tint32,TY.Tfloat64): - case X(TY.Tint32,TY.Tfloat80): - case X(TY.Tint32,TY.Tcomplex32): - case X(TY.Tint32,TY.Tcomplex64): - case X(TY.Tint32,TY.Tcomplex80): - e = el_una(OPER.OPs32_d, TYM.TYdouble, e); - fty = TY.Tfloat64; - goto Lagain; - case X(TY.Tint32,TY.Timaginary32): - case X(TY.Tint32,TY.Timaginary64): - case X(TY.Tint32,TY.Timaginary80): - goto Lzero; - - /* ============================= */ - - case X(TY.Tuns32,TY.Tint8): - case X(TY.Tuns32,TY.Tuns8): - e = el_una(OPER.OP32_16, TYM.TYshort, e); - fty = TY.Tuns16; - goto Lagain; - case X(TY.Tuns32,TY.Tint16): - case X(TY.Tuns32,TY.Tuns16): - eop = OPER.OP32_16; - goto Leop; - case X(TY.Tuns32,TY.Tint32): - goto Lpaint; - case X(TY.Tuns32,TY.Tint64): - case X(TY.Tuns32,TY.Tuns64): - eop = OPER.OPu32_64; - goto Leop; - case X(TY.Tuns32,TY.Tfloat32): - case X(TY.Tuns32,TY.Tfloat64): - case X(TY.Tuns32,TY.Tfloat80): - case X(TY.Tuns32,TY.Tcomplex32): - case X(TY.Tuns32,TY.Tcomplex64): - case X(TY.Tuns32,TY.Tcomplex80): - e = el_una(OPER.OPu32_d, TYM.TYdouble, e); - fty = TY.Tfloat64; - goto Lagain; - case X(TY.Tuns32,TY.Timaginary32): - case X(TY.Tuns32,TY.Timaginary64): - case X(TY.Tuns32,TY.Timaginary80): - goto Lzero; - - /* ============================= */ - - case X(TY.Tint64,TY.Tint8): - case X(TY.Tint64,TY.Tuns8): - case X(TY.Tint64,TY.Tint16): - case X(TY.Tint64,TY.Tuns16): - e = el_una(OPER.OP64_32, TYM.TYint, e); - fty = TY.Tint32; - goto Lagain; - case X(TY.Tint64,TY.Tint32): - case X(TY.Tint64,TY.Tuns32): - eop = OPER.OP64_32; - goto Leop; - case X(TY.Tint64,TY.Tuns64): - goto Lpaint; - case X(TY.Tint64,TY.Tfloat32): - case X(TY.Tint64,TY.Tfloat64): - case X(TY.Tint64,TY.Tfloat80): - case X(TY.Tint64,TY.Tcomplex32): - case X(TY.Tint64,TY.Tcomplex64): - case X(TY.Tint64,TY.Tcomplex80): - e = el_una(OPER.OPs64_d, TYM.TYdouble, e); - fty = TY.Tfloat64; - goto Lagain; - case X(TY.Tint64,TY.Timaginary32): - case X(TY.Tint64,TY.Timaginary64): - case X(TY.Tint64,TY.Timaginary80): - goto Lzero; - - /* ============================= */ - - case X(TY.Tuns64,TY.Tint8): - case X(TY.Tuns64,TY.Tuns8): - case X(TY.Tuns64,TY.Tint16): - case X(TY.Tuns64,TY.Tuns16): - e = el_una(OPER.OP64_32, TYM.TYint, e); - fty = TY.Tint32; - goto Lagain; - case X(TY.Tuns64,TY.Tint32): - case X(TY.Tuns64,TY.Tuns32): - eop = OPER.OP64_32; - goto Leop; - case X(TY.Tuns64,TY.Tint64): - goto Lpaint; - case X(TY.Tuns64,TY.Tfloat32): - case X(TY.Tuns64,TY.Tfloat64): - case X(TY.Tuns64,TY.Tfloat80): - case X(TY.Tuns64,TY.Tcomplex32): - case X(TY.Tuns64,TY.Tcomplex64): - case X(TY.Tuns64,TY.Tcomplex80): - e = el_una(OPER.OPu64_d, TYM.TYdouble, e); - fty = TY.Tfloat64; - goto Lagain; - case X(TY.Tuns64,TY.Timaginary32): - case X(TY.Tuns64,TY.Timaginary64): - case X(TY.Tuns64,TY.Timaginary80): - goto Lzero; - - /* ============================= */ - - case X(TY.Tfloat32,TY.Tint8): - case X(TY.Tfloat32,TY.Tuns8): - case X(TY.Tfloat32,TY.Tint16): - case X(TY.Tfloat32,TY.Tuns16): - case X(TY.Tfloat32,TY.Tint32): - case X(TY.Tfloat32,TY.Tuns32): - case X(TY.Tfloat32,TY.Tint64): - case X(TY.Tfloat32,TY.Tuns64): - case X(TY.Tfloat32,TY.Tfloat80): - e = el_una(OPER.OPf_d, TYM.TYdouble, e); - fty = TY.Tfloat64; - goto Lagain; - case X(TY.Tfloat32,TY.Tfloat64): - eop = OPER.OPf_d; - goto Leop; - case X(TY.Tfloat32,TY.Timaginary32): - goto Lzero; - case X(TY.Tfloat32,TY.Timaginary64): - goto Lzero; - case X(TY.Tfloat32,TY.Timaginary80): - goto Lzero; - case X(TY.Tfloat32,TY.Tcomplex32): - case X(TY.Tfloat32,TY.Tcomplex64): - case X(TY.Tfloat32,TY.Tcomplex80): - e = el_bin(OPER.OPadd,TYM.TYcfloat,el_long(TYM.TYifloat,0),e); - fty = TY.Tcomplex32; - goto Lagain; - - /* ============================= */ - - case X(TY.Tfloat64,TY.Tint8): - case X(TY.Tfloat64,TY.Tuns8): - e = el_una(OPER.OPd_s16, TYM.TYshort, e); - fty = TY.Tint16; - goto Lagain; - case X(TY.Tfloat64,TY.Tint16): - eop = OPER.OPd_s16; - goto Leop; - case X(TY.Tfloat64,TY.Tuns16): - eop = OPER.OPd_u16; - goto Leop; - case X(TY.Tfloat64,TY.Tint32): - eop = OPER.OPd_s32; - goto Leop; - case X(TY.Tfloat64,TY.Tuns32): - eop = OPER.OPd_u32; - goto Leop; - case X(TY.Tfloat64,TY.Tint64): - eop = OPER.OPd_s64; - goto Leop; - case X(TY.Tfloat64,TY.Tuns64): - eop = OPER.OPd_u64; - goto Leop; - case X(TY.Tfloat64,TY.Tfloat32): - eop = OPER.OPd_f; - goto Leop; - case X(TY.Tfloat64,TY.Tfloat80): - eop = OPER.OPd_ld; - goto Leop; - case X(TY.Tfloat64,TY.Timaginary32): - goto Lzero; - case X(TY.Tfloat64,TY.Timaginary64): - goto Lzero; - case X(TY.Tfloat64,TY.Timaginary80): - goto Lzero; - case X(TY.Tfloat64,TY.Tcomplex32): - case X(TY.Tfloat64,TY.Tcomplex64): - case X(TY.Tfloat64,TY.Tcomplex80): - e = el_bin(OPER.OPadd,TYM.TYcfloat,el_long(TYM.TYidouble,0),e); - fty = TY.Tcomplex64; - goto Lagain; - - /* ============================= */ - - case X(TY.Tfloat80,TY.Tint8): - case X(TY.Tfloat80,TY.Tuns8): - case X(TY.Tfloat80,TY.Tint16): - case X(TY.Tfloat80,TY.Tuns16): - case X(TY.Tfloat80,TY.Tint32): - case X(TY.Tfloat80,TY.Tuns32): - case X(TY.Tfloat80,TY.Tint64): - case X(TY.Tfloat80,TY.Tfloat32): - e = el_una(OPER.OPld_d, TYM.TYdouble, e); - fty = TY.Tfloat64; - goto Lagain; - case X(TY.Tfloat80,TY.Tuns64): - eop = OPER.OPld_u64; - goto Leop; - case X(TY.Tfloat80,TY.Tfloat64): - eop = OPER.OPld_d; - goto Leop; - case X(TY.Tfloat80,TY.Timaginary32): - goto Lzero; - case X(TY.Tfloat80,TY.Timaginary64): - goto Lzero; - case X(TY.Tfloat80,TY.Timaginary80): - goto Lzero; - case X(TY.Tfloat80,TY.Tcomplex32): - case X(TY.Tfloat80,TY.Tcomplex64): - case X(TY.Tfloat80,TY.Tcomplex80): - e = el_bin(OPER.OPadd,TYM.TYcldouble,e,el_long(TYM.TYildouble,0)); - fty = TY.Tcomplex80; - goto Lagain; - - /* ============================= */ - - case X(TY.Timaginary32,TY.Tint8): - case X(TY.Timaginary32,TY.Tuns8): - case X(TY.Timaginary32,TY.Tint16): - case X(TY.Timaginary32,TY.Tuns16): - case X(TY.Timaginary32,TY.Tint32): - case X(TY.Timaginary32,TY.Tuns32): - case X(TY.Timaginary32,TY.Tint64): - case X(TY.Timaginary32,TY.Tuns64): - case X(TY.Timaginary32,TY.Tfloat32): - case X(TY.Timaginary32,TY.Tfloat64): - case X(TY.Timaginary32,TY.Tfloat80): - goto Lzero; - case X(TY.Timaginary32,TY.Timaginary64): - eop = OPER.OPf_d; - goto Leop; - case X(TY.Timaginary32,TY.Timaginary80): - e = el_una(OPER.OPf_d, TYM.TYidouble, e); - fty = TY.Timaginary64; - goto Lagain; - case X(TY.Timaginary32,TY.Tcomplex32): - case X(TY.Timaginary32,TY.Tcomplex64): - case X(TY.Timaginary32,TY.Tcomplex80): - e = el_bin(OPER.OPadd,TYM.TYcfloat,el_long(TYM.TYfloat,0),e); - fty = TY.Tcomplex32; - goto Lagain; - - /* ============================= */ - - case X(TY.Timaginary64,TY.Tint8): - case X(TY.Timaginary64,TY.Tuns8): - case X(TY.Timaginary64,TY.Tint16): - case X(TY.Timaginary64,TY.Tuns16): - case X(TY.Timaginary64,TY.Tint32): - case X(TY.Timaginary64,TY.Tuns32): - case X(TY.Timaginary64,TY.Tint64): - case X(TY.Timaginary64,TY.Tuns64): - case X(TY.Timaginary64,TY.Tfloat32): - case X(TY.Timaginary64,TY.Tfloat64): - case X(TY.Timaginary64,TY.Tfloat80): - goto Lzero; - case X(TY.Timaginary64,TY.Timaginary32): - eop = OPER.OPd_f; - goto Leop; - case X(TY.Timaginary64,TY.Timaginary80): - eop = OPER.OPd_ld; - goto Leop; - case X(TY.Timaginary64,TY.Tcomplex32): - case X(TY.Timaginary64,TY.Tcomplex64): - case X(TY.Timaginary64,TY.Tcomplex80): - e = el_bin(OPER.OPadd, TYM.TYcdouble, el_long(TYM.TYdouble,0), e); - fty = TY.Tcomplex64; - goto Lagain; - - /* ============================= */ - - case X(TY.Timaginary80,TY.Tint8): - case X(TY.Timaginary80,TY.Tuns8): - case X(TY.Timaginary80,TY.Tint16): - case X(TY.Timaginary80,TY.Tuns16): - case X(TY.Timaginary80,TY.Tint32): - case X(TY.Timaginary80,TY.Tuns32): - case X(TY.Timaginary80,TY.Tint64): - case X(TY.Timaginary80,TY.Tuns64): - case X(TY.Timaginary80,TY.Tfloat32): - case X(TY.Timaginary80,TY.Tfloat64): - case X(TY.Timaginary80,TY.Tfloat80): - goto Lzero; - case X(TY.Timaginary80,TY.Timaginary32): - e = el_una(OPER.OPf_d, TYM.TYidouble, e); - fty = TY.Timaginary64; - goto Lagain; - case X(TY.Timaginary80,TY.Timaginary64): - eop = OPER.OPld_d; - goto Leop; - case X(TY.Timaginary80,TY.Tcomplex32): - case X(TY.Timaginary80,TY.Tcomplex64): - case X(TY.Timaginary80,TY.Tcomplex80): - e = el_bin(OPER.OPadd, TYM.TYcldouble, el_long(TYM.TYldouble,0), e); - fty = TY.Tcomplex80; - goto Lagain; - - /* ============================= */ - - case X(TY.Tcomplex32,TY.Tint8): - case X(TY.Tcomplex32,TY.Tuns8): - case X(TY.Tcomplex32,TY.Tint16): - case X(TY.Tcomplex32,TY.Tuns16): - case X(TY.Tcomplex32,TY.Tint32): - case X(TY.Tcomplex32,TY.Tuns32): - case X(TY.Tcomplex32,TY.Tint64): - case X(TY.Tcomplex32,TY.Tuns64): - case X(TY.Tcomplex32,TY.Tfloat32): - case X(TY.Tcomplex32,TY.Tfloat64): - case X(TY.Tcomplex32,TY.Tfloat80): - e = el_una(OPER.OPc_r, TYM.TYfloat, e); - fty = TY.Tfloat32; - goto Lagain; - case X(TY.Tcomplex32,TY.Timaginary32): - case X(TY.Tcomplex32,TY.Timaginary64): - case X(TY.Tcomplex32,TY.Timaginary80): - e = el_una(OPER.OPc_i, TYM.TYifloat, e); - fty = TY.Timaginary32; - goto Lagain; - case X(TY.Tcomplex32,TY.Tcomplex64): - case X(TY.Tcomplex32,TY.Tcomplex80): - e = el_una(OPER.OPf_d, TYM.TYcdouble, e); - fty = TY.Tcomplex64; - goto Lagain; - - /* ============================= */ - - case X(TY.Tcomplex64,TY.Tint8): - case X(TY.Tcomplex64,TY.Tuns8): - case X(TY.Tcomplex64,TY.Tint16): - case X(TY.Tcomplex64,TY.Tuns16): - case X(TY.Tcomplex64,TY.Tint32): - case X(TY.Tcomplex64,TY.Tuns32): - case X(TY.Tcomplex64,TY.Tint64): - case X(TY.Tcomplex64,TY.Tuns64): - case X(TY.Tcomplex64,TY.Tfloat32): - case X(TY.Tcomplex64,TY.Tfloat64): - case X(TY.Tcomplex64,TY.Tfloat80): - e = el_una(OPER.OPc_r, TYM.TYdouble, e); - fty = TY.Tfloat64; - goto Lagain; - case X(TY.Tcomplex64,TY.Timaginary32): - case X(TY.Tcomplex64,TY.Timaginary64): - case X(TY.Tcomplex64,TY.Timaginary80): - e = el_una(OPER.OPc_i, TYM.TYidouble, e); - fty = TY.Timaginary64; - goto Lagain; - case X(TY.Tcomplex64,TY.Tcomplex32): - eop = OPER.OPd_f; - goto Leop; - case X(TY.Tcomplex64,TY.Tcomplex80): - eop = OPER.OPd_ld; - goto Leop; - - /* ============================= */ - - case X(TY.Tcomplex80,TY.Tint8): - case X(TY.Tcomplex80,TY.Tuns8): - case X(TY.Tcomplex80,TY.Tint16): - case X(TY.Tcomplex80,TY.Tuns16): - case X(TY.Tcomplex80,TY.Tint32): - case X(TY.Tcomplex80,TY.Tuns32): - case X(TY.Tcomplex80,TY.Tint64): - case X(TY.Tcomplex80,TY.Tuns64): - case X(TY.Tcomplex80,TY.Tfloat32): - case X(TY.Tcomplex80,TY.Tfloat64): - case X(TY.Tcomplex80,TY.Tfloat80): - e = el_una(OPER.OPc_r, TYM.TYldouble, e); - fty = TY.Tfloat80; - goto Lagain; - case X(TY.Tcomplex80,TY.Timaginary32): - case X(TY.Tcomplex80,TY.Timaginary64): - case X(TY.Tcomplex80,TY.Timaginary80): - e = el_una(OPER.OPc_i, TYM.TYildouble, e); - fty = TY.Timaginary80; - goto Lagain; - case X(TY.Tcomplex80,TY.Tcomplex32): - case X(TY.Tcomplex80,TY.Tcomplex64): - e = el_una(OPER.OPld_d, TYM.TYcdouble, e); - fty = TY.Tcomplex64; - goto Lagain; - - /* ============================= */ - - default: - if (fty == tty) - goto Lpaint; - //dump(0); - //printf("fty = %d, tty = %d\n", fty, tty); - error("e2ir: cannot cast from %s to %s", e1.type.toChars(), t.toChars()); - goto Lzero; - - Lzero: - e = el_long(ttym, 0); - break; - - Lpaint: - e.Ety = ttym; - break; - - Leop: - e = el_una(eop, ttym, e); - break; - } - Lret: - // Adjust for any type paints - t = type.toBasetype(); - e.Ety = t.totym(); - - el_setLoc(e,loc); + elem* e; + TY fty; + TY tty; + tym_t ftym; + tym_t ttym; + OPER eop; + Type t; + Type tfrom; + +static if (false) { + printf("CastExp::toElem()\n"); + print(); + printf("\tfrom: %s\n", e1.type.toChars()); + printf("\tto : %s\n", to.toChars()); +} + + e = e1.toElem(irs); + tfrom = e1.type.toBasetype(); + t = to.toBasetype(); // skip over typedef's + if (t.equals(tfrom)) + goto Lret; + + fty = tfrom.ty; + //printf("fty = %d\n", fty); + tty = t.ty; + + if (tty == TY.Tpointer && fty == TY.Tarray +///static if (false) { +/// && (t.next.ty == Tvoid || t.next.equals(e1.type.next)) +///} + ) + { + if (e.Eoper == OPER.OPvar) + { + // e1 . *(&e1 + 4) + e = el_una(OPER.OPaddr, TYM.TYnptr, e); + e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, 4)); + e = el_una(OPER.OPind, t.totym(),e); + } + else + { + // e1 . (unsigned)(e1 >> 32) + e = el_bin(OPER.OPshr, TYM.TYullong, e, el_long(TYM.TYint, 32)); + e = el_una(OPER.OP64_32, t.totym(), e); + } + goto Lret; + } + + if (tty == TY.Tpointer && fty == TY.Tsarray +///static if (false) { +/// && (t.next.ty == Tvoid || t.next.equals(e1.type.next)) +///} + ) + { + // e1 . &e1 + e = el_una(OPER.OPaddr, TYM.TYnptr, e); + goto Lret; + } + + // Convert from static array to dynamic array + if (tty == TY.Tarray && fty == TY.Tsarray) + { + e = sarray_toDarray(loc, tfrom, t, e); + goto Lret; + } + + // Convert from dynamic array to dynamic array + if (tty == TY.Tarray && fty == TY.Tarray) + { + uint fsize = cast(uint)tfrom.nextOf().size(); + uint tsize = cast(uint)t.nextOf().size(); + + if (fsize != tsize) + { + elem* ep = el_params(e, el_long(TYM.TYint, fsize), el_long(TYM.TYint, tsize), null); + e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[RTLSYM.RTLSYM_ARRAYCAST]), ep); + } + goto Lret; + } + +static if (false) { + // Convert from dynamic array string literal to static array + if (tty == TY.Tsarray && fty == TY.Tarray && e1.op == TOK.TOKstring) + { + goto Lret; // treat as a 'paint' + } +} + + // Casting from base class to derived class requires a runtime check + if (fty == TY.Tclass && tty == TY.Tclass) + { + // Casting from derived class to base class is a no-op + ClassDeclaration cdfrom; + ClassDeclaration cdto; + int offset; + int rtl = RTLSYM.RTLSYM_DYNAMIC_CAST; + + cdfrom = tfrom.isClassHandle(); + cdto = t.isClassHandle(); + if (cdfrom.isInterfaceDeclaration()) + { + rtl = RTLSYM.RTLSYM_INTERFACE_CAST; + if (cdfrom.isCPPinterface()) + { + if (cdto.isCPPinterface()) + { + /* Casting from a C++ interface to a C++ interface + * is always a 'paint' operation + */ + goto Lret; // no-op + } + + /* Casting from a C++ interface to a class + * always results in null because there is no runtime + * information available to do it. + * + * Casting from a C++ interface to a non-C++ interface + * always results in null because there's no way one + * can be derived from the other. + */ + e = el_bin(OPER.OPcomma, TYM.TYnptr, e, el_long(TYM.TYnptr, 0)); + goto Lret; + } + } + if (cdto.isBaseOf(cdfrom, &offset) && offset != OFFSET_RUNTIME) + { + /* The offset from cdfrom=>cdto is known at compile time. + */ + + //printf("offset = %d\n", offset); + if (offset) + { + /* Rewrite cast as (e ? e + offset : null) + */ + elem* etmp; + elem* ex; + + if (e1.op == TOK.TOKthis) + { + // Assume 'this' is never null, so skip null check + e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, offset)); + } + else + { + etmp = el_same(&e); + ex = el_bin(OPER.OPadd, TYM.TYnptr, etmp, el_long(TYM.TYint, offset)); + ex = el_bin(OPER.OPcolon, TYM.TYnptr, ex, el_long(TYM.TYnptr, 0)); + e = el_bin(OPER.OPcond, TYM.TYnptr, e, ex); + } + } + goto Lret; // no-op + } + + /* The offset from cdfrom=>cdto can only be determined at runtime. + */ + elem* ep; + + ep = el_param(el_ptr(cdto.toSymbol()), e); + e = el_bin(OPER.OPcall, TYM.TYnptr, el_var(rtlsym[rtl]), ep); + goto Lret; + } + + ftym = e.Ety; + ttym = t.totym(); + if (ftym == ttym) + goto Lret; + + switch (tty) + { + case TY.Tpointer: + if (fty == TY.Tdelegate) + goto Lpaint; + tty = TY.Tuns32; + break; + + case TY.Tchar: + tty = TY.Tuns8; + break; + case TY.Twchar: + tty = TY.Tuns16; + break; + case TY.Tdchar: + tty = TY.Tuns32; + break; + case TY.Tvoid: + goto Lpaint; + + case TY.Tbool: + { + // Construct e?true:false + elem* eq; + + e = el_una(OPER.OPbool, ttym, e); + goto Lret; + } + + default: + break; /// + } + + switch (fty) + { + case TY.Tpointer: fty = TY.Tuns32; break; + case TY.Tchar: fty = TY.Tuns8; break; + case TY.Twchar: fty = TY.Tuns16; break; + case TY.Tdchar: fty = TY.Tuns32; break; + default: break; /// + } + + Lagain: + switch (X(fty,tty)) + { +static if (false) { + case X(TY.Tbit,TY.Tint8): + case X(TY.Tbit,TY.Tuns8): + goto Lpaint; + case X(TY.Tbit,TY.Tint16): + case X(TY.Tbit,TY.Tuns16): + case X(TY.Tbit,TY.Tint32): + case X(TY.Tbit,TY.Tuns32): + eop = OPu8_16; + goto Leop; + case X(TY.Tbit,TY.Tint64): + case X(TY.Tbit,TY.Tuns64): + case X(TY.Tbit,TY.Tfloat32): + case X(TY.Tbit,TY.Tfloat64): + case X(TY.Tbit,TY.Tfloat80): + case X(TY.Tbit,TY.Tcomplex32): + case X(TY.Tbit,TY.Tcomplex64): + case X(TY.Tbit,TY.Tcomplex80): + e = el_una(OPER.OPu8_16, TYM.TYuint, e); + fty = TY.Tuns32; + goto Lagain; + case X(Tbit,Timaginary32): + case X(Tbit,Timaginary64): + case X(Tbit,Timaginary80): + goto Lzero; +} + /* ============================= */ + + case X(TY.Tbool,TY.Tint8): + case X(TY.Tbool,TY.Tuns8): + goto Lpaint; + case X(TY.Tbool,TY.Tint16): + case X(TY.Tbool,TY.Tuns16): + case X(TY.Tbool,TY.Tint32): + case X(TY.Tbool,TY.Tuns32): + eop = OPER.OPu8_16; + goto Leop; + case X(TY.Tbool,TY.Tint64): + case X(TY.Tbool,TY.Tuns64): + case X(TY.Tbool,TY.Tfloat32): + case X(TY.Tbool,TY.Tfloat64): + case X(TY.Tbool,TY.Tfloat80): + case X(TY.Tbool,TY.Tcomplex32): + case X(TY.Tbool,TY.Tcomplex64): + case X(TY.Tbool,TY.Tcomplex80): + e = el_una(OPER.OPu8_16, TYM.TYuint, e); + fty = TY.Tuns32; + goto Lagain; + case X(TY.Tbool,TY.Timaginary32): + case X(TY.Tbool,TY.Timaginary64): + case X(TY.Tbool,TY.Timaginary80): + goto Lzero; + + /* ============================= */ + + case X(TY.Tint8,TY.Tuns8): + goto Lpaint; + case X(TY.Tint8,TY.Tint16): + case X(TY.Tint8,TY.Tuns16): + case X(TY.Tint8,TY.Tint32): + case X(TY.Tint8,TY.Tuns32): + eop = OPER.OPs8_16; + goto Leop; + case X(TY.Tint8,TY.Tint64): + case X(TY.Tint8,TY.Tuns64): + case X(TY.Tint8,TY.Tfloat32): + case X(TY.Tint8,TY.Tfloat64): + case X(TY.Tint8,TY.Tfloat80): + case X(TY.Tint8,TY.Tcomplex32): + case X(TY.Tint8,TY.Tcomplex64): + case X(TY.Tint8,TY.Tcomplex80): + e = el_una(OPER.OPs8_16, TYM.TYint, e); + fty = TY.Tint32; + goto Lagain; + case X(TY.Tint8,TY.Timaginary32): + case X(TY.Tint8,TY.Timaginary64): + case X(TY.Tint8,TY.Timaginary80): + goto Lzero; + + /* ============================= */ + + case X(TY.Tuns8,TY.Tint8): + goto Lpaint; + case X(TY.Tuns8,TY.Tint16): + case X(TY.Tuns8,TY.Tuns16): + case X(TY.Tuns8,TY.Tint32): + case X(TY.Tuns8,TY.Tuns32): + eop = OPER.OPu8_16; + goto Leop; + case X(TY.Tuns8,TY.Tint64): + case X(TY.Tuns8,TY.Tuns64): + case X(TY.Tuns8,TY.Tfloat32): + case X(TY.Tuns8,TY.Tfloat64): + case X(TY.Tuns8,TY.Tfloat80): + case X(TY.Tuns8,TY.Tcomplex32): + case X(TY.Tuns8,TY.Tcomplex64): + case X(TY.Tuns8,TY.Tcomplex80): + e = el_una(OPER.OPu8_16, TYM.TYuint, e); + fty = TY.Tuns32; + goto Lagain; + case X(TY.Tuns8,TY.Timaginary32): + case X(TY.Tuns8,TY.Timaginary64): + case X(TY.Tuns8,TY.Timaginary80): + goto Lzero; + + /* ============================= */ + + case X(TY.Tint16,TY.Tint8): + case X(TY.Tint16,TY.Tuns8): + eop = OPER.OP16_8; + goto Leop; + case X(TY.Tint16,TY.Tuns16): + goto Lpaint; + case X(TY.Tint16,TY.Tint32): + case X(TY.Tint16,TY.Tuns32): + eop = OPER.OPs16_32; + goto Leop; + case X(TY.Tint16,TY.Tint64): + case X(TY.Tint16,TY.Tuns64): + e = el_una(OPER.OPs16_32, TYM.TYint, e); + fty = TY.Tint32; + goto Lagain; + case X(TY.Tint16,TY.Tfloat32): + case X(TY.Tint16,TY.Tfloat64): + case X(TY.Tint16,TY.Tfloat80): + case X(TY.Tint16,TY.Tcomplex32): + case X(TY.Tint16,TY.Tcomplex64): + case X(TY.Tint16,TY.Tcomplex80): + e = el_una(OPER.OPs16_d, TYM.TYdouble, e); + fty = TY.Tfloat64; + goto Lagain; + case X(TY.Tint16,TY.Timaginary32): + case X(TY.Tint16,TY.Timaginary64): + case X(TY.Tint16,TY.Timaginary80): + goto Lzero; + + /* ============================= */ + + case X(TY.Tuns16,TY.Tint8): + case X(TY.Tuns16,TY.Tuns8): + eop = OPER.OP16_8; + goto Leop; + case X(TY.Tuns16,TY.Tint16): + goto Lpaint; + case X(TY.Tuns16,TY.Tint32): + case X(TY.Tuns16,TY.Tuns32): + eop = OPER.OPu16_32; + goto Leop; + case X(TY.Tuns16,TY.Tint64): + case X(TY.Tuns16,TY.Tuns64): + case X(TY.Tuns16,TY.Tfloat64): + case X(TY.Tuns16,TY.Tfloat32): + case X(TY.Tuns16,TY.Tfloat80): + case X(TY.Tuns16,TY.Tcomplex32): + case X(TY.Tuns16,TY.Tcomplex64): + case X(TY.Tuns16,TY.Tcomplex80): + e = el_una(OPER.OPu16_32, TYM.TYuint, e); + fty = TY.Tuns32; + goto Lagain; + case X(TY.Tuns16,TY.Timaginary32): + case X(TY.Tuns16,TY.Timaginary64): + case X(TY.Tuns16,TY.Timaginary80): + goto Lzero; + + /* ============================= */ + + case X(TY.Tint32,TY.Tint8): + case X(TY.Tint32,TY.Tuns8): + e = el_una(OPER.OP32_16, TYM.TYshort, e); + fty = TY.Tint16; + goto Lagain; + case X(TY.Tint32,TY.Tint16): + case X(TY.Tint32,TY.Tuns16): + eop = OPER.OP32_16; + goto Leop; + case X(TY.Tint32,TY.Tuns32): + goto Lpaint; + case X(TY.Tint32,TY.Tint64): + case X(TY.Tint32,TY.Tuns64): + eop = OPER.OPs32_64; + goto Leop; + case X(TY.Tint32,TY.Tfloat32): + case X(TY.Tint32,TY.Tfloat64): + case X(TY.Tint32,TY.Tfloat80): + case X(TY.Tint32,TY.Tcomplex32): + case X(TY.Tint32,TY.Tcomplex64): + case X(TY.Tint32,TY.Tcomplex80): + e = el_una(OPER.OPs32_d, TYM.TYdouble, e); + fty = TY.Tfloat64; + goto Lagain; + case X(TY.Tint32,TY.Timaginary32): + case X(TY.Tint32,TY.Timaginary64): + case X(TY.Tint32,TY.Timaginary80): + goto Lzero; + + /* ============================= */ + + case X(TY.Tuns32,TY.Tint8): + case X(TY.Tuns32,TY.Tuns8): + e = el_una(OPER.OP32_16, TYM.TYshort, e); + fty = TY.Tuns16; + goto Lagain; + case X(TY.Tuns32,TY.Tint16): + case X(TY.Tuns32,TY.Tuns16): + eop = OPER.OP32_16; + goto Leop; + case X(TY.Tuns32,TY.Tint32): + goto Lpaint; + case X(TY.Tuns32,TY.Tint64): + case X(TY.Tuns32,TY.Tuns64): + eop = OPER.OPu32_64; + goto Leop; + case X(TY.Tuns32,TY.Tfloat32): + case X(TY.Tuns32,TY.Tfloat64): + case X(TY.Tuns32,TY.Tfloat80): + case X(TY.Tuns32,TY.Tcomplex32): + case X(TY.Tuns32,TY.Tcomplex64): + case X(TY.Tuns32,TY.Tcomplex80): + e = el_una(OPER.OPu32_d, TYM.TYdouble, e); + fty = TY.Tfloat64; + goto Lagain; + case X(TY.Tuns32,TY.Timaginary32): + case X(TY.Tuns32,TY.Timaginary64): + case X(TY.Tuns32,TY.Timaginary80): + goto Lzero; + + /* ============================= */ + + case X(TY.Tint64,TY.Tint8): + case X(TY.Tint64,TY.Tuns8): + case X(TY.Tint64,TY.Tint16): + case X(TY.Tint64,TY.Tuns16): + e = el_una(OPER.OP64_32, TYM.TYint, e); + fty = TY.Tint32; + goto Lagain; + case X(TY.Tint64,TY.Tint32): + case X(TY.Tint64,TY.Tuns32): + eop = OPER.OP64_32; + goto Leop; + case X(TY.Tint64,TY.Tuns64): + goto Lpaint; + case X(TY.Tint64,TY.Tfloat32): + case X(TY.Tint64,TY.Tfloat64): + case X(TY.Tint64,TY.Tfloat80): + case X(TY.Tint64,TY.Tcomplex32): + case X(TY.Tint64,TY.Tcomplex64): + case X(TY.Tint64,TY.Tcomplex80): + e = el_una(OPER.OPs64_d, TYM.TYdouble, e); + fty = TY.Tfloat64; + goto Lagain; + case X(TY.Tint64,TY.Timaginary32): + case X(TY.Tint64,TY.Timaginary64): + case X(TY.Tint64,TY.Timaginary80): + goto Lzero; + + /* ============================= */ + + case X(TY.Tuns64,TY.Tint8): + case X(TY.Tuns64,TY.Tuns8): + case X(TY.Tuns64,TY.Tint16): + case X(TY.Tuns64,TY.Tuns16): + e = el_una(OPER.OP64_32, TYM.TYint, e); + fty = TY.Tint32; + goto Lagain; + case X(TY.Tuns64,TY.Tint32): + case X(TY.Tuns64,TY.Tuns32): + eop = OPER.OP64_32; + goto Leop; + case X(TY.Tuns64,TY.Tint64): + goto Lpaint; + case X(TY.Tuns64,TY.Tfloat32): + case X(TY.Tuns64,TY.Tfloat64): + case X(TY.Tuns64,TY.Tfloat80): + case X(TY.Tuns64,TY.Tcomplex32): + case X(TY.Tuns64,TY.Tcomplex64): + case X(TY.Tuns64,TY.Tcomplex80): + e = el_una(OPER.OPu64_d, TYM.TYdouble, e); + fty = TY.Tfloat64; + goto Lagain; + case X(TY.Tuns64,TY.Timaginary32): + case X(TY.Tuns64,TY.Timaginary64): + case X(TY.Tuns64,TY.Timaginary80): + goto Lzero; + + /* ============================= */ + + case X(TY.Tfloat32,TY.Tint8): + case X(TY.Tfloat32,TY.Tuns8): + case X(TY.Tfloat32,TY.Tint16): + case X(TY.Tfloat32,TY.Tuns16): + case X(TY.Tfloat32,TY.Tint32): + case X(TY.Tfloat32,TY.Tuns32): + case X(TY.Tfloat32,TY.Tint64): + case X(TY.Tfloat32,TY.Tuns64): + case X(TY.Tfloat32,TY.Tfloat80): + e = el_una(OPER.OPf_d, TYM.TYdouble, e); + fty = TY.Tfloat64; + goto Lagain; + case X(TY.Tfloat32,TY.Tfloat64): + eop = OPER.OPf_d; + goto Leop; + case X(TY.Tfloat32,TY.Timaginary32): + goto Lzero; + case X(TY.Tfloat32,TY.Timaginary64): + goto Lzero; + case X(TY.Tfloat32,TY.Timaginary80): + goto Lzero; + case X(TY.Tfloat32,TY.Tcomplex32): + case X(TY.Tfloat32,TY.Tcomplex64): + case X(TY.Tfloat32,TY.Tcomplex80): + e = el_bin(OPER.OPadd,TYM.TYcfloat,el_long(TYM.TYifloat,0),e); + fty = TY.Tcomplex32; + goto Lagain; + + /* ============================= */ + + case X(TY.Tfloat64,TY.Tint8): + case X(TY.Tfloat64,TY.Tuns8): + e = el_una(OPER.OPd_s16, TYM.TYshort, e); + fty = TY.Tint16; + goto Lagain; + case X(TY.Tfloat64,TY.Tint16): + eop = OPER.OPd_s16; + goto Leop; + case X(TY.Tfloat64,TY.Tuns16): + eop = OPER.OPd_u16; + goto Leop; + case X(TY.Tfloat64,TY.Tint32): + eop = OPER.OPd_s32; + goto Leop; + case X(TY.Tfloat64,TY.Tuns32): + eop = OPER.OPd_u32; + goto Leop; + case X(TY.Tfloat64,TY.Tint64): + eop = OPER.OPd_s64; + goto Leop; + case X(TY.Tfloat64,TY.Tuns64): + eop = OPER.OPd_u64; + goto Leop; + case X(TY.Tfloat64,TY.Tfloat32): + eop = OPER.OPd_f; + goto Leop; + case X(TY.Tfloat64,TY.Tfloat80): + eop = OPER.OPd_ld; + goto Leop; + case X(TY.Tfloat64,TY.Timaginary32): + goto Lzero; + case X(TY.Tfloat64,TY.Timaginary64): + goto Lzero; + case X(TY.Tfloat64,TY.Timaginary80): + goto Lzero; + case X(TY.Tfloat64,TY.Tcomplex32): + case X(TY.Tfloat64,TY.Tcomplex64): + case X(TY.Tfloat64,TY.Tcomplex80): + e = el_bin(OPER.OPadd,TYM.TYcfloat,el_long(TYM.TYidouble,0),e); + fty = TY.Tcomplex64; + goto Lagain; + + /* ============================= */ + + case X(TY.Tfloat80,TY.Tint8): + case X(TY.Tfloat80,TY.Tuns8): + case X(TY.Tfloat80,TY.Tint16): + case X(TY.Tfloat80,TY.Tuns16): + case X(TY.Tfloat80,TY.Tint32): + case X(TY.Tfloat80,TY.Tuns32): + case X(TY.Tfloat80,TY.Tint64): + case X(TY.Tfloat80,TY.Tfloat32): + e = el_una(OPER.OPld_d, TYM.TYdouble, e); + fty = TY.Tfloat64; + goto Lagain; + case X(TY.Tfloat80,TY.Tuns64): + eop = OPER.OPld_u64; + goto Leop; + case X(TY.Tfloat80,TY.Tfloat64): + eop = OPER.OPld_d; + goto Leop; + case X(TY.Tfloat80,TY.Timaginary32): + goto Lzero; + case X(TY.Tfloat80,TY.Timaginary64): + goto Lzero; + case X(TY.Tfloat80,TY.Timaginary80): + goto Lzero; + case X(TY.Tfloat80,TY.Tcomplex32): + case X(TY.Tfloat80,TY.Tcomplex64): + case X(TY.Tfloat80,TY.Tcomplex80): + e = el_bin(OPER.OPadd,TYM.TYcldouble,e,el_long(TYM.TYildouble,0)); + fty = TY.Tcomplex80; + goto Lagain; + + /* ============================= */ + + case X(TY.Timaginary32,TY.Tint8): + case X(TY.Timaginary32,TY.Tuns8): + case X(TY.Timaginary32,TY.Tint16): + case X(TY.Timaginary32,TY.Tuns16): + case X(TY.Timaginary32,TY.Tint32): + case X(TY.Timaginary32,TY.Tuns32): + case X(TY.Timaginary32,TY.Tint64): + case X(TY.Timaginary32,TY.Tuns64): + case X(TY.Timaginary32,TY.Tfloat32): + case X(TY.Timaginary32,TY.Tfloat64): + case X(TY.Timaginary32,TY.Tfloat80): + goto Lzero; + case X(TY.Timaginary32,TY.Timaginary64): + eop = OPER.OPf_d; + goto Leop; + case X(TY.Timaginary32,TY.Timaginary80): + e = el_una(OPER.OPf_d, TYM.TYidouble, e); + fty = TY.Timaginary64; + goto Lagain; + case X(TY.Timaginary32,TY.Tcomplex32): + case X(TY.Timaginary32,TY.Tcomplex64): + case X(TY.Timaginary32,TY.Tcomplex80): + e = el_bin(OPER.OPadd,TYM.TYcfloat,el_long(TYM.TYfloat,0),e); + fty = TY.Tcomplex32; + goto Lagain; + + /* ============================= */ + + case X(TY.Timaginary64,TY.Tint8): + case X(TY.Timaginary64,TY.Tuns8): + case X(TY.Timaginary64,TY.Tint16): + case X(TY.Timaginary64,TY.Tuns16): + case X(TY.Timaginary64,TY.Tint32): + case X(TY.Timaginary64,TY.Tuns32): + case X(TY.Timaginary64,TY.Tint64): + case X(TY.Timaginary64,TY.Tuns64): + case X(TY.Timaginary64,TY.Tfloat32): + case X(TY.Timaginary64,TY.Tfloat64): + case X(TY.Timaginary64,TY.Tfloat80): + goto Lzero; + case X(TY.Timaginary64,TY.Timaginary32): + eop = OPER.OPd_f; + goto Leop; + case X(TY.Timaginary64,TY.Timaginary80): + eop = OPER.OPd_ld; + goto Leop; + case X(TY.Timaginary64,TY.Tcomplex32): + case X(TY.Timaginary64,TY.Tcomplex64): + case X(TY.Timaginary64,TY.Tcomplex80): + e = el_bin(OPER.OPadd, TYM.TYcdouble, el_long(TYM.TYdouble,0), e); + fty = TY.Tcomplex64; + goto Lagain; + + /* ============================= */ + + case X(TY.Timaginary80,TY.Tint8): + case X(TY.Timaginary80,TY.Tuns8): + case X(TY.Timaginary80,TY.Tint16): + case X(TY.Timaginary80,TY.Tuns16): + case X(TY.Timaginary80,TY.Tint32): + case X(TY.Timaginary80,TY.Tuns32): + case X(TY.Timaginary80,TY.Tint64): + case X(TY.Timaginary80,TY.Tuns64): + case X(TY.Timaginary80,TY.Tfloat32): + case X(TY.Timaginary80,TY.Tfloat64): + case X(TY.Timaginary80,TY.Tfloat80): + goto Lzero; + case X(TY.Timaginary80,TY.Timaginary32): + e = el_una(OPER.OPf_d, TYM.TYidouble, e); + fty = TY.Timaginary64; + goto Lagain; + case X(TY.Timaginary80,TY.Timaginary64): + eop = OPER.OPld_d; + goto Leop; + case X(TY.Timaginary80,TY.Tcomplex32): + case X(TY.Timaginary80,TY.Tcomplex64): + case X(TY.Timaginary80,TY.Tcomplex80): + e = el_bin(OPER.OPadd, TYM.TYcldouble, el_long(TYM.TYldouble,0), e); + fty = TY.Tcomplex80; + goto Lagain; + + /* ============================= */ + + case X(TY.Tcomplex32,TY.Tint8): + case X(TY.Tcomplex32,TY.Tuns8): + case X(TY.Tcomplex32,TY.Tint16): + case X(TY.Tcomplex32,TY.Tuns16): + case X(TY.Tcomplex32,TY.Tint32): + case X(TY.Tcomplex32,TY.Tuns32): + case X(TY.Tcomplex32,TY.Tint64): + case X(TY.Tcomplex32,TY.Tuns64): + case X(TY.Tcomplex32,TY.Tfloat32): + case X(TY.Tcomplex32,TY.Tfloat64): + case X(TY.Tcomplex32,TY.Tfloat80): + e = el_una(OPER.OPc_r, TYM.TYfloat, e); + fty = TY.Tfloat32; + goto Lagain; + case X(TY.Tcomplex32,TY.Timaginary32): + case X(TY.Tcomplex32,TY.Timaginary64): + case X(TY.Tcomplex32,TY.Timaginary80): + e = el_una(OPER.OPc_i, TYM.TYifloat, e); + fty = TY.Timaginary32; + goto Lagain; + case X(TY.Tcomplex32,TY.Tcomplex64): + case X(TY.Tcomplex32,TY.Tcomplex80): + e = el_una(OPER.OPf_d, TYM.TYcdouble, e); + fty = TY.Tcomplex64; + goto Lagain; + + /* ============================= */ + + case X(TY.Tcomplex64,TY.Tint8): + case X(TY.Tcomplex64,TY.Tuns8): + case X(TY.Tcomplex64,TY.Tint16): + case X(TY.Tcomplex64,TY.Tuns16): + case X(TY.Tcomplex64,TY.Tint32): + case X(TY.Tcomplex64,TY.Tuns32): + case X(TY.Tcomplex64,TY.Tint64): + case X(TY.Tcomplex64,TY.Tuns64): + case X(TY.Tcomplex64,TY.Tfloat32): + case X(TY.Tcomplex64,TY.Tfloat64): + case X(TY.Tcomplex64,TY.Tfloat80): + e = el_una(OPER.OPc_r, TYM.TYdouble, e); + fty = TY.Tfloat64; + goto Lagain; + case X(TY.Tcomplex64,TY.Timaginary32): + case X(TY.Tcomplex64,TY.Timaginary64): + case X(TY.Tcomplex64,TY.Timaginary80): + e = el_una(OPER.OPc_i, TYM.TYidouble, e); + fty = TY.Timaginary64; + goto Lagain; + case X(TY.Tcomplex64,TY.Tcomplex32): + eop = OPER.OPd_f; + goto Leop; + case X(TY.Tcomplex64,TY.Tcomplex80): + eop = OPER.OPd_ld; + goto Leop; + + /* ============================= */ + + case X(TY.Tcomplex80,TY.Tint8): + case X(TY.Tcomplex80,TY.Tuns8): + case X(TY.Tcomplex80,TY.Tint16): + case X(TY.Tcomplex80,TY.Tuns16): + case X(TY.Tcomplex80,TY.Tint32): + case X(TY.Tcomplex80,TY.Tuns32): + case X(TY.Tcomplex80,TY.Tint64): + case X(TY.Tcomplex80,TY.Tuns64): + case X(TY.Tcomplex80,TY.Tfloat32): + case X(TY.Tcomplex80,TY.Tfloat64): + case X(TY.Tcomplex80,TY.Tfloat80): + e = el_una(OPER.OPc_r, TYM.TYldouble, e); + fty = TY.Tfloat80; + goto Lagain; + case X(TY.Tcomplex80,TY.Timaginary32): + case X(TY.Tcomplex80,TY.Timaginary64): + case X(TY.Tcomplex80,TY.Timaginary80): + e = el_una(OPER.OPc_i, TYM.TYildouble, e); + fty = TY.Timaginary80; + goto Lagain; + case X(TY.Tcomplex80,TY.Tcomplex32): + case X(TY.Tcomplex80,TY.Tcomplex64): + e = el_una(OPER.OPld_d, TYM.TYcdouble, e); + fty = TY.Tcomplex64; + goto Lagain; + + /* ============================= */ + + default: + if (fty == tty) + goto Lpaint; + //dump(0); + //printf("fty = %d, tty = %d\n", fty, tty); + error("e2ir: cannot cast from %s to %s", e1.type.toChars(), t.toChars()); + goto Lzero; + + Lzero: + e = el_long(ttym, 0); + break; + + Lpaint: + e.Ety = ttym; + break; + + Leop: + e = el_una(eop, ttym, e); + break; + } + Lret: + // Adjust for any type paints + t = type.toBasetype(); + e.Ety = t.totym(); + + el_setLoc(e,loc); return e; } - Identifier opId() + override Identifier opId() { return Id.cast_; } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/CatAssignExp.d --- a/dmd/CatAssignExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/CatAssignExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -28,7 +28,7 @@ super(loc, TOK.TOKcatass, CatAssignExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -81,17 +81,17 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - Identifier opId() /* For operator overloading */ + override Identifier opId() /* For operator overloading */ { return Id.catass; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { //printf("CatAssignExp.toElem('%s')\n", toChars()); elem* e; @@ -143,4 +143,4 @@ return e; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/CatExp.d --- a/dmd/CatExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/CatExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,12 +1,12 @@ -module dmd.CatExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.InterState; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.BinExp; +module dmd.CatExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.InterState; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.BinExp; import dmd.TOK; import dmd.Type; import dmd.TY; @@ -15,16 +15,16 @@ import dmd.StringExp; import dmd.WANT; import dmd.Id; -import dmd.GlobalExpressions; - +import dmd.GlobalExpressions; + import dmd.backend.elem; import dmd.backend.Util; import dmd.backend.TYM; import dmd.backend.OPER; import dmd.backend.RTLSYM; import dmd.codegen.Util; -import dmd.expression.Cat; - +import dmd.expression.Cat; + class CatExp : BinExp { this(Loc loc, Expression e1, Expression e2) @@ -32,7 +32,7 @@ super(loc, TOK.TOKcat, CatExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -141,7 +141,7 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { //printf("CatExp::optimize(%d) %s\n", result, toChars()); e1 = e1.optimize(result); @@ -153,43 +153,43 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { - Expression e; - Expression e1; - Expression e2; - -version (LOG) { - printf("CatExp.interpret() %.*s\n", toChars()); -} - e1 = this.e1.interpret(istate); - if (e1 is EXP_CANT_INTERPRET) - { - goto Lcant; - } - e2 = this.e2.interpret(istate); - if (e2 is EXP_CANT_INTERPRET) - goto Lcant; - return Cat(type, e1, e2); - - Lcant: -version (LOG) { - printf("CatExp.interpret() %.*s CANT\n", toChars()); -} + Expression e; + Expression e1; + Expression e2; + +version (LOG) { + printf("CatExp.interpret() %.*s\n", toChars()); +} + e1 = this.e1.interpret(istate); + if (e1 is EXP_CANT_INTERPRET) + { + goto Lcant; + } + e2 = this.e2.interpret(istate); + if (e2 is EXP_CANT_INTERPRET) + goto Lcant; + return Cat(type, e1, e2); + + Lcant: +version (LOG) { + printf("CatExp.interpret() %.*s CANT\n", toChars()); +} return EXP_CANT_INTERPRET; } - Identifier opId() + override Identifier opId() { return Id.cat; } - Identifier opId_r() + override Identifier opId_r() { return Id.cat_r; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem *e; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ClassDeclaration.d --- a/dmd/ClassDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ClassDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,1904 +1,1904 @@ -module dmd.ClassDeclaration; - -import dmd.AggregateDeclaration; -import dmd.InterfaceDeclaration; -import dmd.ThisDeclaration; -import dmd.CompoundStatement; -import dmd.DeleteDeclaration; -import dmd.NewDeclaration; -import dmd.CtorDeclaration; -import dmd.TypeIdentifier; -import dmd.STC; -import dmd.Argument; -import dmd.TypeTuple; -import dmd.TY; -import dmd.LINK; -import dmd.DsymbolTable; -import dmd.FuncDeclaration; -import dmd.Array; -import dmd.TypeClass; -import dmd.Module; -import dmd.Id; -import dmd.Type; -import dmd.OverloadSet; -import dmd.ArrayTypes; -import dmd.BaseClass; -import dmd.ClassInfoDeclaration; -import dmd.Loc; -import dmd.Identifier; -import dmd.Dsymbol; -import dmd.Scope; -import dmd.TypeFunction; -import dmd.OutBuffer; -import dmd.HdrGenState; -import dmd.VarDeclaration; -import dmd.Initializer; -import dmd.ExpInitializer; -import dmd.TypeSArray; -import dmd.ScopeDsymbol; -import dmd.PROT; -import dmd.Util; -import dmd.Global; - -import dmd.expression.Util; - -import dmd.backend.Symbol; -import dmd.backend.dt_t; -import dmd.backend.TYPE; -import dmd.backend.FL; -import dmd.backend.SFL; -import dmd.backend.mTY; -import dmd.backend.SC; -import dmd.backend.mTYman; -import dmd.backend.Util; -import dmd.backend.TYM; -import dmd.backend.Classsym; -import dmd.backend.glue; -import dmd.backend.RTLSYM; -import dmd.backend.LIST; - -import dmd.codegen.Util; - -import std.string; - -version (DMDV2) { - enum CLASSINFO_SIZE = (0x3C+16+4); // value of ClassInfo.size -} else { - enum CLASSINFO_SIZE = (0x3C+12+4); // value of ClassInfo.size -} - -enum OFFSET_RUNTIME = 0x76543210; - -struct Param -{ - int isf(void*, FuncDeclaration fd2) - { - //printf("param = %p, fd = %p %s\n", param, fd, fd.toChars()); - return fd is fd2; - } - - FuncDeclaration fd; -} - -class ClassDeclaration : AggregateDeclaration -{ - static __gshared ClassDeclaration object; - static __gshared ClassDeclaration classinfo; - - ClassDeclaration baseClass; // null only if this is Object - FuncDeclaration staticCtor; - FuncDeclaration staticDtor; - Array vtbl; // Array of FuncDeclaration's making up the vtbl[] - Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[] - - BaseClasses baseclasses; // Array of BaseClass's; first is super, - // rest are Interface's - - int interfaces_dim; - BaseClass* interfaces; // interfaces[interfaces_dim] for this class - // (does not include baseClass) - - BaseClasses vtblInterfaces; // array of base interfaces that have - // their own vtbl[] - - ClassInfoDeclaration vclassinfo; // the ClassInfo object for this ClassDeclaration - bool com; // true if this is a COM class (meaning - // it derives from IUnknown) - bool isauto; // true if this is an auto class - bool isabstract; // true if abstract class - - int inuse; // to prevent recursive attempts - - this(Loc loc, Identifier id, BaseClasses baseclasses) - { - super(loc, id); - - vtbl = new Array(); - vtblFinal = new Array(); - - enum msg = "only object.d can define this reserved class name"; - - if (baseclasses) { - this.baseclasses = baseclasses; - } else { - this.baseclasses = new BaseClasses(); - } - - //printf("ClassDeclaration(%s), dim = %d\n", id.toChars(), this.baseclasses.dim); - - // For forward references - type = new TypeClass(this); - - if (id) - { - // Look for special class names - - if (id is Id.__sizeof || id is Id.alignof_ || id is Id.mangleof_) - error("illegal class name"); - - // BUG: What if this is the wrong TypeInfo, i.e. it is nested? - if (id.toChars()[0] == 'T') - { - if (id is Id.TypeInfo) - { - if (Type.typeinfo) - Type.typeinfo.error("%s", msg); - Type.typeinfo = this; - } - - if (id is Id.TypeInfo_Class) - { - if (Type.typeinfoclass) - Type.typeinfoclass.error("%s", msg); - Type.typeinfoclass = this; - } - - if (id is Id.TypeInfo_Interface) - { - if (Type.typeinfointerface) - Type.typeinfointerface.error("%s", msg); - Type.typeinfointerface = this; - } - - if (id is Id.TypeInfo_Struct) - { - if (Type.typeinfostruct) - Type.typeinfostruct.error("%s", msg); - Type.typeinfostruct = this; - } - - if (id is Id.TypeInfo_Typedef) - { - if (Type.typeinfotypedef) - Type.typeinfotypedef.error("%s", msg); - Type.typeinfotypedef = this; - } - - if (id is Id.TypeInfo_Pointer) - { - if (Type.typeinfopointer) - Type.typeinfopointer.error("%s", msg); - Type.typeinfopointer = this; - } - - if (id is Id.TypeInfo_Array) - { - if (Type.typeinfoarray) - Type.typeinfoarray.error("%s", msg); - Type.typeinfoarray = this; - } - - if (id is Id.TypeInfo_StaticArray) - { //if (Type.typeinfostaticarray) - //Type.typeinfostaticarray.error("%s", msg); - Type.typeinfostaticarray = this; - } - - if (id is Id.TypeInfo_AssociativeArray) - { - if (Type.typeinfoassociativearray) - Type.typeinfoassociativearray.error("%s", msg); - Type.typeinfoassociativearray = this; - } - - if (id is Id.TypeInfo_Enum) - { - if (Type.typeinfoenum) - Type.typeinfoenum.error("%s", msg); - Type.typeinfoenum = this; - } - - if (id is Id.TypeInfo_Function) - { - if (Type.typeinfofunction) - Type.typeinfofunction.error("%s", msg); - Type.typeinfofunction = this; - } - - if (id is Id.TypeInfo_Delegate) - { - if (Type.typeinfodelegate) - Type.typeinfodelegate.error("%s", msg); - Type.typeinfodelegate = this; - } - - if (id is Id.TypeInfo_Tuple) - { - if (Type.typeinfotypelist) - Type.typeinfotypelist.error("%s", msg); - Type.typeinfotypelist = this; - } - - version (DMDV2) { - if (id is Id.TypeInfo_Const) - { - if (Type.typeinfoconst) - Type.typeinfoconst.error("%s", msg); - Type.typeinfoconst = this; - } - - if (id is Id.TypeInfo_Invariant) - { - if (Type.typeinfoinvariant) - Type.typeinfoinvariant.error("%s", msg); - Type.typeinfoinvariant = this; - } - - if (id is Id.TypeInfo_Shared) - { - if (Type.typeinfoshared) - Type.typeinfoshared.error("%s", msg); - Type.typeinfoshared = this; - } - } - } - - if (id is Id.Object_) - { - if (object) - object.error("%s", msg); - object = this; - } - - if (id is Id.ClassInfo) - { - if (classinfo) - classinfo.error("%s", msg); - classinfo = this; - } - - if (id is Id.ModuleInfo) - { - if (Module.moduleinfo) - Module.moduleinfo.error("%s", msg); - Module.moduleinfo = this; - } - } - - com = 0; - isauto = false; - isabstract = false; - inuse = 0; - } - - Dsymbol syntaxCopy(Dsymbol s) - { - ClassDeclaration cd; - - //printf("ClassDeclaration.syntaxCopy('%s')\n", toChars()); - if (s) - cd = cast(ClassDeclaration)s; - else - cd = new ClassDeclaration(loc, ident, null); - - cd.storage_class |= storage_class; - - cd.baseclasses.setDim(this.baseclasses.dim); - for (int i = 0; i < cd.baseclasses.dim; i++) - { - BaseClass b = cast(BaseClass)this.baseclasses.data[i]; - BaseClass b2 = new BaseClass(b.type.syntaxCopy(), b.protection); - cd.baseclasses.data[i] = cast(void*)b2; - } - - ScopeDsymbol.syntaxCopy(cd); - return cd; - } - - void semantic(Scope sc) - { - int i; - uint offset; - - //printf("ClassDeclaration.semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); - //printf("\tparent = %p, '%s'\n", sc.parent, sc.parent ? sc.parent.toChars() : ""); - //printf("sc.stc = %x\n", sc.stc); - - //{ static int n; if (++n == 20) *(char*)0=0; } - - if (!ident) // if anonymous class - { - string id = "__anonclass"; - ident = Identifier.generateId(id); - } - - if (!sc) - sc = scope_; - - if (!parent && sc.parent && !sc.parent.isModule()) - parent = sc.parent; - - type = type.semantic(loc, sc); - handle = type; - - if (!members) // if forward reference - { - //printf("\tclass '%s' is forward referenced\n", toChars()); - return; - } - if (symtab) - { if (!scope_) - { //printf("\tsemantic for '%s' is already completed\n", toChars()); - return; // semantic() already completed - } - } - else - symtab = new DsymbolTable(); - - Scope scx = null; - if (scope_) - { sc = scope_; - scx = scope_; // save so we don't make redundant copies - scope_ = null; - } -version (IN_GCC) { - methods.setDim(0); -} - - if (sc.stc & STC.STCdeprecated) - { - isdeprecated = 1; - } - - if (sc.linkage == LINK.LINKcpp) - error("cannot create C++ classes"); - - // Expand any tuples in baseclasses[] - for (i = 0; i < baseclasses.dim; ) - { - BaseClass b = cast(BaseClass)baseclasses.data[i]; - //printf("test1 %s %s\n", toChars(), b.type.toChars()); - b.type = b.type.semantic(loc, sc); - //printf("test2\n"); - Type tb = b.type.toBasetype(); - - if (tb.ty == TY.Ttuple) - { - TypeTuple tup = cast(TypeTuple)tb; - enum PROT protection = b.protection; - baseclasses.remove(i); - size_t dim = Argument.dim(tup.arguments); - for (size_t j = 0; j < dim; j++) - { - Argument arg = Argument.getNth(tup.arguments, j); - b = new BaseClass(arg.type, protection); - baseclasses.insert(i + j, cast(void*)b); - } - } - else - i++; - } - - // See if there's a base class as first in baseclasses[] - if (baseclasses.dim) - { - TypeClass tc; - BaseClass b; - Type tb; - - b = cast(BaseClass)baseclasses.data[0]; - //b.type = b.type.semantic(loc, sc); - tb = b.type.toBasetype(); - if (tb.ty != TY.Tclass) - { error("base type must be class or interface, not %s", b.type.toChars()); - baseclasses.remove(0); - } - else - { - tc = cast(TypeClass)(tb); - - if (tc.sym.isDeprecated()) - { - if (!isDeprecated()) - { - // Deriving from deprecated class makes this one deprecated too - isdeprecated = 1; - - tc.checkDeprecated(loc, sc); - } - } - - if (tc.sym.isInterfaceDeclaration()) { - ; - } else { - for (ClassDeclaration cdb = tc.sym; cdb; cdb = cdb.baseClass) - { - if (cdb == this) - { - error("circular inheritance"); - baseclasses.remove(0); - goto L7; - } - } - if (!tc.sym.symtab || tc.sym.sizeok == 0) - { // Try to resolve forward reference - if (sc.mustsemantic && tc.sym.scope_) - tc.sym.semantic(null); - } - if (!tc.sym.symtab || tc.sym.scope_ || tc.sym.sizeok == 0) - { - //printf("%s: forward reference of base class %s\n", toChars(), tc.sym.toChars()); - //error("forward reference of base class %s", baseClass.toChars()); - // Forward reference of base class, try again later - //printf("\ttry later, forward reference of base class %s\n", tc.sym.toChars()); - scope_ = scx ? scx : new Scope(sc); - scope_.setNoFree(); - if (tc.sym.scope_) - tc.sym.scope_.module_.addDeferredSemantic(tc.sym); - scope_.module_.addDeferredSemantic(this); - return; - } - else - { baseClass = tc.sym; - b.base = baseClass; - } - L7: ; - } - } - } - - // Treat the remaining entries in baseclasses as interfaces - // Check for errors, handle forward references - for (i = (baseClass ? 1 : 0); i < baseclasses.dim; ) - { TypeClass tc; - BaseClass b; - Type tb; - - b = cast(BaseClass)baseclasses.data[i]; - b.type = b.type.semantic(loc, sc); - tb = b.type.toBasetype(); - if (tb.ty == TY.Tclass) - tc = cast(TypeClass)tb; - else - tc = null; - if (!tc || !tc.sym.isInterfaceDeclaration()) - { - error("base type must be interface, not %s", b.type.toChars()); - baseclasses.remove(i); - continue; - } - else - { - if (tc.sym.isDeprecated()) - { - if (!isDeprecated()) - { - // Deriving from deprecated class makes this one deprecated too - isdeprecated = 1; - - tc.checkDeprecated(loc, sc); - } - } - - // Check for duplicate interfaces - for (size_t j = (baseClass ? 1 : 0); j < i; j++) - { - BaseClass b2 = cast(BaseClass)baseclasses.data[j]; - if (b2.base == tc.sym) - error("inherits from duplicate interface %s", b2.base.toChars()); - } - - if (!tc.sym.symtab) - { // Try to resolve forward reference - if (sc.mustsemantic && tc.sym.scope_) - tc.sym.semantic(null); - } - - b.base = tc.sym; - if (!b.base.symtab || b.base.scope_) - { - //error("forward reference of base class %s", baseClass.toChars()); - // Forward reference of base, try again later - //printf("\ttry later, forward reference of base %s\n", baseClass.toChars()); - scope_ = scx ? scx : new Scope(sc); - scope_.setNoFree(); - if (tc.sym.scope_) - tc.sym.scope_.module_.addDeferredSemantic(tc.sym); - scope_.module_.addDeferredSemantic(this); - return; - } - } - i++; - } - - - // If no base class, and this is not an Object, use Object as base class - if (!baseClass && ident !is Id.Object_) - { - // BUG: what if Object is redefined in an inner scope? - Type tbase = new TypeIdentifier(Loc(0), Id.Object_); - BaseClass b; - TypeClass tc; - Type bt; - - if (!object) - { - error("missing or corrupt object.d"); - fatal(); - } - bt = tbase.semantic(loc, sc).toBasetype(); - b = new BaseClass(bt, PROT.PROTpublic); - baseclasses.shift(cast(void*)b); - assert(b.type.ty == TY.Tclass); - tc = cast(TypeClass)(b.type); - baseClass = tc.sym; - assert(!baseClass.isInterfaceDeclaration()); - b.base = baseClass; - } - - interfaces_dim = baseclasses.dim; - interfaces = cast(BaseClass*)baseclasses.data; - - if (baseClass) - { - if (baseClass.storage_class & STC.STCfinal) - error("cannot inherit from final class %s", baseClass.toChars()); - - interfaces_dim--; - interfaces++; - - // Copy vtbl[] from base class - vtbl.setDim(baseClass.vtbl.dim); - memcpy(vtbl.data, baseClass.vtbl.data, (void*).sizeof * vtbl.dim); - - // Inherit properties from base class - com = baseClass.isCOMclass(); - isauto = baseClass.isauto; - vthis = baseClass.vthis; - storage_class |= baseClass.storage_class & STC.STC_TYPECTOR; - } - else - { - // No base class, so this is the root of the class hierarchy - vtbl.setDim(0); - vtbl.push(cast(void*)this); // leave room for classinfo as first member - } - - protection = sc.protection; - storage_class |= sc.stc; - - if (sizeok == 0) - { - interfaceSemantic(sc); - - for (i = 0; i < members.dim; i++) - { - Dsymbol s = cast(Dsymbol)members.data[i]; - s.addMember(sc, this, true); - } - - /* If this is a nested class, add the hidden 'this' - * member which is a pointer to the enclosing scope. - */ - if (vthis) // if inheriting from nested class - { // Use the base class's 'this' member - isnested = true; - if (storage_class & STC.STCstatic) - error("static class cannot inherit from nested class %s", baseClass.toChars()); - if (toParent2() != baseClass.toParent2()) - { - if (toParent2()) - { - error("is nested within %s, but super class %s is nested within %s", - toParent2().toChars(), - baseClass.toChars(), - baseClass.toParent2().toChars()); - } - else - { - error("is not nested, but super class %s is nested within %s", - baseClass.toChars(), - baseClass.toParent2().toChars()); - } - isnested = false; - } - } - else if (!(storage_class & STC.STCstatic)) - { - Dsymbol s = toParent2(); - if (s) - { - AggregateDeclaration ad = s.isClassDeclaration(); - FuncDeclaration fd = s.isFuncDeclaration(); - - if (ad || fd) - { isnested = true; - Type t; - if (ad) - t = ad.handle; - else if (fd) - { - AggregateDeclaration ad2 = fd.isMember2(); - if (ad2) - t = ad2.handle; - else - { - t = Type.tvoidptr; - } - } - else - assert(0); - if (t.ty == TY.Tstruct) // ref to struct - t = Type.tvoidptr; - assert(!vthis); - vthis = new ThisDeclaration(loc, t); - members.push(cast(void*)vthis); - } - } - } - } - - if (storage_class & (STC.STCauto | STC.STCscope)) - isauto = true; - if (storage_class & STC.STCabstract) - isabstract = true; - if (storage_class & STC.STCimmutable) - type = type.invariantOf(); - else if (storage_class & STC.STCconst) - type = type.constOf(); - else if (storage_class & STC.STCshared) - type = type.sharedOf(); - - sc = sc.push(this); - sc.stc &= ~(STC.STCfinal | STC.STCauto | STC.STCscope | STC.STCstatic | - STC.STCabstract | STC.STCdeprecated | STC.STC_TYPECTOR | STC.STCtls | STC.STCgshared); - sc.stc |= storage_class & STC.STC_TYPECTOR; - sc.parent = this; - sc.inunion = 0; - - if (isCOMclass()) - { -version (_WIN32) { - sc.linkage = LINK.LINKwindows; -} else { - /* This enables us to use COM objects under Linux and - * work with things like XPCOM - */ - sc.linkage = LINK.LINKc; -} - } - sc.protection = PROT.PROTpublic; - sc.explicitProtection = 0; - sc.structalign = 8; - structalign = sc.structalign; - if (baseClass) - { sc.offset = baseClass.structsize; - alignsize = baseClass.alignsize; - // if (isnested) - // sc.offset += PTRSIZE; // room for uplevel context pointer - } - else - { sc.offset = PTRSIZE * 2; // allow room for __vptr and __monitor - alignsize = PTRSIZE; - } - structsize = sc.offset; - Scope scsave = sc; /// a copy must be created? - int members_dim = members.dim; - sizeok = 0; - for (i = 0; i < members_dim; i++) - { - Dsymbol s = cast(Dsymbol)members.data[i]; - s.semantic(sc); - } - - if (sizeok == 2) - { // semantic() failed because of forward references. - // Unwind what we did, and defer it for later - fields.setDim(0); - structsize = 0; - alignsize = 0; - structalign = 0; - - sc = sc.pop(); - - scope_ = scx ? scx : new Scope(sc); - scope_.setNoFree(); - scope_.module_.addDeferredSemantic(this); - - //printf("\tsemantic('%s') failed due to forward references\n", toChars()); - return; - } - - //printf("\tsemantic('%s') successful\n", toChars()); - - structsize = sc.offset; - //members.print(); - - /* Look for special member functions. - * They must be in this class, not in a base class. - */ - ctor = cast(CtorDeclaration)search(Loc(0), Id.ctor, 0); - if (ctor && (ctor.toParent() != this || !ctor.isCtorDeclaration())) - ctor = null; - - // dtor = (DtorDeclaration *)search(Id.dtor, 0); - // if (dtor && dtor.toParent() != this) - // dtor = null; - - // inv = (InvariantDeclaration *)search(Id.classInvariant, 0); - // if (inv && inv.toParent() != this) - // inv = null; - - // Can be in base class - aggNew = cast(NewDeclaration)search(Loc(0), Id.classNew, 0); - aggDelete = cast(DeleteDeclaration)search(Loc(0), Id.classDelete, 0); - - // If this class has no constructor, but base class does, create - // a constructor: - // this() { } - if (!ctor && baseClass && baseClass.ctor) - { - //printf("Creating default this(){} for class %s\n", toChars()); - CtorDeclaration ctor = new CtorDeclaration(loc, Loc(0), null, 0); - ctor.fbody = new CompoundStatement(Loc(0), new Statements()); - members.push(cast(void*)ctor); - ctor.addMember(sc, this, true); - sc = scsave; // why? What about sc.nofree? /// - sc.offset = structsize; - ctor.semantic(sc); - this.ctor = ctor; - defaultCtor = ctor; - } - -static if (false) { - if (baseClass) - { if (!aggDelete) - aggDelete = baseClass.aggDelete; - if (!aggNew) - aggNew = baseClass.aggNew; - } -} - - // Allocate instance of each new interface - for (i = 0; i < vtblInterfaces.dim; i++) - { - BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; - uint thissize = PTRSIZE; - - alignmember(structalign, thissize, &sc.offset); - assert(b.offset == 0); - b.offset = sc.offset; - - // Take care of single inheritance offsets - while (b.baseInterfaces.length) - { - b = b.baseInterfaces[0]; - b.offset = sc.offset; - } - - sc.offset += thissize; - if (alignsize < thissize) - alignsize = thissize; - } - structsize = sc.offset; - sizeok = 1; - Module.dprogress++; - - dtor = buildDtor(sc); - - sc.pop(); - -static if (false) { // Do not call until toObjfile() because of forward references - // Fill in base class vtbl[]s - for (i = 0; i < vtblInterfaces.dim; i++) - { - BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; - - //b.fillVtbl(this, &b.vtbl, 1); - } -} - //printf("-ClassDeclaration.semantic(%s), type = %p\n", toChars(), type); - } - - void toCBuffer(OutBuffer buf, HdrGenState* hgs) - { - assert(false); - } - - /********************************************* - * Determine if 'this' is a base class of cd. - * This is used to detect circular inheritance only. - */ - int isBaseOf2(ClassDeclaration cd) - { - if (!cd) - return 0; - //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); - for (int i = 0; i < cd.baseclasses.dim; i++) - { - BaseClass b = cast(BaseClass)cd.baseclasses.data[i]; - - if (b.base is this || isBaseOf2(b.base)) - return 1; - } - return 0; - } - - /******************************************* - * Determine if 'this' is a base class of cd. - */ -/// #define OFFSET_RUNTIME 0x76543210 - bool isBaseOf(ClassDeclaration cd, int* poffset) - { - if (!cd) - return 0; - //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); - for (int i = 0; i < cd.baseclasses.dim; i++) - { - BaseClass b = cast(BaseClass)cd.baseclasses.data[i]; - - if (b.base == this || isBaseOf2(b.base)) - return 1; - } - - return 0; - } - - Dsymbol search(Loc, Identifier ident, int flags) - { - Dsymbol s; - //printf("%s.ClassDeclaration.search('%s')\n", toChars(), ident.toChars()); - - if (scope_) - { - Scope sc = scope_; - sc.mustsemantic++; - semantic(sc); - sc.mustsemantic--; - } - - if (!members || !symtab || scope_) - { - error("is forward referenced when looking for '%s'", ident.toChars()); - //*(char*)0=0; - return null; - } - - s = ScopeDsymbol.search(loc, ident, flags); - if (!s) - { - // Search bases classes in depth-first, left to right order - - int i; - - for (i = 0; i < baseclasses.dim; i++) - { - BaseClass b = cast(BaseClass)baseclasses.data[i]; - - if (b.base) - { - if (!b.base.symtab) - error("base %s is forward referenced", b.base.ident.toChars()); - else - { - s = b.base.search(loc, ident, flags); - if (s is this) // happens if s is nested in this and derives from this - s = null; - else if (s) - break; - } - } - } - } - return s; - } - -version (DMDV2) { - bool isFuncHidden(FuncDeclaration fd) - { - //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd.toChars()); - Dsymbol s = search(Loc(0), fd.ident, 4|2); - if (!s) - { - //printf("not found\n"); - /* Because, due to a hack, if there are multiple definitions - * of fd.ident, null is returned. - */ - return false; - } - - Param p; p.fd = fd; - - s = s.toAlias(); - OverloadSet os = s.isOverloadSet(); - if (os) - { - for (int i = 0; i < os.a.dim; i++) - { - Dsymbol s2 = cast(Dsymbol)os.a.data[i]; - FuncDeclaration f2 = s2.isFuncDeclaration(); - if (f2 && overloadApply(f2, &p.isf, &p)) - return false; - } - return true; - } - else - { - FuncDeclaration fdstart = s.isFuncDeclaration(); - //printf("%s fdstart = %p\n", s.kind(), fdstart); - return !overloadApply(fdstart, &p.isf, &p); - } - } -} - FuncDeclaration findFunc(Identifier ident, TypeFunction tf) - { - //printf("ClassDeclaration.findFunc(%s, %s) %s\n", ident.toChars(), tf.toChars(), toChars()); - - ClassDeclaration cd = this; - Array vtbl = cd.vtbl; - while (true) - { - for (size_t i = 0; i < vtbl.dim; i++) - { - FuncDeclaration fd = (cast(Dsymbol)vtbl.data[i]).isFuncDeclaration(); - if (!fd) - continue; // the first entry might be a ClassInfo - - //printf("\t[%d] = %s\n", i, fd.toChars()); - if (ident == fd.ident && - //tf.equals(fd.type) - fd.type.covariant(tf) == 1 - ) - { //printf("\t\tfound\n"); - return fd; - } - //else printf("\t\t%d\n", fd.type.covariant(tf)); - } - if (!cd) - break; - - vtbl = cd.vtblFinal; - cd = cd.baseClass; - } - - return null; - } - - void interfaceSemantic(Scope sc) - { - InterfaceDeclaration id = isInterfaceDeclaration(); - - vtblInterfaces = new BaseClasses(); - vtblInterfaces.reserve(interfaces_dim); - - for (size_t i = 0; i < interfaces_dim; i++) - { - BaseClass b = interfaces[i]; - - // If this is an interface, and it derives from a COM interface, - // then this is a COM interface too. - if (b.base.isCOMinterface()) - com = 1; - - if (b.base.isCPPinterface() && id) - id.cpp = 1; - - vtblInterfaces.push(cast(void*)b); - b.copyBaseInterfaces(vtblInterfaces); - } - } - - bool isCOMclass() - { - return com; - } - - bool isCOMinterface() - { - return false; - } - -version (DMDV2) { - bool isCPPinterface() - { - return false; - } -} - bool isAbstract() - { - if (isabstract) - return true; - - for (int i = 1; i < vtbl.dim; i++) - { - FuncDeclaration fd = (cast(Dsymbol)vtbl.data[i]).isFuncDeclaration(); - - //printf("\tvtbl[%d] = %p\n", i, fd); - if (!fd || fd.isAbstract()) - { - isabstract = true; - return true; - } - } - - return false; - } - - int vtblOffset() - { - assert(false); - } - - string kind() - { - return "class"; - } - - string mangle() - { - Dsymbol parentsave = parent; - - //printf("ClassDeclaration.mangle() %s.%s\n", parent.toChars(), toChars()); - - /* These are reserved to the compiler, so keep simple - * names for them. - */ - if (ident is Id.Exception) - { - if (parent.ident is Id.object) - parent = null; - } - else if (ident is Id.TypeInfo || - // ident is Id.Exception || - ident is Id.TypeInfo_Struct || - ident is Id.TypeInfo_Class || - ident is Id.TypeInfo_Typedef || - ident is Id.TypeInfo_Tuple || - this is object || - this is classinfo || - this is Module.moduleinfo || - ident.toChars().startsWith("TypeInfo_") - ) - { - parent = null; - } - - string id = Dsymbol.mangle(); - parent = parentsave; - return id; - } - - void toDocBuffer(OutBuffer buf) - { - assert(false); - } - - PROT getAccess(Dsymbol smember) // determine access to smember - { - PROT access_ret = PROT.PROTnone; - - version (LOG) { - printf("+ClassDeclaration::getAccess(this = '%s', smember = '%s')\n", - toChars(), smember.toChars()); - } - if (smember.toParent() is this) - { - access_ret = smember.prot(); - } - else - { - PROT access; - int i; - - if (smember.isDeclaration().isStatic()) - { - access_ret = smember.prot(); - } - - for (i = 0; i < baseclasses.dim; i++) - { - BaseClass b = cast(BaseClass)baseclasses.data[i]; - - access = b.base.getAccess(smember); - switch (access) - { - case PROT.PROTnone: - break; - - case PROT.PROTprivate: - access = PROT.PROTnone; // private members of base class not accessible - break; - - case PROT.PROTpackage: - case PROT.PROTprotected: - case PROT.PROTpublic: - case PROT.PROTexport: - // If access is to be tightened - if (b.protection < access) - access = b.protection; - - // Pick path with loosest access - if (access > access_ret) - access_ret = access; - break; - - default: - assert(0); - } - } - } - - version (LOG) { - printf("-ClassDeclaration::getAccess(this = '%s', smember = '%s') = %d\n", - toChars(), smember.toChars(), access_ret); - } - - return access_ret; - } - - void addLocalClass(ClassDeclarations aclasses) - { - aclasses.push(cast(void*)this); - } - - // Back end - void toObjFile(int multiobj) // compile to .obj file - { - uint i; - uint offset; - Symbol* sinit; - enum_SC scclass; - - //printf("ClassDeclaration.toObjFile('%s')\n", toChars()); - - if (!members) - return; - - if (multiobj) - { - obj_append(this); - return; - } - - if (global.params.symdebug) - toDebug(); - - assert(!scope_); // semantic() should have been run to completion - - scclass = SCglobal; - if (inTemplateInstance()) - scclass = SCcomdat; - - // Put out the members - for (i = 0; i < members.dim; i++) - { - Dsymbol member; - - member = cast(Dsymbol)members.data[i]; - member.toObjFile(0); - } - -static if (false) { - // Build destructor by aggregating dtors[] - Symbol* sdtor; - switch (dtors.dim) - { - case 0: - // No destructors for this class - sdtor = null; - break; - - case 1: - // One destructor, just use it directly - sdtor = (cast(DtorDeclaration)dtors.data[0]).toSymbol(); - break; - - default: - { - /* Build a destructor that calls all the - * other destructors in dtors[]. - */ - - elem* edtor = null; - - // Declare 'this' pointer for our new destructor - Symbol* sthis = symbol_calloc("this"); - sthis.Stype = type_fake(TYnptr); - sthis.Stype.Tcount++; - sthis.Sclass = SCfastpar; - sthis.Spreg = AX; - sthis.Sfl = FLauto; - - // Call each of the destructors in dtors[] - // in reverse order - for (i = 0; i < dtors.dim; i++) - { - DtorDeclaration d = cast(DtorDeclaration)dtors.data[i]; - Symbol* s = d.toSymbol(); - elem* e = el_bin(OPcall, TYvoid, el_var(s), el_var(sthis)); - edtor = el_combine(e, edtor); - } - - // Create type for the function - .type* t = type_alloc(TYjfunc); - t.Tflags |= TFprototype | TFfixed; - t.Tmangle = mTYman_d; - t.Tnext = tsvoid; - tsvoid.Tcount++; - - // Create the function, sdtor, and write it out - localgot = null; - sdtor = toSymbolX("__dtor", SCglobal, t, "FZv"); - block* b = block_calloc(); - b.BC = BCret; - b.Belem = edtor; - sdtor.Sfunc.Fstartblock = b; - cstate.CSpsymtab = &sdtor.Sfunc.Flocsym; - symbol_add(sthis); - writefunc(sdtor); - } - } -} - - // Generate C symbols - toSymbol(); - toVtblSymbol(); - sinit = toInitializer(); - - ////////////////////////////////////////////// - - // Generate static initializer - sinit.Sclass = scclass; - sinit.Sfl = FLdata; - version (ELFOBJ) { // Burton - sinit.Sseg = Segment.CDATA; - } - version (MACHOBJ) { - sinit.Sseg = Segment.DATA; - } - toDt(&sinit.Sdt); - outdata(sinit); - - ////////////////////////////////////////////// - - // Put out the TypeInfo - type.getTypeInfo(null); - type.vtinfo.toObjFile(multiobj); - - ////////////////////////////////////////////// - - // Put out the ClassInfo - csym.Sclass = scclass; - csym.Sfl = FLdata; - - /* The layout is: - { - void **vptr; - monitor_t monitor; - byte[] initializer; // static initialization data - char[] name; // class name - void *[] vtbl; - Interface[] interfaces; - ClassInfo *base; // base class - void *destructor; - void *invariant; // class invariant - uint flags; - void *deallocator; - OffsetTypeInfo[] offTi; - void *defaultConstructor; - const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function - TypeInfo typeinfo; - } - */ - dt_t* dt = null; - offset = CLASSINFO_SIZE; // must be ClassInfo.size - if (classinfo) - { - if (classinfo.structsize != CLASSINFO_SIZE) - error("D compiler and phobos' object.d are mismatched"); - } - - if (classinfo) - dtxoff(&dt, classinfo.toVtblSymbol(), 0, TYnptr); // vtbl for ClassInfo - else - dtdword(&dt, 0); // BUG: should be an assert() - - dtdword(&dt, 0); // monitor - - // initializer[] - assert(structsize >= 8); - dtdword(&dt, structsize); // size - dtxoff(&dt, sinit, 0, TYnptr); // initializer - - // name[] - string name = ident.toChars(); - size_t namelen = name.length; - if (!(namelen > 9 && name[0..9] == "TypeInfo_")) - { - name = toPrettyChars(); - namelen = name.length; - } - dtdword(&dt, namelen); - dtabytes(&dt, TYnptr, 0, namelen + 1, toStringz(name)); - - // vtbl[] - dtdword(&dt, vtbl.dim); - dtxoff(&dt, vtblsym, 0, TYnptr); - - // interfaces[] - dtdword(&dt, vtblInterfaces.dim); - if (vtblInterfaces.dim) - dtxoff(&dt, csym, offset, TYnptr); // (*) - else - dtdword(&dt, 0); - - // base - if (baseClass) - dtxoff(&dt, baseClass.toSymbol(), 0, TYnptr); - else - dtdword(&dt, 0); - - // destructor - if (dtor) - dtxoff(&dt, dtor.toSymbol(), 0, TYnptr); - else - dtdword(&dt, 0); - - // invariant - if (inv) - dtxoff(&dt, inv.toSymbol(), 0, TYnptr); - else - dtdword(&dt, 0); - - // flags - int flags = 4 | isCOMclass(); - version (DMDV2) { - flags |= 16; - } - flags |= 32; - - if (ctor) - flags |= 8; - for (ClassDeclaration cd = this; cd; cd = cd.baseClass) - { - if (cd.members) - { - for (size_t j = 0; j < cd.members.dim; j++) - { - Dsymbol sm = cast(Dsymbol)cd.members.data[j]; - //printf("sm = %s %s\n", sm.kind(), sm.toChars()); - if (sm.hasPointers()) - goto L2; - } - } - } - flags |= 2; // no pointers - L2: - dtdword(&dt, flags); - - - // deallocator - if (aggDelete) - dtxoff(&dt, aggDelete.toSymbol(), 0, TYnptr); - else - dtdword(&dt, 0); - - // offTi[] - dtdword(&dt, 0); - dtdword(&dt, 0); // null for now, fix later - - // defaultConstructor - if (defaultCtor) - dtxoff(&dt, defaultCtor.toSymbol(), 0, TYnptr); - else - dtdword(&dt, 0); - - version (DMDV2) { - FuncDeclaration sgetmembers = findGetMembers(); - if (sgetmembers) - dtxoff(&dt, sgetmembers.toSymbol(), 0, TYnptr); - else - dtdword(&dt, 0); // module getMembers() function - } - - dtxoff(&dt, type.vtinfo.toSymbol(), 0, TYnptr); // typeinfo - //dtdword(&dt, 0); - - ////////////////////////////////////////////// - - // Put out vtblInterfaces.data[]. Must immediately follow csym, because - // of the fixup (*) - - offset += vtblInterfaces.dim * (4 * PTRSIZE); - for (i = 0; i < vtblInterfaces.dim; i++) - { - BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; - ClassDeclaration id = b.base; - - /* The layout is: - * { - * ClassInfo *interface; - * void *[] vtbl; - * unsigned offset; - * } - */ - - // Fill in vtbl[] - b.fillVtbl(this, b.vtbl, 1); - - dtxoff(&dt, id.toSymbol(), 0, TYnptr); // ClassInfo - - // vtbl[] - dtdword(&dt, id.vtbl.dim); - dtxoff(&dt, csym, offset, TYnptr); - - dtdword(&dt, b.offset); // this offset - - offset += id.vtbl.dim * PTRSIZE; - } - - // Put out the vtblInterfaces.data[].vtbl[] - // This must be mirrored with ClassDeclaration.baseVtblOffset() - //printf("putting out %d interface vtbl[]s for '%s'\n", vtblInterfaces.dim, toChars()); - for (i = 0; i < vtblInterfaces.dim; i++) - { - BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; - ClassDeclaration id = b.base; - int j; - - //printf(" interface[%d] is '%s'\n", i, id.toChars()); - j = 0; - if (id.vtblOffset()) - { - // First entry is ClassInfo reference - //dtxoff(&dt, id.toSymbol(), 0, TYnptr); - - // First entry is struct Interface reference - dtxoff(&dt, csym, CLASSINFO_SIZE + i * (4 * PTRSIZE), TYnptr); - j = 1; - } - - assert(id.vtbl.dim == b.vtbl.dim); - for (; j < id.vtbl.dim; j++) - { - FuncDeclaration fd; - - assert(j < b.vtbl.dim); - static if (false) { - Object o = cast(Object)b.vtbl.data[j]; - if (o) - { - printf("o = %p\n", o); - assert(o.dyncast() == DYNCAST_DSYMBOL); - Dsymbol s = cast(Dsymbol)o; - printf("s.kind() = '%s'\n", s.kind()); - } - } - fd = cast(FuncDeclaration)b.vtbl.data[j]; - if (fd) - dtxoff(&dt, fd.toThunkSymbol(b.offset), 0, TYnptr); - else - dtdword(&dt, 0); - } - } - - static if (true) { - // Put out the overriding interface vtbl[]s. - // This must be mirrored with ClassDeclaration.baseVtblOffset() - //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); - ClassDeclaration cd; - scope Array bvtbl = new Array(); - - for (cd = this.baseClass; cd; cd = cd.baseClass) - { - for (int k = 0; k < cd.vtblInterfaces.dim; k++) - { - BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; - - if (bs.fillVtbl(this, bvtbl, 0)) - { - //printf("\toverriding vtbl[] for %s\n", bs.base.toChars()); - ClassDeclaration id = bs.base; - int j; - - j = 0; - if (id.vtblOffset()) - { - // First entry is ClassInfo reference - //dtxoff(&dt, id.toSymbol(), 0, TYnptr); - - // First entry is struct Interface reference - dtxoff(&dt, cd.toSymbol(), CLASSINFO_SIZE + k * (4 * PTRSIZE), TYnptr); - j = 1; - } - - for (; j < id.vtbl.dim; j++) - { - assert(j < bvtbl.dim); - FuncDeclaration fd = cast(FuncDeclaration)bvtbl.data[j]; - if (fd) - dtxoff(&dt, fd.toThunkSymbol(bs.offset), 0, TYnptr); - else - dtdword(&dt, 0); - } - } - } - } - } - - version (INTERFACE_VIRTUAL) { - // Put out the overriding interface vtbl[]s. - // This must be mirrored with ClassDeclaration.baseVtblOffset() - //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); - for (i = 0; i < vtblInterfaces.dim; i++) - { - BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; - ClassDeclaration cd; - - for (cd = this.baseClass; cd; cd = cd.baseClass) - { - for (int k = 0; k < cd.vtblInterfaces.dim; k++) - { - BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; - - if (b.base == bs.base) - { - //printf("\toverriding vtbl[] for %s\n", b.base.toChars()); - ClassDeclaration id = b.base; - int j; - - j = 0; - if (id.vtblOffset()) - { - // First entry is ClassInfo reference - //dtxoff(&dt, id.toSymbol(), 0, TYnptr); - - // First entry is struct Interface reference - dtxoff(&dt, cd.toSymbol(), CLASSINFO_SIZE + k * (4 * PTRSIZE), TYnptr); - j = 1; - } - - for (; j < id.vtbl.dim; j++) - { - assert(j < b.vtbl.dim); - FuncDeclaration fd = cast(FuncDeclaration)b.vtbl.data[j]; - if (fd) - dtxoff(&dt, fd.toThunkSymbol(bs.offset), 0, TYnptr); - else - dtdword(&dt, 0); - } - } - } - } - } - } - - - csym.Sdt = dt; - version (ELFOBJ_OR_MACHOBJ) { // Burton - // ClassInfo cannot be const data, because we use the monitor on it - csym.Sseg = Segment.DATA; - } - outdata(csym); - if (isExport()) - obj_export(csym,0); - - ////////////////////////////////////////////// - - // Put out the vtbl[] - //printf("putting out %s.vtbl[]\n", toChars()); - dt = null; - if (0) - i = 0; - else - { - dtxoff(&dt, csym, 0, TYnptr); // first entry is ClassInfo reference - i = 1; - } - for (; i < vtbl.dim; i++) - { - FuncDeclaration fd = (cast(Dsymbol)vtbl.data[i]).isFuncDeclaration(); - - //printf("\tvtbl[%d] = %p\n", i, fd); - if (fd && (fd.fbody || !isAbstract())) - { - Symbol* s = fd.toSymbol(); - - version (DMDV2) { - if (isFuncHidden(fd)) - { - /* fd is hidden from the view of this class. - * If fd overlaps with any function in the vtbl[], then - * issue 'hidden' error. - */ - for (int j = 1; j < vtbl.dim; j++) - { - if (j == i) - continue; - FuncDeclaration fd2 = (cast(Dsymbol)vtbl.data[j]).isFuncDeclaration(); - if (!fd2.ident.equals(fd.ident)) - continue; - if (fd.leastAsSpecialized(fd2) || fd2.leastAsSpecialized(fd)) - { - if (global.params.warnings) - { - TypeFunction tf = cast(TypeFunction)fd.type; - if (tf.ty == Tfunction) - warning("%s%s is hidden by %s\n", fd.toPrettyChars(), Argument.argsTypesToChars(tf.parameters, tf.varargs), toChars()); - else - warning("%s is hidden by %s\n", fd.toPrettyChars(), toChars()); - } - s = rtlsym[RTLSYM_DHIDDENFUNC]; - break; - } - } - } - } - dtxoff(&dt, s, 0, TYnptr); - } - else - dtdword(&dt, 0); - } - - vtblsym.Sdt = dt; - vtblsym.Sclass = scclass; - vtblsym.Sfl = FLdata; - version (ELFOBJ) { - vtblsym.Sseg = Segment.CDATA; - } - version (MACHOBJ) { - vtblsym.Sseg = Segment.DATA; - } - outdata(vtblsym); - if (isExport()) - obj_export(vtblsym,0); - } - - void toDebug() - { - assert(false); - } - - /****************************************** - * Get offset of base class's vtbl[] initializer from start of csym. - * Returns ~0 if not this csym. - */ - uint baseVtblOffset(BaseClass bc) - { - uint csymoffset; - int i; - - //printf("ClassDeclaration.baseVtblOffset('%s', bc = %p)\n", toChars(), bc); - csymoffset = CLASSINFO_SIZE; - csymoffset += vtblInterfaces.dim * (4 * PTRSIZE); - - for (i = 0; i < vtblInterfaces.dim; i++) - { - BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; - - if (b == bc) - return csymoffset; - csymoffset += b.base.vtbl.dim * PTRSIZE; - } - - static if (true) { - // Put out the overriding interface vtbl[]s. - // This must be mirrored with ClassDeclaration.baseVtblOffset() - //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); - ClassDeclaration cd; - Array bvtbl; - - for (cd = this.baseClass; cd; cd = cd.baseClass) - { - for (int k = 0; k < cd.vtblInterfaces.dim; k++) - { - BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; - - if (bs.fillVtbl(this, null, 0)) - { - if (bc == bs) - { - //printf("\tcsymoffset = x%x\n", csymoffset); - return csymoffset; - } - csymoffset += bs.base.vtbl.dim * PTRSIZE; - } - } - } - } - version (INTERFACE_VIRTUAL) { - for (i = 0; i < vtblInterfaces.dim; i++) - { - BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; - ClassDeclaration cd; - - for (cd = this.baseClass; cd; cd = cd.baseClass) - { - //printf("\tbase class %s\n", cd.toChars()); - for (int k = 0; k < cd.vtblInterfaces.dim; k++) - { - BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; - - if (bc == bs) - { - //printf("\tcsymoffset = x%x\n", csymoffset); - return csymoffset; - } - if (b.base == bs.base) - csymoffset += bs.base.vtbl.dim * PTRSIZE; - } - } - } - } - - return ~0; - } - - static private __gshared Classsym* scc; - - /************************************* - * Create the "ClassInfo" symbol - */ - Symbol* toSymbol() - { - if (!csym) - { - Symbol* s; - - if (!scc) - scc = fake_classsym(Id.ClassInfo); - - s = toSymbolX("__Class", SC.SCextern, scc.Stype, "Z"); - s.Sfl = FL.FLextern; - s.Sflags |= SFL.SFLnodebug; - csym = s; - slist_add(s); - } - - return csym; - } - - /************************************* - * This is accessible via the ClassData, but since it is frequently - * needed directly (like for rtti comparisons), make it directly accessible. - */ - Symbol* toVtblSymbol() - { - if (!vtblsym) - { - if (!csym) - toSymbol(); - - TYPE* t = type_alloc(TYM.TYnptr | mTY.mTYconst); - t.Tnext = tsvoid; - t.Tnext.Tcount++; - t.Tmangle = mTYman.mTYman_d; - - Symbol* s = toSymbolX("__vtbl", SC.SCextern, t, "Z"); - s.Sflags |= SFL.SFLnodebug; - s.Sfl = FL.FLextern; - vtblsym = s; - slist_add(s); - } - return vtblsym; - } - - // Generate the data for the static initializer. - void toDt(dt_t **pdt) - { - //printf("ClassDeclaration.toDt(this = '%s')\n", toChars()); - - // Put in first two members, the vtbl[] and the monitor - dtxoff(pdt, toVtblSymbol(), 0, TYnptr); - dtdword(pdt, 0); // monitor - - // Put in the rest - toDt2(pdt, this); - - //printf("-ClassDeclaration.toDt(this = '%s')\n", toChars()); - } - - void toDt2(dt_t** pdt, ClassDeclaration cd) - { - uint offset; - uint i; - dt_t* dt; - uint csymoffset; - - version (LOG) { - printf("ClassDeclaration.toDt2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); - } - if (baseClass) - { - baseClass.toDt2(pdt, cd); - offset = baseClass.structsize; - } - else - { - offset = 8; - } - - // Note equivalence of this loop to struct's - for (i = 0; i < fields.dim; i++) - { - VarDeclaration v = cast(VarDeclaration)fields.data[i]; - Initializer init; - - //printf("\t\tv = '%s' v.offset = %2d, offset = %2d\n", v.toChars(), v.offset, offset); - dt = null; - init = v.init; - if (init) - { - //printf("\t\t%s has initializer %s\n", v.toChars(), init.toChars()); - ExpInitializer ei = init.isExpInitializer(); - Type tb = v.type.toBasetype(); - if (ei && tb.ty == Tsarray) - (cast(TypeSArray)tb).toDtElem(&dt, ei.exp); - else - dt = init.toDt(); - } - else if (v.offset >= offset) - { //printf("\t\tdefault initializer\n"); - v.type.toDt(&dt); - } - if (dt) - { - if (v.offset < offset) - error("duplicated union initialization for %s", v.toChars()); - else - { - if (offset < v.offset) - dtnzeros(pdt, v.offset - offset); - dtcat(pdt, dt); - offset = v.offset + cast(uint)v.type.size(); - } - } - } - - // Interface vptr initializations - toSymbol(); // define csym - - for (i = 0; i < vtblInterfaces.dim; i++) - { - BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; - -/// version (1 || INTERFACE_VIRTUAL) { - for (ClassDeclaration cd2 = cd; 1; cd2 = cd2.baseClass) - { - assert(cd2); - csymoffset = cd2.baseVtblOffset(b); - if (csymoffset != ~0) - { - if (offset < b.offset) - dtnzeros(pdt, b.offset - offset); - dtxoff(pdt, cd2.toSymbol(), csymoffset, TYnptr); - break; - } - } -/// } else { -/// csymoffset = baseVtblOffset(b); -/// assert(csymoffset != ~0); -/// dtxoff(pdt, csym, csymoffset, TYnptr); -/// } - offset = b.offset + 4; - } - - if (offset < structsize) - dtnzeros(pdt, structsize - offset); - } - - Symbol* vtblsym; - - ///ClassDeclaration isClassDeclaration() { return cast(ClassDeclaration)this; } /// huh? - ClassDeclaration isClassDeclaration() { return this; } -} +module dmd.ClassDeclaration; + +import dmd.AggregateDeclaration; +import dmd.InterfaceDeclaration; +import dmd.ThisDeclaration; +import dmd.CompoundStatement; +import dmd.DeleteDeclaration; +import dmd.NewDeclaration; +import dmd.CtorDeclaration; +import dmd.TypeIdentifier; +import dmd.STC; +import dmd.Argument; +import dmd.TypeTuple; +import dmd.TY; +import dmd.LINK; +import dmd.DsymbolTable; +import dmd.FuncDeclaration; +import dmd.Array; +import dmd.TypeClass; +import dmd.Module; +import dmd.Id; +import dmd.Type; +import dmd.OverloadSet; +import dmd.ArrayTypes; +import dmd.BaseClass; +import dmd.ClassInfoDeclaration; +import dmd.Loc; +import dmd.Identifier; +import dmd.Dsymbol; +import dmd.Scope; +import dmd.TypeFunction; +import dmd.OutBuffer; +import dmd.HdrGenState; +import dmd.VarDeclaration; +import dmd.Initializer; +import dmd.ExpInitializer; +import dmd.TypeSArray; +import dmd.ScopeDsymbol; +import dmd.PROT; +import dmd.Util; +import dmd.Global; + +import dmd.expression.Util; + +import dmd.backend.Symbol; +import dmd.backend.dt_t; +import dmd.backend.TYPE; +import dmd.backend.FL; +import dmd.backend.SFL; +import dmd.backend.mTY; +import dmd.backend.SC; +import dmd.backend.mTYman; +import dmd.backend.Util; +import dmd.backend.TYM; +import dmd.backend.Classsym; +import dmd.backend.glue; +import dmd.backend.RTLSYM; +import dmd.backend.LIST; + +import dmd.codegen.Util; + +import std.string; + +version (DMDV2) { + enum CLASSINFO_SIZE = (0x3C+16+4); // value of ClassInfo.size +} else { + enum CLASSINFO_SIZE = (0x3C+12+4); // value of ClassInfo.size +} + +enum OFFSET_RUNTIME = 0x76543210; + +struct Param +{ + int isf(void*, FuncDeclaration fd2) + { + //printf("param = %p, fd = %p %s\n", param, fd, fd.toChars()); + return fd is fd2; + } + + FuncDeclaration fd; +} + +class ClassDeclaration : AggregateDeclaration +{ + static __gshared ClassDeclaration object; + static __gshared ClassDeclaration classinfo; + + ClassDeclaration baseClass; // null only if this is Object + FuncDeclaration staticCtor; + FuncDeclaration staticDtor; + Array vtbl; // Array of FuncDeclaration's making up the vtbl[] + Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[] + + BaseClasses baseclasses; // Array of BaseClass's; first is super, + // rest are Interface's + + int interfaces_dim; + BaseClass* interfaces; // interfaces[interfaces_dim] for this class + // (does not include baseClass) + + BaseClasses vtblInterfaces; // array of base interfaces that have + // their own vtbl[] + + ClassInfoDeclaration vclassinfo; // the ClassInfo object for this ClassDeclaration + bool com; // true if this is a COM class (meaning + // it derives from IUnknown) + bool isauto; // true if this is an auto class + bool isabstract; // true if abstract class + + int inuse; // to prevent recursive attempts + + this(Loc loc, Identifier id, BaseClasses baseclasses) + { + super(loc, id); + + vtbl = new Array(); + vtblFinal = new Array(); + + enum msg = "only object.d can define this reserved class name"; + + if (baseclasses) { + this.baseclasses = baseclasses; + } else { + this.baseclasses = new BaseClasses(); + } + + //printf("ClassDeclaration(%s), dim = %d\n", id.toChars(), this.baseclasses.dim); + + // For forward references + type = new TypeClass(this); + + if (id) + { + // Look for special class names + + if (id is Id.__sizeof || id is Id.alignof_ || id is Id.mangleof_) + error("illegal class name"); + + // BUG: What if this is the wrong TypeInfo, i.e. it is nested? + if (id.toChars()[0] == 'T') + { + if (id is Id.TypeInfo) + { + if (Type.typeinfo) + Type.typeinfo.error("%s", msg); + Type.typeinfo = this; + } + + if (id is Id.TypeInfo_Class) + { + if (Type.typeinfoclass) + Type.typeinfoclass.error("%s", msg); + Type.typeinfoclass = this; + } + + if (id is Id.TypeInfo_Interface) + { + if (Type.typeinfointerface) + Type.typeinfointerface.error("%s", msg); + Type.typeinfointerface = this; + } + + if (id is Id.TypeInfo_Struct) + { + if (Type.typeinfostruct) + Type.typeinfostruct.error("%s", msg); + Type.typeinfostruct = this; + } + + if (id is Id.TypeInfo_Typedef) + { + if (Type.typeinfotypedef) + Type.typeinfotypedef.error("%s", msg); + Type.typeinfotypedef = this; + } + + if (id is Id.TypeInfo_Pointer) + { + if (Type.typeinfopointer) + Type.typeinfopointer.error("%s", msg); + Type.typeinfopointer = this; + } + + if (id is Id.TypeInfo_Array) + { + if (Type.typeinfoarray) + Type.typeinfoarray.error("%s", msg); + Type.typeinfoarray = this; + } + + if (id is Id.TypeInfo_StaticArray) + { //if (Type.typeinfostaticarray) + //Type.typeinfostaticarray.error("%s", msg); + Type.typeinfostaticarray = this; + } + + if (id is Id.TypeInfo_AssociativeArray) + { + if (Type.typeinfoassociativearray) + Type.typeinfoassociativearray.error("%s", msg); + Type.typeinfoassociativearray = this; + } + + if (id is Id.TypeInfo_Enum) + { + if (Type.typeinfoenum) + Type.typeinfoenum.error("%s", msg); + Type.typeinfoenum = this; + } + + if (id is Id.TypeInfo_Function) + { + if (Type.typeinfofunction) + Type.typeinfofunction.error("%s", msg); + Type.typeinfofunction = this; + } + + if (id is Id.TypeInfo_Delegate) + { + if (Type.typeinfodelegate) + Type.typeinfodelegate.error("%s", msg); + Type.typeinfodelegate = this; + } + + if (id is Id.TypeInfo_Tuple) + { + if (Type.typeinfotypelist) + Type.typeinfotypelist.error("%s", msg); + Type.typeinfotypelist = this; + } + + version (DMDV2) { + if (id is Id.TypeInfo_Const) + { + if (Type.typeinfoconst) + Type.typeinfoconst.error("%s", msg); + Type.typeinfoconst = this; + } + + if (id is Id.TypeInfo_Invariant) + { + if (Type.typeinfoinvariant) + Type.typeinfoinvariant.error("%s", msg); + Type.typeinfoinvariant = this; + } + + if (id is Id.TypeInfo_Shared) + { + if (Type.typeinfoshared) + Type.typeinfoshared.error("%s", msg); + Type.typeinfoshared = this; + } + } + } + + if (id is Id.Object_) + { + if (object) + object.error("%s", msg); + object = this; + } + + if (id is Id.ClassInfo) + { + if (classinfo) + classinfo.error("%s", msg); + classinfo = this; + } + + if (id is Id.ModuleInfo) + { + if (Module.moduleinfo) + Module.moduleinfo.error("%s", msg); + Module.moduleinfo = this; + } + } + + com = 0; + isauto = false; + isabstract = false; + inuse = 0; + } + + override Dsymbol syntaxCopy(Dsymbol s) + { + ClassDeclaration cd; + + //printf("ClassDeclaration.syntaxCopy('%s')\n", toChars()); + if (s) + cd = cast(ClassDeclaration)s; + else + cd = new ClassDeclaration(loc, ident, null); + + cd.storage_class |= storage_class; + + cd.baseclasses.setDim(this.baseclasses.dim); + for (int i = 0; i < cd.baseclasses.dim; i++) + { + BaseClass b = cast(BaseClass)this.baseclasses.data[i]; + BaseClass b2 = new BaseClass(b.type.syntaxCopy(), b.protection); + cd.baseclasses.data[i] = cast(void*)b2; + } + + ScopeDsymbol.syntaxCopy(cd); + return cd; + } + + override void semantic(Scope sc) + { + int i; + uint offset; + + //printf("ClassDeclaration.semantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); + //printf("\tparent = %p, '%s'\n", sc.parent, sc.parent ? sc.parent.toChars() : ""); + //printf("sc.stc = %x\n", sc.stc); + + //{ static int n; if (++n == 20) *(char*)0=0; } + + if (!ident) // if anonymous class + { + string id = "__anonclass"; + ident = Identifier.generateId(id); + } + + if (!sc) + sc = scope_; + + if (!parent && sc.parent && !sc.parent.isModule()) + parent = sc.parent; + + type = type.semantic(loc, sc); + handle = type; + + if (!members) // if forward reference + { + //printf("\tclass '%s' is forward referenced\n", toChars()); + return; + } + if (symtab) + { if (!scope_) + { //printf("\tsemantic for '%s' is already completed\n", toChars()); + return; // semantic() already completed + } + } + else + symtab = new DsymbolTable(); + + Scope scx = null; + if (scope_) + { sc = scope_; + scx = scope_; // save so we don't make redundant copies + scope_ = null; + } +version (IN_GCC) { + methods.setDim(0); +} + + if (sc.stc & STC.STCdeprecated) + { + isdeprecated = 1; + } + + if (sc.linkage == LINK.LINKcpp) + error("cannot create C++ classes"); + + // Expand any tuples in baseclasses[] + for (i = 0; i < baseclasses.dim; ) + { + BaseClass b = cast(BaseClass)baseclasses.data[i]; + //printf("test1 %s %s\n", toChars(), b.type.toChars()); + b.type = b.type.semantic(loc, sc); + //printf("test2\n"); + Type tb = b.type.toBasetype(); + + if (tb.ty == TY.Ttuple) + { + TypeTuple tup = cast(TypeTuple)tb; + enum PROT protection = b.protection; + baseclasses.remove(i); + size_t dim = Argument.dim(tup.arguments); + for (size_t j = 0; j < dim; j++) + { + Argument arg = Argument.getNth(tup.arguments, j); + b = new BaseClass(arg.type, protection); + baseclasses.insert(i + j, cast(void*)b); + } + } + else + i++; + } + + // See if there's a base class as first in baseclasses[] + if (baseclasses.dim) + { + TypeClass tc; + BaseClass b; + Type tb; + + b = cast(BaseClass)baseclasses.data[0]; + //b.type = b.type.semantic(loc, sc); + tb = b.type.toBasetype(); + if (tb.ty != TY.Tclass) + { error("base type must be class or interface, not %s", b.type.toChars()); + baseclasses.remove(0); + } + else + { + tc = cast(TypeClass)(tb); + + if (tc.sym.isDeprecated()) + { + if (!isDeprecated()) + { + // Deriving from deprecated class makes this one deprecated too + isdeprecated = 1; + + tc.checkDeprecated(loc, sc); + } + } + + if (tc.sym.isInterfaceDeclaration()) { + ; + } else { + for (ClassDeclaration cdb = tc.sym; cdb; cdb = cdb.baseClass) + { + if (cdb == this) + { + error("circular inheritance"); + baseclasses.remove(0); + goto L7; + } + } + if (!tc.sym.symtab || tc.sym.sizeok == 0) + { // Try to resolve forward reference + if (sc.mustsemantic && tc.sym.scope_) + tc.sym.semantic(null); + } + if (!tc.sym.symtab || tc.sym.scope_ || tc.sym.sizeok == 0) + { + //printf("%s: forward reference of base class %s\n", toChars(), tc.sym.toChars()); + //error("forward reference of base class %s", baseClass.toChars()); + // Forward reference of base class, try again later + //printf("\ttry later, forward reference of base class %s\n", tc.sym.toChars()); + scope_ = scx ? scx : new Scope(sc); + scope_.setNoFree(); + if (tc.sym.scope_) + tc.sym.scope_.module_.addDeferredSemantic(tc.sym); + scope_.module_.addDeferredSemantic(this); + return; + } + else + { baseClass = tc.sym; + b.base = baseClass; + } + L7: ; + } + } + } + + // Treat the remaining entries in baseclasses as interfaces + // Check for errors, handle forward references + for (i = (baseClass ? 1 : 0); i < baseclasses.dim; ) + { TypeClass tc; + BaseClass b; + Type tb; + + b = cast(BaseClass)baseclasses.data[i]; + b.type = b.type.semantic(loc, sc); + tb = b.type.toBasetype(); + if (tb.ty == TY.Tclass) + tc = cast(TypeClass)tb; + else + tc = null; + if (!tc || !tc.sym.isInterfaceDeclaration()) + { + error("base type must be interface, not %s", b.type.toChars()); + baseclasses.remove(i); + continue; + } + else + { + if (tc.sym.isDeprecated()) + { + if (!isDeprecated()) + { + // Deriving from deprecated class makes this one deprecated too + isdeprecated = 1; + + tc.checkDeprecated(loc, sc); + } + } + + // Check for duplicate interfaces + for (size_t j = (baseClass ? 1 : 0); j < i; j++) + { + BaseClass b2 = cast(BaseClass)baseclasses.data[j]; + if (b2.base == tc.sym) + error("inherits from duplicate interface %s", b2.base.toChars()); + } + + if (!tc.sym.symtab) + { // Try to resolve forward reference + if (sc.mustsemantic && tc.sym.scope_) + tc.sym.semantic(null); + } + + b.base = tc.sym; + if (!b.base.symtab || b.base.scope_) + { + //error("forward reference of base class %s", baseClass.toChars()); + // Forward reference of base, try again later + //printf("\ttry later, forward reference of base %s\n", baseClass.toChars()); + scope_ = scx ? scx : new Scope(sc); + scope_.setNoFree(); + if (tc.sym.scope_) + tc.sym.scope_.module_.addDeferredSemantic(tc.sym); + scope_.module_.addDeferredSemantic(this); + return; + } + } + i++; + } + + + // If no base class, and this is not an Object, use Object as base class + if (!baseClass && ident !is Id.Object_) + { + // BUG: what if Object is redefined in an inner scope? + Type tbase = new TypeIdentifier(Loc(0), Id.Object_); + BaseClass b; + TypeClass tc; + Type bt; + + if (!object) + { + error("missing or corrupt object.d"); + fatal(); + } + bt = tbase.semantic(loc, sc).toBasetype(); + b = new BaseClass(bt, PROT.PROTpublic); + baseclasses.shift(cast(void*)b); + assert(b.type.ty == TY.Tclass); + tc = cast(TypeClass)(b.type); + baseClass = tc.sym; + assert(!baseClass.isInterfaceDeclaration()); + b.base = baseClass; + } + + interfaces_dim = baseclasses.dim; + interfaces = cast(BaseClass*)baseclasses.data; + + if (baseClass) + { + if (baseClass.storage_class & STC.STCfinal) + error("cannot inherit from final class %s", baseClass.toChars()); + + interfaces_dim--; + interfaces++; + + // Copy vtbl[] from base class + vtbl.setDim(baseClass.vtbl.dim); + memcpy(vtbl.data, baseClass.vtbl.data, (void*).sizeof * vtbl.dim); + + // Inherit properties from base class + com = baseClass.isCOMclass(); + isauto = baseClass.isauto; + vthis = baseClass.vthis; + storage_class |= baseClass.storage_class & STC.STC_TYPECTOR; + } + else + { + // No base class, so this is the root of the class hierarchy + vtbl.setDim(0); + vtbl.push(cast(void*)this); // leave room for classinfo as first member + } + + protection = sc.protection; + storage_class |= sc.stc; + + if (sizeok == 0) + { + interfaceSemantic(sc); + + for (i = 0; i < members.dim; i++) + { + Dsymbol s = cast(Dsymbol)members.data[i]; + s.addMember(sc, this, true); + } + + /* If this is a nested class, add the hidden 'this' + * member which is a pointer to the enclosing scope. + */ + if (vthis) // if inheriting from nested class + { // Use the base class's 'this' member + isnested = true; + if (storage_class & STC.STCstatic) + error("static class cannot inherit from nested class %s", baseClass.toChars()); + if (toParent2() != baseClass.toParent2()) + { + if (toParent2()) + { + error("is nested within %s, but super class %s is nested within %s", + toParent2().toChars(), + baseClass.toChars(), + baseClass.toParent2().toChars()); + } + else + { + error("is not nested, but super class %s is nested within %s", + baseClass.toChars(), + baseClass.toParent2().toChars()); + } + isnested = false; + } + } + else if (!(storage_class & STC.STCstatic)) + { + Dsymbol s = toParent2(); + if (s) + { + AggregateDeclaration ad = s.isClassDeclaration(); + FuncDeclaration fd = s.isFuncDeclaration(); + + if (ad || fd) + { isnested = true; + Type t; + if (ad) + t = ad.handle; + else if (fd) + { + AggregateDeclaration ad2 = fd.isMember2(); + if (ad2) + t = ad2.handle; + else + { + t = Type.tvoidptr; + } + } + else + assert(0); + if (t.ty == TY.Tstruct) // ref to struct + t = Type.tvoidptr; + assert(!vthis); + vthis = new ThisDeclaration(loc, t); + members.push(cast(void*)vthis); + } + } + } + } + + if (storage_class & (STC.STCauto | STC.STCscope)) + isauto = true; + if (storage_class & STC.STCabstract) + isabstract = true; + if (storage_class & STC.STCimmutable) + type = type.invariantOf(); + else if (storage_class & STC.STCconst) + type = type.constOf(); + else if (storage_class & STC.STCshared) + type = type.sharedOf(); + + sc = sc.push(this); + sc.stc &= ~(STC.STCfinal | STC.STCauto | STC.STCscope | STC.STCstatic | + STC.STCabstract | STC.STCdeprecated | STC.STC_TYPECTOR | STC.STCtls | STC.STCgshared); + sc.stc |= storage_class & STC.STC_TYPECTOR; + sc.parent = this; + sc.inunion = 0; + + if (isCOMclass()) + { +version (_WIN32) { + sc.linkage = LINK.LINKwindows; +} else { + /* This enables us to use COM objects under Linux and + * work with things like XPCOM + */ + sc.linkage = LINK.LINKc; +} + } + sc.protection = PROT.PROTpublic; + sc.explicitProtection = 0; + sc.structalign = 8; + structalign = sc.structalign; + if (baseClass) + { sc.offset = baseClass.structsize; + alignsize = baseClass.alignsize; + // if (isnested) + // sc.offset += PTRSIZE; // room for uplevel context pointer + } + else + { sc.offset = PTRSIZE * 2; // allow room for __vptr and __monitor + alignsize = PTRSIZE; + } + structsize = sc.offset; + Scope scsave = sc; /// a copy must be created? + int members_dim = members.dim; + sizeok = 0; + for (i = 0; i < members_dim; i++) + { + Dsymbol s = cast(Dsymbol)members.data[i]; + s.semantic(sc); + } + + if (sizeok == 2) + { // semantic() failed because of forward references. + // Unwind what we did, and defer it for later + fields.setDim(0); + structsize = 0; + alignsize = 0; + structalign = 0; + + sc = sc.pop(); + + scope_ = scx ? scx : new Scope(sc); + scope_.setNoFree(); + scope_.module_.addDeferredSemantic(this); + + //printf("\tsemantic('%s') failed due to forward references\n", toChars()); + return; + } + + //printf("\tsemantic('%s') successful\n", toChars()); + + structsize = sc.offset; + //members.print(); + + /* Look for special member functions. + * They must be in this class, not in a base class. + */ + ctor = cast(CtorDeclaration)search(Loc(0), Id.ctor, 0); + if (ctor && (ctor.toParent() != this || !ctor.isCtorDeclaration())) + ctor = null; + + // dtor = (DtorDeclaration *)search(Id.dtor, 0); + // if (dtor && dtor.toParent() != this) + // dtor = null; + + // inv = (InvariantDeclaration *)search(Id.classInvariant, 0); + // if (inv && inv.toParent() != this) + // inv = null; + + // Can be in base class + aggNew = cast(NewDeclaration)search(Loc(0), Id.classNew, 0); + aggDelete = cast(DeleteDeclaration)search(Loc(0), Id.classDelete, 0); + + // If this class has no constructor, but base class does, create + // a constructor: + // this() { } + if (!ctor && baseClass && baseClass.ctor) + { + //printf("Creating default this(){} for class %s\n", toChars()); + CtorDeclaration ctor = new CtorDeclaration(loc, Loc(0), null, 0); + ctor.fbody = new CompoundStatement(Loc(0), new Statements()); + members.push(cast(void*)ctor); + ctor.addMember(sc, this, true); + sc = scsave; // why? What about sc.nofree? /// + sc.offset = structsize; + ctor.semantic(sc); + this.ctor = ctor; + defaultCtor = ctor; + } + +static if (false) { + if (baseClass) + { if (!aggDelete) + aggDelete = baseClass.aggDelete; + if (!aggNew) + aggNew = baseClass.aggNew; + } +} + + // Allocate instance of each new interface + for (i = 0; i < vtblInterfaces.dim; i++) + { + BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; + uint thissize = PTRSIZE; + + alignmember(structalign, thissize, &sc.offset); + assert(b.offset == 0); + b.offset = sc.offset; + + // Take care of single inheritance offsets + while (b.baseInterfaces.length) + { + b = b.baseInterfaces[0]; + b.offset = sc.offset; + } + + sc.offset += thissize; + if (alignsize < thissize) + alignsize = thissize; + } + structsize = sc.offset; + sizeok = 1; + Module.dprogress++; + + dtor = buildDtor(sc); + + sc.pop(); + +static if (false) { // Do not call until toObjfile() because of forward references + // Fill in base class vtbl[]s + for (i = 0; i < vtblInterfaces.dim; i++) + { + BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; + + //b.fillVtbl(this, &b.vtbl, 1); + } +} + //printf("-ClassDeclaration.semantic(%s), type = %p\n", toChars(), type); + } + + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) + { + assert(false); + } + + /********************************************* + * Determine if 'this' is a base class of cd. + * This is used to detect circular inheritance only. + */ + int isBaseOf2(ClassDeclaration cd) + { + if (!cd) + return 0; + //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); + for (int i = 0; i < cd.baseclasses.dim; i++) + { + BaseClass b = cast(BaseClass)cd.baseclasses.data[i]; + + if (b.base is this || isBaseOf2(b.base)) + return 1; + } + return 0; + } + + /******************************************* + * Determine if 'this' is a base class of cd. + */ +/// #define OFFSET_RUNTIME 0x76543210 + bool isBaseOf(ClassDeclaration cd, int* poffset) + { + if (!cd) + return 0; + //printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); + for (int i = 0; i < cd.baseclasses.dim; i++) + { + BaseClass b = cast(BaseClass)cd.baseclasses.data[i]; + + if (b.base == this || isBaseOf2(b.base)) + return 1; + } + + return 0; + } + + override Dsymbol search(Loc, Identifier ident, int flags) + { + Dsymbol s; + //printf("%s.ClassDeclaration.search('%s')\n", toChars(), ident.toChars()); + + if (scope_) + { + Scope sc = scope_; + sc.mustsemantic++; + semantic(sc); + sc.mustsemantic--; + } + + if (!members || !symtab || scope_) + { + error("is forward referenced when looking for '%s'", ident.toChars()); + //*(char*)0=0; + return null; + } + + s = ScopeDsymbol.search(loc, ident, flags); + if (!s) + { + // Search bases classes in depth-first, left to right order + + int i; + + for (i = 0; i < baseclasses.dim; i++) + { + BaseClass b = cast(BaseClass)baseclasses.data[i]; + + if (b.base) + { + if (!b.base.symtab) + error("base %s is forward referenced", b.base.ident.toChars()); + else + { + s = b.base.search(loc, ident, flags); + if (s is this) // happens if s is nested in this and derives from this + s = null; + else if (s) + break; + } + } + } + } + return s; + } + +version (DMDV2) { + bool isFuncHidden(FuncDeclaration fd) + { + //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd.toChars()); + Dsymbol s = search(Loc(0), fd.ident, 4|2); + if (!s) + { + //printf("not found\n"); + /* Because, due to a hack, if there are multiple definitions + * of fd.ident, null is returned. + */ + return false; + } + + Param p; p.fd = fd; + + s = s.toAlias(); + OverloadSet os = s.isOverloadSet(); + if (os) + { + for (int i = 0; i < os.a.dim; i++) + { + Dsymbol s2 = cast(Dsymbol)os.a.data[i]; + FuncDeclaration f2 = s2.isFuncDeclaration(); + if (f2 && overloadApply(f2, &p.isf, &p)) + return false; + } + return true; + } + else + { + FuncDeclaration fdstart = s.isFuncDeclaration(); + //printf("%s fdstart = %p\n", s.kind(), fdstart); + return !overloadApply(fdstart, &p.isf, &p); + } + } +} + FuncDeclaration findFunc(Identifier ident, TypeFunction tf) + { + //printf("ClassDeclaration.findFunc(%s, %s) %s\n", ident.toChars(), tf.toChars(), toChars()); + + ClassDeclaration cd = this; + Array vtbl = cd.vtbl; + while (true) + { + for (size_t i = 0; i < vtbl.dim; i++) + { + FuncDeclaration fd = (cast(Dsymbol)vtbl.data[i]).isFuncDeclaration(); + if (!fd) + continue; // the first entry might be a ClassInfo + + //printf("\t[%d] = %s\n", i, fd.toChars()); + if (ident == fd.ident && + //tf.equals(fd.type) + fd.type.covariant(tf) == 1 + ) + { //printf("\t\tfound\n"); + return fd; + } + //else printf("\t\t%d\n", fd.type.covariant(tf)); + } + if (!cd) + break; + + vtbl = cd.vtblFinal; + cd = cd.baseClass; + } + + return null; + } + + void interfaceSemantic(Scope sc) + { + InterfaceDeclaration id = isInterfaceDeclaration(); + + vtblInterfaces = new BaseClasses(); + vtblInterfaces.reserve(interfaces_dim); + + for (size_t i = 0; i < interfaces_dim; i++) + { + BaseClass b = interfaces[i]; + + // If this is an interface, and it derives from a COM interface, + // then this is a COM interface too. + if (b.base.isCOMinterface()) + com = 1; + + if (b.base.isCPPinterface() && id) + id.cpp = 1; + + vtblInterfaces.push(cast(void*)b); + b.copyBaseInterfaces(vtblInterfaces); + } + } + + bool isCOMclass() + { + return com; + } + + bool isCOMinterface() + { + return false; + } + +version (DMDV2) { + bool isCPPinterface() + { + return false; + } +} + bool isAbstract() + { + if (isabstract) + return true; + + for (int i = 1; i < vtbl.dim; i++) + { + FuncDeclaration fd = (cast(Dsymbol)vtbl.data[i]).isFuncDeclaration(); + + //printf("\tvtbl[%d] = %p\n", i, fd); + if (!fd || fd.isAbstract()) + { + isabstract = true; + return true; + } + } + + return false; + } + + int vtblOffset() + { + assert(false); + } + + override string kind() + { + return "class"; + } + + override string mangle() + { + Dsymbol parentsave = parent; + + //printf("ClassDeclaration.mangle() %s.%s\n", parent.toChars(), toChars()); + + /* These are reserved to the compiler, so keep simple + * names for them. + */ + if (ident is Id.Exception) + { + if (parent.ident is Id.object) + parent = null; + } + else if (ident is Id.TypeInfo || + // ident is Id.Exception || + ident is Id.TypeInfo_Struct || + ident is Id.TypeInfo_Class || + ident is Id.TypeInfo_Typedef || + ident is Id.TypeInfo_Tuple || + this is object || + this is classinfo || + this is Module.moduleinfo || + ident.toChars().startsWith("TypeInfo_") + ) + { + parent = null; + } + + string id = Dsymbol.mangle(); + parent = parentsave; + return id; + } + + override void toDocBuffer(OutBuffer buf) + { + assert(false); + } + + override PROT getAccess(Dsymbol smember) // determine access to smember + { + PROT access_ret = PROT.PROTnone; + + version (LOG) { + printf("+ClassDeclaration::getAccess(this = '%s', smember = '%s')\n", + toChars(), smember.toChars()); + } + if (smember.toParent() is this) + { + access_ret = smember.prot(); + } + else + { + PROT access; + int i; + + if (smember.isDeclaration().isStatic()) + { + access_ret = smember.prot(); + } + + for (i = 0; i < baseclasses.dim; i++) + { + BaseClass b = cast(BaseClass)baseclasses.data[i]; + + access = b.base.getAccess(smember); + switch (access) + { + case PROT.PROTnone: + break; + + case PROT.PROTprivate: + access = PROT.PROTnone; // private members of base class not accessible + break; + + case PROT.PROTpackage: + case PROT.PROTprotected: + case PROT.PROTpublic: + case PROT.PROTexport: + // If access is to be tightened + if (b.protection < access) + access = b.protection; + + // Pick path with loosest access + if (access > access_ret) + access_ret = access; + break; + + default: + assert(0); + } + } + } + + version (LOG) { + printf("-ClassDeclaration::getAccess(this = '%s', smember = '%s') = %d\n", + toChars(), smember.toChars(), access_ret); + } + + return access_ret; + } + + override void addLocalClass(ClassDeclarations aclasses) + { + aclasses.push(cast(void*)this); + } + + // Back end + override void toObjFile(int multiobj) // compile to .obj file + { + uint i; + uint offset; + Symbol* sinit; + enum_SC scclass; + + //printf("ClassDeclaration.toObjFile('%s')\n", toChars()); + + if (!members) + return; + + if (multiobj) + { + obj_append(this); + return; + } + + if (global.params.symdebug) + toDebug(); + + assert(!scope_); // semantic() should have been run to completion + + scclass = SCglobal; + if (inTemplateInstance()) + scclass = SCcomdat; + + // Put out the members + for (i = 0; i < members.dim; i++) + { + Dsymbol member; + + member = cast(Dsymbol)members.data[i]; + member.toObjFile(0); + } + +static if (false) { + // Build destructor by aggregating dtors[] + Symbol* sdtor; + switch (dtors.dim) + { + case 0: + // No destructors for this class + sdtor = null; + break; + + case 1: + // One destructor, just use it directly + sdtor = (cast(DtorDeclaration)dtors.data[0]).toSymbol(); + break; + + default: + { + /* Build a destructor that calls all the + * other destructors in dtors[]. + */ + + elem* edtor = null; + + // Declare 'this' pointer for our new destructor + Symbol* sthis = symbol_calloc("this"); + sthis.Stype = type_fake(TYnptr); + sthis.Stype.Tcount++; + sthis.Sclass = SCfastpar; + sthis.Spreg = AX; + sthis.Sfl = FLauto; + + // Call each of the destructors in dtors[] + // in reverse order + for (i = 0; i < dtors.dim; i++) + { + DtorDeclaration d = cast(DtorDeclaration)dtors.data[i]; + Symbol* s = d.toSymbol(); + elem* e = el_bin(OPcall, TYvoid, el_var(s), el_var(sthis)); + edtor = el_combine(e, edtor); + } + + // Create type for the function + .type* t = type_alloc(TYjfunc); + t.Tflags |= TFprototype | TFfixed; + t.Tmangle = mTYman_d; + t.Tnext = tsvoid; + tsvoid.Tcount++; + + // Create the function, sdtor, and write it out + localgot = null; + sdtor = toSymbolX("__dtor", SCglobal, t, "FZv"); + block* b = block_calloc(); + b.BC = BCret; + b.Belem = edtor; + sdtor.Sfunc.Fstartblock = b; + cstate.CSpsymtab = &sdtor.Sfunc.Flocsym; + symbol_add(sthis); + writefunc(sdtor); + } + } +} + + // Generate C symbols + toSymbol(); + toVtblSymbol(); + sinit = toInitializer(); + + ////////////////////////////////////////////// + + // Generate static initializer + sinit.Sclass = scclass; + sinit.Sfl = FLdata; + version (ELFOBJ) { // Burton + sinit.Sseg = Segment.CDATA; + } + version (MACHOBJ) { + sinit.Sseg = Segment.DATA; + } + toDt(&sinit.Sdt); + outdata(sinit); + + ////////////////////////////////////////////// + + // Put out the TypeInfo + type.getTypeInfo(null); + type.vtinfo.toObjFile(multiobj); + + ////////////////////////////////////////////// + + // Put out the ClassInfo + csym.Sclass = scclass; + csym.Sfl = FLdata; + + /* The layout is: + { + void **vptr; + monitor_t monitor; + byte[] initializer; // static initialization data + char[] name; // class name + void *[] vtbl; + Interface[] interfaces; + ClassInfo *base; // base class + void *destructor; + void *invariant; // class invariant + uint flags; + void *deallocator; + OffsetTypeInfo[] offTi; + void *defaultConstructor; + const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function + TypeInfo typeinfo; + } + */ + dt_t* dt = null; + offset = CLASSINFO_SIZE; // must be ClassInfo.size + if (classinfo) + { + if (classinfo.structsize != CLASSINFO_SIZE) + error("D compiler and phobos' object.d are mismatched"); + } + + if (classinfo) + dtxoff(&dt, classinfo.toVtblSymbol(), 0, TYnptr); // vtbl for ClassInfo + else + dtdword(&dt, 0); // BUG: should be an assert() + + dtdword(&dt, 0); // monitor + + // initializer[] + assert(structsize >= 8); + dtdword(&dt, structsize); // size + dtxoff(&dt, sinit, 0, TYnptr); // initializer + + // name[] + string name = ident.toChars(); + size_t namelen = name.length; + if (!(namelen > 9 && name[0..9] == "TypeInfo_")) + { + name = toPrettyChars(); + namelen = name.length; + } + dtdword(&dt, namelen); + dtabytes(&dt, TYnptr, 0, namelen + 1, toStringz(name)); + + // vtbl[] + dtdword(&dt, vtbl.dim); + dtxoff(&dt, vtblsym, 0, TYnptr); + + // interfaces[] + dtdword(&dt, vtblInterfaces.dim); + if (vtblInterfaces.dim) + dtxoff(&dt, csym, offset, TYnptr); // (*) + else + dtdword(&dt, 0); + + // base + if (baseClass) + dtxoff(&dt, baseClass.toSymbol(), 0, TYnptr); + else + dtdword(&dt, 0); + + // destructor + if (dtor) + dtxoff(&dt, dtor.toSymbol(), 0, TYnptr); + else + dtdword(&dt, 0); + + // invariant + if (inv) + dtxoff(&dt, inv.toSymbol(), 0, TYnptr); + else + dtdword(&dt, 0); + + // flags + int flags = 4 | isCOMclass(); + version (DMDV2) { + flags |= 16; + } + flags |= 32; + + if (ctor) + flags |= 8; + for (ClassDeclaration cd = this; cd; cd = cd.baseClass) + { + if (cd.members) + { + for (size_t j = 0; j < cd.members.dim; j++) + { + Dsymbol sm = cast(Dsymbol)cd.members.data[j]; + //printf("sm = %s %s\n", sm.kind(), sm.toChars()); + if (sm.hasPointers()) + goto L2; + } + } + } + flags |= 2; // no pointers + L2: + dtdword(&dt, flags); + + + // deallocator + if (aggDelete) + dtxoff(&dt, aggDelete.toSymbol(), 0, TYnptr); + else + dtdword(&dt, 0); + + // offTi[] + dtdword(&dt, 0); + dtdword(&dt, 0); // null for now, fix later + + // defaultConstructor + if (defaultCtor) + dtxoff(&dt, defaultCtor.toSymbol(), 0, TYnptr); + else + dtdword(&dt, 0); + + version (DMDV2) { + FuncDeclaration sgetmembers = findGetMembers(); + if (sgetmembers) + dtxoff(&dt, sgetmembers.toSymbol(), 0, TYnptr); + else + dtdword(&dt, 0); // module getMembers() function + } + + dtxoff(&dt, type.vtinfo.toSymbol(), 0, TYnptr); // typeinfo + //dtdword(&dt, 0); + + ////////////////////////////////////////////// + + // Put out vtblInterfaces.data[]. Must immediately follow csym, because + // of the fixup (*) + + offset += vtblInterfaces.dim * (4 * PTRSIZE); + for (i = 0; i < vtblInterfaces.dim; i++) + { + BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; + ClassDeclaration id = b.base; + + /* The layout is: + * { + * ClassInfo *interface; + * void *[] vtbl; + * unsigned offset; + * } + */ + + // Fill in vtbl[] + b.fillVtbl(this, b.vtbl, 1); + + dtxoff(&dt, id.toSymbol(), 0, TYnptr); // ClassInfo + + // vtbl[] + dtdword(&dt, id.vtbl.dim); + dtxoff(&dt, csym, offset, TYnptr); + + dtdword(&dt, b.offset); // this offset + + offset += id.vtbl.dim * PTRSIZE; + } + + // Put out the vtblInterfaces.data[].vtbl[] + // This must be mirrored with ClassDeclaration.baseVtblOffset() + //printf("putting out %d interface vtbl[]s for '%s'\n", vtblInterfaces.dim, toChars()); + for (i = 0; i < vtblInterfaces.dim; i++) + { + BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; + ClassDeclaration id = b.base; + int j; + + //printf(" interface[%d] is '%s'\n", i, id.toChars()); + j = 0; + if (id.vtblOffset()) + { + // First entry is ClassInfo reference + //dtxoff(&dt, id.toSymbol(), 0, TYnptr); + + // First entry is struct Interface reference + dtxoff(&dt, csym, CLASSINFO_SIZE + i * (4 * PTRSIZE), TYnptr); + j = 1; + } + + assert(id.vtbl.dim == b.vtbl.dim); + for (; j < id.vtbl.dim; j++) + { + FuncDeclaration fd; + + assert(j < b.vtbl.dim); + static if (false) { + Object o = cast(Object)b.vtbl.data[j]; + if (o) + { + printf("o = %p\n", o); + assert(o.dyncast() == DYNCAST_DSYMBOL); + Dsymbol s = cast(Dsymbol)o; + printf("s.kind() = '%s'\n", s.kind()); + } + } + fd = cast(FuncDeclaration)b.vtbl.data[j]; + if (fd) + dtxoff(&dt, fd.toThunkSymbol(b.offset), 0, TYnptr); + else + dtdword(&dt, 0); + } + } + + static if (true) { + // Put out the overriding interface vtbl[]s. + // This must be mirrored with ClassDeclaration.baseVtblOffset() + //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); + ClassDeclaration cd; + scope Array bvtbl = new Array(); + + for (cd = this.baseClass; cd; cd = cd.baseClass) + { + for (int k = 0; k < cd.vtblInterfaces.dim; k++) + { + BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; + + if (bs.fillVtbl(this, bvtbl, 0)) + { + //printf("\toverriding vtbl[] for %s\n", bs.base.toChars()); + ClassDeclaration id = bs.base; + int j; + + j = 0; + if (id.vtblOffset()) + { + // First entry is ClassInfo reference + //dtxoff(&dt, id.toSymbol(), 0, TYnptr); + + // First entry is struct Interface reference + dtxoff(&dt, cd.toSymbol(), CLASSINFO_SIZE + k * (4 * PTRSIZE), TYnptr); + j = 1; + } + + for (; j < id.vtbl.dim; j++) + { + assert(j < bvtbl.dim); + FuncDeclaration fd = cast(FuncDeclaration)bvtbl.data[j]; + if (fd) + dtxoff(&dt, fd.toThunkSymbol(bs.offset), 0, TYnptr); + else + dtdword(&dt, 0); + } + } + } + } + } + + version (INTERFACE_VIRTUAL) { + // Put out the overriding interface vtbl[]s. + // This must be mirrored with ClassDeclaration.baseVtblOffset() + //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); + for (i = 0; i < vtblInterfaces.dim; i++) + { + BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; + ClassDeclaration cd; + + for (cd = this.baseClass; cd; cd = cd.baseClass) + { + for (int k = 0; k < cd.vtblInterfaces.dim; k++) + { + BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; + + if (b.base == bs.base) + { + //printf("\toverriding vtbl[] for %s\n", b.base.toChars()); + ClassDeclaration id = b.base; + int j; + + j = 0; + if (id.vtblOffset()) + { + // First entry is ClassInfo reference + //dtxoff(&dt, id.toSymbol(), 0, TYnptr); + + // First entry is struct Interface reference + dtxoff(&dt, cd.toSymbol(), CLASSINFO_SIZE + k * (4 * PTRSIZE), TYnptr); + j = 1; + } + + for (; j < id.vtbl.dim; j++) + { + assert(j < b.vtbl.dim); + FuncDeclaration fd = cast(FuncDeclaration)b.vtbl.data[j]; + if (fd) + dtxoff(&dt, fd.toThunkSymbol(bs.offset), 0, TYnptr); + else + dtdword(&dt, 0); + } + } + } + } + } + } + + + csym.Sdt = dt; + version (ELFOBJ_OR_MACHOBJ) { // Burton + // ClassInfo cannot be const data, because we use the monitor on it + csym.Sseg = Segment.DATA; + } + outdata(csym); + if (isExport()) + obj_export(csym,0); + + ////////////////////////////////////////////// + + // Put out the vtbl[] + //printf("putting out %s.vtbl[]\n", toChars()); + dt = null; + if (0) + i = 0; + else + { + dtxoff(&dt, csym, 0, TYnptr); // first entry is ClassInfo reference + i = 1; + } + for (; i < vtbl.dim; i++) + { + FuncDeclaration fd = (cast(Dsymbol)vtbl.data[i]).isFuncDeclaration(); + + //printf("\tvtbl[%d] = %p\n", i, fd); + if (fd && (fd.fbody || !isAbstract())) + { + Symbol* s = fd.toSymbol(); + + version (DMDV2) { + if (isFuncHidden(fd)) + { + /* fd is hidden from the view of this class. + * If fd overlaps with any function in the vtbl[], then + * issue 'hidden' error. + */ + for (int j = 1; j < vtbl.dim; j++) + { + if (j == i) + continue; + FuncDeclaration fd2 = (cast(Dsymbol)vtbl.data[j]).isFuncDeclaration(); + if (!fd2.ident.equals(fd.ident)) + continue; + if (fd.leastAsSpecialized(fd2) || fd2.leastAsSpecialized(fd)) + { + if (global.params.warnings) + { + TypeFunction tf = cast(TypeFunction)fd.type; + if (tf.ty == Tfunction) + warning("%s%s is hidden by %s\n", fd.toPrettyChars(), Argument.argsTypesToChars(tf.parameters, tf.varargs), toChars()); + else + warning("%s is hidden by %s\n", fd.toPrettyChars(), toChars()); + } + s = rtlsym[RTLSYM_DHIDDENFUNC]; + break; + } + } + } + } + dtxoff(&dt, s, 0, TYnptr); + } + else + dtdword(&dt, 0); + } + + vtblsym.Sdt = dt; + vtblsym.Sclass = scclass; + vtblsym.Sfl = FLdata; + version (ELFOBJ) { + vtblsym.Sseg = Segment.CDATA; + } + version (MACHOBJ) { + vtblsym.Sseg = Segment.DATA; + } + outdata(vtblsym); + if (isExport()) + obj_export(vtblsym,0); + } + + void toDebug() + { + assert(false); + } + + /****************************************** + * Get offset of base class's vtbl[] initializer from start of csym. + * Returns ~0 if not this csym. + */ + uint baseVtblOffset(BaseClass bc) + { + uint csymoffset; + int i; + + //printf("ClassDeclaration.baseVtblOffset('%s', bc = %p)\n", toChars(), bc); + csymoffset = CLASSINFO_SIZE; + csymoffset += vtblInterfaces.dim * (4 * PTRSIZE); + + for (i = 0; i < vtblInterfaces.dim; i++) + { + BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; + + if (b == bc) + return csymoffset; + csymoffset += b.base.vtbl.dim * PTRSIZE; + } + + static if (true) { + // Put out the overriding interface vtbl[]s. + // This must be mirrored with ClassDeclaration.baseVtblOffset() + //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); + ClassDeclaration cd; + Array bvtbl; + + for (cd = this.baseClass; cd; cd = cd.baseClass) + { + for (int k = 0; k < cd.vtblInterfaces.dim; k++) + { + BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; + + if (bs.fillVtbl(this, null, 0)) + { + if (bc == bs) + { + //printf("\tcsymoffset = x%x\n", csymoffset); + return csymoffset; + } + csymoffset += bs.base.vtbl.dim * PTRSIZE; + } + } + } + } + version (INTERFACE_VIRTUAL) { + for (i = 0; i < vtblInterfaces.dim; i++) + { + BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; + ClassDeclaration cd; + + for (cd = this.baseClass; cd; cd = cd.baseClass) + { + //printf("\tbase class %s\n", cd.toChars()); + for (int k = 0; k < cd.vtblInterfaces.dim; k++) + { + BaseClass bs = cast(BaseClass)cd.vtblInterfaces.data[k]; + + if (bc == bs) + { + //printf("\tcsymoffset = x%x\n", csymoffset); + return csymoffset; + } + if (b.base == bs.base) + csymoffset += bs.base.vtbl.dim * PTRSIZE; + } + } + } + } + + return ~0; + } + + static private __gshared Classsym* scc; + + /************************************* + * Create the "ClassInfo" symbol + */ + override Symbol* toSymbol() + { + if (!csym) + { + Symbol* s; + + if (!scc) + scc = fake_classsym(Id.ClassInfo); + + s = toSymbolX("__Class", SC.SCextern, scc.Stype, "Z"); + s.Sfl = FL.FLextern; + s.Sflags |= SFL.SFLnodebug; + csym = s; + slist_add(s); + } + + return csym; + } + + /************************************* + * This is accessible via the ClassData, but since it is frequently + * needed directly (like for rtti comparisons), make it directly accessible. + */ + Symbol* toVtblSymbol() + { + if (!vtblsym) + { + if (!csym) + toSymbol(); + + TYPE* t = type_alloc(TYM.TYnptr | mTY.mTYconst); + t.Tnext = tsvoid; + t.Tnext.Tcount++; + t.Tmangle = mTYman.mTYman_d; + + Symbol* s = toSymbolX("__vtbl", SC.SCextern, t, "Z"); + s.Sflags |= SFL.SFLnodebug; + s.Sfl = FL.FLextern; + vtblsym = s; + slist_add(s); + } + return vtblsym; + } + + // Generate the data for the static initializer. + void toDt(dt_t **pdt) + { + //printf("ClassDeclaration.toDt(this = '%s')\n", toChars()); + + // Put in first two members, the vtbl[] and the monitor + dtxoff(pdt, toVtblSymbol(), 0, TYnptr); + dtdword(pdt, 0); // monitor + + // Put in the rest + toDt2(pdt, this); + + //printf("-ClassDeclaration.toDt(this = '%s')\n", toChars()); + } + + void toDt2(dt_t** pdt, ClassDeclaration cd) + { + uint offset; + uint i; + dt_t* dt; + uint csymoffset; + + version (LOG) { + printf("ClassDeclaration.toDt2(this = '%s', cd = '%s')\n", toChars(), cd.toChars()); + } + if (baseClass) + { + baseClass.toDt2(pdt, cd); + offset = baseClass.structsize; + } + else + { + offset = 8; + } + + // Note equivalence of this loop to struct's + for (i = 0; i < fields.dim; i++) + { + VarDeclaration v = cast(VarDeclaration)fields.data[i]; + Initializer init; + + //printf("\t\tv = '%s' v.offset = %2d, offset = %2d\n", v.toChars(), v.offset, offset); + dt = null; + init = v.init; + if (init) + { + //printf("\t\t%s has initializer %s\n", v.toChars(), init.toChars()); + ExpInitializer ei = init.isExpInitializer(); + Type tb = v.type.toBasetype(); + if (ei && tb.ty == Tsarray) + (cast(TypeSArray)tb).toDtElem(&dt, ei.exp); + else + dt = init.toDt(); + } + else if (v.offset >= offset) + { //printf("\t\tdefault initializer\n"); + v.type.toDt(&dt); + } + if (dt) + { + if (v.offset < offset) + error("duplicated union initialization for %s", v.toChars()); + else + { + if (offset < v.offset) + dtnzeros(pdt, v.offset - offset); + dtcat(pdt, dt); + offset = v.offset + cast(uint)v.type.size(); + } + } + } + + // Interface vptr initializations + toSymbol(); // define csym + + for (i = 0; i < vtblInterfaces.dim; i++) + { + BaseClass b = cast(BaseClass)vtblInterfaces.data[i]; + +/// version (1 || INTERFACE_VIRTUAL) { + for (ClassDeclaration cd2 = cd; 1; cd2 = cd2.baseClass) + { + assert(cd2); + csymoffset = cd2.baseVtblOffset(b); + if (csymoffset != ~0) + { + if (offset < b.offset) + dtnzeros(pdt, b.offset - offset); + dtxoff(pdt, cd2.toSymbol(), csymoffset, TYnptr); + break; + } + } +/// } else { +/// csymoffset = baseVtblOffset(b); +/// assert(csymoffset != ~0); +/// dtxoff(pdt, csym, csymoffset, TYnptr); +/// } + offset = b.offset + 4; + } + + if (offset < structsize) + dtnzeros(pdt, structsize - offset); + } + + Symbol* vtblsym; + + ///ClassDeclaration isClassDeclaration() { return cast(ClassDeclaration)this; } /// huh? + override ClassDeclaration isClassDeclaration() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ClassInfoDeclaration.d --- a/dmd/ClassInfoDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ClassInfoDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -28,23 +28,23 @@ storage_class = STC.STCstatic | STC.STCgshared; } - Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol) { assert(false); } - void semantic(Scope sc) + override void semantic(Scope sc) { assert(false); } - void emitComment(Scope sc) + override void emitComment(Scope sc) { assert(false); } - Symbol* toSymbol() + override Symbol* toSymbol() { return cd.toSymbol(); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/CmpExp.d --- a/dmd/CmpExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/CmpExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,13 +1,13 @@ -module dmd.CmpExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.backend.elem; -import dmd.InterState; -import dmd.Loc; -import dmd.TOK; -import dmd.Scope; -import dmd.IRState; +module dmd.CmpExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.backend.elem; +import dmd.InterState; +import dmd.Loc; +import dmd.TOK; +import dmd.Scope; +import dmd.IRState; import dmd.Type; import dmd.Id; import dmd.TY; @@ -26,16 +26,16 @@ import dmd.backend.RTLSYM; import dmd.backend.TYM; import dmd.backend.OPER; -import dmd.backend.rel; - +import dmd.backend.rel; + class CmpExp : BinExp { this(TOK op, Loc loc, Expression e1, Expression e2) - { + { super(loc, op, CmpExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; Type t1; @@ -113,7 +113,7 @@ return e; } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -130,27 +130,27 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - int isBit() + override int isBit() { assert(false); } - bool isCommutative() + override bool isCommutative() { return true; } - Identifier opId() + override Identifier opId() { return Id.cmp; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem *e; OPER eop; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ComExp.d --- a/dmd/ComExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ComExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,15 +1,15 @@ -module dmd.ComExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.backend.elem; -import dmd.UnaExp; -import dmd.InterState; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.ArrayTypes; +module dmd.ComExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.backend.elem; +import dmd.UnaExp; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.ArrayTypes; import dmd.TOK; import dmd.TY; @@ -17,8 +17,8 @@ import dmd.backend.OPER; import dmd.expression.Util; -import dmd.expression.Com; - +import dmd.expression.Com; + class ComExp : UnaExp { this(Loc loc, Expression e) @@ -26,7 +26,7 @@ super(loc, TOKtilde, ComExp.sizeof, e); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -46,7 +46,7 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -61,27 +61,27 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { assert(false); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { assert(false); } - Identifier opId() + override Identifier opId() { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem *e; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/CommaExp.d --- a/dmd/CommaExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/CommaExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -22,7 +22,7 @@ super(loc, TOK.TOKcomma, CommaExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { if (!type) { @@ -32,40 +32,40 @@ return this; } - void checkEscape() + override void checkEscape() { e2.checkEscape(); } - IntRange getIntRange() + override IntRange getIntRange() { assert(false); } version (DMDV2) { - int isLvalue() + override int isLvalue() { return e2.isLvalue(); } } - Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression e) { e2 = e2.toLvalue(sc, null); return this; } - Expression modifiableLvalue(Scope sc, Expression e) + override Expression modifiableLvalue(Scope sc, Expression e) { e2 = e2.modifiableLvalue(sc, e); return this; } - bool isBool(bool result) + override bool isBool(bool result) { return e2.isBool(result); } - bool checkSideEffect(int flag) + override bool checkSideEffect(int flag) { if (flag == 2) return e1.checkSideEffect(2) || e2.checkSideEffect(2); @@ -76,12 +76,12 @@ } } - MATCH implicitConvTo(Type t) + override MATCH implicitConvTo(Type t) { return e2.implicitConvTo(t); } - Expression castTo(Scope sc, Type t) + override Expression castTo(Scope sc, Type t) { Expression e2c = e2.castTo(sc, t); Expression e; @@ -99,7 +99,7 @@ return e; } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -118,12 +118,12 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { assert(e1 && e2); elem* eleft = e1.toElem(irs); @@ -133,4 +133,4 @@ el_setLoc(e, loc); return e; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/CompileDeclaration.d --- a/dmd/CompileDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/CompileDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -35,14 +35,14 @@ this.compiled = false; } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { //printf("CompileDeclaration.syntaxCopy('%s')\n", toChars()); CompileDeclaration sc = new CompileDeclaration(loc, exp.syntaxCopy()); return sc; } - bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) + override bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) { //printf("CompileDeclaration.addMember(sc = %p, memnum = %d)\n", sc, memnum); bool m = false; @@ -79,7 +79,7 @@ } } - void semantic(Scope sc) + override void semantic(Scope sc) { //printf("CompileDeclaration.semantic()\n"); @@ -92,7 +92,7 @@ AttribDeclaration.semantic(sc); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("mixin("); exp.toCBuffer(buf, hgs); diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/CompileExp.d --- a/dmd/CompileExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/CompileExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,56 +1,56 @@ -module dmd.CompileExp; - -import dmd.Expression; -import dmd.UnaExp; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.HdrGenState; -import dmd.TOK; -import dmd.PREC; -import dmd.WANT; -import dmd.StringExp; -import dmd.Type; -import dmd.Parser; - -import dmd.expression.Util; - -class CompileExp : UnaExp -{ - this(Loc loc, Expression e) - { - super(loc, TOK.TOKmixin, this.sizeof, e); - } - - Expression semantic(Scope sc) - { - version (LOGSEMANTIC) { - printf("CompileExp.semantic('%s')\n", toChars()); - } - UnaExp.semantic(sc); - e1 = resolveProperties(sc, e1); - e1 = e1.optimize(WANT.WANTvalue | WANT.WANTinterpret); - if (e1.op != TOK.TOKstring) - { error("argument to mixin must be a string, not (%s)", e1.toChars()); - type = Type.terror; - return this; - } - StringExp se = cast(StringExp)e1; - se = se.toUTF8(sc); - Parser p = new Parser(sc.module_, cast(ubyte*)se.string_, se.len, 0); - p.loc = loc; - p.nextToken(); - //printf("p.loc.linnum = %d\n", p.loc.linnum); - Expression e = p.parseExpression(); - if (p.token.value != TOK.TOKeof) - error("incomplete mixin expression (%s)", se.toChars()); - return e.semantic(sc); - } - - void toCBuffer(OutBuffer buf, HdrGenState* hgs) - { - buf.writestring("mixin("); - expToCBuffer(buf, hgs, e1, PREC.PREC_assign); - buf.writeByte(')'); - } -} +module dmd.CompileExp; + +import dmd.Expression; +import dmd.UnaExp; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.HdrGenState; +import dmd.TOK; +import dmd.PREC; +import dmd.WANT; +import dmd.StringExp; +import dmd.Type; +import dmd.Parser; + +import dmd.expression.Util; + +class CompileExp : UnaExp +{ + this(Loc loc, Expression e) + { + super(loc, TOK.TOKmixin, this.sizeof, e); + } + + override Expression semantic(Scope sc) + { + version (LOGSEMANTIC) { + printf("CompileExp.semantic('%s')\n", toChars()); + } + UnaExp.semantic(sc); + e1 = resolveProperties(sc, e1); + e1 = e1.optimize(WANT.WANTvalue | WANT.WANTinterpret); + if (e1.op != TOK.TOKstring) + { error("argument to mixin must be a string, not (%s)", e1.toChars()); + type = Type.terror; + return this; + } + StringExp se = cast(StringExp)e1; + se = se.toUTF8(sc); + Parser p = new Parser(sc.module_, cast(ubyte*)se.string_, se.len, 0); + p.loc = loc; + p.nextToken(); + //printf("p.loc.linnum = %d\n", p.loc.linnum); + Expression e = p.parseExpression(); + if (p.token.value != TOK.TOKeof) + error("incomplete mixin expression (%s)", se.toChars()); + return e.semantic(sc); + } + + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) + { + buf.writestring("mixin("); + expToCBuffer(buf, hgs, e1, PREC.PREC_assign); + buf.writeByte(')'); + } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/CompileStatement.d --- a/dmd/CompileStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/CompileStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -24,14 +24,14 @@ this.exp = exp; } - Statement syntaxCopy() + override Statement syntaxCopy() { Expression e = exp.syntaxCopy(); CompileStatement es = new CompileStatement(loc, e); return es; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("mixin("); exp.toCBuffer(buf, hgs); @@ -40,7 +40,7 @@ buf.writenl(); } - Statements flatten(Scope sc) + override Statements flatten(Scope sc) { //printf("CompileStatement::flatten() %s\n", exp->toChars()); exp = exp.semantic(sc); @@ -65,7 +65,7 @@ return a; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { //printf("CompileStatement::semantic() %s\n", exp->toChars()); Statements a = flatten(sc); diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ComplexExp.d --- a/dmd/ComplexExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ComplexExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,43 +1,43 @@ -module dmd.ComplexExp; - -import dmd.Expression; -import dmd.InterState; -import dmd.Type; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.HdrGenState; +module dmd.ComplexExp; + +import dmd.Expression; +import dmd.InterState; +import dmd.Type; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.HdrGenState; import dmd.Type; import dmd.TOK; import dmd.TY; import dmd.Port; import dmd.Complex; - -import dmd.backend.dt_t; + +import dmd.backend.dt_t; import dmd.backend.elem; import dmd.backend.Util; import dmd.backend.TYM; import dmd.backend.mTY; - + class ComplexExp : Expression { Complex!(real) value; this(Loc loc, Complex!(real) value, Type type) - { + { super(loc, TOK.TOKcomplex80, ComplexExp.sizeof); this.value = value; this.type = type; //printf("ComplexExp.ComplexExp(%s)\n", toChars()); } - bool equals(Object o) + override bool equals(Object o) { assert(false); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { if (!type) type = Type.tcomplex80; @@ -46,42 +46,42 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - string toChars() + override string toChars() { assert(false); } - ulong toInteger() + override ulong toInteger() { return cast(ulong) toReal(); } - ulong toUInteger() + override ulong toUInteger() { return cast(long) toReal(); } - real toReal() + override real toReal() { return value.re; } - real toImaginary() + override real toImaginary() { return value.im; } - Complex!(real) toComplex() + override Complex!(real) toComplex() { return value; } - Expression castTo(Scope sc, Type t) + override Expression castTo(Scope sc, Type t) { Expression e = this; if (type != t) @@ -97,22 +97,22 @@ return e; } - int isConst() + override int isConst() { return 1; } - bool isBool(bool result) + override bool isBool(bool result) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - void toMangleBuffer(OutBuffer buf) + override void toMangleBuffer(OutBuffer buf) { assert(false); } @@ -121,7 +121,7 @@ OutBuffer hexp; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { eve c; tym_t ty; @@ -197,7 +197,7 @@ static private char[6] zeropad; - dt_t** toDt(dt_t** pdt) + override dt_t** toDt(dt_t** pdt) { //printf("ComplexExp.toDt() '%s'\n", toChars()); float fvalue; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/CompoundDeclarationStatement.d --- a/dmd/CompoundDeclarationStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/CompoundDeclarationStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -15,7 +15,7 @@ ///statements = s; } - Statement syntaxCopy() + override Statement syntaxCopy() { Statements a = new Statements(); a.setDim(statements.dim); @@ -30,8 +30,8 @@ return cs; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/CompoundStatement.d --- a/dmd/CompoundStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/CompoundStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -46,7 +46,7 @@ statements.push(cast(void*)s2); } - Statement syntaxCopy() + override Statement syntaxCopy() { Statements a = new Statements(); a.setDim(statements.dim); @@ -62,7 +62,7 @@ return new CompoundStatement(loc, a); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } @@ -70,7 +70,7 @@ static int indent = 0; static int depth = 0; - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { Statement s; @@ -201,12 +201,12 @@ return this; } - bool usesEH() + override bool usesEH() { assert(false); } - BE blockExit() + override BE blockExit() { //printf("CompoundStatement::blockExit(%p) %d\n", this, statements->dim); BE result = BE.BEfallthru; @@ -230,12 +230,12 @@ return result; } - bool comeFrom() + override bool comeFrom() { assert(false); } - bool isEmpty() + override bool isEmpty() { for (int i = 0; i < statements.dim; i++) { @@ -246,12 +246,12 @@ return true; } - Statements flatten(Scope sc) + override Statements flatten(Scope sc) { return statements; } - ReturnStatement isReturnStatement() + override ReturnStatement isReturnStatement() { ReturnStatement rs = null; @@ -268,7 +268,7 @@ return rs; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { Expression e = null; @@ -297,7 +297,7 @@ return e; } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { int cost = 0; @@ -315,7 +315,7 @@ return cost; } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { Expression e = null; @@ -347,7 +347,7 @@ return e; } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { for (size_t i = 0; i < statements.dim; i++) { @@ -359,7 +359,7 @@ return this; } - void toIR(IRState* irs) + override void toIR(IRState* irs) { if (statements) { @@ -375,5 +375,5 @@ } } - CompoundStatement isCompoundStatement() { return this; } -} \ No newline at end of file + override CompoundStatement isCompoundStatement() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/CondExp.d --- a/dmd/CondExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/CondExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -38,12 +38,12 @@ this.econd = econd; } - Expression syntaxCopy() + override Expression syntaxCopy() { return new CondExp(loc, econd.syntaxCopy(), e1.syntaxCopy(), e2.syntaxCopy()); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Type t1; Type t2; @@ -138,7 +138,7 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -157,38 +157,38 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void checkEscape() + override void checkEscape() { e1.checkEscape(); e2.checkEscape(); } - int isLvalue() + override int isLvalue() { assert(false); } - Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression e) { assert(false); } - Expression modifiableLvalue(Scope sc, Expression e) + override Expression modifiableLvalue(Scope sc, Expression e) { assert(false); } - Expression checkToBoolean() + override Expression checkToBoolean() { assert(false); } - bool checkSideEffect(int flag) + override bool checkSideEffect(int flag) { if (flag == 2) { @@ -202,7 +202,7 @@ } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { expToCBuffer(buf, hgs, econd, PREC_oror); buf.writestring(" ? "); @@ -211,7 +211,7 @@ expToCBuffer(buf, hgs, e2, PREC_cond); } - MATCH implicitConvTo(Type t) + override MATCH implicitConvTo(Type t) { MATCH m1 = e1.implicitConvTo(t); MATCH m2 = e2.implicitConvTo(t); @@ -221,7 +221,7 @@ return (m1 < m2) ? m1 : m2; } - Expression castTo(Scope sc, Type t) + override Expression castTo(Scope sc, Type t) { Expression e = this; @@ -238,22 +238,22 @@ return e; } - void scanForNestedRef(Scope sc) + override void scanForNestedRef(Scope sc) { assert(false); } - bool canThrow() + override bool canThrow() { return econd.canThrow() || e1.canThrow() || e2.canThrow(); } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { return 1 + e1.inlineCost(ics) + e2.inlineCost(ics) + econd.inlineCost(ics); } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { CondExp ce = cast(CondExp)copy(); @@ -263,7 +263,7 @@ return ce; } - Expression inlineScan(InlineScanState* iss) + override Expression inlineScan(InlineScanState* iss) { econd = econd.inlineScan(iss); e1 = e1.inlineScan(iss); @@ -271,7 +271,7 @@ return this; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* eleft; elem* eright; @@ -294,4 +294,4 @@ el_setLoc(e, loc); return e; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ConditionalDeclaration.d --- a/dmd/ConditionalDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ConditionalDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -22,7 +22,7 @@ this.elsedecl = elsedecl; } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { ConditionalDeclaration dd; @@ -33,7 +33,7 @@ return dd; } - bool oneMember(Dsymbol* ps) + override bool oneMember(Dsymbol* ps) { //printf("ConditionalDeclaration.oneMember(), inc = %d\n", condition.inc); if (condition.inc) @@ -45,7 +45,7 @@ return true; } - void emitComment(Scope sc) + override void emitComment(Scope sc) { //printf("ConditionalDeclaration.emitComment(sc = %p)\n", sc); if (condition.inc) @@ -67,14 +67,14 @@ // Decide if 'then' or 'else' code should be included - Array include(Scope sc, ScopeDsymbol sd) + override Array include(Scope sc, ScopeDsymbol sd) { //printf("ConditionalDeclaration.include()\n"); assert(condition); return condition.include(sc, sd) ? decl : elsedecl; } - void addComment(ubyte* comment) + override void addComment(ubyte* comment) { /* Because addComment is called by the parser, if we called * include() it would define a version before it was used. @@ -102,7 +102,7 @@ } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { condition.toCBuffer(buf, hgs); if (decl || elsedecl) diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ConditionalStatement.d --- a/dmd/ConditionalStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ConditionalStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -23,7 +23,7 @@ this.elsebody = elsebody; } - Statement syntaxCopy() + override Statement syntaxCopy() { Statement e = null; if (elsebody) @@ -32,7 +32,7 @@ return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { //printf("ConditionalStatement.semantic()\n"); @@ -52,7 +52,7 @@ } } - Statements flatten(Scope sc) + override Statements flatten(Scope sc) { Statement s; @@ -67,18 +67,18 @@ return a; } - bool usesEH() + override bool usesEH() { assert(false); } - BE blockExit() + override BE blockExit() { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ContinueStatement.d --- a/dmd/ContinueStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ContinueStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -30,13 +30,13 @@ this.ident = ident; } - Statement syntaxCopy() + override Statement syntaxCopy() { ContinueStatement s = new ContinueStatement(loc, ident); return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { //printf("ContinueStatement.semantic() %p\n", this); if (ident) @@ -106,17 +106,17 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - BE blockExit() + override BE blockExit() { return ident ? BE.BEgoto : BE.BEcontinue; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("continue"); if (ident) @@ -128,7 +128,7 @@ buf.writenl(); } - void toIR(IRState* irs) + override void toIR(IRState* irs) { block* bcont; block* b; @@ -151,4 +151,4 @@ list_append(&b.Bsucc, bcont); block_next(blx, BCgoto, null); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/CtorDeclaration.d --- a/dmd/CtorDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/CtorDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -35,7 +35,7 @@ //printf("CtorDeclaration(loc = %s) %s\n", loc.toChars(), toChars()); } - Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol) { CtorDeclaration f = new CtorDeclaration(loc, endloc, null, varargs); @@ -49,7 +49,7 @@ return f; } - void semantic(Scope sc) + override void semantic(Scope sc) { AggregateDeclaration ad; Type tret; @@ -110,40 +110,40 @@ } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - string kind() + override string kind() { return "constructor"; } - string toChars() + override string toChars() { return "this"; } - bool isVirtual() + override bool isVirtual() { return false; } - bool addPreInvariant() + override bool addPreInvariant() { return false; } - bool addPostInvariant() + override bool addPostInvariant() { return (isThis() && vthis && global.params.useInvariants); } - void toDocBuffer(OutBuffer buf) + override void toDocBuffer(OutBuffer buf) { assert(false); } - CtorDeclaration isCtorDeclaration() { return this; } -} \ No newline at end of file + override CtorDeclaration isCtorDeclaration() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DVCondition.d --- a/dmd/DVCondition.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DVCondition.d Sat Aug 28 16:19:48 2010 +0200 @@ -19,8 +19,8 @@ this.ident = ident; } - Condition syntaxCopy() + override Condition syntaxCopy() { return this; // don't need to copy } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DebugCondition.d --- a/dmd/DebugCondition.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DebugCondition.d Sat Aug 28 16:19:48 2010 +0200 @@ -35,7 +35,7 @@ super(mod, level, ident); } - bool include(Scope sc, ScopeDsymbol s) + override bool include(Scope sc, ScopeDsymbol s) { //printf("DebugCondition::include() level = %d, debuglevel = %d\n", level, global.params.debuglevel); if (inc == 0) @@ -63,8 +63,8 @@ return (inc == 1); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DebugSymbol.d --- a/dmd/DebugSymbol.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DebugSymbol.d Sat Aug 28 16:19:48 2010 +0200 @@ -22,28 +22,28 @@ assert(false); } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { assert(false); } - bool addMember(Scope sc, ScopeDsymbol s, bool memnum) + override bool addMember(Scope sc, ScopeDsymbol s, bool memnum) { assert(false); } - void semantic(Scope sc) + override void semantic(Scope sc) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - string kind() + override string kind() { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/Declaration.d --- a/dmd/Declaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/Declaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -88,16 +88,16 @@ super(id); } - void semantic(Scope sc) + override void semantic(Scope sc) { } - string kind() + override string kind() { assert(false); } - uint size(Loc loc) + override uint size(Loc loc) { assert(false); } @@ -168,17 +168,17 @@ } } - void emitComment(Scope sc) + override void emitComment(Scope sc) { assert(false); } - void toDocBuffer(OutBuffer buf) + override void toDocBuffer(OutBuffer buf) { assert(false); } - string mangle() + override string mangle() /+out (result) { try @@ -292,7 +292,7 @@ int isParameter() { return storage_class & STC.STCparameter; } - bool isDeprecated() { return (storage_class & STC.STCdeprecated) != 0; } + override bool isDeprecated() { return (storage_class & STC.STCdeprecated) != 0; } int isOverride() { return storage_class & STC.STCoverride; } @@ -302,10 +302,10 @@ int isRef() { return storage_class & STC.STCref; } - PROT prot() + override PROT prot() { return protection; } - Declaration isDeclaration() { return this; } + override Declaration isDeclaration() { return this; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DeclarationExp.d --- a/dmd/DeclarationExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DeclarationExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,336 +1,336 @@ -module dmd.DeclarationExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.InterState; -import dmd.ExpInitializer; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.InlineCostState; -import dmd.IRState; -import dmd.InlineDoState; -import dmd.HdrGenState; -import dmd.TupleDeclaration; -import dmd.InlineScanState; -import dmd.Dsymbol; -import dmd.AttribDeclaration; -import dmd.VarDeclaration; -import dmd.Global; -import dmd.TOK; -import dmd.VoidInitializer; -import dmd.GlobalExpressions; -import dmd.Type; -import dmd.codegen.Util; - -// Declaration of a symbol - +module dmd.DeclarationExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.InterState; +import dmd.ExpInitializer; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.InlineCostState; +import dmd.IRState; +import dmd.InlineDoState; +import dmd.HdrGenState; +import dmd.TupleDeclaration; +import dmd.InlineScanState; +import dmd.Dsymbol; +import dmd.AttribDeclaration; +import dmd.VarDeclaration; +import dmd.Global; +import dmd.TOK; +import dmd.VoidInitializer; +import dmd.GlobalExpressions; +import dmd.Type; +import dmd.codegen.Util; + +// Declaration of a symbol + class DeclarationExp : Expression { Dsymbol declaration; this(Loc loc, Dsymbol declaration) { - super(loc, TOK.TOKdeclaration, DeclarationExp.sizeof); + super(loc, TOK.TOKdeclaration, DeclarationExp.sizeof); this.declaration = declaration; } - Expression syntaxCopy() + override Expression syntaxCopy() { return new DeclarationExp(loc, declaration.syntaxCopy(null)); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { - if (type) - return this; - -version (LOGSEMANTIC) { - printf("DeclarationExp.semantic() %s\n", toChars()); -} - - /* This is here to support extern(linkage) declaration, - * where the extern(linkage) winds up being an AttribDeclaration - * wrapper. - */ - Dsymbol s = declaration; - - AttribDeclaration ad = declaration.isAttribDeclaration(); - if (ad) - { - if (ad.decl && ad.decl.dim == 1) - s = cast(Dsymbol)ad.decl.data[0]; - } - - if (s.isVarDeclaration()) - { - // Do semantic() on initializer first, so: - // int a = a; - // will be illegal. - declaration.semantic(sc); - s.parent = sc.parent; - } - - //printf("inserting '%s' %p into sc = %p\n", s.toChars(), s, sc); - // Insert into both local scope and function scope. - // Must be unique in both. - if (s.ident) - { - if (!sc.insert(s)) - error("declaration %s is already defined", s.toPrettyChars()); - else if (sc.func) - { - VarDeclaration v = s.isVarDeclaration(); - if (s.isFuncDeclaration() && !sc.func.localsymtab.insert(s)) - error("declaration %s is already defined in another scope in %s", s.toPrettyChars(), sc.func.toChars()); - else if (!global.params.useDeprecated) - { - // Disallow shadowing - - for (Scope scx = sc.enclosing; scx && scx.func is sc.func; scx = scx.enclosing) - { - Dsymbol s2; - - if (scx.scopesym && scx.scopesym.symtab && (s2 = scx.scopesym.symtab.lookup(s.ident)) !is null && s !is s2) - { - error("shadowing declaration %s is deprecated", s.toPrettyChars()); - } - } - } - } - } - if (!s.isVarDeclaration()) - { - declaration.semantic(sc); - s.parent = sc.parent; - } - if (!global.errors) - { - declaration.semantic2(sc); - if (!global.errors) - { - declaration.semantic3(sc); - - if (!global.errors && global.params.useInline) - declaration.inlineScan(); - } - } - - type = Type.tvoid; + if (type) + return this; + +version (LOGSEMANTIC) { + printf("DeclarationExp.semantic() %s\n", toChars()); +} + + /* This is here to support extern(linkage) declaration, + * where the extern(linkage) winds up being an AttribDeclaration + * wrapper. + */ + Dsymbol s = declaration; + + AttribDeclaration ad = declaration.isAttribDeclaration(); + if (ad) + { + if (ad.decl && ad.decl.dim == 1) + s = cast(Dsymbol)ad.decl.data[0]; + } + + if (s.isVarDeclaration()) + { + // Do semantic() on initializer first, so: + // int a = a; + // will be illegal. + declaration.semantic(sc); + s.parent = sc.parent; + } + + //printf("inserting '%s' %p into sc = %p\n", s.toChars(), s, sc); + // Insert into both local scope and function scope. + // Must be unique in both. + if (s.ident) + { + if (!sc.insert(s)) + error("declaration %s is already defined", s.toPrettyChars()); + else if (sc.func) + { + VarDeclaration v = s.isVarDeclaration(); + if (s.isFuncDeclaration() && !sc.func.localsymtab.insert(s)) + error("declaration %s is already defined in another scope in %s", s.toPrettyChars(), sc.func.toChars()); + else if (!global.params.useDeprecated) + { + // Disallow shadowing + + for (Scope scx = sc.enclosing; scx && scx.func is sc.func; scx = scx.enclosing) + { + Dsymbol s2; + + if (scx.scopesym && scx.scopesym.symtab && (s2 = scx.scopesym.symtab.lookup(s.ident)) !is null && s !is s2) + { + error("shadowing declaration %s is deprecated", s.toPrettyChars()); + } + } + } + } + } + if (!s.isVarDeclaration()) + { + declaration.semantic(sc); + s.parent = sc.parent; + } + if (!global.errors) + { + declaration.semantic2(sc); + if (!global.errors) + { + declaration.semantic3(sc); + + if (!global.errors && global.params.useInline) + declaration.inlineScan(); + } + } + + type = Type.tvoid; return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { -version (LOG) { - printf("DeclarationExp.interpret() %s\n", toChars()); -} - Expression e; - VarDeclaration v = declaration.isVarDeclaration(); - if (v) - { - Dsymbol s = v.toAlias(); - if (s == v && !v.isStatic() && v.init) - { - ExpInitializer ie = v.init.isExpInitializer(); - if (ie) - e = ie.exp.interpret(istate); - else if (v.init.isVoidInitializer()) - e = null; - } -///version (DMDV2) { - else if (s == v && (v.isConst() || v.isInvariant()) && v.init) -///} else { -/// else if (s == v && v.isConst() && v.init) -///} - { - e = v.init.toExpression(); - if (!e) - e = EXP_CANT_INTERPRET; - else if (!e.type) - e.type = v.type; - } - } - else if (declaration.isAttribDeclaration() || - declaration.isTemplateMixin() || - declaration.isTupleDeclaration()) - { - // These can be made to work, too lazy now - error("Declaration %s is not yet implemented in CTFE", toChars()); - - e = EXP_CANT_INTERPRET; - } - else - { // Others should not contain executable code, so are trivial to evaluate - e = null; - } -version (LOG) { - printf("-DeclarationExp.interpret(%.*s): %p\n", toChars(), e); -} +version (LOG) { + printf("DeclarationExp.interpret() %s\n", toChars()); +} + Expression e; + VarDeclaration v = declaration.isVarDeclaration(); + if (v) + { + Dsymbol s = v.toAlias(); + if (s == v && !v.isStatic() && v.init) + { + ExpInitializer ie = v.init.isExpInitializer(); + if (ie) + e = ie.exp.interpret(istate); + else if (v.init.isVoidInitializer()) + e = null; + } +///version (DMDV2) { + else if (s == v && (v.isConst() || v.isInvariant()) && v.init) +///} else { +/// else if (s == v && v.isConst() && v.init) +///} + { + e = v.init.toExpression(); + if (!e) + e = EXP_CANT_INTERPRET; + else if (!e.type) + e.type = v.type; + } + } + else if (declaration.isAttribDeclaration() || + declaration.isTemplateMixin() || + declaration.isTupleDeclaration()) + { + // These can be made to work, too lazy now + error("Declaration %s is not yet implemented in CTFE", toChars()); + + e = EXP_CANT_INTERPRET; + } + else + { // Others should not contain executable code, so are trivial to evaluate + e = null; + } +version (LOG) { + printf("-DeclarationExp.interpret(%.*s): %p\n", toChars(), e); +} return e; } - bool checkSideEffect(int flag) + override bool checkSideEffect(int flag) { return true; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { declaration.toCBuffer(buf, hgs); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { - //printf("DeclarationExp::toElem() %s\n", toChars()); - elem* e = Dsymbol_toElem(declaration, irs); + //printf("DeclarationExp::toElem() %s\n", toChars()); + elem* e = Dsymbol_toElem(declaration, irs); return e; } - void scanForNestedRef(Scope sc) + override void scanForNestedRef(Scope sc) { assert(false); } - + version (DMDV2) { - bool canThrow() + override bool canThrow() { - VarDeclaration v = declaration.isVarDeclaration(); - if (v && v.init) - { - ExpInitializer ie = v.init.isExpInitializer(); - return ie && ie.exp.canThrow(); - } - + VarDeclaration v = declaration.isVarDeclaration(); + if (v && v.init) + { + ExpInitializer ie = v.init.isExpInitializer(); + return ie && ie.exp.canThrow(); + } + return false; } } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { - int cost = 0; - VarDeclaration vd; - - //printf("DeclarationExp.inlineCost()\n"); - vd = declaration.isVarDeclaration(); - if (vd) - { - TupleDeclaration td = vd.toAlias().isTupleDeclaration(); - if (td) - { - static if (true) { - return COST_MAX; // finish DeclarationExp.doInline - } else { - for (size_t i = 0; i < td.objects.dim; i++) - { - Object o = cast(Object)td.objects.data[i]; - Expression eo = cast(Expression)o; - if (eo is null) - return COST_MAX; - - if (eo.op != TOKdsymbol) - return COST_MAX; - } - - return td.objects.dim; - } - } - if (!ics.hdrscan && vd.isDataseg()) - return COST_MAX; - - cost += 1; - - // Scan initializer (vd.init) - if (vd.init) - { - ExpInitializer ie = vd.init.isExpInitializer(); - - if (ie) - { - cost += ie.exp.inlineCost(ics); - } - } - } - - // These can contain functions, which when copied, get output twice. - if (declaration.isStructDeclaration() || - declaration.isClassDeclaration() || - declaration.isFuncDeclaration() || - declaration.isTypedefDeclaration() || - declaration.isTemplateMixin() - ) - return COST_MAX; - - //printf("DeclarationExp.inlineCost('%s')\n", toChars()); + int cost = 0; + VarDeclaration vd; + + //printf("DeclarationExp.inlineCost()\n"); + vd = declaration.isVarDeclaration(); + if (vd) + { + TupleDeclaration td = vd.toAlias().isTupleDeclaration(); + if (td) + { + static if (true) { + return COST_MAX; // finish DeclarationExp.doInline + } else { + for (size_t i = 0; i < td.objects.dim; i++) + { + Object o = cast(Object)td.objects.data[i]; + Expression eo = cast(Expression)o; + if (eo is null) + return COST_MAX; + + if (eo.op != TOKdsymbol) + return COST_MAX; + } + + return td.objects.dim; + } + } + if (!ics.hdrscan && vd.isDataseg()) + return COST_MAX; + + cost += 1; + + // Scan initializer (vd.init) + if (vd.init) + { + ExpInitializer ie = vd.init.isExpInitializer(); + + if (ie) + { + cost += ie.exp.inlineCost(ics); + } + } + } + + // These can contain functions, which when copied, get output twice. + if (declaration.isStructDeclaration() || + declaration.isClassDeclaration() || + declaration.isFuncDeclaration() || + declaration.isTypedefDeclaration() || + declaration.isTemplateMixin() + ) + return COST_MAX; + + //printf("DeclarationExp.inlineCost('%s')\n", toChars()); return cost; } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { - DeclarationExp de = cast(DeclarationExp)copy(); - VarDeclaration vd; - - //printf("DeclarationExp.doInline(%s)\n", toChars()); - vd = declaration.isVarDeclaration(); - if (vd) - { - static if (false) { - // Need to figure this out before inlining can work for tuples - TupleDeclaration td = vd.toAlias().isTupleDeclaration(); - if (td) - { - for (size_t i = 0; i < td.objects.dim; i++) - { - DsymbolExp se = cast(DsymbolExp)td.objects.data[i]; - assert(se.op == TOKdsymbol); - se.s; - } - return st.objects.dim; - } - } - if (vd.isStatic()) - { - ; - } - else - { - VarDeclaration vto = new VarDeclaration(vd.loc, vd.type, vd.ident, vd.init); - - ///*vto = *vd; - memcpy(cast(void*)vto, cast(void*)vd, VarDeclaration.classinfo.init.length); - - vto.parent = ids.parent; - vto.csym = null; - vto.isym = null; - - ids.from.push(cast(void*)vd); - ids.to.push(cast(void*)vto); - - if (vd.init) - { - if (vd.init.isVoidInitializer()) - { - vto.init = new VoidInitializer(vd.init.loc); - } - else - { - Expression e = vd.init.toExpression(); - assert(e); - vto.init = new ExpInitializer(e.loc, e.doInline(ids)); - } - } - de.declaration = vto; - } - } - /* This needs work, like DeclarationExp.toElem(), if we are - * to handle TemplateMixin's. For now, we just don't inline them. - */ + DeclarationExp de = cast(DeclarationExp)copy(); + VarDeclaration vd; + + //printf("DeclarationExp.doInline(%s)\n", toChars()); + vd = declaration.isVarDeclaration(); + if (vd) + { + static if (false) { + // Need to figure this out before inlining can work for tuples + TupleDeclaration td = vd.toAlias().isTupleDeclaration(); + if (td) + { + for (size_t i = 0; i < td.objects.dim; i++) + { + DsymbolExp se = cast(DsymbolExp)td.objects.data[i]; + assert(se.op == TOKdsymbol); + se.s; + } + return st.objects.dim; + } + } + if (vd.isStatic()) + { + ; + } + else + { + VarDeclaration vto = new VarDeclaration(vd.loc, vd.type, vd.ident, vd.init); + + ///*vto = *vd; + memcpy(cast(void*)vto, cast(void*)vd, VarDeclaration.classinfo.init.length); + + vto.parent = ids.parent; + vto.csym = null; + vto.isym = null; + + ids.from.push(cast(void*)vd); + ids.to.push(cast(void*)vto); + + if (vd.init) + { + if (vd.init.isVoidInitializer()) + { + vto.init = new VoidInitializer(vd.init.loc); + } + else + { + Expression e = vd.init.toExpression(); + assert(e); + vto.init = new ExpInitializer(e.loc, e.doInline(ids)); + } + } + de.declaration = vto; + } + } + /* This needs work, like DeclarationExp.toElem(), if we are + * to handle TemplateMixin's. For now, we just don't inline them. + */ return de; } - Expression inlineScan(InlineScanState* iss) + override Expression inlineScan(InlineScanState* iss) { - //printf("DeclarationExp.inlineScan()\n"); - scanVar(declaration, iss); + //printf("DeclarationExp.inlineScan()\n"); + scanVar(declaration, iss); return this; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DeclarationStatement.d --- a/dmd/DeclarationStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DeclarationStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -27,18 +27,18 @@ super(loc, exp); } - Statement syntaxCopy() + override Statement syntaxCopy() { DeclarationStatement ds = new DeclarationStatement(loc, exp.syntaxCopy()); return ds; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { exp.toCBuffer(buf, hgs); } - void scopeCode(Scope sc, Statement* sentry, Statement* sexception, Statement* sfinally) + override void scopeCode(Scope sc, Statement* sentry, Statement* sexception, Statement* sfinally) { //printf("DeclarationStatement.scopeCode()\n"); //print(); @@ -88,5 +88,5 @@ } } - DeclarationStatement isDeclarationStatement() { return this; } -} \ No newline at end of file + override DeclarationStatement isDeclarationStatement() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DefaultInitExp.d --- a/dmd/DefaultInitExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DefaultInitExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,27 +1,27 @@ -module dmd.DefaultInitExp; - -import dmd.Expression; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.HdrGenState; -import dmd.TOK; -import dmd.Token; - -class DefaultInitExp : Expression -{ - TOK subop; - - this(Loc loc, TOK subop, int size) - { - super(loc, TOKdefault, size); - this.subop = subop; - } - - abstract Expression resolve(Loc loc, Scope sc); - - void toCBuffer(OutBuffer buf, HdrGenState* hgs) - { - buf.writestring(Token.toChars(subop)); - } -} +module dmd.DefaultInitExp; + +import dmd.Expression; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.HdrGenState; +import dmd.TOK; +import dmd.Token; + +class DefaultInitExp : Expression +{ + TOK subop; + + this(Loc loc, TOK subop, int size) + { + super(loc, TOKdefault, size); + this.subop = subop; + } + + abstract Expression resolve(Loc loc, Scope sc); + + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) + { + buf.writestring(Token.toChars(subop)); + } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DefaultStatement.d --- a/dmd/DefaultStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DefaultStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -30,13 +30,13 @@ this.statement = s; } - Statement syntaxCopy() + override Statement syntaxCopy() { DefaultStatement s = new DefaultStatement(loc, statement.syntaxCopy()); return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { //printf("DefaultStatement.semantic()\n"); if (sc.sw) @@ -59,40 +59,40 @@ return this; } - bool usesEH() + override bool usesEH() { return statement.usesEH(); } - BE blockExit() + override BE blockExit() { return statement.blockExit(); } - bool comeFrom() + override bool comeFrom() { return true; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("default:\n"); statement.toCBuffer(buf, hgs); } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { if (statement) statement = statement.inlineScan(iss); return this; } - void toIR(IRState* irs) + override void toIR(IRState* irs) { Blockx* blx = irs.blx; block* bcase = blx.curblock; @@ -105,4 +105,4 @@ if (statement) statement.toIR(irs); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DelegateExp.d --- a/dmd/DelegateExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DelegateExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,21 +1,21 @@ -module dmd.DelegateExp; - -import dmd.Expression; +module dmd.DelegateExp; + +import dmd.Expression; import dmd.backend.elem; -import dmd.AggregateDeclaration; +import dmd.AggregateDeclaration; import dmd.UnaExp; -import dmd.TypeDelegate; -import dmd.FuncDeclaration; -import dmd.MATCH; -import dmd.Type; -import dmd.OutBuffer; +import dmd.TypeDelegate; +import dmd.FuncDeclaration; +import dmd.MATCH; +import dmd.Type; +import dmd.OutBuffer; import dmd.Loc; -import dmd.TY; -import dmd.Scope; -import dmd.InlineCostState; +import dmd.TY; +import dmd.Scope; +import dmd.InlineCostState; import dmd.IRState; -import dmd.PREC; -import dmd.HdrGenState; +import dmd.PREC; +import dmd.HdrGenState; import dmd.TOK; import dmd.expression.Util; @@ -23,21 +23,21 @@ import dmd.backend.Util; import dmd.backend.Symbol; import dmd.backend.TYM; -import dmd.backend.OPER; - +import dmd.backend.OPER; + class DelegateExp : UnaExp { FuncDeclaration func; int hasOverloads; this(Loc loc, Expression e, FuncDeclaration f, int hasOverloads = 0) - { + { super(loc, TOK.TOKdelegate, DelegateExp.sizeof, e); this.func = f; this.hasOverloads = hasOverloads; } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { version (LOGSEMANTIC) { printf("DelegateExp.semantic('%s')\n", toChars()); @@ -54,7 +54,7 @@ return this; } - MATCH implicitConvTo(Type t) + override MATCH implicitConvTo(Type t) { static if (false) { printf("DelegateExp.implicitConvTo(this=%s, type=%s, t=%s)\n", @@ -80,7 +80,7 @@ return result; } - Expression castTo(Scope sc, Type t) + override Expression castTo(Scope sc, Type t) { static if (false) { printf("DelegateExp.castTo(this=%s, type=%s, t=%s)\n", @@ -131,7 +131,7 @@ return e; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writeByte('&'); if (!func.isNested()) @@ -142,17 +142,17 @@ buf.writestring(func.toChars()); } - void dump(int indent) + override void dump(int indent) { assert(false); } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e; elem* ethis; @@ -215,4 +215,4 @@ return e; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DeleteDeclaration.d --- a/dmd/DeleteDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DeleteDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -19,42 +19,42 @@ super(loc, endloc, null, STC.init, null); } - Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol) { assert(false); } - void semantic(Scope sc) + override void semantic(Scope sc) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - string kind() + override string kind() { assert(false); } - bool isDelete() + override bool isDelete() { assert(false); } - bool isVirtual() + override bool isVirtual() { assert(false); } - bool addPreInvariant() + override bool addPreInvariant() { assert(false); } - bool addPostInvariant() + override bool addPostInvariant() { assert(false); } @@ -62,4 +62,4 @@ version (_DH) { DeleteDeclaration isDeleteDeclaration() { return this; } } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DeleteExp.d --- a/dmd/DeleteExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DeleteExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,12 +1,12 @@ -module dmd.DeleteExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.UnaExp; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; +module dmd.DeleteExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.UnaExp; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; import dmd.HdrGenState; import dmd.Type; import dmd.IndexExp; @@ -25,7 +25,7 @@ import dmd.TypePointer; import dmd.ClassDeclaration; import dmd.TypeClass; -import dmd.TY; +import dmd.TY; import dmd.TOK; import dmd.TypeAArray; import dmd.TypeSArray; @@ -36,8 +36,8 @@ import dmd.backend.RTLSYM; import dmd.backend.mTY; import dmd.backend.Symbol; -import dmd.backend.TYM; - +import dmd.backend.TYM; + class DeleteExp : UnaExp { this(Loc loc, Expression e) @@ -45,7 +45,7 @@ super(loc, TOK.TOKdelete, DeleteExp.sizeof, e); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Type tb; @@ -154,22 +154,22 @@ return this; } - Expression checkToBoolean() + override Expression checkToBoolean() { assert(false); } - bool checkSideEffect(int flag) + override bool checkSideEffect(int flag) { return true; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e; int rtl; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DivAssignExp.d --- a/dmd/DivAssignExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DivAssignExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -29,7 +29,7 @@ super(loc, TOK.TOKdivass, DivAssignExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -91,28 +91,28 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { AssignExp_buildArrayIdent(buf, arguments, "Div"); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { assert(false); } - Identifier opId() /* For operator overloading */ + override Identifier opId() /* For operator overloading */ { return Id.divass; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs,OPdivass); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DivExp.d --- a/dmd/DivExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DivExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,26 +1,26 @@ -module dmd.DivExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.backend.elem; -import dmd.InterState; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IntRange; -import dmd.IRState; -import dmd.ArrayTypes; -import dmd.BinExp; -import dmd.TOK; -import dmd.Type; -import dmd.NegExp; -import dmd.TY; -import dmd.Id; - -import dmd.expression.Div; -import dmd.backend.OPER; -import dmd.backend.Util; - +module dmd.DivExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.backend.elem; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IntRange; +import dmd.IRState; +import dmd.ArrayTypes; +import dmd.BinExp; +import dmd.TOK; +import dmd.Type; +import dmd.NegExp; +import dmd.TY; +import dmd.Id; + +import dmd.expression.Div; +import dmd.backend.OPER; +import dmd.backend.Util; + class DivExp : BinExp { this(Loc loc, Expression e1, Expression e2) @@ -28,119 +28,119 @@ super(loc, TOK.TOKdiv, DivExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { - Expression e; - - if (type) - return this; - - super.semanticp(sc); - e = op_overload(sc); - if (e) - return e; - - typeCombine(sc); - if (e1.op != TOK.TOKslice && e2.op != TOK.TOKslice) - { - e1.checkArithmetic(); - e2.checkArithmetic(); - } - if (type.isfloating()) - { - Type t1 = e1.type; - Type t2 = e2.type; - - if (t1.isreal()) - { - type = t2; - if (t2.isimaginary()) - { - // x/iv = i(-x/v) - e2.type = t1; - Expression ee = new NegExp(loc, this); - ee = ee.semantic(sc); - return e; - } - } - else if (t2.isreal()) - { - type = t1; - } - else if (t1.isimaginary()) - { - if (t2.isimaginary()) { - switch (t1.ty) - { - case TY.Timaginary32: type = Type.tfloat32; break; - case TY.Timaginary64: type = Type.tfloat64; break; - case TY.Timaginary80: type = Type.tfloat80; break; - default: assert(0); - } - } else { - type = t2; // t2 is complex - } - } - else if (t2.isimaginary()) - { - type = t1; // t1 is complex - } - } + Expression e; + + if (type) + return this; + + super.semanticp(sc); + e = op_overload(sc); + if (e) + return e; + + typeCombine(sc); + if (e1.op != TOK.TOKslice && e2.op != TOK.TOKslice) + { + e1.checkArithmetic(); + e2.checkArithmetic(); + } + if (type.isfloating()) + { + Type t1 = e1.type; + Type t2 = e2.type; + + if (t1.isreal()) + { + type = t2; + if (t2.isimaginary()) + { + // x/iv = i(-x/v) + e2.type = t1; + Expression ee = new NegExp(loc, this); + ee = ee.semantic(sc); + return e; + } + } + else if (t2.isreal()) + { + type = t1; + } + else if (t1.isimaginary()) + { + if (t2.isimaginary()) { + switch (t1.ty) + { + case TY.Timaginary32: type = Type.tfloat32; break; + case TY.Timaginary64: type = Type.tfloat64; break; + case TY.Timaginary80: type = Type.tfloat80; break; + default: assert(0); + } + } else { + type = t2; // t2 is complex + } + } + else if (t2.isimaginary()) + { + type = t1; // t1 is complex + } + } return this; } - Expression optimize(int result) + override Expression optimize(int result) { - Expression e; - - //printf("DivExp.optimize(%s)\n", toChars()); - e1 = e1.optimize(result); - e2 = e2.optimize(result); - if (e1.isConst() == 1 && e2.isConst() == 1) - { - e = Div(type, e1, e2); - } - else - e = this; + Expression e; + + //printf("DivExp.optimize(%s)\n", toChars()); + e1 = e1.optimize(result); + e2 = e2.optimize(result); + if (e1.isConst() == 1 && e2.isConst() == 1) + { + e = Div(type, e1, e2); + } + else + e = this; return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { Exp_buildArrayIdent(buf, arguments, "Div"); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { - /* Evaluate assign expressions left to right - */ - Expression ex1 = e1.buildArrayLoop(fparams); - Expression ex2 = e2.buildArrayLoop(fparams); - Expression e = new DivExp(Loc(0), ex1, ex2); + /* Evaluate assign expressions left to right + */ + Expression ex1 = e1.buildArrayLoop(fparams); + Expression ex2 = e2.buildArrayLoop(fparams); + Expression e = new DivExp(Loc(0), ex1, ex2); return e; } - IntRange getIntRange() + override IntRange getIntRange() { assert(false); } - Identifier opId() + override Identifier opId() { return Id.div; } - Identifier opId_r() + override Identifier opId_r() { return Id.div_r; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs,OPdiv); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DoStatement.d --- a/dmd/DoStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DoStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -29,13 +29,13 @@ condition = c; } - Statement syntaxCopy() + override Statement syntaxCopy() { DoStatement s = new DoStatement(loc, body_ ? body_.syntaxCopy() : null, condition.syntaxCopy()); return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { sc.noctor++; if (body_) @@ -50,22 +50,22 @@ return this; } - bool hasBreak() + override bool hasBreak() { return true; } - bool hasContinue() + override bool hasContinue() { return true; } - bool usesEH() + override bool usesEH() { return body_ ? body_.usesEH() : false; } - BE blockExit() + override BE blockExit() { BE result; @@ -92,29 +92,29 @@ return result; } - bool comeFrom() + override bool comeFrom() { assert(false); } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { body_ = body_ ? body_.inlineScan(iss) : null; condition = condition.inlineScan(iss); return this; } - void toIR(IRState* irs) + override void toIR(IRState* irs) { Blockx *blx = irs.blx; @@ -138,4 +138,4 @@ block_appendexp(mystate.contBlock, condition.toElem(&mystate)); block_next(blx, BCiftrue, mystate.breakBlock); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DotExp.d --- a/dmd/DotExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DotExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,20 +1,20 @@ -module dmd.DotExp; - -import dmd.Expression; -import dmd.Loc; -import dmd.Scope; -import dmd.BinExp; -import dmd.TOK; - +module dmd.DotExp; + +import dmd.Expression; +import dmd.Loc; +import dmd.Scope; +import dmd.BinExp; +import dmd.TOK; + class DotExp : BinExp { this(Loc loc, Expression e1, Expression e2) { - assert(false); + assert(false); super(loc, TOK.init, 0, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DotIdExp.d --- a/dmd/DotIdExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DotIdExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,371 +1,371 @@ -module dmd.DotIdExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.IntegerExp; -import dmd.Type; -import dmd.TY; -import dmd.ScopeExp; -import dmd.StringExp; -import dmd.PtrExp; -import dmd.TypePointer; -import dmd.Dsymbol; -import dmd.EnumMember; -import dmd.VarDeclaration; -import dmd.ThisExp; -import dmd.DotVarExp; -import dmd.VarExp; -import dmd.CommaExp; -import dmd.FuncDeclaration; -import dmd.OverloadSet; -import dmd.OverExp; -import dmd.TypeExp; -import dmd.TupleDeclaration; -import dmd.ScopeDsymbol; -import dmd.Import; -import dmd.Id; -import dmd.TupleExp; -import dmd.ArrayTypes; -import dmd.UnaExp; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.TOK; -import dmd.HdrGenState; -import dmd.ClassDeclaration; -import dmd.StructDeclaration; -import dmd.AggregateDeclaration; -import dmd.DotExp; -import dmd.Global; -import dmd.IdentifierExp; -import dmd.CallExp; -import dmd.PREC; - -import dmd.expression.Util; - +module dmd.DotIdExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.IntegerExp; +import dmd.Type; +import dmd.TY; +import dmd.ScopeExp; +import dmd.StringExp; +import dmd.PtrExp; +import dmd.TypePointer; +import dmd.Dsymbol; +import dmd.EnumMember; +import dmd.VarDeclaration; +import dmd.ThisExp; +import dmd.DotVarExp; +import dmd.VarExp; +import dmd.CommaExp; +import dmd.FuncDeclaration; +import dmd.OverloadSet; +import dmd.OverExp; +import dmd.TypeExp; +import dmd.TupleDeclaration; +import dmd.ScopeDsymbol; +import dmd.Import; +import dmd.Id; +import dmd.TupleExp; +import dmd.ArrayTypes; +import dmd.UnaExp; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.TOK; +import dmd.HdrGenState; +import dmd.ClassDeclaration; +import dmd.StructDeclaration; +import dmd.AggregateDeclaration; +import dmd.DotExp; +import dmd.Global; +import dmd.IdentifierExp; +import dmd.CallExp; +import dmd.PREC; + +import dmd.expression.Util; + class DotIdExp : UnaExp { Identifier ident; this(Loc loc, Expression e, Identifier ident) { - super(loc, TOK.TOKdot, DotIdExp.sizeof, e); + super(loc, TOK.TOKdot, DotIdExp.sizeof, e); this.ident = ident; } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { - Expression e; - Expression eleft; - Expression eright; - -version (LOGSEMANTIC) { - printf("DotIdExp.semantic(this = %p, '%s')\n", this, toChars()); - //printf("e1.op = %d, '%s'\n", e1.op, Token.toChars(e1.op)); -} - - //{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; } - -static if (false) { - /* Don't do semantic analysis if we'll be converting - * it to a string. - */ - if (ident == Id.stringof) - { - char *s = e1.toChars(); - e = new StringExp(loc, s, strlen(s), 'c'); - e = e.semantic(sc); - return e; - } -} - - /* Special case: rewrite this.id and super.id - * to be classtype.id and baseclasstype.id - * if we have no this pointer. - */ - if ((e1.op == TOK.TOKthis || e1.op == TOK.TOKsuper) && !hasThis(sc)) - { - ClassDeclaration cd; - StructDeclaration sd; - AggregateDeclaration ad; - - ad = sc.getStructClassScope(); - if (ad) - { - cd = ad.isClassDeclaration(); - if (cd) - { - if (e1.op == TOK.TOKthis) - { - e = typeDotIdExp(loc, cd.type, ident); - return e.semantic(sc); - } - else if (cd.baseClass && e1.op == TOK.TOKsuper) - { - e = typeDotIdExp(loc, cd.baseClass.type, ident); - return e.semantic(sc); - } - } - else - { - sd = ad.isStructDeclaration(); - if (sd) - { - if (e1.op == TOK.TOKthis) - { - e = typeDotIdExp(loc, sd.type, ident); - return e.semantic(sc); - } - } - } - } - } - - UnaExp.semantic(sc); - - if (e1.op == TOK.TOKdotexp) - { - DotExp de = cast(DotExp)e1; - eleft = de.e1; - eright = de.e2; - } - else - { - e1 = resolveProperties(sc, e1); - eleft = null; - eright = e1; - } - -version (DMDV2) { - if (e1.op == TOK.TOKtuple && ident == Id.offsetof) - { - /* 'distribute' the .offsetof to each of the tuple elements. - */ - TupleExp te = cast(TupleExp)e1; - Expressions exps = new Expressions(); - exps.setDim(te.exps.dim); - for (int i = 0; i < exps.dim; i++) - { - Expression ee = cast(Expression)te.exps.data[i]; - ee = ee.semantic(sc); - ee = new DotIdExp(e.loc, ee, Id.offsetof); - exps.data[i] = cast(void*)ee; - } - e = new TupleExp(loc, exps); - e = e.semantic(sc); - return e; - } -} - - if (e1.op == TOK.TOKtuple && ident == Id.length) - { - TupleExp te = cast(TupleExp)e1; - e = new IntegerExp(loc, te.exps.dim, Type.tsize_t); - return e; - } - - if (e1.op == TOK.TOKdottd) - { - error("template %s does not have property %s", e1.toChars(), ident.toChars()); - return e1; - } - - if (!e1.type) - { - error("expression %s does not have property %s", e1.toChars(), ident.toChars()); - return e1; - } - - Type t1b = e1.type.toBasetype(); - - if (eright.op == TOK.TOKimport) // also used for template alias's - { - ScopeExp ie = cast(ScopeExp)eright; - - /* Disable access to another module's private imports. - * The check for 'is sds our current module' is because - * the current module should have access to its own imports. - */ - Dsymbol s = ie.sds.search(loc, ident, - (ie.sds.isModule() && ie.sds != sc.module_) ? 1 : 0); - if (s) - { - s = s.toAlias(); - checkDeprecated(sc, s); - - EnumMember em = s.isEnumMember(); - if (em) - { - e = em.value; - e = e.semantic(sc); - return e; - } - - VarDeclaration v = s.isVarDeclaration(); - if (v) - { - //printf("DotIdExp. Identifier '%s' is a variable, type '%s'\n", toChars(), v.type.toChars()); - if (v.inuse) - { - error("circular reference to '%s'", v.toChars()); - type = Type.tint32; - return this; - } - type = v.type; - if (v.needThis()) - { - if (!eleft) - eleft = new ThisExp(loc); - e = new DotVarExp(loc, eleft, v); - e = e.semantic(sc); - } - else - { - e = new VarExp(loc, v); - if (eleft) - { - e = new CommaExp(loc, eleft, e); - e.type = v.type; - } - } - return e.deref(); - } - - FuncDeclaration f = s.isFuncDeclaration(); - if (f) - { - //printf("it's a function\n"); - if (f.needThis()) - { - if (!eleft) - eleft = new ThisExp(loc); - e = new DotVarExp(loc, eleft, f); - e = e.semantic(sc); - } - else - { - e = new VarExp(loc, f, 1); - if (eleft) - { e = new CommaExp(loc, eleft, e); - e.type = f.type; - } - } - return e; - } -version (DMDV2) { - OverloadSet o = s.isOverloadSet(); - if (o) - { - //printf("'%s' is an overload set\n", o.toChars()); - return new OverExp(o); - } -} - - Type t = s.getType(); - if (t) - { - return new TypeExp(loc, t); - } - - TupleDeclaration tup = s.isTupleDeclaration(); - if (tup) - { - if (eleft) - error("cannot have e.tuple"); - e = new TupleExp(loc, tup); - e = e.semantic(sc); - return e; - } - - ScopeDsymbol sds = s.isScopeDsymbol(); - if (sds) - { - //printf("it's a ScopeDsymbol\n"); - e = new ScopeExp(loc, sds); - e = e.semantic(sc); - if (eleft) - e = new DotExp(loc, eleft, e); - return e; - } - - Import imp = s.isImport(); - if (imp) - { - ScopeExp iee = new ScopeExp(loc, imp.pkg); - return iee.semantic(sc); - } - - // BUG: handle other cases like in IdentifierExp.semantic() -version (DEBUG) { - printf("s = '%s', kind = '%s'\n", s.toChars(), s.kind()); -} - assert(0); - } - else if (ident is Id.stringof_) - { - string ss = ie.toChars(); - e = new StringExp(loc, ss, 'c'); - e = e.semantic(sc); - return e; - } - error("undefined identifier %s", toChars()); - type = Type.tvoid; - return this; - } - else if (t1b.ty == TY.Tpointer && - ident !is Id.init_ && ident !is Id.__sizeof && - ident !is Id.alignof_ && ident !is Id.offsetof && - ident !is Id.mangleof_ && ident !is Id.stringof_) - { /* Rewrite: - * p.ident - * as: - * (*p).ident - */ - e = new PtrExp(loc, e1); - e.type = (cast(TypePointer)t1b).next; - return e.type.dotExp(sc, e, ident); - } -///version (DMDV2) { - else if (t1b.ty == TY.Tarray || - t1b.ty == TY.Tsarray || - t1b.ty == TY.Taarray) - { - /* If ident is not a valid property, rewrite: - * e1.ident - * as: - * .ident(e1) - */ - uint errors = global.errors; - global.gag++; - e = e1.type.dotExp(sc, e1, ident); - global.gag--; - if (errors != global.errors) // if failed to find the property - { - global.errors = errors; - e = new DotIdExp(loc, new IdentifierExp(loc, Id.empty), ident); - e = new CallExp(loc, e, e1); - } - e = e.semantic(sc); - return e; - } -///} - else - { - e = e1.type.dotExp(sc, e1, ident); - e = e.semantic(sc); - return e; + Expression e; + Expression eleft; + Expression eright; + +version (LOGSEMANTIC) { + printf("DotIdExp.semantic(this = %p, '%s')\n", this, toChars()); + //printf("e1.op = %d, '%s'\n", e1.op, Token.toChars(e1.op)); +} + + //{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; } + +static if (false) { + /* Don't do semantic analysis if we'll be converting + * it to a string. + */ + if (ident == Id.stringof) + { + char *s = e1.toChars(); + e = new StringExp(loc, s, strlen(s), 'c'); + e = e.semantic(sc); + return e; + } +} + + /* Special case: rewrite this.id and super.id + * to be classtype.id and baseclasstype.id + * if we have no this pointer. + */ + if ((e1.op == TOK.TOKthis || e1.op == TOK.TOKsuper) && !hasThis(sc)) + { + ClassDeclaration cd; + StructDeclaration sd; + AggregateDeclaration ad; + + ad = sc.getStructClassScope(); + if (ad) + { + cd = ad.isClassDeclaration(); + if (cd) + { + if (e1.op == TOK.TOKthis) + { + e = typeDotIdExp(loc, cd.type, ident); + return e.semantic(sc); + } + else if (cd.baseClass && e1.op == TOK.TOKsuper) + { + e = typeDotIdExp(loc, cd.baseClass.type, ident); + return e.semantic(sc); + } + } + else + { + sd = ad.isStructDeclaration(); + if (sd) + { + if (e1.op == TOK.TOKthis) + { + e = typeDotIdExp(loc, sd.type, ident); + return e.semantic(sc); + } + } + } + } + } + + UnaExp.semantic(sc); + + if (e1.op == TOK.TOKdotexp) + { + DotExp de = cast(DotExp)e1; + eleft = de.e1; + eright = de.e2; + } + else + { + e1 = resolveProperties(sc, e1); + eleft = null; + eright = e1; + } + +version (DMDV2) { + if (e1.op == TOK.TOKtuple && ident == Id.offsetof) + { + /* 'distribute' the .offsetof to each of the tuple elements. + */ + TupleExp te = cast(TupleExp)e1; + Expressions exps = new Expressions(); + exps.setDim(te.exps.dim); + for (int i = 0; i < exps.dim; i++) + { + Expression ee = cast(Expression)te.exps.data[i]; + ee = ee.semantic(sc); + ee = new DotIdExp(e.loc, ee, Id.offsetof); + exps.data[i] = cast(void*)ee; + } + e = new TupleExp(loc, exps); + e = e.semantic(sc); + return e; + } +} + + if (e1.op == TOK.TOKtuple && ident == Id.length) + { + TupleExp te = cast(TupleExp)e1; + e = new IntegerExp(loc, te.exps.dim, Type.tsize_t); + return e; + } + + if (e1.op == TOK.TOKdottd) + { + error("template %s does not have property %s", e1.toChars(), ident.toChars()); + return e1; + } + + if (!e1.type) + { + error("expression %s does not have property %s", e1.toChars(), ident.toChars()); + return e1; + } + + Type t1b = e1.type.toBasetype(); + + if (eright.op == TOK.TOKimport) // also used for template alias's + { + ScopeExp ie = cast(ScopeExp)eright; + + /* Disable access to another module's private imports. + * The check for 'is sds our current module' is because + * the current module should have access to its own imports. + */ + Dsymbol s = ie.sds.search(loc, ident, + (ie.sds.isModule() && ie.sds != sc.module_) ? 1 : 0); + if (s) + { + s = s.toAlias(); + checkDeprecated(sc, s); + + EnumMember em = s.isEnumMember(); + if (em) + { + e = em.value; + e = e.semantic(sc); + return e; + } + + VarDeclaration v = s.isVarDeclaration(); + if (v) + { + //printf("DotIdExp. Identifier '%s' is a variable, type '%s'\n", toChars(), v.type.toChars()); + if (v.inuse) + { + error("circular reference to '%s'", v.toChars()); + type = Type.tint32; + return this; + } + type = v.type; + if (v.needThis()) + { + if (!eleft) + eleft = new ThisExp(loc); + e = new DotVarExp(loc, eleft, v); + e = e.semantic(sc); + } + else + { + e = new VarExp(loc, v); + if (eleft) + { + e = new CommaExp(loc, eleft, e); + e.type = v.type; + } + } + return e.deref(); + } + + FuncDeclaration f = s.isFuncDeclaration(); + if (f) + { + //printf("it's a function\n"); + if (f.needThis()) + { + if (!eleft) + eleft = new ThisExp(loc); + e = new DotVarExp(loc, eleft, f); + e = e.semantic(sc); + } + else + { + e = new VarExp(loc, f, 1); + if (eleft) + { e = new CommaExp(loc, eleft, e); + e.type = f.type; + } + } + return e; + } +version (DMDV2) { + OverloadSet o = s.isOverloadSet(); + if (o) + { + //printf("'%s' is an overload set\n", o.toChars()); + return new OverExp(o); + } +} + + Type t = s.getType(); + if (t) + { + return new TypeExp(loc, t); + } + + TupleDeclaration tup = s.isTupleDeclaration(); + if (tup) + { + if (eleft) + error("cannot have e.tuple"); + e = new TupleExp(loc, tup); + e = e.semantic(sc); + return e; + } + + ScopeDsymbol sds = s.isScopeDsymbol(); + if (sds) + { + //printf("it's a ScopeDsymbol\n"); + e = new ScopeExp(loc, sds); + e = e.semantic(sc); + if (eleft) + e = new DotExp(loc, eleft, e); + return e; + } + + Import imp = s.isImport(); + if (imp) + { + ScopeExp iee = new ScopeExp(loc, imp.pkg); + return iee.semantic(sc); + } + + // BUG: handle other cases like in IdentifierExp.semantic() +version (DEBUG) { + printf("s = '%s', kind = '%s'\n", s.toChars(), s.kind()); +} + assert(0); + } + else if (ident is Id.stringof_) + { + string ss = ie.toChars(); + e = new StringExp(loc, ss, 'c'); + e = e.semantic(sc); + return e; + } + error("undefined identifier %s", toChars()); + type = Type.tvoid; + return this; + } + else if (t1b.ty == TY.Tpointer && + ident !is Id.init_ && ident !is Id.__sizeof && + ident !is Id.alignof_ && ident !is Id.offsetof && + ident !is Id.mangleof_ && ident !is Id.stringof_) + { /* Rewrite: + * p.ident + * as: + * (*p).ident + */ + e = new PtrExp(loc, e1); + e.type = (cast(TypePointer)t1b).next; + return e.type.dotExp(sc, e, ident); + } +///version (DMDV2) { + else if (t1b.ty == TY.Tarray || + t1b.ty == TY.Tsarray || + t1b.ty == TY.Taarray) + { + /* If ident is not a valid property, rewrite: + * e1.ident + * as: + * .ident(e1) + */ + uint errors = global.errors; + global.gag++; + e = e1.type.dotExp(sc, e1, ident); + global.gag--; + if (errors != global.errors) // if failed to find the property + { + global.errors = errors; + e = new DotIdExp(loc, new IdentifierExp(loc, Id.empty), ident); + e = new CallExp(loc, e, e1); + } + e = e.semantic(sc); + return e; + } +///} + else + { + e = e1.type.dotExp(sc, e1, ident); + e = e.semantic(sc); + return e; } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - //printf("DotIdExp.toCBuffer()\n"); - expToCBuffer(buf, hgs, e1, PREC.PREC_primary); - buf.writeByte('.'); + //printf("DotIdExp.toCBuffer()\n"); + expToCBuffer(buf, hgs, e1, PREC.PREC_primary); + buf.writeByte('.'); buf.writestring(ident.toChars()); } - void dump(int i) + override void dump(int i) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DotTemplateExp.d --- a/dmd/DotTemplateExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DotTemplateExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,31 +1,31 @@ -module dmd.DotTemplateExp; - -import dmd.Expression; -import dmd.UnaExp; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.TOK; -import dmd.PREC; -import dmd.HdrGenState; -import dmd.TemplateDeclaration; - -import dmd.expression.Util; - -class DotTemplateExp : UnaExp -{ - TemplateDeclaration td; - - this(Loc loc, Expression e, TemplateDeclaration td) - { - super(loc, TOK.TOKdottd, this.sizeof, e); - this.td = td; - } - - void toCBuffer(OutBuffer buf, HdrGenState* hgs) - { - expToCBuffer(buf, hgs, e1, PREC.PREC_primary); - buf.writeByte('.'); - buf.writestring(td.toChars()); - } -} - +module dmd.DotTemplateExp; + +import dmd.Expression; +import dmd.UnaExp; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.TOK; +import dmd.PREC; +import dmd.HdrGenState; +import dmd.TemplateDeclaration; + +import dmd.expression.Util; + +class DotTemplateExp : UnaExp +{ + TemplateDeclaration td; + + this(Loc loc, Expression e, TemplateDeclaration td) + { + super(loc, TOK.TOKdottd, this.sizeof, e); + this.td = td; + } + + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) + { + expToCBuffer(buf, hgs, e1, PREC.PREC_primary); + buf.writeByte('.'); + buf.writestring(td.toChars()); + } +} + diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DotTemplateInstanceExp.d --- a/dmd/DotTemplateInstanceExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DotTemplateInstanceExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,12 +1,12 @@ -module dmd.DotTemplateInstanceExp; - -import dmd.Expression; -import dmd.UnaExp; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.TemplateInstance; -import dmd.HdrGenState; +module dmd.DotTemplateInstanceExp; + +import dmd.Expression; +import dmd.UnaExp; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.TemplateInstance; +import dmd.HdrGenState; import dmd.TOK; import dmd.PREC; import dmd.Declaration; @@ -23,29 +23,29 @@ import dmd.TemplateDeclaration; import dmd.Dsymbol; -import dmd.expression.Util; +import dmd.expression.Util; /* Things like: * foo.bar!(args) - */ + */ class DotTemplateInstanceExp : UnaExp { TemplateInstance ti; this(Loc loc, Expression e, TemplateInstance ti) - { + { super(loc, TOK.TOKdotti, DotTemplateInstanceExp.sizeof, e); //printf("DotTemplateInstanceExp()\n"); this.ti = ti; } - Expression syntaxCopy() + override Expression syntaxCopy() { DotTemplateInstanceExp de = new DotTemplateInstanceExp(loc, e1.syntaxCopy(), cast(TemplateInstance)ti.syntaxCopy(null)); return de; } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Dsymbol s; Dsymbol s2; @@ -170,14 +170,14 @@ return new ErrorExp(); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { expToCBuffer(buf, hgs, e1, PREC.PREC_primary); buf.writeByte('.'); ti.toCBuffer(buf, hgs); } - void dump(int indent) + override void dump(int indent) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DotTypeExp.d --- a/dmd/DotTypeExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DotTypeExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,30 +1,30 @@ -module dmd.DotTypeExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.UnaExp; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.HdrGenState; -import dmd.Dsymbol; +module dmd.DotTypeExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.UnaExp; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.HdrGenState; +import dmd.Dsymbol; import dmd.TOK; import dmd.PREC; -import dmd.expression.Util; - +import dmd.expression.Util; + class DotTypeExp : UnaExp { Dsymbol sym; this(Loc loc, Expression e, Dsymbol s) - { + { super(loc, TOK.TOKdottype, DotTypeExp.sizeof, e); this.sym = s; this.type = s.getType(); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { version (LOGSEMANTIC) { printf("DotTypeExp.semantic('%s')\n", toChars()); @@ -33,14 +33,14 @@ return this; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { expToCBuffer(buf, hgs, e1, PREC.PREC_primary); buf.writeByte('.'); buf.writestring(sym.toChars()); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DotVarExp.d --- a/dmd/DotVarExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DotVarExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,42 +1,42 @@ -module dmd.DotVarExp; - -import dmd.Expression; -import dmd.Declaration; -import dmd.backend.elem; -import dmd.UnaExp; -import dmd.InterState; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.HdrGenState; -import dmd.TOK; -import dmd.TupleDeclaration; -import dmd.ArrayTypes; -import dmd.DsymbolExp; -import dmd.TupleExp; -import dmd.Global; -import dmd.Type; -import dmd.Dsymbol; -import dmd.AggregateDeclaration; -import dmd.VarDeclaration; -import dmd.WANT; -import dmd.TY; -import dmd.ErrorExp; -import dmd.FuncDeclaration; -import dmd.STC; -import dmd.GlobalExpressions; -import dmd.VarExp; -import dmd.StructLiteralExp; -import dmd.PREC; - -import dmd.expression.Util; -import dmd.codegen.Util; -import dmd.backend.Util; -import dmd.backend.mTY; -import dmd.backend.OPER; -import dmd.backend.TYM; - +module dmd.DotVarExp; + +import dmd.Expression; +import dmd.Declaration; +import dmd.backend.elem; +import dmd.UnaExp; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.HdrGenState; +import dmd.TOK; +import dmd.TupleDeclaration; +import dmd.ArrayTypes; +import dmd.DsymbolExp; +import dmd.TupleExp; +import dmd.Global; +import dmd.Type; +import dmd.Dsymbol; +import dmd.AggregateDeclaration; +import dmd.VarDeclaration; +import dmd.WANT; +import dmd.TY; +import dmd.ErrorExp; +import dmd.FuncDeclaration; +import dmd.STC; +import dmd.GlobalExpressions; +import dmd.VarExp; +import dmd.StructLiteralExp; +import dmd.PREC; + +import dmd.expression.Util; +import dmd.codegen.Util; +import dmd.backend.Util; +import dmd.backend.mTY; +import dmd.backend.OPER; +import dmd.backend.TYM; + class DotVarExp : UnaExp { Declaration var; @@ -45,236 +45,236 @@ this(Loc loc, Expression e, Declaration var, int hasOverloads = 0) { - super(loc, TOK.TOKdotvar, DotVarExp.sizeof, e); - //printf("DotVarExp()\n"); - this.var = var; - this.hasOverloads = hasOverloads; + super(loc, TOK.TOKdotvar, DotVarExp.sizeof, e); + //printf("DotVarExp()\n"); + this.var = var; + this.hasOverloads = hasOverloads; } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { -version (LOGSEMANTIC) { - printf("DotVarExp.semantic('%s')\n", toChars()); -} - if (!type) - { - var = var.toAlias().isDeclaration(); - - TupleDeclaration tup = var.isTupleDeclaration(); - if (tup) - { - /* Replace: - * e1.tuple(a, b, c) - * with: - * tuple(e1.a, e1.b, e1.c) - */ - Expressions exps = new Expressions; - - exps.reserve(tup.objects.dim); - for (size_t i = 0; i < tup.objects.dim; i++) - { - Object o = cast(Object)tup.objects.data[i]; - if (auto e = cast(Expression)o) - { - if (e.op != TOK.TOKdsymbol) - error("%s is not a member", e.toChars()); - else - { - DsymbolExp ve = cast(DsymbolExp)e; - e = new DotVarExp(loc, e1, ve.s.isDeclaration()); - exps.push(cast(void*)e); - } - } else { - error("%s is not an expression", o.toString()); - } - } - Expression e = new TupleExp(loc, exps); - e = e.semantic(sc); - return e; - } - - e1 = e1.semantic(sc); - type = var.type; - if (!type && global.errors) - { - // var is goofed up, just return 0 - return new ErrorExp(); - } - assert(type); - - if (!var.isFuncDeclaration()) // for functions, do checks after overload resolution - { - Type t1 = e1.type; - if (t1.ty == TY.Tpointer) - t1 = t1.nextOf(); - - type = type.addMod(t1.mod); - - Dsymbol vparent = var.toParent(); - AggregateDeclaration ad = vparent ? vparent.isAggregateDeclaration() : null; - e1 = getRightThis(loc, sc, ad, e1, var); - if (!sc.noaccesscheck) - accessCheck(loc, sc, e1, var); - - VarDeclaration v = var.isVarDeclaration(); - Expression e = expandVar(WANT.WANTvalue, v); - if (e) - return e; - } - } - //printf("-DotVarExp.semantic('%s')\n", toChars()); +version (LOGSEMANTIC) { + printf("DotVarExp.semantic('%s')\n", toChars()); +} + if (!type) + { + var = var.toAlias().isDeclaration(); + + TupleDeclaration tup = var.isTupleDeclaration(); + if (tup) + { + /* Replace: + * e1.tuple(a, b, c) + * with: + * tuple(e1.a, e1.b, e1.c) + */ + Expressions exps = new Expressions; + + exps.reserve(tup.objects.dim); + for (size_t i = 0; i < tup.objects.dim; i++) + { + Object o = cast(Object)tup.objects.data[i]; + if (auto e = cast(Expression)o) + { + if (e.op != TOK.TOKdsymbol) + error("%s is not a member", e.toChars()); + else + { + DsymbolExp ve = cast(DsymbolExp)e; + e = new DotVarExp(loc, e1, ve.s.isDeclaration()); + exps.push(cast(void*)e); + } + } else { + error("%s is not an expression", o.toString()); + } + } + Expression e = new TupleExp(loc, exps); + e = e.semantic(sc); + return e; + } + + e1 = e1.semantic(sc); + type = var.type; + if (!type && global.errors) + { + // var is goofed up, just return 0 + return new ErrorExp(); + } + assert(type); + + if (!var.isFuncDeclaration()) // for functions, do checks after overload resolution + { + Type t1 = e1.type; + if (t1.ty == TY.Tpointer) + t1 = t1.nextOf(); + + type = type.addMod(t1.mod); + + Dsymbol vparent = var.toParent(); + AggregateDeclaration ad = vparent ? vparent.isAggregateDeclaration() : null; + e1 = getRightThis(loc, sc, ad, e1, var); + if (!sc.noaccesscheck) + accessCheck(loc, sc, e1, var); + + VarDeclaration v = var.isVarDeclaration(); + Expression e = expandVar(WANT.WANTvalue, v); + if (e) + return e; + } + } + //printf("-DotVarExp.semantic('%s')\n", toChars()); return this; } - int isLvalue() + override int isLvalue() { return 1; } - Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression e) { - //printf("DotVarExp::toLvalue(%s)\n", toChars()); + //printf("DotVarExp::toLvalue(%s)\n", toChars()); return this; } - Expression modifiableLvalue(Scope sc, Expression e) + override Expression modifiableLvalue(Scope sc, Expression e) { -static if (false) { - printf("DotVarExp::modifiableLvalue(%s)\n", toChars()); - printf("e1.type = %s\n", e1.type.toChars()); - printf("var.type = %s\n", var.type.toChars()); -} - - if (var.isCtorinit()) - { - // It's only modifiable if inside the right constructor - Dsymbol s = sc.func; - while (true) - { - FuncDeclaration fd = null; - if (s) - fd = s.isFuncDeclaration(); - if (fd && ((fd.isCtorDeclaration() && var.storage_class & STC.STCfield) || - (fd.isStaticCtorDeclaration() && !(var.storage_class & STC.STCfield))) && - fd.toParent() == var.toParent() && e1.op == TOK.TOKthis) - { - VarDeclaration v = var.isVarDeclaration(); - assert(v); - v.ctorinit = 1; - //printf("setting ctorinit\n"); - } - else - { - if (s) - { - s = s.toParent2(); - continue; - } - else - { - string p = var.isStatic() ? "static " : ""; - error("can only initialize %sconst member %s inside %sconstructor", p, var.toChars(), p); - } - } - break; - } - } - else - { -version (DMDV2) { - Type t1 = e1.type.toBasetype(); - - if (!t1.isMutable() || (t1.ty == TY.Tpointer && !t1.nextOf().isMutable()) || - !var.type.isMutable() || !var.type.isAssignable() || var.storage_class & STC.STCmanifest) - { - error("cannot modify const/immutable expression %s", toChars()); - } -} - } - +static if (false) { + printf("DotVarExp::modifiableLvalue(%s)\n", toChars()); + printf("e1.type = %s\n", e1.type.toChars()); + printf("var.type = %s\n", var.type.toChars()); +} + + if (var.isCtorinit()) + { + // It's only modifiable if inside the right constructor + Dsymbol s = sc.func; + while (true) + { + FuncDeclaration fd = null; + if (s) + fd = s.isFuncDeclaration(); + if (fd && ((fd.isCtorDeclaration() && var.storage_class & STC.STCfield) || + (fd.isStaticCtorDeclaration() && !(var.storage_class & STC.STCfield))) && + fd.toParent() == var.toParent() && e1.op == TOK.TOKthis) + { + VarDeclaration v = var.isVarDeclaration(); + assert(v); + v.ctorinit = 1; + //printf("setting ctorinit\n"); + } + else + { + if (s) + { + s = s.toParent2(); + continue; + } + else + { + string p = var.isStatic() ? "static " : ""; + error("can only initialize %sconst member %s inside %sconstructor", p, var.toChars(), p); + } + } + break; + } + } + else + { +version (DMDV2) { + Type t1 = e1.type.toBasetype(); + + if (!t1.isMutable() || (t1.ty == TY.Tpointer && !t1.nextOf().isMutable()) || + !var.type.isMutable() || !var.type.isAssignable() || var.storage_class & STC.STCmanifest) + { + error("cannot modify const/immutable expression %s", toChars()); + } +} + } + return this; } - Expression optimize(int result) + override Expression optimize(int result) { - //printf("DotVarExp.optimize(result = x%x) %s\n", result, toChars()); - e1 = e1.optimize(result); - - 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; - } - } - } - else if (e1.op == TOK.TOKstructliteral) - { - StructLiteralExp sle = cast(StructLiteralExp)e1; - VarDeclaration vf = var.isVarDeclaration(); - if (vf) - { - Expression e = sle.getField(type, vf.offset); - if (e && e !is EXP_CANT_INTERPRET) - return e; - } - } - + //printf("DotVarExp.optimize(result = x%x) %s\n", result, toChars()); + e1 = e1.optimize(result); + + 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; + } + } + } + else if (e1.op == TOK.TOKstructliteral) + { + StructLiteralExp sle = cast(StructLiteralExp)e1; + VarDeclaration vf = var.isVarDeclaration(); + if (vf) + { + Expression e = sle.getField(type, vf.offset); + if (e && e !is EXP_CANT_INTERPRET) + return e; + } + } + return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - expToCBuffer(buf, hgs, e1, PREC.PREC_primary); - buf.writeByte('.'); + expToCBuffer(buf, hgs, e1, PREC.PREC_primary); + buf.writeByte('.'); buf.writestring(var.toChars()); } - void dump(int indent) + override void dump(int indent) { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { - // *(&e + offset) - //printf("DotVarExp.toElem('%s')\n", toChars()); - - VarDeclaration v = var.isVarDeclaration(); - if (!v) - { - error("%s is not a field, but a %s", var.toChars(), var.kind()); - } - - elem* e = e1.toElem(irs); - Type tb1 = e1.type.toBasetype(); - - if (tb1.ty != TY.Tclass && tb1.ty != TY.Tpointer) - //e = el_una(OPaddr, TYnptr, e); - e = addressElem(e, tb1); - - e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, v ? v.offset : 0)); - e = el_una(OPER.OPind, type.totym(), e); - if (tybasic(e.Ety) == TYM.TYstruct) - { - e.Enumbytes = cast(uint)type.size(); - } - el_setLoc(e,loc); - + // *(&e + offset) + //printf("DotVarExp.toElem('%s')\n", toChars()); + + VarDeclaration v = var.isVarDeclaration(); + if (!v) + { + error("%s is not a field, but a %s", var.toChars(), var.kind()); + } + + elem* e = e1.toElem(irs); + Type tb1 = e1.type.toBasetype(); + + if (tb1.ty != TY.Tclass && tb1.ty != TY.Tpointer) + //e = el_una(OPaddr, TYnptr, e); + e = addressElem(e, tb1); + + e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, v ? v.offset : 0)); + e = el_una(OPER.OPind, type.totym(), e); + if (tybasic(e.Ety) == TYM.TYstruct) + { + e.Enumbytes = cast(uint)type.size(); + } + el_setLoc(e,loc); + return e; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DsymbolExp.d --- a/dmd/DsymbolExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DsymbolExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,38 +1,38 @@ -module dmd.DsymbolExp; - -import dmd.Expression; -import dmd.OutBuffer; -import dmd.EnumMember; -import dmd.VarDeclaration; -import dmd.FuncDeclaration; -import dmd.FuncLiteralDeclaration; -import dmd.OverloadSet; -import dmd.Declaration; -import dmd.ClassDeclaration; -import dmd.Import; -import dmd.Package; -import dmd.Type; -import dmd.DotVarExp; -import dmd.ThisExp; -import dmd.VarExp; -import dmd.FuncExp; -import dmd.OverExp; -import dmd.DotTypeExp; -import dmd.ScopeExp; -import dmd.Module; -import dmd.TypeExp; -import dmd.TupleDeclaration; -import dmd.TupleExp; -import dmd.TemplateInstance; -import dmd.Global; -import dmd.TemplateDeclaration; -import dmd.TemplateExp; -import dmd.Loc; -import dmd.Scope; -import dmd.HdrGenState; -import dmd.Dsymbol; -import dmd.TOK; - +module dmd.DsymbolExp; + +import dmd.Expression; +import dmd.OutBuffer; +import dmd.EnumMember; +import dmd.VarDeclaration; +import dmd.FuncDeclaration; +import dmd.FuncLiteralDeclaration; +import dmd.OverloadSet; +import dmd.Declaration; +import dmd.ClassDeclaration; +import dmd.Import; +import dmd.Package; +import dmd.Type; +import dmd.DotVarExp; +import dmd.ThisExp; +import dmd.VarExp; +import dmd.FuncExp; +import dmd.OverExp; +import dmd.DotTypeExp; +import dmd.ScopeExp; +import dmd.Module; +import dmd.TypeExp; +import dmd.TupleDeclaration; +import dmd.TupleExp; +import dmd.TemplateInstance; +import dmd.Global; +import dmd.TemplateDeclaration; +import dmd.TemplateExp; +import dmd.Loc; +import dmd.Scope; +import dmd.HdrGenState; +import dmd.Dsymbol; +import dmd.TOK; + class DsymbolExp : Expression { Dsymbol s; @@ -40,210 +40,210 @@ this(Loc loc, Dsymbol s, int hasOverloads = 0) { - super(loc, TOK.TOKdsymbol, DsymbolExp.sizeof); - this.s = s; + super(loc, TOK.TOKdsymbol, DsymbolExp.sizeof); + this.s = s; this.hasOverloads = hasOverloads; } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { -version (LOGSEMANTIC) { - printf("DsymbolExp.semantic('%s')\n", s.toChars()); -} - - Lagain: - EnumMember em; - Expression e; - VarDeclaration v; - FuncDeclaration f; - FuncLiteralDeclaration fld; - OverloadSet o; - Declaration d; - ClassDeclaration cd; - ClassDeclaration thiscd = null; - Import imp; - Package pkg; - Type t; - - //printf("DsymbolExp. %p '%s' is a symbol\n", this, toChars()); - //printf("s = '%s', s.kind = '%s'\n", s.toChars(), s.kind()); - if (type) - return this; - - if (!s.isFuncDeclaration()) // functions are checked after overloading - checkDeprecated(sc, s); - - s = s.toAlias(); - //printf("s = '%s', s.kind = '%s', s.needThis() = %p\n", s.toChars(), s.kind(), s.needThis()); - if (!s.isFuncDeclaration()) - checkDeprecated(sc, s); - - if (sc.func) - thiscd = sc.func.parent.isClassDeclaration(); - - // BUG: This should happen after overload resolution for functions, not before - if (s.needThis()) - { -version (DMDV2) { - bool cond = !s.isFuncDeclaration(); -} else { - bool cond = true; -} - if (hasThis(sc) && cond) - { - // Supply an implicit 'this', as in - // this.ident - DotVarExp de = new DotVarExp(loc, new ThisExp(loc), s.isDeclaration()); - return de.semantic(sc); - } - } - - em = s.isEnumMember(); - if (em) - { - e = em.value; - e = e.semantic(sc); - return e; - } - v = s.isVarDeclaration(); - if (v) - { - //printf("Identifier '%s' is a variable, type '%s'\n", toChars(), v.type.toChars()); - if (!type) - { - type = v.type; - if (!v.type) - { - error("forward reference of %s %s", v.kind(), v.toChars()); - type = Type.terror; - } - } - - e = new VarExp(loc, v); - e.type = type; - e = e.semantic(sc); - return e.deref(); - } - - fld = s.isFuncLiteralDeclaration(); - if (fld) - { - //printf("'%s' is a function literal\n", fld.toChars()); - e = new FuncExp(loc, fld); - return e.semantic(sc); - } - f = s.isFuncDeclaration(); - if (f) - { - //printf("'%s' is a function\n", f.toChars()); - - if (!f.type.deco) - { - error("forward reference to %s", toChars()); - } - return new VarExp(loc, f, hasOverloads); - } - o = s.isOverloadSet(); - if (o) - { - //printf("'%s' is an overload set\n", o.toChars()); - return new OverExp(o); - } - cd = s.isClassDeclaration(); - if (cd && thiscd && cd.isBaseOf(thiscd, null) && sc.func.needThis()) - { - // We need to add an implicit 'this' if cd is this class or a base class. - DotTypeExp dte = new DotTypeExp(loc, new ThisExp(loc), s); - return dte.semantic(sc); - } - imp = s.isImport(); - if (imp) - { - if (!imp.pkg) - { - error("forward reference of import %s", imp.toChars()); - return this; - } - ScopeExp ie = new ScopeExp(loc, imp.pkg); - return ie.semantic(sc); - } - pkg = s.isPackage(); - if (pkg) - { - ScopeExp ie = new ScopeExp(loc, pkg); - return ie.semantic(sc); - } - Module mod = s.isModule(); - if (mod) - { - ScopeExp ie = new ScopeExp(loc, mod); - return ie.semantic(sc); - } - - t = s.getType(); - if (t) - { - return new TypeExp(loc, t); - } - - TupleDeclaration tup = s.isTupleDeclaration(); - if (tup) - { - e = new TupleExp(loc, tup); - e = e.semantic(sc); - return e; - } - - TemplateInstance ti = s.isTemplateInstance(); - if (ti && !global.errors) - { - if (!ti.semanticRun) - ti.semantic(sc); - - s = ti.inst.toAlias(); - if (!s.isTemplateInstance()) - goto Lagain; - - e = new ScopeExp(loc, ti); - e = e.semantic(sc); - return e; - } - - TemplateDeclaration td = s.isTemplateDeclaration(); - if (td) - { - e = new TemplateExp(loc, td); - e = e.semantic(sc); - return e; - } - - Lerr: - error("%s '%s' is not a variable", s.kind(), s.toChars()); - type = Type.terror; +version (LOGSEMANTIC) { + printf("DsymbolExp.semantic('%s')\n", s.toChars()); +} + + Lagain: + EnumMember em; + Expression e; + VarDeclaration v; + FuncDeclaration f; + FuncLiteralDeclaration fld; + OverloadSet o; + Declaration d; + ClassDeclaration cd; + ClassDeclaration thiscd = null; + Import imp; + Package pkg; + Type t; + + //printf("DsymbolExp. %p '%s' is a symbol\n", this, toChars()); + //printf("s = '%s', s.kind = '%s'\n", s.toChars(), s.kind()); + if (type) + return this; + + if (!s.isFuncDeclaration()) // functions are checked after overloading + checkDeprecated(sc, s); + + s = s.toAlias(); + //printf("s = '%s', s.kind = '%s', s.needThis() = %p\n", s.toChars(), s.kind(), s.needThis()); + if (!s.isFuncDeclaration()) + checkDeprecated(sc, s); + + if (sc.func) + thiscd = sc.func.parent.isClassDeclaration(); + + // BUG: This should happen after overload resolution for functions, not before + if (s.needThis()) + { +version (DMDV2) { + bool cond = !s.isFuncDeclaration(); +} else { + bool cond = true; +} + if (hasThis(sc) && cond) + { + // Supply an implicit 'this', as in + // this.ident + DotVarExp de = new DotVarExp(loc, new ThisExp(loc), s.isDeclaration()); + return de.semantic(sc); + } + } + + em = s.isEnumMember(); + if (em) + { + e = em.value; + e = e.semantic(sc); + return e; + } + v = s.isVarDeclaration(); + if (v) + { + //printf("Identifier '%s' is a variable, type '%s'\n", toChars(), v.type.toChars()); + if (!type) + { + type = v.type; + if (!v.type) + { + error("forward reference of %s %s", v.kind(), v.toChars()); + type = Type.terror; + } + } + + e = new VarExp(loc, v); + e.type = type; + e = e.semantic(sc); + return e.deref(); + } + + fld = s.isFuncLiteralDeclaration(); + if (fld) + { + //printf("'%s' is a function literal\n", fld.toChars()); + e = new FuncExp(loc, fld); + return e.semantic(sc); + } + f = s.isFuncDeclaration(); + if (f) + { + //printf("'%s' is a function\n", f.toChars()); + + if (!f.type.deco) + { + error("forward reference to %s", toChars()); + } + return new VarExp(loc, f, hasOverloads); + } + o = s.isOverloadSet(); + if (o) + { + //printf("'%s' is an overload set\n", o.toChars()); + return new OverExp(o); + } + cd = s.isClassDeclaration(); + if (cd && thiscd && cd.isBaseOf(thiscd, null) && sc.func.needThis()) + { + // We need to add an implicit 'this' if cd is this class or a base class. + DotTypeExp dte = new DotTypeExp(loc, new ThisExp(loc), s); + return dte.semantic(sc); + } + imp = s.isImport(); + if (imp) + { + if (!imp.pkg) + { + error("forward reference of import %s", imp.toChars()); + return this; + } + ScopeExp ie = new ScopeExp(loc, imp.pkg); + return ie.semantic(sc); + } + pkg = s.isPackage(); + if (pkg) + { + ScopeExp ie = new ScopeExp(loc, pkg); + return ie.semantic(sc); + } + Module mod = s.isModule(); + if (mod) + { + ScopeExp ie = new ScopeExp(loc, mod); + return ie.semantic(sc); + } + + t = s.getType(); + if (t) + { + return new TypeExp(loc, t); + } + + TupleDeclaration tup = s.isTupleDeclaration(); + if (tup) + { + e = new TupleExp(loc, tup); + e = e.semantic(sc); + return e; + } + + TemplateInstance ti = s.isTemplateInstance(); + if (ti && !global.errors) + { + if (!ti.semanticRun) + ti.semantic(sc); + + s = ti.inst.toAlias(); + if (!s.isTemplateInstance()) + goto Lagain; + + e = new ScopeExp(loc, ti); + e = e.semantic(sc); + return e; + } + + TemplateDeclaration td = s.isTemplateDeclaration(); + if (td) + { + e = new TemplateExp(loc, td); + e = e.semantic(sc); + return e; + } + + Lerr: + error("%s '%s' is not a variable", s.kind(), s.toChars()); + type = Type.terror; return this; } - string toChars() + override string toChars() { assert(false); } - void dump(int indent) + override void dump(int indent) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - int isLvalue() + override int isLvalue() { assert(false); } - Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression e) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/DtorDeclaration.d --- a/dmd/DtorDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/DtorDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -28,12 +28,12 @@ super(loc, endloc, null, STC.init, null); } - Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol) { assert(false); } - 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); @@ -58,22 +58,22 @@ sc.pop(); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - string kind() + override string kind() { assert(false); } - string toChars() + override string toChars() { return "~this"; } - 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,25 +85,25 @@ } } - bool addPreInvariant() + override bool addPreInvariant() { return (isThis() && vthis && global.params.useInvariants); } - bool addPostInvariant() + override bool addPostInvariant() { return false; } - bool overloadInsert(Dsymbol s) + override bool overloadInsert(Dsymbol s) { assert(false); } - void emitComment(Scope sc) + override void emitComment(Scope sc) { assert(false); } - DtorDeclaration isDtorDeclaration() { return this; } -} \ No newline at end of file + override DtorDeclaration isDtorDeclaration() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/EnumDeclaration.d --- a/dmd/EnumDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/EnumDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -63,7 +63,7 @@ this.memtype = memtype; } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { Type t = null; if (memtype) @@ -80,7 +80,7 @@ return ed; } - void semantic(Scope sc) + override void semantic(Scope sc) { Type t; Scope sce; @@ -296,14 +296,14 @@ //members.print(); } - bool oneMember(Dsymbol* ps) + override bool oneMember(Dsymbol* ps) { if (isAnonymous()) return Dsymbol.oneMembers(members, ps); return Dsymbol.oneMember(ps); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { int i; @@ -340,18 +340,18 @@ buf.writenl(); } - Type getType() + override Type getType() { return type; } - string kind() + override string kind() { return "enum"; } version (DMDV2) { - Dsymbol search(Loc, Identifier ident, int flags) + override Dsymbol search(Loc, Identifier ident, int flags) { //printf("%s.EnumDeclaration.search('%s')\n", toChars(), ident.toChars()); if (scope_) @@ -368,24 +368,24 @@ return ScopeDsymbol.search(loc, ident, flags); } } - bool isDeprecated() // is Dsymbol deprecated? + override bool isDeprecated() // is Dsymbol deprecated? { return isdeprecated; } - void emitComment(Scope sc) + override void emitComment(Scope sc) { assert(false); } - void toDocBuffer(OutBuffer buf) + override void toDocBuffer(OutBuffer buf) { assert(false); } - EnumDeclaration isEnumDeclaration() { return this; } + override EnumDeclaration isEnumDeclaration() { return this; } - void toObjFile(int multiobj) // compile to .obj file + override void toObjFile(int multiobj) // compile to .obj file { //printf("EnumDeclaration.toObjFile('%s')\n", toChars()); version (DMDV2) { @@ -432,7 +432,7 @@ assert(false); } - int cvMember(ubyte* p) + override int cvMember(ubyte* p) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/EnumMember.d --- a/dmd/EnumMember.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/EnumMember.d Sat Aug 28 16:19:48 2010 +0200 @@ -23,7 +23,7 @@ this.loc = loc; } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { Expression e = null; if (value) @@ -45,7 +45,7 @@ return em; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { if (type) type.toCBuffer(buf, ident, hgs); @@ -58,20 +58,20 @@ } } - string kind() + override string kind() { return "enum member"; } - void emitComment(Scope sc) + override void emitComment(Scope sc) { assert(false); } - void toDocBuffer(OutBuffer buf) + override void toDocBuffer(OutBuffer buf) { assert(false); } - EnumMember isEnumMember() { return this; } + override EnumMember isEnumMember() { return this; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/EqualExp.d --- a/dmd/EqualExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/EqualExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,13 +1,13 @@ -module dmd.EqualExp; - -import dmd.Expression; +module dmd.EqualExp; + +import dmd.Expression; import dmd.Id; -import dmd.Identifier; -import dmd.InterState; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.BinExp; +import dmd.Identifier; +import dmd.InterState; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.BinExp; import dmd.TOK; import dmd.Type; import dmd.AddrExp; @@ -17,8 +17,8 @@ import dmd.Token; import dmd.NotExp; import dmd.WANT; -import dmd.GlobalExpressions; - +import dmd.GlobalExpressions; + import dmd.backend.elem; import dmd.backend.OPER; import dmd.backend.Util; @@ -29,8 +29,8 @@ import dmd.expression.util.arrayTypeCompatible; import dmd.expression.Util; -import dmd.expression.Equal; - +import dmd.expression.Equal; + class EqualExp : BinExp { this(TOK op, Loc loc, Expression e1, Expression e2) @@ -39,7 +39,7 @@ assert(op == TOK.TOKequal || op == TOK.TOKnotequal); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; Type t1; @@ -113,7 +113,7 @@ return e; } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -131,27 +131,27 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - int isBit() + override int isBit() { assert(false); } - bool isCommutative() + override bool isCommutative() { return true; } - Identifier opId() + override Identifier opId() { return Id.eq; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { //printf("EqualExp::toElem() %s\n", toChars()); elem* e; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ErrorExp.d --- a/dmd/ErrorExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ErrorExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,15 +1,15 @@ -module dmd.ErrorExp; - -import dmd.OutBuffer; -import dmd.IntegerExp; -import dmd.Loc; +module dmd.ErrorExp; + +import dmd.OutBuffer; +import dmd.IntegerExp; +import dmd.Loc; import dmd.HdrGenState; -import dmd.Type; +import dmd.Type; /* Use this expression for error recovery. * It should behave as a 'sink' to prevent further cascaded error messages. */ - + class ErrorExp : IntegerExp { this() @@ -17,7 +17,7 @@ super(Loc(0), 0, Type.terror); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("__error"); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ExpInitializer.d --- a/dmd/ExpInitializer.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ExpInitializer.d Sat Aug 28 16:19:48 2010 +0200 @@ -26,12 +26,12 @@ this.exp = exp; } - Initializer syntaxCopy() + override Initializer syntaxCopy() { return new ExpInitializer(loc, exp.syntaxCopy()); } - Initializer semantic(Scope sc, Type t) + override Initializer semantic(Scope sc, Type t) { //printf("ExpInitializer.semantic(%s), type = %s\n", exp.toChars(), t.toChars()); exp = exp.semantic(sc); @@ -70,7 +70,7 @@ return this; } - Type inferType(Scope sc) + override Type inferType(Scope sc) { //printf("ExpInitializer::inferType() %s\n", toChars()); exp = exp.semantic(sc); @@ -91,17 +91,17 @@ return t; } - Expression toExpression() + override Expression toExpression() { return exp; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - dt_t* toDt() + override dt_t* toDt() { dt_t* dt = null; @@ -111,5 +111,5 @@ return dt; } - ExpInitializer isExpInitializer() { return this; } -} \ No newline at end of file + override ExpInitializer isExpInitializer() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ExpStatement.d --- a/dmd/ExpStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ExpStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -31,14 +31,14 @@ this.exp = exp; } - Statement syntaxCopy() + override Statement syntaxCopy() { Expression e = exp ? exp.syntaxCopy() : null; ExpStatement es = new ExpStatement(loc, e); return es; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { if (exp) exp.toCBuffer(buf, hgs); @@ -47,7 +47,7 @@ buf.writenl(); } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { if (exp) { @@ -66,7 +66,7 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { version (LOG) { printf("ExpStatement.interpret(%s)\n", exp ? exp.toChars() : ""); @@ -84,7 +84,7 @@ return null; } - BE blockExit() + override BE blockExit() { BE result = BE.BEfallthru; @@ -105,12 +105,12 @@ return result; } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { return exp ? exp.inlineCost(ics) : 0; } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { version (LOG) { if (exp) printf("ExpStatement.doInline() '%s'\n", exp.toChars()); @@ -118,7 +118,7 @@ return exp ? exp.doInline(ids) : null; } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { version (LOG) { printf("ExpStatement.inlineScan(%s)\n", toChars()); @@ -128,7 +128,7 @@ return this; } - void toIR(IRState* irs) + override void toIR(IRState* irs) { Blockx* blx = irs.blx; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/FileExp.d --- a/dmd/FileExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/FileExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,27 +1,27 @@ -module dmd.FileExp; - -import dmd.Expression; -import dmd.UnaExp; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.HdrGenState; -import dmd.TOK; - +module dmd.FileExp; + +import dmd.Expression; +import dmd.UnaExp; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.HdrGenState; +import dmd.TOK; + class FileExp : UnaExp { this(Loc loc, Expression e) { - assert(false); + assert(false); super(loc, TOK.init, 0, e); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/FileInitExp.d --- a/dmd/FileInitExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/FileInitExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,34 +1,34 @@ -module dmd.FileInitExp; - -import dmd.Expression; -import dmd.Loc; -import dmd.Scope; -import dmd.DefaultInitExp; -import dmd.StringExp; -import dmd.TOK; -import dmd.Util; -import dmd.Type; - -class FileInitExp : DefaultInitExp -{ - this(Loc loc) - { - super(loc, TOK.TOKfile, this.sizeof); - } - - Expression semantic(Scope sc) - { - type = Type.tchar.invariantOf().arrayOf(); - return this; - } - - Expression resolve(Loc loc, Scope sc) - { - //printf("FileInitExp::resolve() %.*s\n", toChars()); - string s = loc.filename ? loc.filename : sc.module_.ident.toChars(); - Expression e = new StringExp(loc, s); - e = e.semantic(sc); - e = e.castTo(sc, type); - return e; - } -} +module dmd.FileInitExp; + +import dmd.Expression; +import dmd.Loc; +import dmd.Scope; +import dmd.DefaultInitExp; +import dmd.StringExp; +import dmd.TOK; +import dmd.Util; +import dmd.Type; + +class FileInitExp : DefaultInitExp +{ + this(Loc loc) + { + super(loc, TOK.TOKfile, this.sizeof); + } + + override Expression semantic(Scope sc) + { + type = Type.tchar.invariantOf().arrayOf(); + return this; + } + + override Expression resolve(Loc loc, Scope sc) + { + //printf("FileInitExp::resolve() %.*s\n", toChars()); + string s = loc.filename ? loc.filename : sc.module_.ident.toChars(); + Expression e = new StringExp(loc, s); + e = e.semantic(sc); + e = e.castTo(sc, type); + return e; + } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/FileName.d --- a/dmd/FileName.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/FileName.d Sat Aug 28 16:19:48 2010 +0200 @@ -39,7 +39,7 @@ super(combine(path, name)); } - hash_t hashCode() + override hash_t hashCode() { version (_WIN32) { // We need a different hashCode because it must be case-insensitive @@ -84,7 +84,7 @@ } } - bool opEquals(Object obj) + override bool opEquals(Object obj) { return opCmp(obj) == 0; } @@ -94,7 +94,7 @@ return compare(name1, name2) == 0; } - int opCmp(Object obj) + override int opCmp(Object obj) { return compare(str, (cast(FileName)obj).str); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ForStatement.d --- a/dmd/ForStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ForStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -35,7 +35,7 @@ this.body_ = body_; } - Statement syntaxCopy() + override Statement syntaxCopy() { Statement i = null; if (init) @@ -50,7 +50,7 @@ return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { ScopeDsymbol sym = new ScopeDsymbol(); sym.parent = sc.scopesym; @@ -81,7 +81,7 @@ return this; } - void scopeCode(Scope sc, Statement* sentry, Statement* sexception, Statement* sfinally) + override void scopeCode(Scope sc, Statement* sentry, Statement* sexception, Statement* sfinally) { //printf("ForStatement::scopeCode()\n"); //print(); @@ -91,23 +91,23 @@ Statement.scopeCode(sc, sentry, sexception, sfinally); } - bool hasBreak() + override bool hasBreak() { //printf("ForStatement.hasBreak()\n"); return true; } - bool hasContinue() + override bool hasContinue() { return true; } - bool usesEH() + override bool usesEH() { return (init && init.usesEH()) || body_.usesEH(); } - BE blockExit() + override BE blockExit() { BE result = BE.BEfallthru; @@ -140,7 +140,7 @@ return result; } - bool comeFrom() + override bool comeFrom() { //printf("ForStatement.comeFrom()\n"); if (body_) @@ -152,12 +152,12 @@ return false; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("for ("); if (init) @@ -187,7 +187,7 @@ buf.writenl(); } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { if (init) init = init.inlineScan(iss); @@ -200,7 +200,7 @@ return this; } - void toIR(IRState* irs) + override void toIR(IRState* irs) { Blockx* blx = irs.blx; @@ -248,4 +248,4 @@ */ block_next(blx,BCgoto, mystate.breakBlock); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ForeachRangeStatement.d --- a/dmd/ForeachRangeStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ForeachRangeStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -51,7 +51,7 @@ this.body_ = body_; } - Statement syntaxCopy() + override Statement syntaxCopy() { ForeachRangeStatement s = new ForeachRangeStatement(loc, op, arg.syntaxCopy(), @@ -62,7 +62,7 @@ return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { //printf("ForeachRangeStatement.semantic() %p\n", this); ScopeDsymbol sym; @@ -177,48 +177,48 @@ } } - bool hasBreak() + override bool hasBreak() { assert(false); } - bool hasContinue() + override bool hasContinue() { assert(false); } - bool usesEH() + override bool usesEH() { assert(false); } - BE blockExit() + override BE blockExit() { assert(false); } - bool comeFrom() + override bool comeFrom() { assert(false); } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { assert(false); } - void toIR(IRState* irs) + override void toIR(IRState* irs) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ForeachStatement.d --- a/dmd/ForeachStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ForeachStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -98,7 +98,7 @@ cases = new Array(); } - Statement syntaxCopy() + override Statement syntaxCopy() { Arguments args = Argument.arraySyntaxCopy(arguments); Expression exp = aggr.syntaxCopy(); @@ -107,7 +107,7 @@ return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { //printf("ForeachStatement.semantic() %p\n", this); ScopeDsymbol sym; @@ -781,22 +781,22 @@ return result; } - bool hasBreak() + override bool hasBreak() { return true; } - bool hasContinue() + override bool hasContinue() { return true; } - bool usesEH() + override bool usesEH() { return body_.usesEH(); } - BE blockExit() + override BE blockExit() { BE result = BEfallthru; @@ -810,7 +810,7 @@ return result; } - bool comeFrom() + override bool comeFrom() { if (body_) return body_.comeFrom(); @@ -818,12 +818,12 @@ return false; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring(Token.toChars(op)); buf.writestring(" ("); @@ -851,7 +851,7 @@ buf.writenl(); } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { aggr = aggr.inlineScan(iss); if (body_) @@ -859,8 +859,8 @@ return this; } - void toIR(IRState* irs) + override void toIR(IRState* irs) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/FuncAliasDeclaration.d --- a/dmd/FuncAliasDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/FuncAliasDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -19,15 +19,15 @@ this.funcalias = funcalias; } - FuncAliasDeclaration isFuncAliasDeclaration() { return this; } + override FuncAliasDeclaration isFuncAliasDeclaration() { return this; } - string kind() + override string kind() { return "function alias"; } - Symbol* toSymbol() + override Symbol* toSymbol() { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/FuncDeclaration.d --- a/dmd/FuncDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/FuncDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -116,7 +116,7 @@ import core.stdc.string; version (Bug4054) import core.memory; -import dmd.interpret.Util; +import dmd.interpret.Util; import std.string; @@ -209,7 +209,7 @@ } } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { FuncDeclaration f; @@ -229,7 +229,7 @@ } // Do the semantic analysis on the external interface to the function. - void semantic(Scope sc) + override void semantic(Scope sc) { TypeFunction f; StructDeclaration sd; @@ -745,12 +745,12 @@ error("identity assignment operator overload is illegal"); } - void semantic2(Scope sc) + override void semantic2(Scope sc) { } // Do the semantic analysis on the internals of the function. - void semantic3(Scope sc) + override void semantic3(Scope sc) { TypeFunction f; VarDeclaration argptr = null; @@ -1528,7 +1528,7 @@ assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } @@ -1605,7 +1605,7 @@ * Overload this FuncDeclaration with the new one f. * Return !=0 if successful; i.e. no conflict. */ - bool overloadInsert(Dsymbol s) + override bool overloadInsert(Dsymbol s) { FuncDeclaration f; AliasDeclaration a; @@ -1829,7 +1829,7 @@ } return MATCHnomatch; } - + /******************************** * Labels are in a separate scope, one per function. */ @@ -1855,7 +1855,7 @@ * return the aggregate it is a member of. * Otherwise, return null. */ - AggregateDeclaration isThis() + override AggregateDeclaration isThis() { AggregateDeclaration ad = null; @@ -1952,7 +1952,7 @@ assert(false); } - string mangle() + override string mangle() out (result) { assert(result.length > 0); @@ -1971,7 +1971,7 @@ return Declaration.mangle(); } - string toPrettyChars() + override string toPrettyChars() { if (isMain()) return "D main"; @@ -2047,29 +2047,29 @@ return builtin; } - bool isExport() + override bool isExport() { return protection == PROT.PROTexport; } - bool isImportedSymbol() + override bool isImportedSymbol() { //printf("isImportedSymbol()\n"); //printf("protection = %d\n", protection); return (protection == PROT.PROTexport) && !fbody; } - bool isAbstract() + override bool isAbstract() { return (storage_class & STC.STCabstract) != 0; } - bool isCodeseg() + override bool isCodeseg() { return true; // functions are always in the code segment } - bool isOverloadable() + override bool isOverloadable() { return 1; // functions can be overloaded } @@ -2090,7 +2090,7 @@ (toParent2().isFuncDeclaration() !is null); } - bool needThis() + override bool needThis() { //printf("FuncDeclaration.needThis() '%s'\n", toChars()); bool needThis = isThis() !is null; @@ -2116,7 +2116,7 @@ return isMember() && !(isStatic() || protection == PROT.PROTprivate || protection == PROT.PROTpackage) && toParent().isClassDeclaration(); } - int isFinal() + override int isFinal() { ClassDeclaration cd; static if (false) { @@ -2428,7 +2428,7 @@ return e; } - void inlineScan() + override void inlineScan() { InlineScanState iss; @@ -2699,12 +2699,12 @@ return Expression.combine(e, eb); } - string kind() + override string kind() { return "function"; } - void toDocBuffer(OutBuffer buf) + override void toDocBuffer(OutBuffer buf) { assert(false); } @@ -2808,7 +2808,7 @@ return fd; } - Symbol* toSymbol() + override Symbol* toSymbol() { if (!csym) { @@ -2923,9 +2923,9 @@ type *t; n = sym.Sident; - version (Bug4054) { + version (Bug4054) { id = cast(char*) GC.malloc(8 + 5 + strlen(n) + 1); - } else { + } else { id = cast(char*) alloca(8 + 5 + strlen(n) + 1); } sprintf(id, "_thunk%d__%s", offset, n); @@ -2940,7 +2940,7 @@ return sthunk; } - void toObjFile(int multiobj) // compile to .obj file + override void toObjFile(int multiobj) // compile to .obj file { Symbol* s; func_t* f; @@ -3119,9 +3119,9 @@ pi += parameters.dim; // Allow extra 2 for sthis and shidden - version (Bug4054) + version (Bug4054) params = cast(Symbol**)GC.malloc((pi + 2) * (Symbol*).sizeof); - else + else params = cast(Symbol**)alloca((pi + 2) * (Symbol*).sizeof); // Get the actual number of parameters, pi, and fill in the params[] @@ -3377,7 +3377,7 @@ } } - int cvMember(ubyte* p) + override int cvMember(ubyte* p) { assert(false); } @@ -3529,5 +3529,5 @@ } } - FuncDeclaration isFuncDeclaration() { return this; } -} + override FuncDeclaration isFuncDeclaration() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/FuncExp.d --- a/dmd/FuncExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/FuncExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,14 +1,14 @@ -module dmd.FuncExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.InlineCostState; -import dmd.IRState; -import dmd.HdrGenState; -import dmd.FuncLiteralDeclaration; +module dmd.FuncExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.InlineCostState; +import dmd.IRState; +import dmd.HdrGenState; +import dmd.FuncLiteralDeclaration; import dmd.TOK; import dmd.TypeFunction; import dmd.TypeDelegate; @@ -19,8 +19,8 @@ import dmd.backend.Util; import dmd.codegen.Util; import dmd.backend.TYM; -import dmd.backend.Symbol; - +import dmd.backend.Symbol; + class FuncExp : Expression { FuncLiteralDeclaration fd; @@ -31,12 +31,12 @@ this.fd = fd; } - Expression syntaxCopy() + override Expression syntaxCopy() { return new FuncExp(loc, cast(FuncLiteralDeclaration)fd.syntaxCopy(null)); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { version (LOGSEMANTIC) { printf("FuncExp.semantic(%s)\n", toChars()); @@ -84,22 +84,22 @@ return this; } - void scanForNestedRef(Scope sc) + override void scanForNestedRef(Scope sc) { assert(false); } - string toChars() + override string toChars() { return fd.toChars(); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e; Symbol* s; @@ -118,7 +118,7 @@ return e; } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/FuncLiteralDeclaration.d --- a/dmd/FuncLiteralDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/FuncLiteralDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -35,12 +35,12 @@ //printf("FuncLiteralDeclaration() id = '%s', type = '%s'\n", this->ident->toChars(), type->toChars()); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { FuncLiteralDeclaration f; @@ -56,21 +56,21 @@ return f; } - bool isNested() + override bool isNested() { //printf("FuncLiteralDeclaration::isNested() '%s'\n", toChars()); return (tok == TOK.TOKdelegate); } - bool isVirtual() + override bool isVirtual() { return false; } - FuncLiteralDeclaration isFuncLiteralDeclaration() { return this; } + override FuncLiteralDeclaration isFuncLiteralDeclaration() { return this; } - string kind() + override string kind() { return (tok == TOKdelegate) ? "delegate" : "function"; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/GotoCaseStatement.d --- a/dmd/GotoCaseStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/GotoCaseStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -24,14 +24,14 @@ this.exp = exp; } - Statement syntaxCopy() + override Statement syntaxCopy() { Expression e = exp ? exp.syntaxCopy() : null; GotoCaseStatement s = new GotoCaseStatement(loc, e); return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { if (exp) exp = exp.semantic(sc); @@ -50,17 +50,17 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - BE blockExit() + override BE blockExit() { return BEgoto; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("goto case"); if (exp) @@ -72,8 +72,8 @@ buf.writenl(); } - void toIR(IRState* irs) + override void toIR(IRState* irs) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/GotoDefaultStatement.d --- a/dmd/GotoDefaultStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/GotoDefaultStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -26,13 +26,13 @@ sw = null; } - Statement syntaxCopy() + override Statement syntaxCopy() { GotoDefaultStatement s = new GotoDefaultStatement(loc); return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { sw = sc.sw; if (!sw) @@ -40,22 +40,22 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - BE blockExit() + override BE blockExit() { return BEgoto; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("goto default;\n"); } - void toIR(IRState *irs) + override void toIR(IRState *irs) { block *b; Blockx *blx = irs.blx; @@ -86,4 +86,4 @@ incUsage(irs, loc); block_next(blx,BCgoto,null); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/GotoStatement.d --- a/dmd/GotoStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/GotoStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -34,13 +34,13 @@ this.ident = ident; } - Statement syntaxCopy() + override Statement syntaxCopy() { GotoStatement s = new GotoStatement(loc, ident); return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { FuncDeclaration fd = sc.parent.isFuncDeclaration(); @@ -69,18 +69,18 @@ return this; } - BE blockExit() + override BE blockExit() { //printf("GotoStatement.blockExit(%p)\n", this); return BE.BEgoto; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void toIR(IRState* irs) + override void toIR(IRState* irs) { block* b; block* bdest; @@ -121,7 +121,7 @@ block_next(blx,BCgoto,null); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("goto "); buf.writestring(ident.toChars()); @@ -129,5 +129,5 @@ buf.writenl(); } - GotoStatement isGotoStatement() { return this; } -} \ No newline at end of file + override GotoStatement isGotoStatement() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/HaltExp.d --- a/dmd/HaltExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/HaltExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,20 +1,20 @@ -module dmd.HaltExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; +module dmd.HaltExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; import dmd.IRState; -import dmd.Type; -import dmd.HdrGenState; -import dmd.Loc; +import dmd.Type; +import dmd.HdrGenState; +import dmd.Loc; import dmd.TOK; import dmd.backend.Util; import dmd.backend.OPER; -import dmd.backend.TYM; - +import dmd.backend.TYM; + class HaltExp : Expression { this(Loc loc) @@ -22,7 +22,7 @@ super(loc, TOK.TOKhalt, HaltExp.sizeof); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { version (LOGSEMANTIC) { printf("HaltExp.semantic()\n"); @@ -31,17 +31,17 @@ return this; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("halt"); } - bool checkSideEffect(int flag) + override bool checkSideEffect(int flag) { return true; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem *e; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/Identifier.d --- a/dmd/Identifier.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/Identifier.d Sat Aug 28 16:19:48 2010 +0200 @@ -28,7 +28,7 @@ assert(false); } - int opCmp(Object o) + override int opCmp(Object o) { assert(false); } @@ -76,4 +76,4 @@ string id = buf.extractString(); return Lexer.idPool(id); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/IdentifierExp.d --- a/dmd/IdentifierExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/IdentifierExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,26 +1,26 @@ -module dmd.IdentifierExp; - -import dmd.Expression; -import dmd.Declaration; -import dmd.TY; -import dmd.TypePointer; -import dmd.FuncDeclaration; -import dmd.TemplateInstance; -import dmd.TemplateDeclaration; -import dmd.TemplateExp; -import dmd.DsymbolExp; -import dmd.Identifier; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.Dsymbol; -import dmd.WithScopeSymbol; -import dmd.VarExp; -import dmd.DotIdExp; -import dmd.Type; -import dmd.HdrGenState; -import dmd.TOK; - +module dmd.IdentifierExp; + +import dmd.Expression; +import dmd.Declaration; +import dmd.TY; +import dmd.TypePointer; +import dmd.FuncDeclaration; +import dmd.TemplateInstance; +import dmd.TemplateDeclaration; +import dmd.TemplateExp; +import dmd.DsymbolExp; +import dmd.Identifier; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.Dsymbol; +import dmd.WithScopeSymbol; +import dmd.VarExp; +import dmd.DotIdExp; +import dmd.Type; +import dmd.HdrGenState; +import dmd.TOK; + class IdentifierExp : Expression { Identifier ident; @@ -29,142 +29,142 @@ this(Loc loc, Identifier ident) { - super(loc, TOK.TOKidentifier, IdentifierExp.sizeof); + super(loc, TOK.TOKidentifier, IdentifierExp.sizeof); this.ident = ident; } this(Loc loc, Declaration var) { - assert(false); + assert(false); super(loc, TOK.init, 0); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { - Dsymbol s; - Dsymbol scopesym; - -version (LOGSEMANTIC) { - printf("IdentifierExp.semantic('%s')\n", ident.toChars()); -} - s = sc.search(loc, ident, &scopesym); - if (s) - { - Expression e; - WithScopeSymbol withsym; - - /* See if the symbol was a member of an enclosing 'with' - */ - withsym = scopesym.isWithScopeSymbol(); - if (withsym) - { -version (DMDV2) { - /* Disallow shadowing - */ - // First find the scope of the with - Scope scwith = sc; - while (scwith.scopesym !is scopesym) - { - scwith = scwith.enclosing; - assert(scwith); - } - - // Look at enclosing scopes for symbols with the same name, - // in the same function - for (Scope scx = scwith; scx && scx.func == scwith.func; scx = scx.enclosing) - { - Dsymbol s2; - - if (scx.scopesym && scx.scopesym.symtab && (s2 = scx.scopesym.symtab.lookup(s.ident)) !is null && s !is s2) - { - error("with symbol %s is shadowing local symbol %s", s.toPrettyChars(), s2.toPrettyChars()); - } - } -} - s = s.toAlias(); - - // Same as wthis.ident - if (s.needThis() || s.isTemplateDeclaration()) - { - e = new VarExp(loc, withsym.withstate.wthis); - e = new DotIdExp(loc, e, ident); - } - else - { - Type t = withsym.withstate.wthis.type; - if (t.ty == TY.Tpointer) - t = (cast(TypePointer)t).next; - e = typeDotIdExp(loc, t, ident); - } - } - else - { - /* If f is really a function template, - * then replace f with the function template declaration. - */ - FuncDeclaration f = s.isFuncDeclaration(); - if (f && f.parent) - { - TemplateInstance ti = f.parent.isTemplateInstance(); - - if (ti && !ti.isTemplateMixin() && - (ti.name == f.ident || ti.toAlias().ident == f.ident) && - ti.tempdecl && ti.tempdecl.onemember) - { - TemplateDeclaration tempdecl = ti.tempdecl; - - if (tempdecl.overroot) // if not start of overloaded list of TemplateDeclaration's - tempdecl = tempdecl.overroot; // then get the start - - e = new TemplateExp(loc, tempdecl); - e = e.semantic(sc); - - return e; - } - } - - // Haven't done overload resolution yet, so pass 1 - e = new DsymbolExp(loc, s, 1); - } - - return e.semantic(sc); - } - - error("undefined identifier %s", ident.toChars()); - type = Type.terror; + Dsymbol s; + Dsymbol scopesym; + +version (LOGSEMANTIC) { + printf("IdentifierExp.semantic('%s')\n", ident.toChars()); +} + s = sc.search(loc, ident, &scopesym); + if (s) + { + Expression e; + WithScopeSymbol withsym; + + /* See if the symbol was a member of an enclosing 'with' + */ + withsym = scopesym.isWithScopeSymbol(); + if (withsym) + { +version (DMDV2) { + /* Disallow shadowing + */ + // First find the scope of the with + Scope scwith = sc; + while (scwith.scopesym !is scopesym) + { + scwith = scwith.enclosing; + assert(scwith); + } + + // Look at enclosing scopes for symbols with the same name, + // in the same function + for (Scope scx = scwith; scx && scx.func == scwith.func; scx = scx.enclosing) + { + Dsymbol s2; + + if (scx.scopesym && scx.scopesym.symtab && (s2 = scx.scopesym.symtab.lookup(s.ident)) !is null && s !is s2) + { + error("with symbol %s is shadowing local symbol %s", s.toPrettyChars(), s2.toPrettyChars()); + } + } +} + s = s.toAlias(); + + // Same as wthis.ident + if (s.needThis() || s.isTemplateDeclaration()) + { + e = new VarExp(loc, withsym.withstate.wthis); + e = new DotIdExp(loc, e, ident); + } + else + { + Type t = withsym.withstate.wthis.type; + if (t.ty == TY.Tpointer) + t = (cast(TypePointer)t).next; + e = typeDotIdExp(loc, t, ident); + } + } + else + { + /* If f is really a function template, + * then replace f with the function template declaration. + */ + FuncDeclaration f = s.isFuncDeclaration(); + if (f && f.parent) + { + TemplateInstance ti = f.parent.isTemplateInstance(); + + if (ti && !ti.isTemplateMixin() && + (ti.name == f.ident || ti.toAlias().ident == f.ident) && + ti.tempdecl && ti.tempdecl.onemember) + { + TemplateDeclaration tempdecl = ti.tempdecl; + + if (tempdecl.overroot) // if not start of overloaded list of TemplateDeclaration's + tempdecl = tempdecl.overroot; // then get the start + + e = new TemplateExp(loc, tempdecl); + e = e.semantic(sc); + + return e; + } + } + + // Haven't done overload resolution yet, so pass 1 + e = new DsymbolExp(loc, s, 1); + } + + return e.semantic(sc); + } + + error("undefined identifier %s", ident.toChars()); + type = Type.terror; return this; } - string toChars() + override string toChars() { return ident.toChars(); } - void dump(int indent) + override void dump(int indent) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - if (hgs.hdrgen) - buf.writestring(ident.toHChars2()); - else + if (hgs.hdrgen) + buf.writestring(ident.toHChars2()); + else buf.writestring(ident.toChars()); } - int isLvalue() + override int isLvalue() { return 1; } - Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression e) { -static if (false) { - tym = tybasic(e1.ET.Tty); - if (!(tyscalar(tym) || tym == TYM.TYstruct || tym == TYM.TYarray && e.Eoper == TOK.TOKaddr)) - synerr(EM_lvalue); // lvalue expected -} +static if (false) { + tym = tybasic(e1.ET.Tty); + if (!(tyscalar(tym) || tym == TYM.TYstruct || tym == TYM.TYarray && e.Eoper == TOK.TOKaddr)) + synerr(EM_lvalue); // lvalue expected +} return this; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/IdentityExp.d --- a/dmd/IdentityExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/IdentityExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,23 +1,23 @@ -module dmd.IdentityExp; - -import dmd.Expression; -import dmd.InterState; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.BinExp; +module dmd.IdentityExp; + +import dmd.Expression; +import dmd.InterState; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.BinExp; import dmd.TOK; import dmd.Type; import dmd.WANT; import dmd.TY; -import dmd.expression.Identity; - +import dmd.expression.Identity; + import dmd.backend.elem; import dmd.backend.TYM; import dmd.backend.OPER; import dmd.backend.Util; -import dmd.codegen.Util; - +import dmd.codegen.Util; + class IdentityExp : BinExp { this(TOK op, Loc loc, Expression e1, Expression e2) @@ -25,7 +25,7 @@ super(loc, op, IdentityExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { if (type) return this; @@ -44,12 +44,12 @@ return this; } - int isBit() + override int isBit() { assert(false); } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -66,12 +66,12 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem *e; OPER eop; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/IfStatement.d --- a/dmd/IfStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/IfStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -47,7 +47,7 @@ this.elsebody = elsebody; } - Statement syntaxCopy() + override Statement syntaxCopy() { Statement i = null; if (ifbody) @@ -62,7 +62,7 @@ return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { condition = condition.semantic(sc); condition = resolveProperties(sc, condition); @@ -119,22 +119,22 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - bool usesEH() + override bool usesEH() { assert(false); } - BE blockExit() + override BE blockExit() { //printf("IfStatement::blockExit(%p)\n", this); @@ -172,9 +172,9 @@ return result; } - IfStatement isIfStatement() { return this; } + override IfStatement isIfStatement() { return this; } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { int cost; @@ -214,7 +214,7 @@ return cost; } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { Expression econd; Expression e1; @@ -254,7 +254,7 @@ return e; } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { condition = condition.inlineScan(iss); if (ifbody) @@ -264,7 +264,7 @@ return this; } - void toIR(IRState* irs) + override void toIR(IRState* irs) { elem* e; Blockx* blx = irs.blx; @@ -318,4 +318,4 @@ block_next(blx, BC.BCgoto, bexit); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/Import.d --- a/dmd/Import.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/Import.d Sat Aug 28 16:19:48 2010 +0200 @@ -88,12 +88,12 @@ aliases.push(cast(void*)alias_); } - string kind() + override string kind() { return isstatic ? "static import" : "import"; } - Dsymbol syntaxCopy(Dsymbol s) // copy only syntax trees + override Dsymbol syntaxCopy(Dsymbol s) // copy only syntax trees { assert(false); } @@ -137,7 +137,7 @@ //writef("-Import::load('%s'), pkg = %p\n", toChars(), pkg); } - void semantic(Scope sc) + override void semantic(Scope sc) { //writef("Import.semantic('%s')\n", toChars()); @@ -261,7 +261,7 @@ //printf("-Import.semantic('%s'), pkg = %p\n", toChars(), pkg); } - void semantic2(Scope sc) + override void semantic2(Scope sc) { //printf("Import::semantic2('%s')\n", toChars()); mod.semantic2(); @@ -269,7 +269,7 @@ sc.module_.needmoduleinfo = 1; } - Dsymbol toAlias() + override Dsymbol toAlias() { if (aliasId) return mod; @@ -279,7 +279,7 @@ /***************************** * Add import to sd's symbol table. */ - bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) + override bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) { bool result = false; @@ -310,7 +310,7 @@ return result; } - Dsymbol search(Loc loc, Identifier ident, int flags) + override Dsymbol search(Loc loc, Identifier ident, int flags) { //printf("%s.Import.search(ident = '%s', flags = x%x)\n", toChars(), ident.toChars(), flags); @@ -324,16 +324,16 @@ return pkg.search(loc, ident, flags); } - bool overloadInsert(Dsymbol s) + override bool overloadInsert(Dsymbol s) { // Allow multiple imports of the same name return s.isImport() !is null; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - Import isImport() { return this; } -} \ No newline at end of file + override Import isImport() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/InExp.d --- a/dmd/InExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/InExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,26 +1,26 @@ -module dmd.InExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.BinExp; +module dmd.InExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.BinExp; import dmd.TOK; import dmd.Type; -import dmd.Id; +import dmd.Id; import dmd.TY; import dmd.TypeAArray; import dmd.expression.util.arrayTypeCompatible; - -import dmd.backend.elem; -import dmd.backend.TYM; -import dmd.backend.mTY; -import dmd.backend.OPER; -import dmd.backend.Symbol; -import dmd.backend.Util; - + +import dmd.backend.elem; +import dmd.backend.TYM; +import dmd.backend.mTY; +import dmd.backend.OPER; +import dmd.backend.Symbol; +import dmd.backend.Util; + class InExp : BinExp { this(Loc loc, Expression e1, Expression e2) @@ -28,7 +28,7 @@ super(loc, TOKin, InExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { if (type) return this; @@ -63,47 +63,47 @@ return this; } - int isBit() + override int isBit() { return 0; } - Identifier opId() + override Identifier opId() { return Id.opIn; } - Identifier opId_r() + override Identifier opId_r() { return Id.opIn_r; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { - elem* e; - elem* key = e1.toElem(irs); - elem* aa = e2.toElem(irs); - elem* ep; - elem* keyti; - TypeAArray taa = cast(TypeAArray)e2.type.toBasetype(); - - - // set to: - // aaIn(aa, keyti, key); - - if (tybasic(key.Ety) == TYstruct) - { - key = el_una(OPstrpar, TYstruct, key); - key.Enumbytes = key.E1.Enumbytes; - assert(key.Enumbytes); - } - - Symbol* s = taa.aaGetSymbol("In", 0); - keyti = taa.index.getInternalTypeInfo(null).toElem(irs); - ep = el_params(key, keyti, aa, null); - e = el_bin(OPcall, type.totym(), el_var(s), ep); - - el_setLoc(e,loc); + elem* e; + elem* key = e1.toElem(irs); + elem* aa = e2.toElem(irs); + elem* ep; + elem* keyti; + TypeAArray taa = cast(TypeAArray)e2.type.toBasetype(); + + + // set to: + // aaIn(aa, keyti, key); + + if (tybasic(key.Ety) == TYstruct) + { + key = el_una(OPstrpar, TYstruct, key); + key.Enumbytes = key.E1.Enumbytes; + assert(key.Enumbytes); + } + + Symbol* s = taa.aaGetSymbol("In", 0); + keyti = taa.index.getInternalTypeInfo(null).toElem(irs); + ep = el_params(key, keyti, aa, null); + e = el_bin(OPcall, type.totym(), el_var(s), ep); + + el_setLoc(e,loc); return e; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/IndexExp.d --- a/dmd/IndexExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/IndexExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,12 +1,12 @@ -module dmd.IndexExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.InterState; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.VarDeclaration; +module dmd.IndexExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.VarDeclaration; import dmd.InlineDoState; import dmd.Type; import dmd.ScopeDsymbol; @@ -15,10 +15,10 @@ import dmd.TypeNext; import dmd.TypeSArray; import dmd.TypeAArray; -import dmd.UnaExp; -import dmd.IRState; -import dmd.BinExp; -import dmd.HdrGenState; +import dmd.UnaExp; +import dmd.IRState; +import dmd.BinExp; +import dmd.HdrGenState; import dmd.TOK; import dmd.WANT; import dmd.TupleExp; @@ -42,8 +42,8 @@ import dmd.backend.mTY; import dmd.backend.TYM; -import core.stdc.string; - +import core.stdc.string; + class IndexExp : BinExp { VarDeclaration lengthVar; @@ -55,7 +55,7 @@ //printf("IndexExp.IndexExp('%s')\n", toChars()); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; BinExp b; @@ -184,19 +184,19 @@ return e; } - int isLvalue() + override int isLvalue() { assert(false); } - Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression e) { // if (type && type.toBasetype().ty == Tvoid) // error("voids have no value"); return this; } - Expression modifiableLvalue(Scope sc, Expression e) + override Expression modifiableLvalue(Scope sc, Expression e) { //printf("IndexExp::modifiableLvalue(%s)\n", toChars()); modifiable = 1; @@ -209,12 +209,12 @@ return toLvalue(sc, e); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -242,12 +242,12 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { IndexExp are = cast(IndexExp)copy(); @@ -284,12 +284,12 @@ return are; } - void scanForNestedRef(Scope sc) + override void scanForNestedRef(Scope sc) { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e; elem* n1 = e1.toElem(irs); diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/IntegerExp.d --- a/dmd/IntegerExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/IntegerExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,559 +1,559 @@ -module dmd.IntegerExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.TY; -import dmd.TypeEnum; -import dmd.TypeTypedef; -import dmd.Global; -import dmd.InterState; -import dmd.MATCH; -import dmd.Type; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IntRange; -import dmd.IRState; -import dmd.HdrGenState; -import dmd.TOK; -import dmd.Complex; - -import dmd.backend.dt_t; -import dmd.backend.Util; - -import core.stdc.ctype : isprint; - +module dmd.IntegerExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.TY; +import dmd.TypeEnum; +import dmd.TypeTypedef; +import dmd.Global; +import dmd.InterState; +import dmd.MATCH; +import dmd.Type; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IntRange; +import dmd.IRState; +import dmd.HdrGenState; +import dmd.TOK; +import dmd.Complex; + +import dmd.backend.dt_t; +import dmd.backend.Util; + +import core.stdc.ctype : isprint; + class IntegerExp : Expression { ulong value; this(Loc loc, ulong value, Type type) { - super(loc, TOK.TOKint64, IntegerExp.sizeof); - - //printf("IntegerExp(value = %lld, type = '%s')\n", value, type ? type.toChars() : ""); - if (type && !type.isscalar()) - { - //printf("%s, loc = %d\n", toChars(), loc.linnum); - error("integral constant must be scalar type, not %s", type.toChars()); - type = Type.terror; - } - this.type = type; + super(loc, TOK.TOKint64, IntegerExp.sizeof); + + //printf("IntegerExp(value = %lld, type = '%s')\n", value, type ? type.toChars() : ""); + if (type && !type.isscalar()) + { + //printf("%s, loc = %d\n", toChars(), loc.linnum); + error("integral constant must be scalar type, not %s", type.toChars()); + type = Type.terror; + } + this.type = type; this.value = value; } this(ulong value) - { + { super(Loc(0), TOK.TOKint64, IntegerExp.sizeof); - this.type = Type.tint32; + this.type = Type.tint32; this.value = value; } - bool equals(Object o) + override bool equals(Object o) { - IntegerExp ne; - - if (this == o || - ((cast(Expression)o).op == TOKint64 && - ((ne = cast(IntegerExp)o), type.toHeadMutable().equals(ne.type.toHeadMutable())) && - value == ne.value) - ) - return 1; - + IntegerExp ne; + + if (this == o || + ((cast(Expression)o).op == TOKint64 && + ((ne = cast(IntegerExp)o), type.toHeadMutable().equals(ne.type.toHeadMutable())) && + value == ne.value) + ) + return 1; + return 0; } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { - if (!type) - { - // Determine what the type of this number is - ulong number = value; - - if (number & 0x8000000000000000) - type = Type.tuns64; - else if (number & 0xFFFFFFFF80000000) - type = Type.tint64; - else - type = Type.tint32; - } - else - { if (!type.deco) - type = type.semantic(loc, sc); - } + if (!type) + { + // Determine what the type of this number is + ulong number = value; + + if (number & 0x8000000000000000) + type = Type.tuns64; + else if (number & 0xFFFFFFFF80000000) + type = Type.tint64; + else + type = Type.tint32; + } + else + { if (!type.deco) + type = type.semantic(loc, sc); + } return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { -version (LOG) { - printf("IntegerExp.interpret() %s\n", toChars()); -} +version (LOG) { + printf("IntegerExp.interpret() %s\n", toChars()); +} return this; } - string toChars() + override string toChars() { -static if (true) { - return Expression.toChars(); -} else { - static char buffer[value.sizeof * 3 + 1]; - int len = sprintf(buffer.ptr, "%jd", value); - return buffer[0..len].idup; +static if (true) { + return Expression.toChars(); +} else { + static char buffer[value.sizeof * 3 + 1]; + int len = sprintf(buffer.ptr, "%jd", value); + return buffer[0..len].idup; } } - void dump(int indent) + override void dump(int indent) { assert(false); } - IntRange getIntRange() + override IntRange getIntRange() { - IntRange ir; - ir.imin = value & type.sizemask(); - ir.imax = ir.imin; + IntRange ir; + ir.imin = value & type.sizemask(); + ir.imax = ir.imin; return ir; } - ulong toInteger() + override ulong toInteger() { - Type t; - - t = type; - while (t) - { - switch (t.ty) - { - case TY.Tbit: - case TY.Tbool: value = (value != 0); break; - case TY.Tint8: value = cast(byte) value; break; - case TY.Tchar: - case TY.Tuns8: value = cast(ubyte) value; break; - case TY.Tint16: value = cast(short) value; break; - case TY.Twchar: - case TY.Tuns16: value = cast(ushort)value; break; - case TY.Tint32: value = cast(int) value; break; - case TY.Tdchar: - case TY.Tuns32: value = cast(uint) value; break; - case TY.Tint64: value = cast(long) value; break; - case TY.Tuns64: value = cast(ulong) value; break; - case TY.Tpointer: - if (PTRSIZE == 4) - value = cast(uint) value; - else if (PTRSIZE == 8) - value = cast(ulong) value; - else - assert(0); - break; - - case TY.Tenum: - { - TypeEnum te = cast(TypeEnum)t; - t = te.sym.memtype; - continue; - } - - case TY.Ttypedef: - { - TypeTypedef tt = cast(TypeTypedef)t; - t = tt.sym.basetype; - continue; - } - - default: - /* This can happen if errors, such as - * the type is painted on like in fromConstInitializer(). - */ - if (!global.errors) - { - ///type.print(); - assert(0); - } - break; - } - break; - } + Type t; + + t = type; + while (t) + { + switch (t.ty) + { + case TY.Tbit: + case TY.Tbool: value = (value != 0); break; + case TY.Tint8: value = cast(byte) value; break; + case TY.Tchar: + case TY.Tuns8: value = cast(ubyte) value; break; + case TY.Tint16: value = cast(short) value; break; + case TY.Twchar: + case TY.Tuns16: value = cast(ushort)value; break; + case TY.Tint32: value = cast(int) value; break; + case TY.Tdchar: + case TY.Tuns32: value = cast(uint) value; break; + case TY.Tint64: value = cast(long) value; break; + case TY.Tuns64: value = cast(ulong) value; break; + case TY.Tpointer: + if (PTRSIZE == 4) + value = cast(uint) value; + else if (PTRSIZE == 8) + value = cast(ulong) value; + else + assert(0); + break; + + case TY.Tenum: + { + TypeEnum te = cast(TypeEnum)t; + t = te.sym.memtype; + continue; + } + + case TY.Ttypedef: + { + TypeTypedef tt = cast(TypeTypedef)t; + t = tt.sym.basetype; + continue; + } + + default: + /* This can happen if errors, such as + * the type is painted on like in fromConstInitializer(). + */ + if (!global.errors) + { + ///type.print(); + assert(0); + } + break; + } + break; + } return value; } - real toReal() + override real toReal() { - Type t; - - toInteger(); - t = type.toBasetype(); - if (t.ty == Tuns64) - return cast(real)cast(ulong)value; - else + Type t; + + toInteger(); + t = type.toBasetype(); + if (t.ty == Tuns64) + return cast(real)cast(ulong)value; + else return cast(real)cast(long)value; } - real toImaginary() + override real toImaginary() { assert(false); } - Complex!(real) toComplex() + override Complex!(real) toComplex() { assert(false); } - int isConst() + override int isConst() { return 1; } - bool isBool(bool result) + override bool isBool(bool result) { return result ? value != 0 : value == 0; } - MATCH implicitConvTo(Type t) + override MATCH implicitConvTo(Type t) { -static if (false) { - printf("IntegerExp.implicitConvTo(this=%s, type=%s, t=%s)\n", - toChars(), type.toChars(), t.toChars()); -} - - MATCH m = type.implicitConvTo(t); - if (m >= MATCH.MATCHconst) - return m; - - TY ty = type.toBasetype().ty; - TY toty = t.toBasetype().ty; - - if (m == MATCH.MATCHnomatch && t.ty == TY.Tenum) - goto Lno; - - switch (ty) - { - case TY.Tbit: - case TY.Tbool: - value &= 1; - ty = TY.Tint32; - break; - - case TY.Tint8: - value = cast(byte)value; - ty = TY.Tint32; - break; - - case TY.Tchar: - case TY.Tuns8: - value &= 0xFF; - ty = TY.Tint32; - break; - - case TY.Tint16: - value = cast(short)value; - ty = TY.Tint32; - break; - - case TY.Tuns16: - case TY.Twchar: - value &= 0xFFFF; - ty = TY.Tint32; - break; - - case TY.Tint32: - value = cast(int)value; - break; - - case TY.Tuns32: - case TY.Tdchar: - value &= 0xFFFFFFFF; - ty = TY.Tuns32; - break; - - default: - break; - } - - // Only allow conversion if no change in value - switch (toty) - { - case TY.Tbit: - case TY.Tbool: - if ((value & 1) != value) - goto Lno; - goto Lyes; - - case TY.Tint8: - if (cast(byte)value != value) - goto Lno; - goto Lyes; - - case TY.Tchar: - case TY.Tuns8: - //printf("value = %llu %llu\n", (dinteger_t)(unsigned char)value, value); - if (cast(ubyte)value != value) - goto Lno; - goto Lyes; - - case TY.Tint16: - if (cast(short)value != value) - goto Lno; - goto Lyes; - - case TY.Tuns16: - if (cast(ushort)value != value) - goto Lno; - goto Lyes; - - case TY.Tint32: - if (ty == TY.Tuns32) { - ; - } - else if (cast(int)value != value) { - goto Lno; - } - goto Lyes; - - case TY.Tuns32: - if (ty == TY.Tint32) { - } else if (cast(uint)value != value) { - goto Lno; - } - goto Lyes; - - case TY.Tdchar: - if (value > 0x10FFFF) { - goto Lno; - } - goto Lyes; - - case TY.Twchar: - if (cast(ushort)value != value) { - goto Lno; - } - goto Lyes; - - case TY.Tfloat32: - { - /*volatile*/ float f; /// - if (type.isunsigned()) { - f = cast(float)value; - if (f != value) { - goto Lno; - } - } else { - f = cast(float)cast(long)value; - if (f != cast(long)value) { - goto Lno; - } - } - goto Lyes; - } - - case TY.Tfloat64: - { - /*volatile*/ double f; /// - if (type.isunsigned()) { - f = cast(double)value; - if (f != value) - goto Lno; - } else { - f = cast(double)cast(long)value; - if (f != cast(long)value) - goto Lno; - } - goto Lyes; - } - - case TY.Tfloat80: - { - /*volatile*/ real f; /// - if (type.isunsigned()) { - f = cast(real)value; - if (f != value) - goto Lno; - } else { - f = cast(real)cast(long)value; - if (f != cast(long)value) - goto Lno; - } - goto Lyes; - } - - case TY.Tpointer: - //printf("type = %s\n", type.toBasetype().toChars()); - //printf("t = %s\n", t.toBasetype().toChars()); - if (ty == TY.Tpointer && type.toBasetype().nextOf().ty == t.toBasetype().nextOf().ty) - { - /* Allow things like: - * const char* P = cast(char *)3; - * char* q = P; - */ - goto Lyes; - } - break; - - default: - break; /// - } - - return Expression.implicitConvTo(t); - - Lyes: - //printf("MATCHconvert\n"); - return MATCH.MATCHconvert; - - Lno: - //printf("MATCHnomatch\n"); +static if (false) { + printf("IntegerExp.implicitConvTo(this=%s, type=%s, t=%s)\n", + toChars(), type.toChars(), t.toChars()); +} + + MATCH m = type.implicitConvTo(t); + if (m >= MATCH.MATCHconst) + return m; + + TY ty = type.toBasetype().ty; + TY toty = t.toBasetype().ty; + + if (m == MATCH.MATCHnomatch && t.ty == TY.Tenum) + goto Lno; + + switch (ty) + { + case TY.Tbit: + case TY.Tbool: + value &= 1; + ty = TY.Tint32; + break; + + case TY.Tint8: + value = cast(byte)value; + ty = TY.Tint32; + break; + + case TY.Tchar: + case TY.Tuns8: + value &= 0xFF; + ty = TY.Tint32; + break; + + case TY.Tint16: + value = cast(short)value; + ty = TY.Tint32; + break; + + case TY.Tuns16: + case TY.Twchar: + value &= 0xFFFF; + ty = TY.Tint32; + break; + + case TY.Tint32: + value = cast(int)value; + break; + + case TY.Tuns32: + case TY.Tdchar: + value &= 0xFFFFFFFF; + ty = TY.Tuns32; + break; + + default: + break; + } + + // Only allow conversion if no change in value + switch (toty) + { + case TY.Tbit: + case TY.Tbool: + if ((value & 1) != value) + goto Lno; + goto Lyes; + + case TY.Tint8: + if (cast(byte)value != value) + goto Lno; + goto Lyes; + + case TY.Tchar: + case TY.Tuns8: + //printf("value = %llu %llu\n", (dinteger_t)(unsigned char)value, value); + if (cast(ubyte)value != value) + goto Lno; + goto Lyes; + + case TY.Tint16: + if (cast(short)value != value) + goto Lno; + goto Lyes; + + case TY.Tuns16: + if (cast(ushort)value != value) + goto Lno; + goto Lyes; + + case TY.Tint32: + if (ty == TY.Tuns32) { + ; + } + else if (cast(int)value != value) { + goto Lno; + } + goto Lyes; + + case TY.Tuns32: + if (ty == TY.Tint32) { + } else if (cast(uint)value != value) { + goto Lno; + } + goto Lyes; + + case TY.Tdchar: + if (value > 0x10FFFF) { + goto Lno; + } + goto Lyes; + + case TY.Twchar: + if (cast(ushort)value != value) { + goto Lno; + } + goto Lyes; + + case TY.Tfloat32: + { + /*volatile*/ float f; /// + if (type.isunsigned()) { + f = cast(float)value; + if (f != value) { + goto Lno; + } + } else { + f = cast(float)cast(long)value; + if (f != cast(long)value) { + goto Lno; + } + } + goto Lyes; + } + + case TY.Tfloat64: + { + /*volatile*/ double f; /// + if (type.isunsigned()) { + f = cast(double)value; + if (f != value) + goto Lno; + } else { + f = cast(double)cast(long)value; + if (f != cast(long)value) + goto Lno; + } + goto Lyes; + } + + case TY.Tfloat80: + { + /*volatile*/ real f; /// + if (type.isunsigned()) { + f = cast(real)value; + if (f != value) + goto Lno; + } else { + f = cast(real)cast(long)value; + if (f != cast(long)value) + goto Lno; + } + goto Lyes; + } + + case TY.Tpointer: + //printf("type = %s\n", type.toBasetype().toChars()); + //printf("t = %s\n", t.toBasetype().toChars()); + if (ty == TY.Tpointer && type.toBasetype().nextOf().ty == t.toBasetype().nextOf().ty) + { + /* Allow things like: + * const char* P = cast(char *)3; + * char* q = P; + */ + goto Lyes; + } + break; + + default: + break; /// + } + + return Expression.implicitConvTo(t); + + Lyes: + //printf("MATCHconvert\n"); + return MATCH.MATCHconvert; + + Lno: + //printf("MATCHnomatch\n"); return MATCH.MATCHnomatch; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - long v = toInteger(); - - if (type) - { - Type t = type; - - L1: - switch (t.ty) - { - case TY.Tenum: - { - TypeEnum te = cast(TypeEnum)t; - buf.printf("cast(%s)", te.sym.toChars()); - t = te.sym.memtype; - goto L1; - } - - case TY.Ttypedef: - { - TypeTypedef tt = cast(TypeTypedef)t; - buf.printf("cast(%s)", tt.sym.toChars()); - t = tt.sym.basetype; - goto L1; - } - - case TY.Twchar: // BUG: need to cast(wchar) - case TY.Tdchar: // BUG: need to cast(dchar) - if (cast(ulong)v > 0xFF) - { - buf.printf("'\\U%08x'", v); - break; - } - case TY.Tchar: - if (v == '\'') - buf.writestring("'\\''"); - else if (isprint(cast(int)v) && v != '\\') - buf.printf("'%c'", cast(int)v); - else - buf.printf("'\\x%02x'", cast(int)v); - break; - - case TY.Tint8: - buf.writestring("cast(byte)"); - goto L2; - - case TY.Tint16: - buf.writestring("cast(short)"); - goto L2; - - case TY.Tint32: - L2: - buf.printf("%d", cast(int)v); - break; - - case TY.Tuns8: - buf.writestring("cast(ubyte)"); - goto L3; - - case TY.Tuns16: - buf.writestring("cast(ushort)"); - goto L3; - - case TY.Tuns32: - L3: - buf.printf("%du", cast(uint)v); - break; - - case TY.Tint64: - //buf.printf("%jdL", v); - buf.printf("%sL", v); - break; - - case TY.Tuns64: - L4: - //buf.printf("%juLU", v); - buf.printf("%sLU", v); - break; - - case TY.Tbit: - case TY.Tbool: - buf.writestring(v ? "true" : "false"); - break; - - case TY.Tpointer: - buf.writestring("cast("); - buf.writestring(t.toChars()); - buf.writeByte(')'); - if (PTRSIZE == 4) - goto L3; - else if (PTRSIZE == 8) - goto L4; - else - assert(0); - - default: - /* This can happen if errors, such as - * the type is painted on like in fromConstInitializer(). - */ - if (!global.errors) - { - debug { - writef("%s\n", t.toChars()); - } - assert(0); - } - break; - } - } - else if (v & 0x8000000000000000L) - buf.printf("0x%jx", v); - else + long v = toInteger(); + + if (type) + { + Type t = type; + + L1: + switch (t.ty) + { + case TY.Tenum: + { + TypeEnum te = cast(TypeEnum)t; + buf.printf("cast(%s)", te.sym.toChars()); + t = te.sym.memtype; + goto L1; + } + + case TY.Ttypedef: + { + TypeTypedef tt = cast(TypeTypedef)t; + buf.printf("cast(%s)", tt.sym.toChars()); + t = tt.sym.basetype; + goto L1; + } + + case TY.Twchar: // BUG: need to cast(wchar) + case TY.Tdchar: // BUG: need to cast(dchar) + if (cast(ulong)v > 0xFF) + { + buf.printf("'\\U%08x'", v); + break; + } + case TY.Tchar: + if (v == '\'') + buf.writestring("'\\''"); + else if (isprint(cast(int)v) && v != '\\') + buf.printf("'%c'", cast(int)v); + else + buf.printf("'\\x%02x'", cast(int)v); + break; + + case TY.Tint8: + buf.writestring("cast(byte)"); + goto L2; + + case TY.Tint16: + buf.writestring("cast(short)"); + goto L2; + + case TY.Tint32: + L2: + buf.printf("%d", cast(int)v); + break; + + case TY.Tuns8: + buf.writestring("cast(ubyte)"); + goto L3; + + case TY.Tuns16: + buf.writestring("cast(ushort)"); + goto L3; + + case TY.Tuns32: + L3: + buf.printf("%du", cast(uint)v); + break; + + case TY.Tint64: + //buf.printf("%jdL", v); + buf.printf("%sL", v); + break; + + case TY.Tuns64: + L4: + //buf.printf("%juLU", v); + buf.printf("%sLU", v); + break; + + case TY.Tbit: + case TY.Tbool: + buf.writestring(v ? "true" : "false"); + break; + + case TY.Tpointer: + buf.writestring("cast("); + buf.writestring(t.toChars()); + buf.writeByte(')'); + if (PTRSIZE == 4) + goto L3; + else if (PTRSIZE == 8) + goto L4; + else + assert(0); + + default: + /* This can happen if errors, such as + * the type is painted on like in fromConstInitializer(). + */ + if (!global.errors) + { + debug { + writef("%s\n", t.toChars()); + } + assert(0); + } + break; + } + } + else if (v & 0x8000000000000000L) + buf.printf("0x%jx", v); + else buf.printf("%jd", v); } - void toMangleBuffer(OutBuffer buf) + override void toMangleBuffer(OutBuffer buf) { - if (cast(long)value < 0) - buf.printf("N%d", -value); - else - buf.printf("%d", value); + if (cast(long)value < 0) + buf.printf("N%d", -value); + else + buf.printf("%d", value); } - Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression e) { - if (!e) - e = this; - else if (!loc.filename) - loc = e.loc; - e.error("constant %s is not an lvalue", e.toChars()); + if (!e) + e = this; + else if (!loc.filename) + loc = e.loc; + e.error("constant %s is not an lvalue", e.toChars()); return this; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { - elem* e = el_long(type.totym(), value); - el_setLoc(e,loc); + elem* e = el_long(type.totym(), value); + el_setLoc(e,loc); return e; } - dt_t** toDt(dt_t** pdt) + override dt_t** toDt(dt_t** pdt) { - //printf("IntegerExp.toDt() %d\n", op); - uint sz = cast(uint)type.size(); - if (value == 0) - pdt = dtnzeros(pdt, sz); - else - pdt = dtnbytes(pdt, sz, cast(char*)&value); - + //printf("IntegerExp.toDt() %d\n", op); + uint sz = cast(uint)type.size(); + if (value == 0) + pdt = dtnzeros(pdt, sz); + else + pdt = dtnbytes(pdt, sz, cast(char*)&value); + return pdt; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/InterfaceDeclaration.d --- a/dmd/InterfaceDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/InterfaceDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -47,12 +47,12 @@ } } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { assert(false); } - void semantic(Scope sc) + override void semantic(Scope sc) { int i; @@ -252,7 +252,7 @@ //printf("-InterfaceDeclaration.semantic(%s), type = %p\n", toChars(), type); } - bool isBaseOf(ClassDeclaration cd, int* poffset) + override bool isBaseOf(ClassDeclaration cd, int* poffset) { uint j; @@ -319,7 +319,7 @@ return 0; } - string kind() + override string kind() { assert(false); } @@ -330,7 +330,7 @@ * For COM interfaces, no. * For non-COM interfaces, yes, this is where the Interface ptr goes. */ - int vtblOffset() + override int vtblOffset() { if (isCOMinterface() || isCPPinterface()) return 0; @@ -338,17 +338,17 @@ } version (DMDV2) { - bool isCPPinterface() + override bool isCPPinterface() { return cpp; } } - bool isCOMinterface() + override bool isCOMinterface() { return com; } - void toObjFile(int multiobj) // compile to .obj file + override void toObjFile(int multiobj) // compile to .obj file { uint i; uint offset; @@ -514,7 +514,7 @@ /************************************* * Create the "InterfaceInfo" symbol */ - Symbol* toSymbol() + override Symbol* toSymbol() { if (!csym) { @@ -532,5 +532,5 @@ return csym; } - InterfaceDeclaration isInterfaceDeclaration() { return this; } + override InterfaceDeclaration isInterfaceDeclaration() { return this; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/InvariantDeclaration.d --- a/dmd/InvariantDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/InvariantDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -20,7 +20,7 @@ super(loc, endloc, Id.classInvariant, STCundefined, null); } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { assert(!s); InvariantDeclaration id = new InvariantDeclaration(loc, endloc); @@ -28,7 +28,7 @@ return id; } - void semantic(Scope sc) + override void semantic(Scope sc) { AggregateDeclaration ad; Type tret; @@ -58,27 +58,27 @@ sc.pop(); } - bool isVirtual() + override bool isVirtual() { return false; } - bool addPreInvariant() + override bool addPreInvariant() { return false; } - bool addPostInvariant() + override bool addPostInvariant() { return false; } - void emitComment(Scope sc) + override void emitComment(Scope sc) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { if (hgs.hdrgen) return; @@ -86,5 +86,5 @@ bodyToCBuffer(buf, hgs); } - InvariantDeclaration isInvariantDeclaration() { return this; } -} \ No newline at end of file + override InvariantDeclaration isInvariantDeclaration() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/IsExp.d --- a/dmd/IsExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/IsExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,13 +1,13 @@ -module dmd.IsExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.ArrayTypes; -import dmd.Type; -import dmd.TOK; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; +module dmd.IsExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.ArrayTypes; +import dmd.Type; +import dmd.TOK; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; import dmd.HdrGenState; import dmd.TY; import dmd.TypeEnum; @@ -27,9 +27,9 @@ import dmd.TypeFunction; import dmd.MATCH; import dmd.TypePointer; -import dmd.Argument; -import dmd.Token; - +import dmd.Argument; +import dmd.Token; + class IsExp : Expression { /* is(targ id tok tspec) @@ -54,31 +54,31 @@ this.parameters = parameters; } - Expression syntaxCopy() + override Expression syntaxCopy() { - // This section is identical to that in TemplateDeclaration.syntaxCopy() - TemplateParameters p = null; - if (parameters) - { - p = new TemplateParameters(); - p.setDim(parameters.dim); - for (int i = 0; i < p.dim; i++) - { - TemplateParameter tp = cast(TemplateParameter)parameters.data[i]; - p.data[i] = cast(void*)tp.syntaxCopy(); - } - } - - return new IsExp(loc, - targ.syntaxCopy(), - id, - tok, - tspec ? tspec.syntaxCopy() : null, - tok2, + // This section is identical to that in TemplateDeclaration.syntaxCopy() + TemplateParameters p = null; + if (parameters) + { + p = new TemplateParameters(); + p.setDim(parameters.dim); + for (int i = 0; i < p.dim; i++) + { + TemplateParameter tp = cast(TemplateParameter)parameters.data[i]; + p.data[i] = cast(void*)tp.syntaxCopy(); + } + } + + return new IsExp(loc, + targ.syntaxCopy(), + id, + tok, + tspec ? tspec.syntaxCopy() : null, + tok2, p); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Type tded; @@ -335,34 +335,34 @@ return new IntegerExp(loc, 0, Type.tbool); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - buf.writestring("is("); - targ.toCBuffer(buf, id, hgs); - if (tok2 != TOKreserved) - { - buf.printf(" %s %s", Token.toChars(tok), Token.toChars(tok2)); - } - else if (tspec) - { - if (tok == TOKcolon) - buf.writestring(" : "); - else - buf.writestring(" == "); - tspec.toCBuffer(buf, null, hgs); - } -version (DMDV2) { - if (parameters) - { - // First parameter is already output, so start with second - for (int i = 1; i < parameters.dim; i++) - { - buf.writeByte(','); - TemplateParameter tp = cast(TemplateParameter)parameters.data[i]; - tp.toCBuffer(buf, hgs); - } - } -} + buf.writestring("is("); + targ.toCBuffer(buf, id, hgs); + if (tok2 != TOKreserved) + { + buf.printf(" %s %s", Token.toChars(tok), Token.toChars(tok2)); + } + else if (tspec) + { + if (tok == TOKcolon) + buf.writestring(" : "); + else + buf.writestring(" == "); + tspec.toCBuffer(buf, null, hgs); + } +version (DMDV2) { + if (parameters) + { + // First parameter is already output, so start with second + for (int i = 1; i < parameters.dim; i++) + { + buf.writeByte(','); + TemplateParameter tp = cast(TemplateParameter)parameters.data[i]; + tp.toCBuffer(buf, hgs); + } + } +} buf.writeByte(')'); } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/LabelDsymbol.d --- a/dmd/LabelDsymbol.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/LabelDsymbol.d Sat Aug 28 16:19:48 2010 +0200 @@ -17,8 +17,8 @@ super(ident); } - LabelDsymbol isLabel() + override LabelDsymbol isLabel() { return this; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/LabelStatement.d --- a/dmd/LabelStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/LabelStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -38,13 +38,13 @@ this.statement = statement; } - Statement syntaxCopy() + override Statement syntaxCopy() { LabelStatement s = new LabelStatement(loc, ident, statement.syntaxCopy()); return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { LabelDsymbol ls; FuncDeclaration fd = sc.parent.isFuncDeclaration(); @@ -66,7 +66,7 @@ return this; } - Statements flatten(Scope sc) + override Statements flatten(Scope sc) { Statements a = null; @@ -88,29 +88,29 @@ return a; } - bool usesEH() + override bool usesEH() { return statement ? statement.usesEH() : false; } - BE blockExit() + override BE blockExit() { //printf("LabelStatement.blockExit(%p)\n", this); return statement ? statement.blockExit() : BE.BEfallthru; } - bool comeFrom() + override bool comeFrom() { //printf("LabelStatement.comeFrom()\n"); return true; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring(ident.toChars()); buf.writebyte(':'); @@ -119,14 +119,14 @@ statement.toCBuffer(buf, hgs); } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { if (statement) statement = statement.inlineScan(iss); return this; } - void toIR(IRState* irs) + override void toIR(IRState* irs) { //printf("LabelStatement.toIR() %p, statement = %p\n", this, statement); Blockx* blx = irs.blx; @@ -150,4 +150,4 @@ if (statement) statement.toIR(&mystate); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/LineInitExp.d --- a/dmd/LineInitExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/LineInitExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,30 +1,30 @@ -module dmd.LineInitExp; - -import dmd.Expression; -import dmd.Loc; -import dmd.Scope; -import dmd.DefaultInitExp; -import dmd.IntegerExp; -import dmd.TOK; -import dmd.Type; - -class LineInitExp : DefaultInitExp -{ - this(Loc loc) - { - super(loc, TOK.TOKline, this.sizeof); - } - - Expression semantic(Scope sc) - { - type = Type.tint32; - return this; - } - - Expression resolve(Loc loc, Scope sc) - { - Expression e = new IntegerExp(loc, loc.linnum, Type.tint32); - e = e.castTo(sc, type); - return e; - } -} +module dmd.LineInitExp; + +import dmd.Expression; +import dmd.Loc; +import dmd.Scope; +import dmd.DefaultInitExp; +import dmd.IntegerExp; +import dmd.TOK; +import dmd.Type; + +class LineInitExp : DefaultInitExp +{ + this(Loc loc) + { + super(loc, TOK.TOKline, this.sizeof); + } + + override Expression semantic(Scope sc) + { + type = Type.tint32; + return this; + } + + override Expression resolve(Loc loc, Scope sc) + { + Expression e = new IntegerExp(loc, loc.linnum, Type.tint32); + e = e.castTo(sc, type); + return e; + } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/LinkDeclaration.d --- a/dmd/LinkDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/LinkDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -19,12 +19,12 @@ linkage = p; } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { assert(false); } - void setScope(Scope sc) + override void setScope(Scope sc) { //printf("LinkDeclaration::setScope(linkage = %d, decl = %p)\n", linkage, decl); if (decl) @@ -33,7 +33,7 @@ } } - void semantic(Scope sc) + override void semantic(Scope sc) { //printf("LinkDeclaration::semantic(linkage = %d, decl = %p)\n", linkage, decl); if (decl) @@ -42,7 +42,7 @@ } } - void semantic3(Scope sc) + override void semantic3(Scope sc) { //printf("LinkDeclaration::semantic3(linkage = %d, decl = %p)\n", linkage, decl); if (decl) @@ -63,13 +63,13 @@ } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - string toChars() + override string toChars() { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/MinAssignExp.d --- a/dmd/MinAssignExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/MinAssignExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -24,7 +24,7 @@ super(loc, TOK.TOKminass, MinAssignExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -66,28 +66,28 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { AssignExp_buildArrayIdent(buf, arguments, "Min"); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { assert(false); } - Identifier opId() /* For operator overloading */ + override Identifier opId() /* For operator overloading */ { return Id.subass; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs,OPminass); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/MinExp.d --- a/dmd/MinExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/MinExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,27 +1,27 @@ -module dmd.MinExp; - -import dmd.Expression; -import dmd.TY; -import dmd.ErrorExp; -import dmd.Identifier; -import dmd.IntegerExp; -import dmd.DivExp; -import dmd.Type; -import dmd.InterState; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.ArrayTypes; -import dmd.BinExp; -import dmd.TOK; -import dmd.Id; -import dmd.expression.Min; - -import dmd.backend.elem; -import dmd.backend.Util; -import dmd.backend.OPER; - +module dmd.MinExp; + +import dmd.Expression; +import dmd.TY; +import dmd.ErrorExp; +import dmd.Identifier; +import dmd.IntegerExp; +import dmd.DivExp; +import dmd.Type; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.ArrayTypes; +import dmd.BinExp; +import dmd.TOK; +import dmd.Id; +import dmd.expression.Min; + +import dmd.backend.elem; +import dmd.backend.Util; +import dmd.backend.OPER; + class MinExp : BinExp { this(Loc loc, Expression e1, Expression e2) @@ -29,156 +29,156 @@ super(loc, TOK.TOKmin, MinExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { - Expression e; - Type t1; - Type t2; - -version (LOGSEMANTIC) { - printf("MinExp.semantic('%s')\n", toChars()); -} - if (type) - return this; - - super.semanticp(sc); - - e = op_overload(sc); - if (e) - return e; - - e = this; - t1 = e1.type.toBasetype(); - t2 = e2.type.toBasetype(); - if (t1.ty == TY.Tpointer) - { - if (t2.ty == TY.Tpointer) - { // Need to divide the result by the stride - // Replace (ptr - ptr) with (ptr - ptr) / stride - long stride; - Expression ee; - - typeCombine(sc); // make sure pointer types are compatible - type = Type.tptrdiff_t; - stride = t2.nextOf().size(); - if (stride == 0) - { - ee = new IntegerExp(loc, 0, Type.tptrdiff_t); - } - else - { - ee = new DivExp(loc, this, new IntegerExp(Loc(0), stride, Type.tptrdiff_t)); - ee.type = Type.tptrdiff_t; - } - return ee; - } - else if (t2.isintegral()) - e = scaleFactor(sc); - else - { - error("incompatible types for minus"); - return new ErrorExp(); - } - } - else if (t2.ty == TY.Tpointer) - { - type = e2.type; - error("can't subtract pointer from %s", e1.type.toChars()); - return new ErrorExp(); - } - else - { - typeCombine(sc); - t1 = e1.type.toBasetype(); - t2 = e2.type.toBasetype(); - if ((t1.isreal() && t2.isimaginary()) || - (t1.isimaginary() && t2.isreal())) - { - switch (type.ty) - { - case TY.Tfloat32: - case TY.Timaginary32: - type = Type.tcomplex32; - break; - - case TY.Tfloat64: - case TY.Timaginary64: - type = Type.tcomplex64; - break; - - case TY.Tfloat80: - case TY.Timaginary80: - type = Type.tcomplex80; - break; - - default: - assert(0); - } - } - } + Expression e; + Type t1; + Type t2; + +version (LOGSEMANTIC) { + printf("MinExp.semantic('%s')\n", toChars()); +} + if (type) + return this; + + super.semanticp(sc); + + e = op_overload(sc); + if (e) + return e; + + e = this; + t1 = e1.type.toBasetype(); + t2 = e2.type.toBasetype(); + if (t1.ty == TY.Tpointer) + { + if (t2.ty == TY.Tpointer) + { // Need to divide the result by the stride + // Replace (ptr - ptr) with (ptr - ptr) / stride + long stride; + Expression ee; + + typeCombine(sc); // make sure pointer types are compatible + type = Type.tptrdiff_t; + stride = t2.nextOf().size(); + if (stride == 0) + { + ee = new IntegerExp(loc, 0, Type.tptrdiff_t); + } + else + { + ee = new DivExp(loc, this, new IntegerExp(Loc(0), stride, Type.tptrdiff_t)); + ee.type = Type.tptrdiff_t; + } + return ee; + } + else if (t2.isintegral()) + e = scaleFactor(sc); + else + { + error("incompatible types for minus"); + return new ErrorExp(); + } + } + else if (t2.ty == TY.Tpointer) + { + type = e2.type; + error("can't subtract pointer from %s", e1.type.toChars()); + return new ErrorExp(); + } + else + { + typeCombine(sc); + t1 = e1.type.toBasetype(); + t2 = e2.type.toBasetype(); + if ((t1.isreal() && t2.isimaginary()) || + (t1.isimaginary() && t2.isreal())) + { + switch (type.ty) + { + case TY.Tfloat32: + case TY.Timaginary32: + type = Type.tcomplex32; + break; + + case TY.Tfloat64: + case TY.Timaginary64: + type = Type.tcomplex64; + break; + + case TY.Tfloat80: + case TY.Timaginary80: + type = Type.tcomplex80; + break; + + default: + assert(0); + } + } + } return e; } - Expression optimize(int result) + override Expression optimize(int result) { - Expression e; - - e1 = e1.optimize(result); - e2 = e2.optimize(result); - if (e1.isConst() && e2.isConst()) - { - if (e2.op == TOK.TOKsymoff) - return this; - e = Min(type, e1, e2); - } - else - e = this; - + Expression e; + + e1 = e1.optimize(result); + e2 = e2.optimize(result); + if (e1.isConst() && e2.isConst()) + { + if (e2.op == TOK.TOKsymoff) + return this; + e = Min(type, e1, e2); + } + else + e = this; + return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { Exp_buildArrayIdent(buf, arguments, "Min"); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { - /* Evaluate assign expressions left to right - */ - Expression ex1 = e1.buildArrayLoop(fparams); - Expression ex2 = e2.buildArrayLoop(fparams); - Expression e = new MinExp(Loc(0), ex1, ex2); + /* Evaluate assign expressions left to right + */ + Expression ex1 = e1.buildArrayLoop(fparams); + Expression ex2 = e2.buildArrayLoop(fparams); + Expression e = new MinExp(Loc(0), ex1, ex2); return e; } - Identifier opId() + override Identifier opId() { return Id.sub; } - Identifier opId_r() + override Identifier opId_r() { return Id.sub_r; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { - Type tb1 = e1.type.toBasetype(); - Type tb2 = e2.type.toBasetype(); - - if ((tb1.ty == TY.Tarray || tb1.ty == TY.Tsarray) && (tb2.ty == TY.Tarray || tb2.ty == TY.Tsarray)) - { - error("Array operation %s not implemented", toChars()); - return el_long(type.totym(), 0); // error recovery - } - - return toElemBin(irs, OPER.OPmin); + Type tb1 = e1.type.toBasetype(); + Type tb2 = e2.type.toBasetype(); + + if ((tb1.ty == TY.Tarray || tb1.ty == TY.Tsarray) && (tb2.ty == TY.Tarray || tb2.ty == TY.Tsarray)) + { + error("Array operation %s not implemented", toChars()); + return el_long(type.totym(), 0); // error recovery + } + + return toElemBin(irs, OPER.OPmin); } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ModAssignExp.d --- a/dmd/ModAssignExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ModAssignExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -22,32 +22,32 @@ super(loc, TOK.TOKmodass, this.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { return commonSemanticAssign(sc); } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { assert(false); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { assert(false); } - Identifier opId() /* For operator overloading */ + override Identifier opId() /* For operator overloading */ { return Id.modass; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs,OPmodass); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ModExp.d --- a/dmd/ModExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ModExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,15 +1,15 @@ -module dmd.ModExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.backend.elem; -import dmd.InterState; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.ArrayTypes; -import dmd.BinExp; +module dmd.ModExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.backend.elem; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.ArrayTypes; +import dmd.BinExp; import dmd.TOK; import dmd.Id; import dmd.ErrorExp; @@ -18,8 +18,8 @@ import dmd.expression.Mod; import dmd.backend.RTLSYM; import dmd.backend.OPER; -import dmd.backend.Util; - +import dmd.backend.Util; + class ModExp : BinExp { this(Loc loc, Expression e1, Expression e2) @@ -27,7 +27,7 @@ super(loc, TOK.TOKmod, ModExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -57,7 +57,7 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -72,37 +72,37 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { Exp_buildArrayIdent(buf, arguments, "Mod"); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { - /* Evaluate assign expressions left to right - */ - Expression ex1 = e1.buildArrayLoop(fparams); - Expression ex2 = e2.buildArrayLoop(fparams); - Expression e = new ModExp(Loc(0), ex1, ex2); + /* Evaluate assign expressions left to right + */ + Expression ex1 = e1.buildArrayLoop(fparams); + Expression ex2 = e2.buildArrayLoop(fparams); + Expression e = new ModExp(Loc(0), ex1, ex2); return e; } - Identifier opId() + override Identifier opId() { return Id.mod; } - Identifier opId_r() + override Identifier opId_r() { return Id.mod_r; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e; elem* e1; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/Module.d --- a/dmd/Module.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/Module.d Sat Aug 28 16:19:48 2010 +0200 @@ -393,12 +393,12 @@ return m; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - string kind() + override string kind() { return "module"; } @@ -796,7 +796,7 @@ semanticRun = semanticstarted; } - void inlineScan() // scan for functions to inline + override void inlineScan() // scan for functions to inline { int i; @@ -1154,7 +1154,7 @@ return needmoduleinfo || global.params.cov; } - Dsymbol search(Loc loc, Identifier ident, int flags) + override Dsymbol search(Loc loc, Identifier ident, int flags) { /* Since modules can be circularly referenced, * need to stop infinite recursive searches. @@ -1390,7 +1390,7 @@ /************************************* * Create the "ModuleInfo" symbol */ - Symbol* toSymbol() + override Symbol* toSymbol() { if (!csym) { @@ -1579,5 +1579,5 @@ obj_moduleinfo(msym); } - Module isModule() { return this; } + override Module isModule() { return this; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ModuleInfoDeclaration.d --- a/dmd/ModuleInfoDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ModuleInfoDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -18,12 +18,12 @@ super(Loc(0), null, null, null); } - Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol) { assert(false); } - void semantic(Scope sc) + override void semantic(Scope sc) { assert(false); } @@ -33,8 +33,8 @@ assert(false); } - Symbol* toSymbol() + override Symbol* toSymbol() { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/MulAssignExp.d --- a/dmd/MulAssignExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/MulAssignExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -25,7 +25,7 @@ super(loc, TOK.TOKmulass, MulAssignExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -83,28 +83,28 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { AssignExp_buildArrayIdent(buf, arguments, "Mul"); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { assert(false); } - Identifier opId() /* For operator overloading */ + override Identifier opId() /* For operator overloading */ { return Id.mulass; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs,OPmulass); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/MulExp.d --- a/dmd/MulExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/MulExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,17 +1,17 @@ -module dmd.MulExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.backend.elem; -import dmd.InterState; +module dmd.MulExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.backend.elem; +import dmd.InterState; import dmd.OutBuffer; -import dmd.NegExp; -import dmd.Loc; +import dmd.NegExp; +import dmd.Loc; import dmd.Id; -import dmd.Scope; -import dmd.IRState; -import dmd.BinExp; -import dmd.ArrayTypes; +import dmd.Scope; +import dmd.IRState; +import dmd.BinExp; +import dmd.ArrayTypes; import dmd.TOK; import dmd.Type; import dmd.TY; @@ -19,16 +19,16 @@ import dmd.expression.Util; import dmd.expression.Mul; import dmd.backend.OPER; -import dmd.backend.Util; - +import dmd.backend.Util; + class MulExp : BinExp { this(Loc loc, Expression e1, Expression e2) - { + { super(loc, TOK.TOKmul, MulExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -94,7 +94,7 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -110,42 +110,42 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { Exp_buildArrayIdent(buf, arguments, "Mul"); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { - /* Evaluate assign expressions left to right - */ - Expression ex1 = e1.buildArrayLoop(fparams); - Expression ex2 = e2.buildArrayLoop(fparams); - Expression e = new MulExp(Loc(0), ex1, ex2); + /* Evaluate assign expressions left to right + */ + Expression ex1 = e1.buildArrayLoop(fparams); + Expression ex2 = e2.buildArrayLoop(fparams); + Expression e = new MulExp(Loc(0), ex1, ex2); return e; } - bool isCommutative() + override bool isCommutative() { return true; } - Identifier opId() + override Identifier opId() { return Id.mul; } - Identifier opId_r() + override Identifier opId_r() { return Id.mul_r; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs,OPmul); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/NegExp.d --- a/dmd/NegExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/NegExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,23 +1,23 @@ -module dmd.NegExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.backend.elem; -import dmd.UnaExp; -import dmd.InterState; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.ArrayTypes; -import dmd.TOK; +module dmd.NegExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.backend.elem; +import dmd.UnaExp; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.ArrayTypes; +import dmd.TOK; import dmd.Id; import dmd.expression.Neg; import dmd.backend.Util; -import dmd.backend.OPER; - +import dmd.backend.OPER; + class NegExp : UnaExp { this(Loc loc, Expression e) @@ -25,7 +25,7 @@ super(loc, TOKneg, NegExp.sizeof, e); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -49,7 +49,7 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -64,27 +64,27 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { assert(false); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { assert(false); } - Identifier opId() + override Identifier opId() { return Id.neg; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem *e = el_una(OPneg, type.totym(), e1.toElem(irs)); el_setLoc(e,loc); diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/NewAnonClassExp.d --- a/dmd/NewAnonClassExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/NewAnonClassExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,14 +1,14 @@ -module dmd.NewAnonClassExp; - -import dmd.Expression; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.ClassDeclaration; -import dmd.HdrGenState; +module dmd.NewAnonClassExp; + +import dmd.Expression; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.ClassDeclaration; +import dmd.HdrGenState; import dmd.ArrayTypes; -import dmd.TOK; - +import dmd.TOK; + class NewAnonClassExp : Expression { /* thisexp.new(newargs) class baseclasses { } (arguments) @@ -24,17 +24,17 @@ super(loc, TOK.init, 0); } - Expression syntaxCopy() + override Expression syntaxCopy() { assert(false); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { assert(false); } - bool checkSideEffect(int flag) + override bool checkSideEffect(int flag) { assert(false); } @@ -44,7 +44,7 @@ assert(false); } - bool canThrow() + override bool canThrow() { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/NewDeclaration.d --- a/dmd/NewDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/NewDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -20,40 +20,40 @@ super(loc, loc, null, STC.init, null); } - Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol) { assert(false); } - void semantic(Scope sc) + override void semantic(Scope sc) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - string kind() + override string kind() { assert(false); } - bool isVirtual() + override bool isVirtual() { assert(false); } - bool addPreInvariant() + override bool addPreInvariant() { assert(false); } - bool addPostInvariant() + override bool addPostInvariant() { assert(false); } - NewDeclaration isNewDeclaration() { return this; } -} \ No newline at end of file + override NewDeclaration isNewDeclaration() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/NewExp.d --- a/dmd/NewExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/NewExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,17 +1,17 @@ -module dmd.NewExp; - -import dmd.Expression; -import dmd.NewDeclaration; +module dmd.NewExp; + +import dmd.Expression; +import dmd.NewDeclaration; import dmd.CtorDeclaration; -import dmd.ClassDeclaration; -import dmd.Type; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.InlineDoState; -import dmd.HdrGenState; -import dmd.ArrayTypes; +import dmd.ClassDeclaration; +import dmd.Type; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.InlineDoState; +import dmd.HdrGenState; +import dmd.ArrayTypes; import dmd.TOK; import dmd.TY; import dmd.TypeFunction; @@ -28,7 +28,7 @@ import dmd.Global; import dmd.IntegerExp; import dmd.TypePointer; - + import dmd.backend.elem; import dmd.backend.TYM; import dmd.backend.SC; @@ -42,19 +42,19 @@ import dmd.expression.Util; import dmd.codegen.Util; -import std.string : toStringz; - +import std.string : toStringz; + class NewExp : Expression { - /* thisexp.new(newargs) newtype(arguments) - */ - Expression thisexp; // if !null, 'this' for class being allocated - Expressions newargs; // Array of Expression's to call new operator - Type newtype; - Expressions arguments; // Array of Expression's - - CtorDeclaration member; // constructor function - NewDeclaration allocator; // allocator function + /* thisexp.new(newargs) newtype(arguments) + */ + Expression thisexp; // if !null, 'this' for class being allocated + Expressions newargs; // Array of Expression's to call new operator + Type newtype; + Expressions arguments; // Array of Expression's + + CtorDeclaration member; // constructor function + NewDeclaration allocator; // allocator function int onstack; // allocate on stack this(Loc loc, Expression thisexp, Expressions newargs, Type newtype, Expressions arguments) @@ -66,15 +66,15 @@ this.arguments = arguments; } - Expression syntaxCopy() + override Expression syntaxCopy() { - return new NewExp(loc, - thisexp ? thisexp.syntaxCopy() : null, - arraySyntaxCopy(newargs), + return new NewExp(loc, + thisexp ? thisexp.syntaxCopy() : null, + arraySyntaxCopy(newargs), newtype.syntaxCopy(), arraySyntaxCopy(arguments)); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { int i; Type tb; @@ -376,7 +376,7 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { if (thisexp) thisexp = thisexp.optimize(WANTvalue); @@ -406,7 +406,7 @@ return this; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e; Type t; @@ -724,36 +724,36 @@ return e; } - bool checkSideEffect(int flag) + override bool checkSideEffect(int flag) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - void scanForNestedRef(Scope sc) + override void scanForNestedRef(Scope sc) { - //printf("NewExp.scanForNestedRef(Scope *sc): %s\n", toChars()); - - if (thisexp) - thisexp.scanForNestedRef(sc); - arrayExpressionScanForNestedRef(sc, newargs); + //printf("NewExp.scanForNestedRef(Scope *sc): %s\n", toChars()); + + if (thisexp) + thisexp.scanForNestedRef(sc); + arrayExpressionScanForNestedRef(sc, newargs); arrayExpressionScanForNestedRef(sc, arguments); } version (DMDV2) { - bool canThrow() + override bool canThrow() { return 1; - } + } } - + //int inlineCost(InlineCostState *ics); - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { //printf("NewExp.doInline(): %s\n", toChars()); NewExp ne = cast(NewExp)copy(); @@ -763,8 +763,8 @@ ne.newargs = arrayExpressiondoInline(ne.newargs, ids); ne.arguments = arrayExpressiondoInline(ne.arguments, ids); return ne; - } - + } + //Expression inlineScan(InlineScanState *iss); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/NotExp.d --- a/dmd/NotExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/NotExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,20 +1,20 @@ -module dmd.NotExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.UnaExp; -import dmd.InterState; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; +module dmd.NotExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.UnaExp; +import dmd.InterState; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; import dmd.TOK; import dmd.Type; import dmd.expression.Not; import dmd.backend.OPER; -import dmd.backend.Util; - +import dmd.backend.Util; + class NotExp : UnaExp { this(Loc loc, Expression e) @@ -22,7 +22,7 @@ super(loc, TOK.TOKnot, NotExp.sizeof, e); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { UnaExp.semantic(sc); e1 = resolveProperties(sc, e1); @@ -31,7 +31,7 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -44,20 +44,20 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - int isBit() + override int isBit() { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e = el_una(OPnot, type.totym(), e1.toElem(irs)); el_setLoc(e,loc); return e; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/NullExp.d --- a/dmd/NullExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/NullExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,153 +1,153 @@ -module dmd.NullExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.InterState; -import dmd.MATCH; -import dmd.Type; -import dmd.TY; -import dmd.TypeTypedef; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.HdrGenState; -import dmd.TOK; -import dmd.backend.dt_t; -import dmd.backend.Util; - +module dmd.NullExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.InterState; +import dmd.MATCH; +import dmd.Type; +import dmd.TY; +import dmd.TypeTypedef; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.HdrGenState; +import dmd.TOK; +import dmd.backend.dt_t; +import dmd.backend.Util; + class NullExp : Expression { ubyte committed; this(Loc loc) - { + { super(loc, TOK.TOKnull, NullExp.sizeof); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { -version (LOGSEMANTIC) { - printf("NullExp.semantic('%s')\n", toChars()); -} - // null is the same as (void*)0 - if (!type) - type = Type.tvoid.pointerTo(); - +version (LOGSEMANTIC) { + printf("NullExp.semantic('%s')\n", toChars()); +} + // null is the same as (void*)0 + if (!type) + type = Type.tvoid.pointerTo(); + return this; } - bool isBool(bool result) + override bool isBool(bool result) { assert(false); } - int isConst() + override int isConst() { return 0; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("null"); } - void toMangleBuffer(OutBuffer buf) + override void toMangleBuffer(OutBuffer buf) { buf.writeByte('n'); } - MATCH implicitConvTo(Type t) + override MATCH implicitConvTo(Type t) { -static if (false) { - printf("NullExp.implicitConvTo(this=%s, type=%s, t=%s, committed = %d)\n", - toChars(), type.toChars(), t.toChars(), committed); -} - if (this.type.equals(t)) - return MATCH.MATCHexact; - - /* Allow implicit conversions from invariant to mutable|const, - * and mutable to invariant. It works because, after all, a null - * doesn't actually point to anything. - */ - if (t.invariantOf().equals(type.invariantOf())) - return MATCH.MATCHconst; - - // null implicitly converts to any pointer type or dynamic array - if (type.ty == TY.Tpointer && type.nextOf().ty == TY.Tvoid) - { - if (t.ty == TY.Ttypedef) - t = (cast(TypeTypedef)t).sym.basetype; - if (t.ty == TY.Tpointer || t.ty == TY.Tarray || - t.ty == TY.Taarray || t.ty == TY.Tclass || - t.ty == TY.Tdelegate) - { - return committed ? MATCH.MATCHconvert : MATCH.MATCHexact; - } - } - +static if (false) { + printf("NullExp.implicitConvTo(this=%s, type=%s, t=%s, committed = %d)\n", + toChars(), type.toChars(), t.toChars(), committed); +} + if (this.type.equals(t)) + return MATCH.MATCHexact; + + /* Allow implicit conversions from invariant to mutable|const, + * and mutable to invariant. It works because, after all, a null + * doesn't actually point to anything. + */ + if (t.invariantOf().equals(type.invariantOf())) + return MATCH.MATCHconst; + + // null implicitly converts to any pointer type or dynamic array + if (type.ty == TY.Tpointer && type.nextOf().ty == TY.Tvoid) + { + if (t.ty == TY.Ttypedef) + t = (cast(TypeTypedef)t).sym.basetype; + if (t.ty == TY.Tpointer || t.ty == TY.Tarray || + t.ty == TY.Taarray || t.ty == TY.Tclass || + t.ty == TY.Tdelegate) + { + return committed ? MATCH.MATCHconvert : MATCH.MATCHexact; + } + } + return Expression.implicitConvTo(t); } - Expression castTo(Scope sc, Type t) + override Expression castTo(Scope sc, Type t) { - NullExp e; - Type tb; - - //printf("NullExp::castTo(t = %p)\n", t); - if (type is t) - { - committed = 1; - return this; - } - - e = cast(NullExp)copy(); - e.committed = 1; - tb = t.toBasetype(); - e.type = type.toBasetype(); - - if (tb !is e.type) - { - // null implicitly converts to any pointer type or dynamic array - if (e.type.ty == TY.Tpointer && e.type.nextOf().ty == TY.Tvoid && - (tb.ty == TY.Tpointer || tb.ty == TY.Tarray || tb.ty == TY.Taarray || - tb.ty == TY.Tdelegate)) - { -static if (false) { - if (tb.ty == TY.Tdelegate) - { - TypeDelegate td = cast(TypeDelegate)tb; - TypeFunction tf = cast(TypeFunction)td.nextOf(); - - if (!tf.varargs && !(tf.arguments && tf.arguments.dim)) - { - return Expression.castTo(sc, t); - } - } -} - } - else - { - return e.Expression.castTo(sc, t); - } - } - e.type = t; + NullExp e; + Type tb; + + //printf("NullExp::castTo(t = %p)\n", t); + if (type is t) + { + committed = 1; + return this; + } + + e = cast(NullExp)copy(); + e.committed = 1; + tb = t.toBasetype(); + e.type = type.toBasetype(); + + if (tb !is e.type) + { + // null implicitly converts to any pointer type or dynamic array + if (e.type.ty == TY.Tpointer && e.type.nextOf().ty == TY.Tvoid && + (tb.ty == TY.Tpointer || tb.ty == TY.Tarray || tb.ty == TY.Taarray || + tb.ty == TY.Tdelegate)) + { +static if (false) { + if (tb.ty == TY.Tdelegate) + { + TypeDelegate td = cast(TypeDelegate)tb; + TypeFunction tf = cast(TypeFunction)td.nextOf(); + + if (!tf.varargs && !(tf.arguments && tf.arguments.dim)) + { + return Expression.castTo(sc, t); + } + } +} + } + else + { + return e.Expression.castTo(sc, t); + } + } + e.type = t; return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return el_long(type.totym(), 0); } - dt_t** toDt(dt_t** pdt) + override dt_t** toDt(dt_t** pdt) { - assert(type); + assert(type); return dtnzeros(pdt, cast(uint)type.size()); } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/OnScopeStatement.d --- a/dmd/OnScopeStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/OnScopeStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -35,36 +35,36 @@ this.statement = statement; } - Statement syntaxCopy() + override Statement syntaxCopy() { OnScopeStatement s = new OnScopeStatement(loc, tok, statement.syntaxCopy()); return s; } - BE blockExit() + override BE blockExit() { // At this point, this statement is just an empty placeholder return BE.BEfallthru; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { /* semantic is called on results of scopeCode() */ return this; } - bool usesEH() + override bool usesEH() { assert(false); } - void scopeCode(Scope sc, Statement* sentry, Statement* sexception, Statement* sfinally) + override void scopeCode(Scope sc, Statement* sentry, Statement* sexception, Statement* sfinally) { //printf("OnScopeStatement::scopeCode()\n"); //print(); @@ -110,7 +110,7 @@ } } - void toIR(IRState* irs) + override void toIR(IRState* irs) { } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/OrAssignExp.d --- a/dmd/OrAssignExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/OrAssignExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -22,33 +22,33 @@ super(loc, TOK.TOKorass, OrAssignExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { return commonSemanticAssignIntegral(sc); } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { assert(false); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { assert(false); } - Identifier opId() /* For operator overloading */ + override Identifier opId() /* For operator overloading */ { return Id.orass; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs, OPorass); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/OrExp.d --- a/dmd/OrExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/OrExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,26 +1,26 @@ -module dmd.OrExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.InterState; -import dmd.MATCH; -import dmd.Type; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IntRange; -import dmd.IRState; -import dmd.ArrayTypes; -import dmd.BinExp; +module dmd.OrExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.InterState; +import dmd.MATCH; +import dmd.Type; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IntRange; +import dmd.IRState; +import dmd.ArrayTypes; +import dmd.BinExp; import dmd.TOK; import dmd.TY; -import dmd.Id; - +import dmd.Id; + import dmd.backend.elem; import dmd.backend.OPER; -import dmd.expression.Or; - +import dmd.expression.Or; + class OrExp : BinExp { this(Loc loc, Expression e1, Expression e2) @@ -28,7 +28,7 @@ super(loc, TOK.TOKor, OrExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -59,7 +59,7 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -74,22 +74,22 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { assert(false); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { assert(false); } - MATCH implicitConvTo(Type t) + override MATCH implicitConvTo(Type t) { MATCH result = Expression.implicitConvTo(t); @@ -105,45 +105,45 @@ return result; } - IntRange getIntRange() + override IntRange getIntRange() { - IntRange ir; - IntRange ir1 = e1.getIntRange(); - IntRange ir2 = e2.getIntRange(); - - ir.imin = ir1.imin; - if (ir2.imin < ir.imin) - ir.imin = ir2.imin; - - ir.imax = ir1.imax; - if (ir2.imax > ir.imax) - ir.imax = ir2.imax; - - ir.imin &= type.sizemask(); - ir.imax &= type.sizemask(); - - //printf("OrExp: imin = x%llx, imax = x%llx\n", ir.imin, ir.imax); - //e1.dump(0); - + IntRange ir; + IntRange ir1 = e1.getIntRange(); + IntRange ir2 = e2.getIntRange(); + + ir.imin = ir1.imin; + if (ir2.imin < ir.imin) + ir.imin = ir2.imin; + + ir.imax = ir1.imax; + if (ir2.imax > ir.imax) + ir.imax = ir2.imax; + + ir.imin &= type.sizemask(); + ir.imax &= type.sizemask(); + + //printf("OrExp: imin = x%llx, imax = x%llx\n", ir.imin, ir.imax); + //e1.dump(0); + return ir; } - bool isCommutative() + override bool isCommutative() { return true; } - Identifier opId() + override Identifier opId() { return Id.ior; } - Identifier opId_r() + override Identifier opId_r() { return Id.ior_r; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs, OPER.OPor); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/OrOrExp.d --- a/dmd/OrOrExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/OrOrExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -28,7 +28,7 @@ super(loc, TOK.TOKoror, OrOrExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { uint cs1; @@ -63,18 +63,18 @@ return this; } - Expression checkToBoolean() + override Expression checkToBoolean() { e2 = e2.checkToBoolean(); return this; } - int isBit() + override int isBit() { assert(false); } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -108,12 +108,12 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - bool checkSideEffect(int flag) + override bool checkSideEffect(int flag) { if (flag == 2) { @@ -126,11 +126,11 @@ } } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e = toElemBin(irs,OPoror); if (global.params.cov && e2.loc.linnum) e.E2() = el_combine(incUsageElem(irs, e2.loc), e.E2); return e; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/OverExp.d --- a/dmd/OverExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/OverExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,30 +1,30 @@ -module dmd.OverExp; - -import dmd.Expression; -import dmd.OverloadSet; -import dmd.Scope; -import dmd.Loc; -import dmd.TOK; -import dmd.Type; - +module dmd.OverExp; + +import dmd.Expression; +import dmd.OverloadSet; +import dmd.Scope; +import dmd.Loc; +import dmd.TOK; +import dmd.Type; + class OverExp : Expression { OverloadSet vars; this(OverloadSet s) { - super(loc, TOKoverloadset, OverExp.sizeof); - //printf("OverExp(this = %p, '%s')\n", this, var.toChars()); - vars = s; + super(loc, TOKoverloadset, OverExp.sizeof); + //printf("OverExp(this = %p, '%s')\n", this, var.toChars()); + vars = s; type = Type.tvoid; } - int isLvalue() + override int isLvalue() { assert(false); } - Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression e) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/OverloadSet.d --- a/dmd/OverloadSet.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/OverloadSet.d Sat Aug 28 16:19:48 2010 +0200 @@ -17,10 +17,10 @@ a.push(cast(void*)s); } - OverloadSet isOverloadSet() { return this; } + override OverloadSet isOverloadSet() { return this; } - string kind() + override string kind() { return "overloadset"; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/Package.d --- a/dmd/Package.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/Package.d Sat Aug 28 16:19:48 2010 +0200 @@ -16,7 +16,7 @@ super(ident); } - string kind() + override string kind() { assert(false); } @@ -69,7 +69,7 @@ return dst; } - Package isPackage() { return this; } + override Package isPackage() { return this; } - void semantic(Scope sc) { } -} \ No newline at end of file + override void semantic(Scope sc) { } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/PeelStatement.d --- a/dmd/PeelStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/PeelStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,20 +1,20 @@ -module dmd.PeelStatement; - -import dmd.Statement; -import dmd.Scope; -import dmd.Loc; - +module dmd.PeelStatement; + +import dmd.Statement; +import dmd.Scope; +import dmd.Loc; + class PeelStatement : Statement { Statement s; this(Statement s) { - assert(false); + assert(false); super(Loc(0)); } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/PostBlitDeclaration.d --- a/dmd/PostBlitDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/PostBlitDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -23,45 +23,45 @@ super(loc, loc, null, STC.init, null); } - Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol) { assert(false); } - void semantic(Scope sc) + override void semantic(Scope sc) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - bool isVirtual() + override bool isVirtual() { assert(false); } - bool addPreInvariant() + override bool addPreInvariant() { assert(false); } - bool addPostInvariant() + override bool addPostInvariant() { assert(false); } - bool overloadInsert(Dsymbol s) + override bool overloadInsert(Dsymbol s) { assert(false); } - void emitComment(Scope sc) + override void emitComment(Scope sc) { assert(false); } - PostBlitDeclaration isPostBlitDeclaration() { return this; } -} \ No newline at end of file + override PostBlitDeclaration isPostBlitDeclaration() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/PostExp.d --- a/dmd/PostExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/PostExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,24 +1,24 @@ -module dmd.PostExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.backend.elem; -import dmd.InterState; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.BinExp; +module dmd.PostExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.backend.elem; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.BinExp; import dmd.HdrGenState; -import dmd.IntegerExp; +import dmd.IntegerExp; import dmd.TOK; import dmd.Type; import dmd.TY; import dmd.Id; import dmd.backend.Util; -import dmd.backend.OPER; - +import dmd.backend.OPER; + class PostExp : BinExp { this(TOK op, Loc loc, Expression e) @@ -26,7 +26,7 @@ super(loc, op, PostExp.sizeof, e, new IntegerExp(loc, 1, Type.tint32)); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e = this; @@ -52,22 +52,22 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - Identifier opId() + override Identifier opId() { return (op == TOKplusplus) ? Id.postinc : Id.postdec; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e; elem* einc; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/PragmaDeclaration.d --- a/dmd/PragmaDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/PragmaDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -34,7 +34,7 @@ this.args = args; } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { //printf("PragmaDeclaration.syntaxCopy(%s)\n", toChars()); PragmaDeclaration pd; @@ -44,7 +44,7 @@ return pd; } - void semantic(Scope sc) + override void semantic(Scope sc) { // Should be merged with PragmaStatement @@ -194,7 +194,7 @@ error("pragma is missing closing ';'"); } - void setScope(Scope sc) + override void setScope(Scope sc) { version (TARGET_NET) { if (ident == Lexer.idPool("assembly")) @@ -227,22 +227,22 @@ } } - bool oneMember(Dsymbol* ps) + override bool oneMember(Dsymbol* ps) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - string kind() + override string kind() { assert(false); } - void toObjFile(int multiobj) // compile to .obj file + override void toObjFile(int multiobj) // compile to .obj file { if (ident == Id.lib) { diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/PragmaStatement.d --- a/dmd/PragmaStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/PragmaStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -22,33 +22,33 @@ super(loc); } - Statement syntaxCopy() + override Statement syntaxCopy() { assert(false); } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { assert(false); } - bool usesEH() + override bool usesEH() { assert(false); } - BE blockExit() + override BE blockExit() { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - void toIR(IRState* irs) + override void toIR(IRState* irs) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ProtDeclaration.d --- a/dmd/ProtDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ProtDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -20,7 +20,7 @@ //printf("decl = %p\n", decl); } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { ProtDeclaration pd; @@ -29,7 +29,7 @@ return pd; } - void setScope(Scope sc) + override void setScope(Scope sc) { if (decl) { @@ -37,7 +37,7 @@ } } - void semantic(Scope sc) + override void semantic(Scope sc) { if (decl) { @@ -45,7 +45,7 @@ } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } @@ -54,4 +54,4 @@ { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/PtrExp.d --- a/dmd/PtrExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/PtrExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,16 +1,16 @@ -module dmd.PtrExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.backend.elem; -import dmd.UnaExp; -import dmd.InterState; -import dmd.Type; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.HdrGenState; +module dmd.PtrExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.backend.elem; +import dmd.UnaExp; +import dmd.InterState; +import dmd.Type; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.HdrGenState; import dmd.TOK; import dmd.GlobalExpressions; import dmd.SymOffExp; @@ -27,8 +27,8 @@ import dmd.backend.Util; import dmd.backend.TYM; import dmd.backend.mTY; -import dmd.backend.OPER; - +import dmd.backend.OPER; + class PtrExp : UnaExp { this(Loc loc, Expression e) @@ -44,7 +44,7 @@ type = t; } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { version (LOGSEMANTIC) { printf("PtrExp::semantic('%s')\n", toChars()); @@ -80,12 +80,12 @@ return this; } - int isLvalue() + override int isLvalue() { return 1; } - Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression e) { static if (false) { tym = tybasic(e1.ET.Tty); @@ -99,7 +99,7 @@ } version (DMDV2) { - Expression modifiableLvalue(Scope sc, Expression e) + override Expression modifiableLvalue(Scope sc, Expression e) { //printf("PtrExp.modifiableLvalue() %s, type %s\n", toChars(), type.toChars()); @@ -113,12 +113,12 @@ return Expression.modifiableLvalue(sc, e); } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e; @@ -135,7 +135,7 @@ return e; } - Expression optimize(int result) + override Expression optimize(int result) { //printf("PtrExp.optimize(result = x%x) %s\n", result, toChars()); e1 = e1.optimize(result); @@ -180,12 +180,12 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - Identifier opId() + override Identifier opId() { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/RealExp.d --- a/dmd/RealExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/RealExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,26 +1,26 @@ -module dmd.RealExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.InterState; -import dmd.Type; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.TOK; -import dmd.Scope; +module dmd.RealExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.InterState; +import dmd.Type; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.TOK; +import dmd.Scope; import dmd.IRState; -import dmd.Type; +import dmd.Type; import dmd.HdrGenState; import dmd.Port; import dmd.TY; - + import dmd.backend.dt_t; import dmd.backend.Util; import dmd.backend.TYM; import dmd.backend.mTY; -import dmd.Complex; - +import dmd.Complex; + class RealExp : Expression { real value; @@ -33,12 +33,12 @@ this.type = type; } - bool equals(Object o) + override bool equals(Object o) { assert(false); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { if (!type) type = Type.tfloat64; @@ -47,42 +47,42 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - string toChars() + override string toChars() { assert(false); } - ulong toInteger() + override ulong toInteger() { assert(false); } - ulong toUInteger() + override ulong toUInteger() { assert(false); } - real toReal() + override real toReal() { return type.isreal() ? value : 0; } - real toImaginary() + override real toImaginary() { return type.isreal() ? 0 : value; } - Complex!(real) toComplex() + override Complex!(real) toComplex() { return Complex!(real)(toReal(), toImaginary()); } - Expression castTo(Scope sc, Type t) + override Expression castTo(Scope sc, Type t) { Expression e = this; if (type != t) @@ -100,27 +100,27 @@ return e; } - int isConst() + override int isConst() { return 1; } - bool isBool(bool result) + override bool isBool(bool result) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - void toMangleBuffer(OutBuffer buf) + override void toMangleBuffer(OutBuffer buf) { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { eve c; tym_t ty; @@ -166,7 +166,7 @@ static private char[6] zeropad; - dt_t** toDt(dt_t** pdt) + override dt_t** toDt(dt_t** pdt) { float fvalue; double dvalue; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/RemoveExp.d --- a/dmd/RemoveExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/RemoveExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,10 +1,10 @@ -module dmd.RemoveExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.Loc; -import dmd.IRState; -import dmd.BinExp; +module dmd.RemoveExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.Loc; +import dmd.IRState; +import dmd.BinExp; import dmd.TOK; import dmd.Type; import dmd.TypeAArray; @@ -14,11 +14,11 @@ import dmd.backend.OPER; import dmd.backend.Symbol; import dmd.backend.TYM; -import dmd.backend.mTY; +import dmd.backend.mTY; /* This deletes the key e1 from the associative array e2 */ - + class RemoveExp : BinExp { this(Loc loc, Expression e1, Expression e2) @@ -27,7 +27,7 @@ type = Type.tvoid; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e; Type tb = e1.type.toBasetype(); diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ReturnStatement.d --- a/dmd/ReturnStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ReturnStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -57,18 +57,18 @@ this.exp = exp; } - Statement syntaxCopy() + override Statement syntaxCopy() { Expression e = exp ? exp.syntaxCopy() : null; return new ReturnStatement(loc, e); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { //printf("ReturnStatement.semantic() %s\n", toChars()); @@ -346,7 +346,7 @@ return this; } - BE blockExit() + override BE blockExit() { BE result = BE.BEreturn; if (exp && exp.canThrow()) @@ -355,7 +355,7 @@ return result; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { version (LOG) { printf("ReturnStatement.interpret(%s)\n", exp ? exp.toChars() : ""); @@ -372,7 +372,7 @@ } } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { // Can't handle return statements nested in if's if (ics.nested) @@ -380,13 +380,13 @@ return exp ? exp.inlineCost(ics) : 0; } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { //printf("ReturnStatement.doInline() '%s'\n", exp ? exp.toChars() : ""); return exp ? exp.doInline(ids) : null; } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { //printf("ReturnStatement.inlineScan()\n"); if (exp) @@ -396,7 +396,7 @@ return this; } - void toIR(IRState* irs) + override void toIR(IRState* irs) { Blockx* blx = irs.blx; @@ -513,5 +513,5 @@ block_next(blx, BC.BCret, null); } - ReturnStatement isReturnStatement() { return this; } -} \ No newline at end of file + override ReturnStatement isReturnStatement() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ScopeDsymbol.d --- a/dmd/ScopeDsymbol.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ScopeDsymbol.d Sat Aug 28 16:19:48 2010 +0200 @@ -36,7 +36,7 @@ super(id); } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { //printf("ScopeDsymbol.syntaxCopy('%s')\n", toChars()); @@ -49,7 +49,7 @@ return sd; } - Dsymbol search(Loc loc, Identifier ident, int flags) + override Dsymbol search(Loc loc, Identifier ident, int flags) { //printf("%s.ScopeDsymbol.search(ident='%s', flags=x%x)\n", toChars(), ident.toChars(), flags); //if (strcmp(ident.toChars(),"c") == 0) *(char*)0=0; @@ -186,12 +186,12 @@ } } - int isforwardRef() + override int isforwardRef() { assert(false); } - void defineRef(Dsymbol s) + override void defineRef(Dsymbol s) { assert(false); } @@ -222,7 +222,7 @@ assert(false); } - string kind() + override string kind() { assert(false); } @@ -276,5 +276,5 @@ assert(false); } - ScopeDsymbol isScopeDsymbol() { return this; } + override ScopeDsymbol isScopeDsymbol() { return this; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ScopeExp.d --- a/dmd/ScopeExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ScopeExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,41 +1,41 @@ -module dmd.ScopeExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.ScopeDsymbol; +module dmd.ScopeExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.ScopeDsymbol; import dmd.OutBuffer; -import dmd.TemplateInstance; -import dmd.Loc; -import dmd.TOK; -import dmd.Scope; -import dmd.IRState; +import dmd.TemplateInstance; +import dmd.Loc; +import dmd.TOK; +import dmd.Scope; +import dmd.IRState; import dmd.HdrGenState; import dmd.Global; import dmd.Dsymbol; import dmd.VarExp; import dmd.DotVarExp; import dmd.DsymbolExp; -import dmd.Type; - +import dmd.Type; + class ScopeExp : Expression { ScopeDsymbol sds; this(Loc loc, ScopeDsymbol pkg) - { + { super(loc, TOK.TOKimport, ScopeExp.sizeof); //printf("ScopeExp.ScopeExp(pkg = '%s')\n", pkg.toChars()); //static int count; if (++count == 38) *(char*)0=0; this.sds = pkg; } - Expression syntaxCopy() + override Expression syntaxCopy() { ScopeExp se = new ScopeExp(loc, cast(ScopeDsymbol)sds.syntaxCopy(null)); return se; } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { TemplateInstance ti; ScopeDsymbol sds2; @@ -88,12 +88,12 @@ return this; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { if (sds.isTemplateInstance()) { diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ScopeStatement.d --- a/dmd/ScopeStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ScopeStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -28,14 +28,14 @@ this.statement = s; } - Statement syntaxCopy() + override Statement syntaxCopy() { Statement s = statement ? statement.syntaxCopy() : null; s = new ScopeStatement(loc, s); return s; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writeByte('{'); buf.writenl(); @@ -47,9 +47,9 @@ buf.writenl(); } - ScopeStatement isScopeStatement() { return this; } + override ScopeStatement isScopeStatement() { return this; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { ScopeDsymbol sym; @@ -88,53 +88,53 @@ return this; } - bool hasBreak() + override bool hasBreak() { //printf("ScopeStatement.hasBreak() %s\n", toChars()); return statement ? statement.hasBreak() : false; } - bool hasContinue() + override bool hasContinue() { return statement ? statement.hasContinue() : false; } - bool usesEH() + override bool usesEH() { return statement ? statement.usesEH() : false; } - BE blockExit() + override BE blockExit() { //printf("ScopeStatement::blockExit(%p)\n", statement); return statement ? statement.blockExit() : BE.BEfallthru; } - bool comeFrom() + override bool comeFrom() { //printf("ScopeStatement.comeFrom()\n"); return statement ? statement.comeFrom() : false; } - bool isEmpty() + override bool isEmpty() { //printf("ScopeStatement::isEmpty() %d\n", statement ? statement->isEmpty() : TRUE); return statement ? statement.isEmpty() : true; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { if (statement) statement = statement.inlineScan(iss); return this; } - void toIR(IRState* irs) + override void toIR(IRState* irs) { if (statement) { @@ -150,4 +150,4 @@ block_goto(blx, BC.BCgoto, mystate.breakBlock); } } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ShlAssignExp.d --- a/dmd/ShlAssignExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ShlAssignExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -21,7 +21,7 @@ super(loc, TOK.TOKshlass, ShlAssignExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -44,18 +44,18 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - Identifier opId() /* For operator overloading */ + override Identifier opId() /* For operator overloading */ { return Id.shlass; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs,OPshlass); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ShlExp.d --- a/dmd/ShlExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ShlExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,14 +1,14 @@ -module dmd.ShlExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.backend.elem; -import dmd.InterState; -import dmd.Loc; -import dmd.Scope; -import dmd.IntRange; -import dmd.IRState; -import dmd.BinExp; +module dmd.ShlExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.backend.elem; +import dmd.InterState; +import dmd.Loc; +import dmd.Scope; +import dmd.IntRange; +import dmd.IRState; +import dmd.BinExp; import dmd.TOK; import dmd.Id; import dmd.Type; @@ -16,8 +16,8 @@ import dmd.expression.shift_optimize; import dmd.expression.Shl; -import dmd.backend.OPER; - +import dmd.backend.OPER; + class ShlExp : BinExp { this(Loc loc, Expression e1, Expression e2) @@ -25,7 +25,7 @@ super(loc, TOK.TOKshl, ShlExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -48,33 +48,33 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { //printf("ShlExp::optimize(result = %d) %s\n", result, toChars()); return shift_optimize(result, this, &Shl); } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - IntRange getIntRange() + override IntRange getIntRange() { assert(false); } - Identifier opId() + override Identifier opId() { return Id.shl; } - Identifier opId_r() + override Identifier opId_r() { return Id.shl_r; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs, OPER.OPshl); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ShrAssignExp.d --- a/dmd/ShrAssignExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ShrAssignExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -23,7 +23,7 @@ super(loc, TOK.TOKshrass, ShrAssignExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -46,18 +46,18 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - Identifier opId() /* For operator overloading */ + override Identifier opId() /* For operator overloading */ { return Id.shrass; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs, OPshrass); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ShrExp.d --- a/dmd/ShrExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ShrExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,23 +1,23 @@ -module dmd.ShrExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.InterState; -import dmd.Loc; -import dmd.Scope; -import dmd.IntRange; -import dmd.IRState; -import dmd.BinExp; +module dmd.ShrExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.InterState; +import dmd.Loc; +import dmd.Scope; +import dmd.IntRange; +import dmd.IRState; +import dmd.BinExp; import dmd.TOK; import dmd.Type; -import dmd.Id; - +import dmd.Id; + import dmd.backend.elem; import dmd.backend.OPER; import dmd.expression.shift_optimize; -import dmd.expression.Shr; - +import dmd.expression.Shr; + class ShrExp : BinExp { this(Loc loc, Expression e1, Expression e2) @@ -25,7 +25,7 @@ super(loc, TOK.TOKshr, ShrExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -46,33 +46,33 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { //printf("ShrExp::optimize(result = %d) %s\n", result, toChars()); return shift_optimize(result, this, &Shr); } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - IntRange getIntRange() + override IntRange getIntRange() { assert(false); } - Identifier opId() + override Identifier opId() { return Id.shr; } - Identifier opId_r() + override Identifier opId_r() { return Id.shr_r; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs, OPER.OPshr); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/SliceExp.d --- a/dmd/SliceExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/SliceExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,13 +1,13 @@ -module dmd.SliceExp; - -import dmd.Expression; -import dmd.expression.ArrayLength; -import dmd.backend.elem; -import dmd.UnaExp; -import dmd.Identifier; -import dmd.IdentifierExp; -import dmd.ArrayExp; -import dmd.STC; +module dmd.SliceExp; + +import dmd.Expression; +import dmd.expression.ArrayLength; +import dmd.backend.elem; +import dmd.UnaExp; +import dmd.Identifier; +import dmd.IdentifierExp; +import dmd.ArrayExp; +import dmd.STC; import dmd.InterState; import dmd.ScopeDsymbol; import dmd.WANT; @@ -22,21 +22,21 @@ import dmd.TypeClass; import dmd.TY; import dmd.Type; -import dmd.AggregateDeclaration; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.InlineCostState; +import dmd.AggregateDeclaration; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.InlineCostState; import dmd.VarDeclaration; import dmd.ErrorExp; import dmd.TypeExp; import dmd.Argument; -import dmd.ExpInitializer; -import dmd.IRState; -import dmd.InlineDoState; -import dmd.ArrayTypes; -import dmd.HdrGenState; -import dmd.InlineScanState; +import dmd.ExpInitializer; +import dmd.IRState; +import dmd.InlineDoState; +import dmd.ArrayTypes; +import dmd.HdrGenState; +import dmd.InlineScanState; import dmd.TOK; import dmd.TypeSArray; import dmd.GlobalExpressions; @@ -52,8 +52,8 @@ import dmd.backend.TYM; import dmd.codegen.Util; -import core.stdc.string; - +import core.stdc.string; + class SliceExp : UnaExp { Expression upr; // null if implicit 0 @@ -62,26 +62,26 @@ VarDeclaration lengthVar = null; this(Loc loc, Expression e1, Expression lwr, Expression upr) - { + { super(loc, TOK.TOKslice, SliceExp.sizeof, e1); this.upr = upr; this.lwr = lwr; } - Expression syntaxCopy() + override Expression syntaxCopy() { - Expression lwr = null; - if (this.lwr) - lwr = this.lwr.syntaxCopy(); - - Expression upr = null; - if (this.upr) - upr = this.upr.syntaxCopy(); - + Expression lwr = null; + if (this.lwr) + lwr = this.lwr.syntaxCopy(); + + Expression upr = null; + if (this.upr) + upr = this.upr.syntaxCopy(); + return new SliceExp(loc, e1.syntaxCopy(), lwr, upr); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; AggregateDeclaration ad; @@ -260,29 +260,29 @@ return e; } - void checkEscape() + override void checkEscape() { e1.checkEscape(); } version (DMDV2) { - int isLvalue() + override int isLvalue() { return 1; } } - Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression e) { return this; } - Expression modifiableLvalue(Scope sc, Expression e) + override Expression modifiableLvalue(Scope sc, Expression e) { error("slice expression %s is not a modifiable lvalue", toChars()); return this; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { expToCBuffer(buf, hgs, e1, precedence[op]); buf.writeByte('['); @@ -301,7 +301,7 @@ buf.writeByte(']'); } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -329,54 +329,54 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { - Expression e; - Expression e1; - Expression lwr; - Expression upr; - -version (LOG) { - printf("SliceExp.interpret() %s\n", toChars()); -} - e1 = this.e1.interpret(istate); - if (e1 is EXP_CANT_INTERPRET) - goto Lcant; - if (!this.lwr) - { - e = e1.castTo(null, type); - return e.interpret(istate); - } - - /* Set the $ variable - */ - e = ArrayLength(Type.tsize_t, e1); - if (e is EXP_CANT_INTERPRET) - goto Lcant; - if (lengthVar) - lengthVar.value = e; - - /* Evaluate lower and upper bounds of slice - */ - lwr = this.lwr.interpret(istate); - if (lwr is EXP_CANT_INTERPRET) - goto Lcant; - upr = this.upr.interpret(istate); - if (upr is EXP_CANT_INTERPRET) - goto Lcant; - - return Slice(type, e1, lwr, upr); - - Lcant: + Expression e; + Expression e1; + Expression lwr; + Expression upr; + +version (LOG) { + printf("SliceExp.interpret() %s\n", toChars()); +} + e1 = this.e1.interpret(istate); + if (e1 is EXP_CANT_INTERPRET) + goto Lcant; + if (!this.lwr) + { + e = e1.castTo(null, type); + return e.interpret(istate); + } + + /* Set the $ variable + */ + e = ArrayLength(Type.tsize_t, e1); + if (e is EXP_CANT_INTERPRET) + goto Lcant; + if (lengthVar) + lengthVar.value = e; + + /* Evaluate lower and upper bounds of slice + */ + lwr = this.lwr.interpret(istate); + if (lwr is EXP_CANT_INTERPRET) + goto Lcant; + upr = this.upr.interpret(istate); + if (upr is EXP_CANT_INTERPRET) + goto Lcant; + + return Slice(type, e1, lwr, upr); + + Lcant: return EXP_CANT_INTERPRET; } - void dump(int indent) + override void dump(int indent) { assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e; Type t1; @@ -487,41 +487,41 @@ return e; } - void scanForNestedRef(Scope sc) + override void scanForNestedRef(Scope sc) { - e1.scanForNestedRef(sc); - - if (lengthVar) - { - //printf("lengthVar\n"); - lengthVar.parent = sc.parent; - } - if (lwr) - lwr.scanForNestedRef(sc); - if (upr) + e1.scanForNestedRef(sc); + + if (lengthVar) + { + //printf("lengthVar\n"); + lengthVar.parent = sc.parent; + } + if (lwr) + lwr.scanForNestedRef(sc); + if (upr) upr.scanForNestedRef(sc); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { - buf.writestring("Slice"); + buf.writestring("Slice"); arguments.shift(cast(void*)this); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { - Identifier id = Identifier.generateId("p", fparams.dim); - Argument param = new Argument(STCconst, type, id, null); - fparams.shift(cast(void*)param); - Expression e = new IdentifierExp(Loc(0), id); - Expressions arguments = new Expressions(); - Expression index = new IdentifierExp(Loc(0), Id.p); - arguments.push(cast(void*)index); - e = new ArrayExp(Loc(0), e, arguments); + Identifier id = Identifier.generateId("p", fparams.dim); + Argument param = new Argument(STCconst, type, id, null); + fparams.shift(cast(void*)param); + Expression e = new IdentifierExp(Loc(0), id); + Expressions arguments = new Expressions(); + Expression index = new IdentifierExp(Loc(0), Id.p); + arguments.push(cast(void*)index); + e = new ArrayExp(Loc(0), e, arguments); return e; } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { int cost = 1 + e1.inlineCost(ics); if (lwr) @@ -531,7 +531,7 @@ return cost; } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { SliceExp are = cast(SliceExp)copy(); @@ -574,7 +574,7 @@ return are; } - Expression inlineScan(InlineScanState* iss) + override Expression inlineScan(InlineScanState* iss) { e1 = e1.inlineScan(iss); if (lwr) diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/StaticAssert.d --- a/dmd/StaticAssert.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/StaticAssert.d Sat Aug 28 16:19:48 2010 +0200 @@ -26,7 +26,7 @@ this.msg = msg; } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { StaticAssert sa; @@ -35,16 +35,16 @@ return sa; } - bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) + override bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) { return false; // we didn't add anything } - void semantic(Scope sc) + override void semantic(Scope sc) { } - void semantic2(Scope sc) + override void semantic2(Scope sc) { Expression e; @@ -80,27 +80,27 @@ } } - void inlineScan() + override void inlineScan() { } - bool oneMember(Dsymbol* ps) + override bool oneMember(Dsymbol* ps) { //printf("StaticAssert.oneMember())\n"); *ps = null; return true; } - void toObjFile(int multiobj) + override void toObjFile(int multiobj) { } - string kind() + override string kind() { return "static assert"; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring(kind()); buf.writeByte('('); diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/StaticAssertStatement.d --- a/dmd/StaticAssertStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/StaticAssertStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -17,20 +17,20 @@ this.sa = sa; } - Statement syntaxCopy() + override Statement syntaxCopy() { StaticAssertStatement s = new StaticAssertStatement(cast(StaticAssert)sa.syntaxCopy(null)); return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { sa.semantic2(sc); return null; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/StaticCtorDeclaration.d --- a/dmd/StaticCtorDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/StaticCtorDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -35,12 +35,12 @@ super(loc, endloc, Identifier.generateId("_staticCtor"), STCstatic, null); } - Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol) { assert(false); } - void semantic(Scope sc) + override void semantic(Scope sc) { //printf("StaticCtorDeclaration.semantic()\n"); @@ -90,40 +90,40 @@ } } - AggregateDeclaration isThis() + override AggregateDeclaration isThis() { return null; } - bool isStaticConstructor() + override bool isStaticConstructor() { return true; } - bool isVirtual() + override bool isVirtual() { return false; } - bool addPreInvariant() + override bool addPreInvariant() { return false; } - bool addPostInvariant() + override bool addPostInvariant() { return false; } - void emitComment(Scope sc) + override void emitComment(Scope sc) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - StaticCtorDeclaration isStaticCtorDeclaration() { return this; } -} \ No newline at end of file + override StaticCtorDeclaration isStaticCtorDeclaration() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/StaticDtorDeclaration.d --- a/dmd/StaticDtorDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/StaticDtorDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -38,12 +38,12 @@ super(loc, endloc, Identifier.generateId("_staticDtor"), STCstatic, null); } - Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol) { assert(false); } - void semantic(Scope sc) + override void semantic(Scope sc) { ClassDeclaration cd; Type tret; @@ -99,40 +99,40 @@ } } - AggregateDeclaration isThis() + override AggregateDeclaration isThis() { return null; } - bool isStaticDestructor() + override bool isStaticDestructor() { return true; } - bool isVirtual() + override bool isVirtual() { return false; } - bool addPreInvariant() + override bool addPreInvariant() { return false; } - bool addPostInvariant() + override bool addPostInvariant() { return false; } - void emitComment(Scope sc) + override void emitComment(Scope sc) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - StaticDtorDeclaration isStaticDtorDeclaration() { return this; } -} \ No newline at end of file + override StaticDtorDeclaration isStaticDtorDeclaration() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/StaticIfCondition.d --- a/dmd/StaticIfCondition.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/StaticIfCondition.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,15 +1,15 @@ -module dmd.StaticIfCondition; - -import dmd.Expression; -import dmd.ScopeDsymbol; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.Condition; +module dmd.StaticIfCondition; + +import dmd.Expression; +import dmd.ScopeDsymbol; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.Condition; import dmd.HdrGenState; import dmd.WANT; -import dmd.Util; - +import dmd.Util; + class StaticIfCondition : Condition { Expression exp; @@ -20,12 +20,12 @@ this.exp = exp; } - Condition syntaxCopy() + override Condition syntaxCopy() { - return new StaticIfCondition(loc, exp.syntaxCopy()); + return new StaticIfCondition(loc, exp.syntaxCopy()); } - bool include(Scope sc, ScopeDsymbol s) + override bool include(Scope sc, ScopeDsymbol s) { static if (false) { printf("StaticIfCondition.include(sc = %p, s = %p)\n", sc, s); @@ -62,7 +62,7 @@ return (inc == 1); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/StaticIfDeclaration.d --- a/dmd/StaticIfDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/StaticIfDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -19,7 +19,7 @@ //printf("StaticIfDeclaration::StaticIfDeclaration()\n"); } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { StaticIfDeclaration dd; @@ -30,7 +30,7 @@ return dd; } - bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) + override bool addMember(Scope sc, ScopeDsymbol sd, bool memnum) { //printf("StaticIfDeclaration.addMember() '%s'\n",toChars()); /* This is deferred until semantic(), so that @@ -55,7 +55,7 @@ return m; } - void semantic(Scope sc) + override void semantic(Scope sc) { Array d = include(sc, sd); @@ -77,7 +77,7 @@ } } - string kind() + override string kind() { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/StorageClassDeclaration.d --- a/dmd/StorageClassDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/StorageClassDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -21,7 +21,7 @@ this.stc = stc; } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { StorageClassDeclaration scd; @@ -30,7 +30,7 @@ return scd; } - void setScope(Scope sc) + override void setScope(Scope sc) { if (decl) { @@ -53,7 +53,7 @@ } } - void semantic(Scope sc) + override void semantic(Scope sc) { if (decl) { @@ -76,7 +76,7 @@ } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } @@ -125,4 +125,4 @@ } } } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/String.d --- a/dmd/String.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/String.d Sat Aug 28 16:19:48 2010 +0200 @@ -73,7 +73,7 @@ return str == (cast(String)obj).str; } - int opCmp(Object obj) + override int opCmp(Object obj) { return cmp(str, (cast(String)obj).str); } @@ -87,4 +87,4 @@ { writefln("String '%s'", str); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/StringExp.d --- a/dmd/StringExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/StringExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -62,7 +62,7 @@ this.postfix = postfix; } - bool equals(Object o) + override bool equals(Object o) { Expression e; //printf("StringExp.equals('%s')\n", o.toChars()); @@ -77,7 +77,7 @@ return false; } - string toChars() + override string toChars() { scope OutBuffer buf = new OutBuffer(); HdrGenState hgs; @@ -89,7 +89,7 @@ return buf.extractString(); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { version (LOGSEMANTIC) { printf("StringExp.semantic() %s\n", toChars()); @@ -168,7 +168,7 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { version (LOG) { printf("StringExp.interpret() %.*s\n", toChars()); @@ -243,7 +243,7 @@ return this; } - Expression implicitCastTo(Scope sc, Type t) + override Expression implicitCastTo(Scope sc, Type t) { //printf("StringExp.implicitCastTo(%s of type %s) => %s\n", toChars(), type.toChars(), t.toChars()); ubyte committed = this.committed; @@ -256,7 +256,7 @@ return e; } - MATCH implicitConvTo(Type t) + override MATCH implicitConvTo(Type t) { MATCH m; @@ -338,7 +338,7 @@ return ((tf) * 256 + (tt)); } - Expression castTo(Scope sc, Type t) + override Expression castTo(Scope sc, Type t) { /* This follows copy-on-write; any changes to 'this' * will result in a copy. @@ -577,7 +577,7 @@ return e; } - int opCmp(Object obj) + override int opCmp(Object obj) { // Used to sort case statement expressions so we can do an efficient lookup StringExp se2 = cast(StringExp)(obj); @@ -635,7 +635,7 @@ return len1 - len2; } - bool isBool(bool result) + override bool isBool(bool result) { assert(false); } @@ -665,7 +665,7 @@ return value; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writeByte('"'); for (size_t i = 0; i < len; i++) @@ -698,7 +698,7 @@ buf.writeByte(postfix); } - void toMangleBuffer(OutBuffer buf) + override void toMangleBuffer(OutBuffer buf) { char m; OutBuffer tmp = new OutBuffer(); @@ -751,7 +751,7 @@ buf.printf("%02x", q[i]); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* e; Type tb = type.toBasetype(); @@ -858,7 +858,7 @@ return e; } - dt_t** toDt(dt_t** pdt) + override dt_t** toDt(dt_t** pdt) { //printf("StringExp.toDt() '%s', type = %s\n", toChars(), type.toChars()); Type t = type.toBasetype(); diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/StructDeclaration.d --- a/dmd/StructDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/StructDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -82,7 +82,7 @@ postblits = new FuncDeclarations(); /// } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { StructDeclaration sd; @@ -94,7 +94,7 @@ return sd; } - void semantic(Scope sc) + override void semantic(Scope sc) { int i; Scope sc2; @@ -363,18 +363,18 @@ } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - string mangle() + override string mangle() { //printf("StructDeclaration.mangle() '%s'\n", toChars()); return Dsymbol.mangle(); } - string kind() + override string kind() { assert(false); } @@ -700,17 +700,17 @@ return fcp; } - void toDocBuffer(OutBuffer buf) + override void toDocBuffer(OutBuffer buf) { assert(false); } - PROT getAccess(Dsymbol smember) // determine access to smember + override PROT getAccess(Dsymbol smember) // determine access to smember { assert(false); } - void toObjFile(int multiobj) // compile to .obj file + override void toObjFile(int multiobj) // compile to .obj file { //printf("StructDeclaration.toObjFile('%s')\n", toChars()); @@ -854,5 +854,5 @@ assert(false); } - StructDeclaration isStructDeclaration() { return this; } -} \ No newline at end of file + override StructDeclaration isStructDeclaration() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/StructInitializer.d --- a/dmd/StructInitializer.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/StructInitializer.d Sat Aug 28 16:19:48 2010 +0200 @@ -49,7 +49,7 @@ vars = new Array(); } - Initializer syntaxCopy() + override Initializer syntaxCopy() { StructInitializer ai = new StructInitializer(loc); @@ -75,7 +75,7 @@ this.value.push(cast(void*)value); } - Initializer semantic(Scope sc, Type t) + override Initializer semantic(Scope sc, Type t) { TypeStruct ts; int errors = 0; @@ -179,7 +179,7 @@ * a struct literal. In the future, the two should be the * same thing. */ - Expression toExpression() + override Expression toExpression() { Expression e; @@ -214,12 +214,12 @@ return null; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - dt_t* toDt() + override dt_t* toDt() { scope Array dts = new Array(); uint i; @@ -339,5 +339,5 @@ return dt; } - StructInitializer isStructInitializer() { return this; } -} \ No newline at end of file + override StructInitializer isStructInitializer() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/StructLiteralExp.d --- a/dmd/StructLiteralExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/StructLiteralExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,158 +1,158 @@ -module dmd.StructLiteralExp; - -import dmd.Expression; -import dmd.MOD; -import dmd.TypeStruct; -import dmd.TypeSArray; -import dmd.expression.Util; -import dmd.ErrorExp; -import dmd.Dsymbol; -import dmd.VarDeclaration; -import dmd.StructDeclaration; -import dmd.FuncDeclaration; -import dmd.ThisDeclaration; -import dmd.backend.elem; -import dmd.InterState; -import dmd.MATCH; -import dmd.WANT; -import dmd.TY; -import dmd.Type; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.InlineCostState; -import dmd.IRState; -import dmd.InlineDoState; -import dmd.backend.Symbol; -import dmd.HdrGenState; -import dmd.backend.dt_t; -import dmd.InlineScanState; -import dmd.ArrayTypes; -import dmd.TOK; - -import dmd.codegen.Util; -import dmd.backend.Util; -import dmd.backend.RTLSYM; -import dmd.backend.TYM; -import dmd.backend.mTY; -import dmd.backend.OPER; - - +module dmd.StructLiteralExp; + +import dmd.Expression; +import dmd.MOD; +import dmd.TypeStruct; +import dmd.TypeSArray; +import dmd.expression.Util; +import dmd.ErrorExp; +import dmd.Dsymbol; +import dmd.VarDeclaration; +import dmd.StructDeclaration; +import dmd.FuncDeclaration; +import dmd.ThisDeclaration; +import dmd.backend.elem; +import dmd.InterState; +import dmd.MATCH; +import dmd.WANT; +import dmd.TY; +import dmd.Type; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.InlineCostState; +import dmd.IRState; +import dmd.InlineDoState; +import dmd.backend.Symbol; +import dmd.HdrGenState; +import dmd.backend.dt_t; +import dmd.InlineScanState; +import dmd.ArrayTypes; +import dmd.TOK; + +import dmd.codegen.Util; +import dmd.backend.Util; +import dmd.backend.RTLSYM; +import dmd.backend.TYM; +import dmd.backend.mTY; +import dmd.backend.OPER; + + class StructLiteralExp : Expression { - StructDeclaration sd; // which aggregate this is for - Expressions elements; // parallels sd->fields[] with - // NULL entries for fields to skip - - Symbol* sym; // back end symbol to initialize with literal - size_t soffset; // offset from start of s + StructDeclaration sd; // which aggregate this is for + Expressions elements; // parallels sd->fields[] with + // NULL entries for fields to skip + + Symbol* sym; // back end symbol to initialize with literal + size_t soffset; // offset from start of s int fillHoles; // fill alignment 'holes' with zero this(Loc loc, StructDeclaration sd, Expressions elements) { - super(loc, TOKstructliteral, StructLiteralExp.sizeof); - this.sd = sd; - this.elements = elements; - this.sym = null; - this.soffset = 0; - this.fillHoles = 1; + super(loc, TOKstructliteral, StructLiteralExp.sizeof); + this.sd = sd; + this.elements = elements; + this.sym = null; + this.soffset = 0; + this.fillHoles = 1; } - Expression syntaxCopy() + override Expression syntaxCopy() { assert(false); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { - Expression e; - int nfields = sd.fields.dim - sd.isnested; - -version (LOGSEMANTIC) { - printf("StructLiteralExp.semantic('%s')\n", toChars()); -} - if (type) - return this; - - // Run semantic() on each element - for (size_t i = 0; i < elements.dim; i++) - { - e = cast(Expression)elements.data[i]; - if (!e) - continue; - e = e.semantic(sc); - elements.data[i] = cast(void*)e; - } - expandTuples(elements); - size_t offset = 0; - for (size_t i = 0; i < elements.dim; i++) - { - e = cast(Expression)elements.data[i]; - if (!e) - continue; - - if (!e.type) - error("%s has no value", e.toChars()); - e = resolveProperties(sc, e); - if (i >= nfields) - { - error("more initializers than fields of %s", sd.toChars()); - return new ErrorExp(); - } - Dsymbol s = cast(Dsymbol)sd.fields.data[i]; - VarDeclaration v = s.isVarDeclaration(); - assert(v); - if (v.offset < offset) - error("overlapping initialization for %s", v.toChars()); - offset = v.offset + cast(uint)v.type.size(); - - Type telem = v.type; - while (!e.implicitConvTo(telem) && telem.toBasetype().ty == Tsarray) - { - /* Static array initialization, as in: - * T[3][5] = e; - */ - telem = telem.toBasetype().nextOf(); - } - - e = e.implicitCastTo(sc, telem); - - elements.data[i] = cast(void*)e; - } - - /* Fill out remainder of elements[] with default initializers for fields[] - */ - for (size_t i = elements.dim; i < nfields; i++) - { - Dsymbol s = cast(Dsymbol)sd.fields.data[i]; - VarDeclaration v = s.isVarDeclaration(); - assert(v); - assert(!v.isThisDeclaration()); - - if (v.offset < offset) - { - e = null; - sd.hasUnions = 1; - } - else - { - if (v.init) - { - e = v.init.toExpression(); - if (!e) - error("cannot make expression out of initializer for %s", v.toChars()); - } - else - { - e = v.type.defaultInit(Loc(0)); - e.loc = loc; - } - offset = v.offset + cast(uint)v.type.size(); - } - elements.push(cast(void*)e); - } - - type = sd.type; + Expression e; + int nfields = sd.fields.dim - sd.isnested; + +version (LOGSEMANTIC) { + printf("StructLiteralExp.semantic('%s')\n", toChars()); +} + if (type) + return this; + + // Run semantic() on each element + for (size_t i = 0; i < elements.dim; i++) + { + e = cast(Expression)elements.data[i]; + if (!e) + continue; + e = e.semantic(sc); + elements.data[i] = cast(void*)e; + } + expandTuples(elements); + size_t offset = 0; + for (size_t i = 0; i < elements.dim; i++) + { + e = cast(Expression)elements.data[i]; + if (!e) + continue; + + if (!e.type) + error("%s has no value", e.toChars()); + e = resolveProperties(sc, e); + if (i >= nfields) + { + error("more initializers than fields of %s", sd.toChars()); + return new ErrorExp(); + } + Dsymbol s = cast(Dsymbol)sd.fields.data[i]; + VarDeclaration v = s.isVarDeclaration(); + assert(v); + if (v.offset < offset) + error("overlapping initialization for %s", v.toChars()); + offset = v.offset + cast(uint)v.type.size(); + + Type telem = v.type; + while (!e.implicitConvTo(telem) && telem.toBasetype().ty == Tsarray) + { + /* Static array initialization, as in: + * T[3][5] = e; + */ + telem = telem.toBasetype().nextOf(); + } + + e = e.implicitCastTo(sc, telem); + + elements.data[i] = cast(void*)e; + } + + /* Fill out remainder of elements[] with default initializers for fields[] + */ + for (size_t i = elements.dim; i < nfields; i++) + { + Dsymbol s = cast(Dsymbol)sd.fields.data[i]; + VarDeclaration v = s.isVarDeclaration(); + assert(v); + assert(!v.isThisDeclaration()); + + if (v.offset < offset) + { + e = null; + sd.hasUnions = 1; + } + else + { + if (v.init) + { + e = v.init.toExpression(); + if (!e) + error("cannot make expression out of initializer for %s", v.toChars()); + } + else + { + e = v.type.defaultInit(Loc(0)); + e.loc = loc; + } + offset = v.offset + cast(uint)v.type.size(); + } + elements.push(cast(void*)e); + } + + type = sd.type; return this; } @@ -166,277 +166,277 @@ assert(false); } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { - elem* e; - size_t dim; - - //printf("StructLiteralExp.toElem() %s\n", toChars()); - - // struct symbol to initialize with the literal - Symbol* stmp = sym ? sym : symbol_genauto(sd.type.toCtype()); - - e = null; - - if (fillHoles) - { - /* Initialize all alignment 'holes' to zero. - * Do before initializing fields, as the hole filling process - * can spill over into the fields. - */ - size_t offset = 0; - for (size_t i = 0; i < sd.fields.dim; i++) - { - Dsymbol s = cast(Dsymbol)sd.fields.data[i]; - VarDeclaration v = s.isVarDeclaration(); - assert(v); - - e = el_combine(e, fillHole(stmp, &offset, v.offset, sd.structsize)); - size_t vend = v.offset + cast(uint)v.type.size(); - if (offset < vend) - offset = vend; - } - e = el_combine(e, fillHole(stmp, &offset, sd.structsize, sd.structsize)); - } - - if (elements) - { - dim = elements.dim; - assert(dim <= sd.fields.dim); - for (size_t i = 0; i < dim; i++) - { - Expression el = cast(Expression)elements.data[i]; - if (!el) - continue; - - Dsymbol s = cast(Dsymbol)sd.fields.data[i]; - VarDeclaration v = s.isVarDeclaration(); - assert(v); - assert(!v.isThisDeclaration()); - - elem* e1; - if (tybasic(stmp.Stype.Tty) == TYnptr) - { - e1 = el_var(stmp); - e1.EV.sp.Voffset = soffset; - } - else - { - e1 = el_ptr(stmp); - if (soffset) - e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); - } - e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset)); - elem* ec = e1; // pointer to destination - - elem* ep = el.toElem(irs); - - Type t1b = v.type.toBasetype(); - Type t2b = el.type.toBasetype(); - if (t1b.ty == Tsarray) - { - if (t2b.implicitConvTo(t1b)) - { - ///version (DMDV2) { - // Determine if postblit is needed - int postblit = 0; - if (needsPostblit(t1b)) - postblit = 1; - - if (postblit) - { - /* Generate: - * _d_arrayctor(ti, From: ep, To: e1) - */ - Expression ti = t1b.nextOf().toBasetype().getTypeInfo(null); - elem* esize = el_long(TYsize_t, (cast(TypeSArray)t1b).dim.toInteger()); - e1 = el_pair(TYdarray, esize, e1); - ep = el_pair(TYdarray, el_copytree(esize), array_toPtr(el.type, ep)); - ep = el_params(e1, ep, ti.toElem(irs), null); - int rtl = RTLSYM_ARRAYCTOR; - e1 = el_bin(OPcall, type.totym(), el_var(rtlsym[rtl]), ep); - } - else - ///} - { - elem* esize = el_long(TYsize_t, t1b.size()); - ep = array_toPtr(el.type, ep); - e1 = el_bin(OPmemcpy, TYnptr, e1, el_param(ep, esize)); - } - } - else - { - elem* edim = el_long(TYsize_t, t1b.size() / t2b.size()); - e1 = setArray(e1, edim, t2b, ep, irs, TOKconstruct); - } - } - else - { - tym_t ty = v.type.totym(); - e1 = el_una(OPind, ty, e1); - if (tybasic(ty) == TYstruct) - e1.Enumbytes = cast(uint)v.type.size(); - e1 = el_bin(OPeq, ty, e1, ep); - if (tybasic(ty) == TYstruct) - { - e1.Eoper = OPstreq; - e1.Enumbytes = cast(uint)v.type.size(); - } -version (DMDV2) { - /* Call postblit() on e1 - */ - StructDeclaration sd = needsPostblit(v.type); - if (sd) - { - FuncDeclaration fd = sd.postblit; - ec = el_copytree(ec); - ec = callfunc(loc, irs, 1, Type.tvoid, ec, sd.type.pointerTo(), fd, fd.type, null, null); - e1 = el_bin(OPcomma, ec.Ety, e1, ec); - } -} - } - e = el_combine(e, e1); - } - } - -version (DMDV2) { - if (sd.isnested) - { // Initialize the hidden 'this' pointer - assert(sd.fields.dim); - Dsymbol s = cast(Dsymbol)sd.fields.data[sd.fields.dim - 1]; - ThisDeclaration v = s.isThisDeclaration(); - assert(v); - - elem* e1; - if (tybasic(stmp.Stype.Tty) == TYnptr) - { - e1 = el_var(stmp); - e1.EV.sp.Voffset = soffset; - } - else - { - e1 = el_ptr(stmp); - if (soffset) - e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); - } - e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset)); - e1 = setEthis(loc, irs, e1, sd); - - e = el_combine(e, e1); - } -} - - elem* ev = el_var(stmp); - ev.Enumbytes = sd.structsize; - e = el_combine(e, ev); - el_setLoc(e,loc); + elem* e; + size_t dim; + + //printf("StructLiteralExp.toElem() %s\n", toChars()); + + // struct symbol to initialize with the literal + Symbol* stmp = sym ? sym : symbol_genauto(sd.type.toCtype()); + + e = null; + + if (fillHoles) + { + /* Initialize all alignment 'holes' to zero. + * Do before initializing fields, as the hole filling process + * can spill over into the fields. + */ + size_t offset = 0; + for (size_t i = 0; i < sd.fields.dim; i++) + { + Dsymbol s = cast(Dsymbol)sd.fields.data[i]; + VarDeclaration v = s.isVarDeclaration(); + assert(v); + + e = el_combine(e, fillHole(stmp, &offset, v.offset, sd.structsize)); + size_t vend = v.offset + cast(uint)v.type.size(); + if (offset < vend) + offset = vend; + } + e = el_combine(e, fillHole(stmp, &offset, sd.structsize, sd.structsize)); + } + + if (elements) + { + dim = elements.dim; + assert(dim <= sd.fields.dim); + for (size_t i = 0; i < dim; i++) + { + Expression el = cast(Expression)elements.data[i]; + if (!el) + continue; + + Dsymbol s = cast(Dsymbol)sd.fields.data[i]; + VarDeclaration v = s.isVarDeclaration(); + assert(v); + assert(!v.isThisDeclaration()); + + elem* e1; + if (tybasic(stmp.Stype.Tty) == TYnptr) + { + e1 = el_var(stmp); + e1.EV.sp.Voffset = soffset; + } + else + { + e1 = el_ptr(stmp); + if (soffset) + e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); + } + e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset)); + elem* ec = e1; // pointer to destination + + elem* ep = el.toElem(irs); + + Type t1b = v.type.toBasetype(); + Type t2b = el.type.toBasetype(); + if (t1b.ty == Tsarray) + { + if (t2b.implicitConvTo(t1b)) + { + ///version (DMDV2) { + // Determine if postblit is needed + int postblit = 0; + if (needsPostblit(t1b)) + postblit = 1; + + if (postblit) + { + /* Generate: + * _d_arrayctor(ti, From: ep, To: e1) + */ + Expression ti = t1b.nextOf().toBasetype().getTypeInfo(null); + elem* esize = el_long(TYsize_t, (cast(TypeSArray)t1b).dim.toInteger()); + e1 = el_pair(TYdarray, esize, e1); + ep = el_pair(TYdarray, el_copytree(esize), array_toPtr(el.type, ep)); + ep = el_params(e1, ep, ti.toElem(irs), null); + int rtl = RTLSYM_ARRAYCTOR; + e1 = el_bin(OPcall, type.totym(), el_var(rtlsym[rtl]), ep); + } + else + ///} + { + elem* esize = el_long(TYsize_t, t1b.size()); + ep = array_toPtr(el.type, ep); + e1 = el_bin(OPmemcpy, TYnptr, e1, el_param(ep, esize)); + } + } + else + { + elem* edim = el_long(TYsize_t, t1b.size() / t2b.size()); + e1 = setArray(e1, edim, t2b, ep, irs, TOKconstruct); + } + } + else + { + tym_t ty = v.type.totym(); + e1 = el_una(OPind, ty, e1); + if (tybasic(ty) == TYstruct) + e1.Enumbytes = cast(uint)v.type.size(); + e1 = el_bin(OPeq, ty, e1, ep); + if (tybasic(ty) == TYstruct) + { + e1.Eoper = OPstreq; + e1.Enumbytes = cast(uint)v.type.size(); + } +version (DMDV2) { + /* Call postblit() on e1 + */ + StructDeclaration sd = needsPostblit(v.type); + if (sd) + { + FuncDeclaration fd = sd.postblit; + ec = el_copytree(ec); + ec = callfunc(loc, irs, 1, Type.tvoid, ec, sd.type.pointerTo(), fd, fd.type, null, null); + e1 = el_bin(OPcomma, ec.Ety, e1, ec); + } +} + } + e = el_combine(e, e1); + } + } + +version (DMDV2) { + if (sd.isnested) + { // Initialize the hidden 'this' pointer + assert(sd.fields.dim); + Dsymbol s = cast(Dsymbol)sd.fields.data[sd.fields.dim - 1]; + ThisDeclaration v = s.isThisDeclaration(); + assert(v); + + elem* e1; + if (tybasic(stmp.Stype.Tty) == TYnptr) + { + e1 = el_var(stmp); + e1.EV.sp.Voffset = soffset; + } + else + { + e1 = el_ptr(stmp); + if (soffset) + e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); + } + e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset)); + e1 = setEthis(loc, irs, e1, sd); + + e = el_combine(e, e1); + } +} + + elem* ev = el_var(stmp); + ev.Enumbytes = sd.structsize; + e = el_combine(e, ev); + el_setLoc(e,loc); return e; } - bool checkSideEffect(int flag) + override bool checkSideEffect(int flag) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - void toMangleBuffer(OutBuffer buf) + override void toMangleBuffer(OutBuffer buf) { assert(false); } - void scanForNestedRef(Scope sc) + override void scanForNestedRef(Scope sc) { assert(false); } - Expression optimize(int result) + override Expression optimize(int result) { - if (elements) - { - for (size_t i = 0; i < elements.dim; i++) - { - Expression e = cast(Expression)elements.data[i]; - if (!e) - continue; - e = e.optimize(WANTvalue | (result & WANTinterpret)); - elements.data[i] = cast(void*)e; - } - } + if (elements) + { + for (size_t i = 0; i < elements.dim; i++) + { + Expression e = cast(Expression)elements.data[i]; + if (!e) + continue; + e = e.optimize(WANTvalue | (result & WANTinterpret)); + elements.data[i] = cast(void*)e; + } + } return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - dt_t** toDt(dt_t** pdt) + override dt_t** toDt(dt_t** pdt) { assert(false); } - int isLvalue() + override int isLvalue() { assert(false); } - Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression e) { assert(false); } - bool canThrow() + override bool canThrow() { return arrayExpressionCanThrow(elements); } - MATCH implicitConvTo(Type t) + override MATCH implicitConvTo(Type t) { -static if (false) { - printf("StructLiteralExp.implicitConvTo(this=%.*s, type=%.*s, t=%.*s)\n", - toChars(), type.toChars(), t.toChars()); -} - MATCH m = Expression.implicitConvTo(t); - if (m != MATCHnomatch) - return m; - if (type.ty == t.ty && type.ty == Tstruct && (cast(TypeStruct)type).sym == (cast(TypeStruct)t).sym) - { - m = MATCHconst; - for (int i = 0; i < elements.dim; i++) - { - Expression e = cast(Expression)elements.data[i]; - Type te = e.type; - if (t.mod == 0) - te = te.mutableOf(); - else - { - assert(t.mod == MODinvariant); - te = te.invariantOf(); - } - MATCH m2 = e.implicitConvTo(te); - //printf("\t%s => %s, match = %d\n", e.toChars(), te.toChars(), m2); - if (m2 < m) - m = m2; - } - } +static if (false) { + printf("StructLiteralExp.implicitConvTo(this=%.*s, type=%.*s, t=%.*s)\n", + toChars(), type.toChars(), t.toChars()); +} + MATCH m = Expression.implicitConvTo(t); + if (m != MATCHnomatch) + return m; + if (type.ty == t.ty && type.ty == Tstruct && (cast(TypeStruct)type).sym == (cast(TypeStruct)t).sym) + { + m = MATCHconst; + for (int i = 0; i < elements.dim; i++) + { + Expression e = cast(Expression)elements.data[i]; + Type te = e.type; + if (t.mod == 0) + te = te.mutableOf(); + else + { + assert(t.mod == MODinvariant); + te = te.invariantOf(); + } + MATCH m2 = e.implicitConvTo(te); + //printf("\t%s => %s, match = %d\n", e.toChars(), te.toChars(), m2); + if (m2 < m) + m = m2; + } + } return m; } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { assert(false); } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { assert(false); } - Expression inlineScan(InlineScanState* iss) + override Expression inlineScan(InlineScanState* iss) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/SuperExp.d --- a/dmd/SuperExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/SuperExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,20 +1,20 @@ -module dmd.SuperExp; - -import dmd.Expression; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.InlineCostState; +module dmd.SuperExp; + +import dmd.Expression; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.InlineCostState; import dmd.InlineDoState; import dmd.FuncDeclaration; import dmd.ClassDeclaration; -import dmd.Dsymbol; -import dmd.HdrGenState; -import dmd.ThisExp; +import dmd.Dsymbol; +import dmd.HdrGenState; +import dmd.ThisExp; import dmd.TOK; import dmd.CSX; -import dmd.Type; - +import dmd.Type; + class SuperExp : ThisExp { this(Loc loc) @@ -23,7 +23,7 @@ op = TOK.TOKsuper; } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { FuncDeclaration fd; FuncDeclaration fdthis; @@ -102,22 +102,22 @@ return this; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("super"); } - void scanForNestedRef(Scope sc) + override void scanForNestedRef(Scope sc) { assert(false); } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { assert(false); } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/SwitchErrorStatement.d --- a/dmd/SwitchErrorStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/SwitchErrorStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,9 +1,9 @@ -module dmd.SwitchErrorStatement; - -import dmd.Statement; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.IRState; +module dmd.SwitchErrorStatement; + +import dmd.Statement; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.IRState; import dmd.HdrGenState; import dmd.BE; @@ -12,8 +12,8 @@ import dmd.backend.Util; import dmd.backend.TYM; import dmd.backend.OPER; -import dmd.backend.RTLSYM; - +import dmd.backend.RTLSYM; + class SwitchErrorStatement : Statement { this(Loc loc) @@ -21,18 +21,18 @@ super(loc); } - BE blockExit() + override BE blockExit() { return BE.BEthrow; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("SwitchErrorStatement.toCBuffer()"); buf.writenl(); } - void toIR(IRState* irs) + override void toIR(IRState* irs) { elem* e; elem* elinnum; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/SwitchStatement.d --- a/dmd/SwitchStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/SwitchStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -75,14 +75,14 @@ gotoCases = new Array(); } - Statement syntaxCopy() + override Statement syntaxCopy() { SwitchStatement s = new SwitchStatement(loc, condition.syntaxCopy(), body_.syntaxCopy(), isFinal); return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { //printf("SwitchStatement.semantic(%p)\n", this); tf = sc.tf; @@ -213,17 +213,17 @@ return this; } - bool hasBreak() + override bool hasBreak() { assert(false); } - bool usesEH() + override bool usesEH() { assert(false); } - BE blockExit() + override BE blockExit() { BE result = BE.BEnone; if (condition.canThrow()) @@ -243,17 +243,17 @@ return result; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { //printf("SwitchStatement.inlineScan()\n"); condition = condition.inlineScan(iss); @@ -271,7 +271,7 @@ return this; } - void toIR(IRState* irs) + override void toIR(IRState* irs) { int string; Blockx* blx = irs.blx; @@ -444,4 +444,4 @@ */ block_goto(blx, BCgoto, mystate.breakBlock); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/SymOffExp.d --- a/dmd/SymOffExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/SymOffExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,15 +1,15 @@ -module dmd.SymOffExp; - -import dmd.Expression; -import dmd.Declaration; -import dmd.MATCH; -import dmd.Type; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.InlineDoState; -import dmd.HdrGenState; -import dmd.backend.dt_t; +module dmd.SymOffExp; + +import dmd.Expression; +import dmd.Declaration; +import dmd.MATCH; +import dmd.Type; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.InlineDoState; +import dmd.HdrGenState; +import dmd.backend.dt_t; import dmd.SymbolExp; import dmd.VarDeclaration; import dmd.DelegateExp; @@ -17,13 +17,13 @@ import dmd.FuncDeclaration; import dmd.IntegerExp; import dmd.ErrorExp; -import dmd.TY; +import dmd.TY; import dmd.TOK; import dmd.backend.Symbol; import dmd.backend.Util; import dmd.backend.TYM; - + class SymOffExp : SymbolExp { uint offset; @@ -38,7 +38,7 @@ error("need 'this' for address of %s", v.toChars()); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { version(LOGSEMANTIC) { printf("SymOffExp::semantic('%s')\n", toChars()); @@ -52,7 +52,7 @@ return this; } - void checkEscape() + override void checkEscape() { VarDeclaration v = var.isVarDeclaration(); if (v) @@ -62,22 +62,22 @@ } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - int isConst() + override int isConst() { return 2; } - bool isBool(bool result) + override bool isBool(bool result) { assert(false); } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { int i; @@ -95,7 +95,7 @@ return this; } - MATCH implicitConvTo(Type t) + override MATCH implicitConvTo(Type t) { static if (false) { printf("SymOffExp::implicitConvTo(this=%s, type=%s, t=%s)\n", toChars(), type.toChars(), t.toChars()); @@ -131,7 +131,7 @@ return result; } - Expression castTo(Scope sc, Type t) + override Expression castTo(Scope sc, Type t) { static if (false) { printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n", toChars(), type.toChars(), t.toChars()); @@ -204,15 +204,15 @@ return e; } - void scanForNestedRef(Scope sc) + override void scanForNestedRef(Scope sc) { - //printf("SymOffExp.scanForNestedRef(%s)\n", toChars()); - VarDeclaration v = var.isVarDeclaration(); - if (v) + //printf("SymOffExp.scanForNestedRef(%s)\n", toChars()); + VarDeclaration v = var.isVarDeclaration(); + if (v) v.checkNestedReference(sc, Loc(0)); } - dt_t** toDt(dt_t** pdt) + override dt_t** toDt(dt_t** pdt) { //printf("SymOffExp.toDt('%s')\n", var.toChars()); assert(var); diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/SymbolDeclaration.d --- a/dmd/SymbolDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/SymbolDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -32,11 +32,11 @@ storage_class |= STCconst; } - Symbol* toSymbol() + override Symbol* toSymbol() { return sym; } // Eliminate need for dynamic_cast - SymbolDeclaration isSymbolDeclaration() { return this; } -} \ No newline at end of file + override SymbolDeclaration isSymbolDeclaration() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/SymbolExp.d --- a/dmd/SymbolExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/SymbolExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,24 +1,24 @@ -module dmd.SymbolExp; - -import dmd.Expression; -import dmd.Declaration; -import dmd.Loc; -import dmd.IRState; -import dmd.TOK; -import dmd.TY; -import dmd.Type; -import dmd.SymOffExp; -import dmd.FuncDeclaration; -import dmd.VarDeclaration; -import dmd.backend.OPER; -import dmd.backend.TYM; -import dmd.backend.mTY; -import dmd.backend.SC; -import dmd.backend.elem; -import dmd.backend.Symbol; -import dmd.backend.Util; -import dmd.codegen.Util; - +module dmd.SymbolExp; + +import dmd.Expression; +import dmd.Declaration; +import dmd.Loc; +import dmd.IRState; +import dmd.TOK; +import dmd.TY; +import dmd.Type; +import dmd.SymOffExp; +import dmd.FuncDeclaration; +import dmd.VarDeclaration; +import dmd.backend.OPER; +import dmd.backend.TYM; +import dmd.backend.mTY; +import dmd.backend.SC; +import dmd.backend.elem; +import dmd.backend.Symbol; +import dmd.backend.Util; +import dmd.codegen.Util; + class SymbolExp : Expression { Declaration var; @@ -27,175 +27,175 @@ this(Loc loc, TOK op, int size, Declaration var, int hasOverloads) { - super(loc, op, size); - assert(var); - this.var = var; + super(loc, op, size); + assert(var); + this.var = var; this.hasOverloads = hasOverloads; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { - Symbol* s; - elem* e; - tym_t tym; - Type tb = (op == TOK.TOKsymoff) ? var.type.toBasetype() : type.toBasetype(); - int offset = (op == TOK.TOKsymoff) ? (cast(SymOffExp)this).offset : 0; - FuncDeclaration fd; - VarDeclaration v = var.isVarDeclaration(); - - //printf("SymbolExp::toElem('%s') %p\n", toChars(), this); - //printf("\tparent = '%s'\n", var.parent ? var.parent.toChars() : "null"); - if (op == TOK.TOKvar && var.needThis()) - { - error("need 'this' to access member %s", toChars()); - return el_long(TYM.TYint, 0); - } - s = var.toSymbol(); - fd = null; - if (var.toParent2()) - fd = var.toParent2().isFuncDeclaration(); - - int nrvo = 0; - if (fd && fd.nrvo_can && fd.nrvo_var == var) - { - s = fd.shidden; - nrvo = 1; - } - - if (s.Sclass == SC.SCauto || s.Sclass == SC.SCparameter) - { - if (fd && fd != irs.getFunc()) - { - // 'var' is a variable in an enclosing function. - elem* ethis; - int soffset; - - ethis = getEthis(loc, irs, fd); - ethis = el_una(OPER.OPaddr, TYM.TYnptr, ethis); - - if (v && v.offset) - soffset = v.offset; - else - { - soffset = s.Soffset; - /* If fd is a non-static member function of a class or struct, - * then ethis isn't the frame pointer. - * ethis is the 'this' pointer to the class/struct instance. - * We must offset it. - */ - if (fd.vthis) - { - soffset -= fd.vthis.toSymbol().Soffset; - } - //printf("\tSoffset = x%x, sthis.Soffset = x%x\n", s.Soffset, irs.sthis.Soffset); - } - - if (!nrvo) - soffset += offset; - - e = el_bin(OPER.OPadd, TYM.TYnptr, ethis, el_long(TYM.TYnptr, soffset)); - - if (op == TOK.TOKvar) - e = el_una(OPER.OPind, TYM.TYnptr, e); - if ((var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef()) - e = el_una(OPER.OPind, s.ty(), e); - else if (op == TOK.TOKsymoff && nrvo) - { - e = el_una(OPER.OPind, TYM.TYnptr, e); - e = el_bin(OPER.OPadd, e.Ety, e, el_long(TYM.TYint, offset)); - } - goto L1; - } - } - - /* If var is a member of a closure - */ - if (v && v.offset) - { - assert(irs.sclosure); - e = el_var(irs.sclosure); - e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, v.offset)); - if (op == TOK.TOKvar) - { - e = el_una(OPER.OPind, type.totym(), e); - if (tybasic(e.Ety) == TYM.TYstruct) - e.Enumbytes = cast(uint)type.size(); - el_setLoc(e, loc); - } - if ((var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef()) - { - e.Ety = TYM.TYnptr; - e = el_una(OPER.OPind, s.ty(), e); - } - else if (op == TOK.TOKsymoff && nrvo) - { e = el_una(OPER.OPind, TYM.TYnptr, e); - e = el_bin(OPER.OPadd, e.Ety, e, el_long(TYM.TYint, offset)); - } - else if (op == TOK.TOKsymoff) - { - e = el_bin(OPER.OPadd, e.Ety, e, el_long(TYM.TYint, offset)); - } - goto L1; - } - - if (s.Sclass == SC.SCauto && s.Ssymnum == -1) - { - //printf("\tadding symbol\n"); - symbol_add(s); - } - - if (var.isImportedSymbol()) - { - assert(op == TOK.TOKvar); - 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()) - { - // Static arrays are really passed as pointers to the array - // Out parameters are really references - e = el_var(s); - e.Ety = TYM.TYnptr; - if (op == TOK.TOKvar) - e = el_una(OPER.OPind, s.ty(), e); - else if (offset) - e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, offset)); - } - else if (op == TOK.TOKvar) - e = el_var(s); - else - { - e = nrvo ? el_var(s) : el_ptr(s); - e = el_bin(OPER.OPadd, e.Ety, e, el_long(TYM.TYint, offset)); - } - L1: - if (op == TOK.TOKvar) - { - if (nrvo) - { - e.Ety = TYM.TYnptr; - e = el_una(OPER.OPind, 0, e); - } - if (tb.ty == TY.Tfunction) - { - tym = s.Stype.Tty; - } - else - tym = type.totym(); - e.Ejty = cast(ubyte)tym; - e.Ety = e.Ejty; - if (tybasic(tym) == TYM.TYstruct) - { - e.Enumbytes = cast(uint)type.size(); - } - else if (tybasic(tym) == TYM.TYarray) - { - e.Ejty = TYM.TYstruct; - e.Ety = e.Ejty; - e.Enumbytes = cast(uint)type.size(); - } - } - el_setLoc(e,loc); + Symbol* s; + elem* e; + tym_t tym; + Type tb = (op == TOK.TOKsymoff) ? var.type.toBasetype() : type.toBasetype(); + int offset = (op == TOK.TOKsymoff) ? (cast(SymOffExp)this).offset : 0; + FuncDeclaration fd; + VarDeclaration v = var.isVarDeclaration(); + + //printf("SymbolExp::toElem('%s') %p\n", toChars(), this); + //printf("\tparent = '%s'\n", var.parent ? var.parent.toChars() : "null"); + if (op == TOK.TOKvar && var.needThis()) + { + error("need 'this' to access member %s", toChars()); + return el_long(TYM.TYint, 0); + } + s = var.toSymbol(); + fd = null; + if (var.toParent2()) + fd = var.toParent2().isFuncDeclaration(); + + int nrvo = 0; + if (fd && fd.nrvo_can && fd.nrvo_var == var) + { + s = fd.shidden; + nrvo = 1; + } + + if (s.Sclass == SC.SCauto || s.Sclass == SC.SCparameter) + { + if (fd && fd != irs.getFunc()) + { + // 'var' is a variable in an enclosing function. + elem* ethis; + int soffset; + + ethis = getEthis(loc, irs, fd); + ethis = el_una(OPER.OPaddr, TYM.TYnptr, ethis); + + if (v && v.offset) + soffset = v.offset; + else + { + soffset = s.Soffset; + /* If fd is a non-static member function of a class or struct, + * then ethis isn't the frame pointer. + * ethis is the 'this' pointer to the class/struct instance. + * We must offset it. + */ + if (fd.vthis) + { + soffset -= fd.vthis.toSymbol().Soffset; + } + //printf("\tSoffset = x%x, sthis.Soffset = x%x\n", s.Soffset, irs.sthis.Soffset); + } + + if (!nrvo) + soffset += offset; + + e = el_bin(OPER.OPadd, TYM.TYnptr, ethis, el_long(TYM.TYnptr, soffset)); + + if (op == TOK.TOKvar) + e = el_una(OPER.OPind, TYM.TYnptr, e); + if ((var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef()) + e = el_una(OPER.OPind, s.ty(), e); + else if (op == TOK.TOKsymoff && nrvo) + { + e = el_una(OPER.OPind, TYM.TYnptr, e); + e = el_bin(OPER.OPadd, e.Ety, e, el_long(TYM.TYint, offset)); + } + goto L1; + } + } + + /* If var is a member of a closure + */ + if (v && v.offset) + { + assert(irs.sclosure); + e = el_var(irs.sclosure); + e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, v.offset)); + if (op == TOK.TOKvar) + { + e = el_una(OPER.OPind, type.totym(), e); + if (tybasic(e.Ety) == TYM.TYstruct) + e.Enumbytes = cast(uint)type.size(); + el_setLoc(e, loc); + } + if ((var.isParameter() && tb.ty == TY.Tsarray) || var.isOut() || var.isRef()) + { + e.Ety = TYM.TYnptr; + e = el_una(OPER.OPind, s.ty(), e); + } + else if (op == TOK.TOKsymoff && nrvo) + { e = el_una(OPER.OPind, TYM.TYnptr, e); + e = el_bin(OPER.OPadd, e.Ety, e, el_long(TYM.TYint, offset)); + } + else if (op == TOK.TOKsymoff) + { + e = el_bin(OPER.OPadd, e.Ety, e, el_long(TYM.TYint, offset)); + } + goto L1; + } + + if (s.Sclass == SC.SCauto && s.Ssymnum == -1) + { + //printf("\tadding symbol\n"); + symbol_add(s); + } + + if (var.isImportedSymbol()) + { + assert(op == TOK.TOKvar); + 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()) + { + // Static arrays are really passed as pointers to the array + // Out parameters are really references + e = el_var(s); + e.Ety = TYM.TYnptr; + if (op == TOK.TOKvar) + e = el_una(OPER.OPind, s.ty(), e); + else if (offset) + e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, offset)); + } + else if (op == TOK.TOKvar) + e = el_var(s); + else + { + e = nrvo ? el_var(s) : el_ptr(s); + e = el_bin(OPER.OPadd, e.Ety, e, el_long(TYM.TYint, offset)); + } + L1: + if (op == TOK.TOKvar) + { + if (nrvo) + { + e.Ety = TYM.TYnptr; + e = el_una(OPER.OPind, 0, e); + } + if (tb.ty == TY.Tfunction) + { + tym = s.Stype.Tty; + } + else + tym = type.totym(); + e.Ejty = cast(ubyte)tym; + e.Ety = e.Ejty; + if (tybasic(tym) == TYM.TYstruct) + { + e.Enumbytes = cast(uint)type.size(); + } + else if (tybasic(tym) == TYM.TYarray) + { + e.Ejty = TYM.TYstruct; + e.Ety = e.Ejty; + e.Enumbytes = cast(uint)type.size(); + } + } + el_setLoc(e,loc); return e; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/SynchronizedStatement.d --- a/dmd/SynchronizedStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/SynchronizedStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -50,12 +50,12 @@ this.esync = null; } - Statement syntaxCopy() + override Statement syntaxCopy() { assert(false); } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { if (exp) { @@ -147,32 +147,32 @@ return this; } - bool hasBreak() + override bool hasBreak() { assert(false); } - bool hasContinue() + override bool hasContinue() { assert(false); } - bool usesEH() + override bool usesEH() { assert(false); } - BE blockExit() + override BE blockExit() { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { assert(false); } @@ -186,8 +186,8 @@ super(loc); } - void toIR(IRState* irs) + override void toIR(IRState* irs) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TemplateAliasParameter.d --- a/dmd/TemplateAliasParameter.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TemplateAliasParameter.d Sat Aug 28 16:19:48 2010 +0200 @@ -67,12 +67,12 @@ this.defaultAlias = defaultAlias; } - TemplateAliasParameter isTemplateAliasParameter() + override TemplateAliasParameter isTemplateAliasParameter() { return this; } - TemplateParameter syntaxCopy() + override TemplateParameter syntaxCopy() { TemplateAliasParameter tp = new TemplateAliasParameter(loc, ident, specType, specAlias, defaultAlias); if (tp.specType) @@ -82,7 +82,7 @@ return tp; } - void declareParameter(Scope sc) + override void declareParameter(Scope sc) { TypeIdentifier ti = new TypeIdentifier(loc, ident); sparam = new AliasDeclaration(loc, ident, ti); @@ -90,7 +90,7 @@ error(loc, "parameter '%s' multiply defined", ident.toChars()); } - void semantic(Scope sc) + override void semantic(Scope sc) { if (specType) { @@ -103,7 +103,7 @@ } } - void print(Object oarg, Object oded) + override void print(Object oarg, Object oded) { printf(" %s\n", ident.toChars()); @@ -113,7 +113,7 @@ printf("\tArgument alias: %s\n", sa.toChars()); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("alias "); if (specType) @@ -134,18 +134,18 @@ } } - Object specialization() + override Object specialization() { return specAlias; } - Object defaultArg(Loc loc, Scope sc) + override Object defaultArg(Loc loc, Scope sc) { Object o = aliasParameterSemantic(loc, sc, defaultAlias); return o; } - bool overloadMatch(TemplateParameter tp) + override bool overloadMatch(TemplateParameter tp) { TemplateAliasParameter tap = tp.isTemplateAliasParameter(); @@ -161,7 +161,7 @@ return false; } - MATCH matchArg(Scope sc, Objects tiargs, int i, TemplateParameters parameters, Objects dedtypes, Declaration* psparam, int flags) + override MATCH matchArg(Scope sc, Objects tiargs, int i, TemplateParameters parameters, Objects dedtypes, Declaration* psparam, int flags) { Object sa; Object oarg; @@ -250,7 +250,7 @@ return MATCHnomatch; } - void* dummyArg() + override void* dummyArg() { Object s; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TemplateDeclaration.d --- a/dmd/TemplateDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TemplateDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -149,7 +149,7 @@ instances = new Array(); } - Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol) { //printf("TemplateDeclaration.syntaxCopy()\n"); TemplateDeclaration td; @@ -176,7 +176,7 @@ return td; } - void semantic(Scope sc) + override void semantic(Scope sc) { version (LOG) { printf("TemplateDeclaration.semantic(this = %p, id = '%s')\n", this, ident.toChars()); @@ -272,7 +272,7 @@ * Overload existing TemplateDeclaration 'this' with the new one 's'. * Return !=0 if successful; i.e. no conflict. */ - bool overloadInsert(Dsymbol s) + override bool overloadInsert(Dsymbol s) { TemplateDeclaration *pf; TemplateDeclaration f; @@ -322,19 +322,19 @@ return true; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - string kind() + override string kind() { return (onemember && onemember.isAggregateDeclaration()) ? onemember.kind() : "template"; } - string toChars() + override string toChars() { OutBuffer buf = new OutBuffer(); HdrGenState hgs; @@ -362,7 +362,7 @@ return buf.extractString(); } - void emitComment(Scope sc) + override void emitComment(Scope sc) { assert(false); } @@ -1283,7 +1283,7 @@ s.semantic(sc); } - TemplateDeclaration isTemplateDeclaration() { return this; } + override TemplateDeclaration isTemplateDeclaration() { return this; } TemplateTupleParameter isVariadic() { @@ -1293,8 +1293,8 @@ /*********************************** * We can overload templates. */ - bool isOverloadable() + override bool isOverloadable() { return 1; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TemplateExp.d --- a/dmd/TemplateExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TemplateExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,29 +1,29 @@ -module dmd.TemplateExp; - -import dmd.Expression; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.HdrGenState; -import dmd.TemplateDeclaration; -import dmd.TOK; - +module dmd.TemplateExp; + +import dmd.Expression; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.HdrGenState; +import dmd.TemplateDeclaration; +import dmd.TOK; + class TemplateExp : Expression { TemplateDeclaration td; this(Loc loc, TemplateDeclaration td) - { + { super(loc, TOK.TOKtemplate, TemplateExp.sizeof); //printf("TemplateExp(): %s\n", td.toChars()); this.td = td; } - void rvalue() + override void rvalue() { error("template %s has no value", toChars()); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring(td.toChars()); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TemplateInstance.d --- a/dmd/TemplateInstance.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TemplateInstance.d Sat Aug 28 16:19:48 2010 +0200 @@ -242,7 +242,7 @@ return a; } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { TemplateInstance ti; @@ -257,7 +257,7 @@ return ti; } - void semantic(Scope sc) + override void semantic(Scope sc) { if (global.errors) { @@ -607,7 +607,7 @@ } } - void semantic2(Scope sc) + override void semantic2(Scope sc) { int i; @@ -645,7 +645,7 @@ } } - void semantic3(Scope sc) + override void semantic3(Scope sc) { version (LOG) { printf("TemplateInstance.semantic3('%s'), semanticRun = %d\n", toChars(), semanticRun); @@ -670,7 +670,7 @@ } } - void inlineScan() + override void inlineScan() { version (LOG) { printf("TemplateInstance.inlineScan('%s')\n", toChars()); @@ -685,7 +685,7 @@ } } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { int i; @@ -710,7 +710,7 @@ buf.writeByte(')'); } - Dsymbol toAlias() // resolve real symbol + override Dsymbol toAlias() // resolve real symbol { version (LOG) { printf("TemplateInstance.toAlias()\n"); @@ -732,18 +732,18 @@ return inst; } - string kind() + override string kind() { return "template instance"; } - bool oneMember(Dsymbol* ps) + override bool oneMember(Dsymbol* ps) { *ps = null; return true; } - string toChars() + override string toChars() { scope OutBuffer buf = new OutBuffer(); HdrGenState hgs; @@ -752,7 +752,7 @@ return buf.extractString(); } - string mangle() + override string mangle() { OutBuffer buf = new OutBuffer(); string id; @@ -786,7 +786,7 @@ return; } - void toObjFile(int multiobj) // compile to .obj file + override void toObjFile(int multiobj) // compile to .obj file { version (LOG) { printf("TemplateInstance.toObjFile('%s', this = %p)\n", toChars(), this); @@ -1423,9 +1423,9 @@ return new Identifier(id, TOKidentifier); } - TemplateInstance isTemplateInstance() { return this; } + override TemplateInstance isTemplateInstance() { return this; } - AliasDeclaration isAliasDeclaration() + override AliasDeclaration isAliasDeclaration() { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TemplateMixin.d --- a/dmd/TemplateMixin.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TemplateMixin.d Sat Aug 28 16:19:48 2010 +0200 @@ -37,7 +37,7 @@ this.tiargs = tiargs ? tiargs : new Objects(); } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { TemplateMixin tm; @@ -63,7 +63,7 @@ return tm; } - void semantic(Scope sc) + override void semantic(Scope sc) { version (LOG) { printf("+TemplateMixin.semantic('%s', this=%p)\n", toChars(), this); @@ -344,7 +344,7 @@ } } - void semantic2(Scope sc) + override void semantic2(Scope sc) { int i; @@ -375,7 +375,7 @@ } } - void semantic3(Scope sc) + override void semantic3(Scope sc) { int i; @@ -399,22 +399,22 @@ } } - void inlineScan() + override void inlineScan() { TemplateInstance.inlineScan(); } - string kind() + override string kind() { return "mixin"; } - bool oneMember(Dsymbol* ps) + override bool oneMember(Dsymbol* ps) { return Dsymbol.oneMember(ps); } - bool hasPointers() + override bool hasPointers() { //printf("TemplateMixin.hasPointers() %s\n", toChars()); for (size_t i = 0; i < members.dim; i++) @@ -429,7 +429,7 @@ return 0; } - string toChars() + override string toChars() { OutBuffer buf = new OutBuffer(); HdrGenState hgs; @@ -441,7 +441,7 @@ return s; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("mixin "); @@ -491,11 +491,11 @@ buf.writenl(); } - void toObjFile(int multiobj) // compile to .obj file + override void toObjFile(int multiobj) // compile to .obj file { //printf("TemplateMixin.toObjFile('%s')\n", toChars()); TemplateInstance.toObjFile(multiobj); } - TemplateMixin isTemplateMixin() { return this; } + override TemplateMixin isTemplateMixin() { return this; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TemplateThisParameter.d --- a/dmd/TemplateThisParameter.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TemplateThisParameter.d Sat Aug 28 16:19:48 2010 +0200 @@ -22,18 +22,18 @@ super(loc, ident, specType, defaultType); } - TemplateThisParameter isTemplateThisParameter() + override TemplateThisParameter isTemplateThisParameter() { assert(false); } - TemplateParameter syntaxCopy() + override TemplateParameter syntaxCopy() { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TemplateTupleParameter.d --- a/dmd/TemplateTupleParameter.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TemplateTupleParameter.d Sat Aug 28 16:19:48 2010 +0200 @@ -31,18 +31,18 @@ this.ident = ident; } - TemplateTupleParameter isTemplateTupleParameter() + override TemplateTupleParameter isTemplateTupleParameter() { return this; } - TemplateParameter syntaxCopy() + override TemplateParameter syntaxCopy() { TemplateTupleParameter tp = new TemplateTupleParameter(loc, ident); return tp; } - void declareParameter(Scope sc) + override void declareParameter(Scope sc) { TypeIdentifier ti = new TypeIdentifier(loc, ident); sparam = new AliasDeclaration(loc, ident, ti); @@ -50,11 +50,11 @@ error(loc, "parameter '%s' multiply defined", ident.toChars()); } - void semantic(Scope) + override void semantic(Scope) { } - void print(Object oarg, Object oded) + override void print(Object oarg, Object oded) { writef(" %s... [", ident.toChars()); Tuple v = isTuple(oded); @@ -86,23 +86,23 @@ writef("]\n"); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring(ident.toChars()); buf.writestring("..."); } - Object specialization() + override Object specialization() { return null; } - Object defaultArg(Loc loc, Scope sc) + override Object defaultArg(Loc loc, Scope sc) { return null; } - bool overloadMatch(TemplateParameter tp) + override bool overloadMatch(TemplateParameter tp) { TemplateTupleParameter tvp = tp.isTemplateTupleParameter(); if (tvp) { @@ -113,7 +113,7 @@ return false; } - MATCH matchArg(Scope sc, Objects tiargs, int i, TemplateParameters parameters, Objects dedtypes, Declaration* psparam, int flags) + override MATCH matchArg(Scope sc, Objects tiargs, int i, TemplateParameters parameters, Objects dedtypes, Declaration* psparam, int flags) { //printf("TemplateTupleParameter.matchArg()\n"); @@ -142,8 +142,8 @@ return MATCH.MATCHexact; } - void* dummyArg() + override void* dummyArg() { return null; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TemplateTypeParameter.d --- a/dmd/TemplateTypeParameter.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TemplateTypeParameter.d Sat Aug 28 16:19:48 2010 +0200 @@ -31,12 +31,12 @@ this.defaultType = defaultType; } - TemplateTypeParameter isTemplateTypeParameter() + override TemplateTypeParameter isTemplateTypeParameter() { return this; } - TemplateParameter syntaxCopy() + override TemplateParameter syntaxCopy() { TemplateTypeParameter tp = new TemplateTypeParameter(loc, ident, specType, defaultType); if (tp.specType) @@ -46,7 +46,7 @@ return tp; } - void declareParameter(Scope sc) + override void declareParameter(Scope sc) { //printf("TemplateTypeParameter.declareParameter('%s')\n", ident.toChars()); TypeIdentifier ti = new TypeIdentifier(loc, ident); @@ -55,7 +55,7 @@ error(loc, "parameter '%s' multiply defined", ident.toChars()); } - void semantic(Scope sc) + override void semantic(Scope sc) { //printf("TemplateTypeParameter.semantic('%s')\n", ident.toChars()); if (specType) @@ -70,12 +70,12 @@ } } - void print(Object oarg, Object oded) + override void print(Object oarg, Object oded) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring(ident.toChars()); if (specType) @@ -90,12 +90,12 @@ } } - Object specialization() + override Object specialization() { return specType; } - Object defaultArg(Loc loc, Scope sc) + override Object defaultArg(Loc loc, Scope sc) { Type t; @@ -108,7 +108,7 @@ return t; } - bool overloadMatch(TemplateParameter) + override bool overloadMatch(TemplateParameter) { assert(false); } @@ -123,7 +123,7 @@ * *psparam set to symbol declared and initialized to dedtypes[i] * flags 1: don't do 'toHeadMutable()' */ - MATCH matchArg(Scope sc, Objects tiargs, int i, TemplateParameters parameters, Objects dedtypes, Declaration* psparam, int flags) + override MATCH matchArg(Scope sc, Objects tiargs, int i, TemplateParameters parameters, Objects dedtypes, Declaration* psparam, int flags) { //printf("TemplateTypeParameter.matchArg()\n"); Type t; @@ -213,7 +213,7 @@ return MATCHnomatch; } - void* dummyArg() + override void* dummyArg() { Type t; @@ -226,4 +226,4 @@ } return cast(void *)t; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TemplateValueParameter.d --- a/dmd/TemplateValueParameter.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TemplateValueParameter.d Sat Aug 28 16:19:48 2010 +0200 @@ -44,12 +44,12 @@ this.defaultValue = defaultValue; } - TemplateValueParameter isTemplateValueParameter() + override TemplateValueParameter isTemplateValueParameter() { return this; } - TemplateParameter syntaxCopy() + override TemplateParameter syntaxCopy() { TemplateValueParameter tp = new TemplateValueParameter(loc, ident, valType, specValue, defaultValue); tp.valType = valType.syntaxCopy(); @@ -60,7 +60,7 @@ return tp; } - void declareParameter(Scope sc) + override void declareParameter(Scope sc) { VarDeclaration v = new VarDeclaration(loc, valType, ident, null); v.storage_class = STC.STCtemplateparameter; @@ -69,7 +69,7 @@ sparam = v; } - void semantic(Scope sc) + override void semantic(Scope sc) { sparam.semantic(sc); valType = valType.semantic(loc, sc); @@ -104,12 +104,12 @@ } } - void print(Object oarg, Object oded) + override void print(Object oarg, Object oded) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { valType.toCBuffer(buf, ident, hgs); if (specValue) @@ -124,12 +124,12 @@ } } - Object specialization() + override Object specialization() { return specValue; } - Object defaultArg(Loc loc, Scope sc) + override Object defaultArg(Loc loc, Scope sc) { Expression e = defaultValue; if (e) @@ -147,7 +147,7 @@ return e; } - bool overloadMatch(TemplateParameter tp) + override bool overloadMatch(TemplateParameter tp) { TemplateValueParameter tvp = tp.isTemplateValueParameter(); @@ -168,7 +168,7 @@ return false; } - MATCH matchArg(Scope sc, Objects tiargs, int i, TemplateParameters parameters, Objects dedtypes, Declaration* psparam, int flags) + override MATCH matchArg(Scope sc, Objects tiargs, int i, TemplateParameters parameters, Objects dedtypes, Declaration* psparam, int flags) { //printf("TemplateValueParameter.matchArg()\n"); @@ -260,7 +260,7 @@ return MATCHnomatch; } - void* dummyArg() + override void* dummyArg() { Expression e; @@ -274,4 +274,4 @@ } return cast(void*)e; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ThisDeclaration.d --- a/dmd/ThisDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ThisDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -16,10 +16,10 @@ noauto = true; } - Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol) { assert(false); } - ThisDeclaration isThisDeclaration() { return this; } -} \ No newline at end of file + override ThisDeclaration isThisDeclaration() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ThisExp.d --- a/dmd/ThisExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ThisExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,22 +1,22 @@ -module dmd.ThisExp; - -import dmd.Expression; +module dmd.ThisExp; + +import dmd.Expression; import dmd.Declaration; import dmd.StructDeclaration; import dmd.ClassDeclaration; import dmd.Dsymbol; -import dmd.FuncDeclaration; +import dmd.FuncDeclaration; import dmd.backend.elem; -import dmd.CSX; -import dmd.InterState; -import dmd.OutBuffer; -import dmd.Loc; +import dmd.CSX; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; import dmd.Scope; -import dmd.Type; -import dmd.TOK; -import dmd.InlineCostState; -import dmd.InlineDoState; -import dmd.IRState; +import dmd.Type; +import dmd.TOK; +import dmd.InlineCostState; +import dmd.InlineDoState; +import dmd.IRState; import dmd.HdrGenState; import dmd.VarExp; import dmd.TY; @@ -25,7 +25,7 @@ import dmd.backend.TYM; import dmd.backend.Util; import dmd.backend.OPER; - + class ThisExp : Expression { Declaration var; @@ -36,7 +36,7 @@ //printf("ThisExp::ThisExp() loc = %d\n", loc.linnum); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { FuncDeclaration fd; FuncDeclaration fdthis; @@ -102,38 +102,38 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - bool isBool(bool result) + override bool isBool(bool result) { return result ? true : false; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring("this"); } version (DMDV2) { - int isLvalue() + override int isLvalue() { return 1; } } - Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression e) { return this; } - void scanForNestedRef(Scope sc) + override void scanForNestedRef(Scope sc) { assert(false); } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { FuncDeclaration fd = ics.fd; if (!ics.hdrscan) @@ -143,7 +143,7 @@ return 1; } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { //if (!ids.vthis) //error("no 'this' when inlining %s", ids.parent.toChars()); @@ -157,7 +157,7 @@ return ve; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem* ethis; FuncDeclaration fd; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/ThrowStatement.d --- a/dmd/ThrowStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/ThrowStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -29,13 +29,13 @@ this.exp = exp; } - Statement syntaxCopy() + override Statement syntaxCopy() { ThrowStatement s = new ThrowStatement(loc, exp.syntaxCopy()); return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { //printf("ThrowStatement::semantic()\n"); @@ -51,24 +51,24 @@ return this; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - BE blockExit() + override BE blockExit() { return BE.BEthrow; // obviously } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { if (exp) exp = exp.inlineScan(iss); return this; } - void toIR(IRState* irs) + override void toIR(IRState* irs) { // throw(exp) @@ -83,4 +83,4 @@ } block_appendexp(blx.curblock, e); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TraitsExp.d --- a/dmd/TraitsExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TraitsExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,454 +1,454 @@ -module dmd.TraitsExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.ArrayTypes; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.HdrGenState; -import dmd.TOK; -import dmd.TY; -import dmd.STC; -import dmd.WANT; -import dmd.Id; -import dmd.Global; -import dmd.Lexer; -import dmd.ArrayLiteralExp; -import dmd.VarExp; -import dmd.StringExp; -import dmd.DotIdExp; -import dmd.DotVarExp; -import dmd.IntegerExp; -import dmd.TupleExp; -import dmd.Type; -import dmd.Dsymbol; -import dmd.DsymbolExp; -import dmd.ScopeDsymbol; -import dmd.FuncDeclaration; -import dmd.ClassDeclaration; -import dmd.TemplateDeclaration; -import dmd.TemplateInstance; -import dmd.TypeClass; -import dmd.Util; -import dmd.expression.Util; - -import core.stdc.string : strcmp; - -/************************************************ - * Delegate to be passed to overloadApply() that looks - * for virtual functions. - */ - -struct Pvirtuals -{ - Expression e1; - Expressions exps; - int fpvirtuals(void* param, FuncDeclaration f) - { Pvirtuals p = *cast(Pvirtuals*)param; - - if (f.isVirtual()) - { Expression e; - - if (p.e1.op == TOK.TOKdotvar) - { DotVarExp dve = cast(DotVarExp)p.e1; - e = new DotVarExp(Loc(0), dve.e1, f); - } - else - e = new DsymbolExp(Loc(0), f); - p.exps.push(cast(void*)e); - } - return 0; - } -} - - - -class TraitsExp : Expression -{ - Identifier ident; - - Objects args; - - this(Loc loc, Identifier ident, Objects args) - { - super(loc, TOK.TOKtraits, this.sizeof); - this.ident = ident; - this.args = args; - } - - Expression syntaxCopy() - { - return new TraitsExp(loc, ident, TemplateInstance.arraySyntaxCopy(args)); - } - - Expression semantic(Scope sc) - { - version (LOGSEMANTIC) { - printf("TraitsExp.semantic() %s\n", toChars()); - } - if (ident != Id.compiles && ident != Id.isSame) - TemplateInstance.semanticTiargs(loc, sc, args, 1); - size_t dim = args ? args.dim : 0; - Object o; - FuncDeclaration f; - - string ISTYPE(string cond) - { - return ` - for (size_t i = 0; i < dim; i++) - { Type t = getType(cast(Object)args.data[i]); - if (!t) - goto Lfalse; - if (!(`~cond~`)) - goto Lfalse; - } - if (!dim) - goto Lfalse; - goto Ltrue; - `; - } - - string ISDSYMBOL(string cond) - { - return `for (size_t i = 0; i < dim; i++) - { Dsymbol s = getDsymbol(cast(Object)args.data[i]); - if (!s) - goto Lfalse; - if (!(`~cond~`)) - goto Lfalse; - } - if (!dim) - goto Lfalse; - goto Ltrue;`; - } - - if (ident == Id.isArithmetic) - { - mixin(ISTYPE(`t.isintegral() || t.isfloating()`)); - } - else if (ident == Id.isFloating) - { - mixin(ISTYPE(q{t.isfloating()})); - } - else if (ident == Id.isIntegral) - { - mixin(ISTYPE(q{t.isintegral()})); - } - else if (ident == Id.isScalar) - { - mixin(ISTYPE(q{t.isscalar()})); - } - else if (ident == Id.isUnsigned) - { - mixin(ISTYPE(q{t.isunsigned()})); - } - else if (ident == Id.isAssociativeArray) - { - mixin(ISTYPE(q{t.toBasetype().ty == TY.Taarray})); - } - else if (ident == Id.isStaticArray) - { - mixin(ISTYPE(q{t.toBasetype().ty == TY.Tsarray})); - } - else if (ident == Id.isAbstractClass) - { - mixin(ISTYPE(q{t.toBasetype().ty == TY.Tclass && (cast(TypeClass)t.toBasetype()).sym.isAbstract()})); - } - else if (ident == Id.isFinalClass) - { - mixin(ISTYPE(q{t.toBasetype().ty == TY.Tclass && (cast(TypeClass)t.toBasetype()).sym.storage_class & STC.STCfinal})); - } - else if (ident == Id.isAbstractFunction) - { - mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && f.isAbstract()})); - } - else if (ident == Id.isVirtualFunction) - { - mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && f.isVirtual()})); - } - else if (ident == Id.isFinalFunction) - { - mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && f.isFinal()})); - } - else if (ident == Id.hasMember || - ident == Id.getMember || - ident == Id.getVirtualFunctions) - { - if (dim != 2) - goto Ldimerror; - Object o_ = cast(Object)args.data[0]; - Expression e = isExpression(cast(Object)args.data[1]); - if (!e) - { error("expression expected as second argument of __traits %s", ident.toChars()); - goto Lfalse; - } - e = e.optimize(WANT.WANTvalue | WANT.WANTinterpret); - if (e.op != TOKstring) - { error("string expected as second argument of __traits %s instead of %s", ident.toChars(), e.toChars()); - goto Lfalse; - } - StringExp se = cast(StringExp)e; - se = se.toUTF8(sc); - if (se.sz != 1) - { error("string must be chars"); - goto Lfalse; - } - Identifier id = Lexer.idPool(fromStringz(cast(char*)se.string_)); - - Type t = isType(o_); - e = isExpression(o_); - Dsymbol s = isDsymbol(o_); - if (t) - e = typeDotIdExp(loc, t, id); - else if (e) - e = new DotIdExp(loc, e, id); - else if (s) - { e = new DsymbolExp(loc, s); - e = new DotIdExp(loc, e, id); - } - else - { error("invalid first argument"); - goto Lfalse; - } - - if (ident == Id.hasMember) - { /* Take any errors as meaning it wasn't found - */ - e = e.trySemantic(sc); - if (!e) - { if (global.gag) - global.errors++; - goto Lfalse; - } - else - goto Ltrue; - } - else if (ident == Id.getMember) - { - e = e.semantic(sc); - return e; - } - else if (ident == Id.getVirtualFunctions) - { - uint errors = global.errors; - Expression ex = e; - e = e.semantic(sc); - if (errors < global.errors) - error("%s cannot be resolved", ex.toChars()); - - /* Create tuple of virtual function overloads of e - */ - //e.dump(0); - Expressions exps = new Expressions(); - FuncDeclaration f_; - if (e.op == TOKvar) - { VarExp ve = cast(VarExp)e; - f_ = ve.var.isFuncDeclaration(); - } - else if (e.op == TOKdotvar) - { DotVarExp dve = cast(DotVarExp)e; - f_ = dve.var.isFuncDeclaration(); - } - else - f_ = null; - Pvirtuals p; - p.exps = exps; - p.e1 = e; - overloadApply(f_, &p.fpvirtuals, &p); - - TupleExp tup = new TupleExp(loc, exps); - return tup.semantic(sc); - } - else - assert(0); - } - else if (ident == Id.classInstanceSize) - { - if (dim != 1) - goto Ldimerror; - Object o_ = cast(Object)args.data[0]; - Dsymbol s = getDsymbol(o_); - ClassDeclaration cd; - if (!s || (cd = s.isClassDeclaration()) is null) - { - error("first argument is not a class"); - goto Lfalse; - } - return new IntegerExp(loc, cd.structsize, Type.tsize_t); - } - else if (ident == Id.allMembers || ident == Id.derivedMembers) - { - if (dim != 1) - goto Ldimerror; - Object o_ = cast(Object)args.data[0]; - Dsymbol s = getDsymbol(o_); - ScopeDsymbol sd; - if (!s) - { - error("argument has no members"); - goto Lfalse; - } - if ((sd = s.isScopeDsymbol()) is null) - { - error("%s %s has no members", s.kind(), s.toChars()); - goto Lfalse; - } - Expressions exps = new Expressions; - while (1) - { size_t dim_ = ScopeDsymbol.dim(sd.members); - for (size_t i = 0; i < dim_; i++) - { - Dsymbol sm = ScopeDsymbol.getNth(sd.members, i); - //printf("\t[%i] %s %s\n", i, sm.kind(), sm.toChars()); - if (sm.ident) - { - //printf("\t%s\n", sm.ident.toChars()); - auto str = sm.ident.toChars(); - - /* Skip if already present in exps[] - */ - for (size_t j = 0; j < exps.dim; j++) - { StringExp se2 = cast(StringExp)exps.data[j]; - if (strcmp(toStringz(str), cast(char*)se2.string_) == 0) - goto Lnext; - } - - StringExp se = new StringExp(loc, str); - exps.push(cast(void*)se); - } -Lnext: - ; - } - ClassDeclaration cd = sd.isClassDeclaration(); - if (cd && cd.baseClass && ident == Id.allMembers) - sd = cd.baseClass; // do again with base class - else - break; - } - Expression e = new ArrayLiteralExp(loc, exps); - e = e.semantic(sc); - return e; - } - else if (ident == Id.compiles) - { - /* Determine if all the objects - types, expressions, or symbols - - * compile without error - */ - if (!dim) - goto Lfalse; - - for (size_t i = 0; i < dim; i++) - { Object o_ = cast(Object)args.data[i]; - Expression e; - - uint errors = global.errors; - global.gag++; - - Type t = isType(o_); - if (t) - { Dsymbol s; - t.resolve(loc, sc, &e, &t, &s); - if (t) - t.semantic(loc, sc); - else if (e) - e.semantic(sc); - } - else - { e = isExpression(o); - if (e) - e.semantic(sc); - } - - global.gag--; - if (errors != global.errors) - { if (global.gag == 0) - global.errors = errors; - goto Lfalse; - } - } - goto Ltrue; - } - else if (ident == Id.isSame) - { /* Determine if two symbols are the same - */ - if (dim != 2) - goto Ldimerror; - TemplateInstance.semanticTiargs(loc, sc, args, 0); - Object o1 = cast(Object)args.data[0]; - Object o2 = cast(Object)args.data[1]; - Dsymbol s1 = getDsymbol(o1); - Dsymbol s2 = getDsymbol(o2); - - static if (0) { - printf("o1: %p\n", o1); - printf("o2: %p\n", o2); - if (!s1) - { Expression ea = isExpression(o1); - if (ea) - printf("%s\n", ea.toChars()); - Type ta = isType(o1); - if (ta) - printf("%s\n", ta.toChars()); - goto Lfalse; - } - else - printf("%s %s\n", s1.kind(), s1.toChars()); - } - if (!s1 && !s2) - { Expression ea1 = isExpression(o1); - Expression ea2 = isExpression(o2); - if (ea1 && ea2 && ea1.equals(ea2)) - goto Ltrue; - } - - if (!s1 || !s2) - goto Lfalse; - - s1 = s1.toAlias(); - s2 = s2.toAlias(); - - if (s1 == s2) - goto Ltrue; - else - goto Lfalse; - } - else - { error("unrecognized trait %s", ident.toChars()); - goto Lfalse; - } - - return null; - -Lnottype: - error("%s is not a type", o/*.toChars()*/); // BUG: o is Object, no member toChars() - goto Lfalse; - -Ldimerror: - error("wrong number of arguments %d", dim); - goto Lfalse; - - -Lfalse: - return new IntegerExp(loc, 0, Type.tbool); - -Ltrue: - return new IntegerExp(loc, 1, Type.tbool); - } - - void toCBuffer(OutBuffer buf, HdrGenState* hgs) - { - buf.writestring("__traits("); - buf.writestring(ident.toChars()); - if (args) - { - for (int i = 0; i < args.dim; i++) - { - buf.writeByte(','); - Object oarg = cast(Object)args.data[i]; - ObjectToCBuffer(buf, hgs, oarg); - } - } - buf.writeByte(')'); - } -} +module dmd.TraitsExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.ArrayTypes; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.HdrGenState; +import dmd.TOK; +import dmd.TY; +import dmd.STC; +import dmd.WANT; +import dmd.Id; +import dmd.Global; +import dmd.Lexer; +import dmd.ArrayLiteralExp; +import dmd.VarExp; +import dmd.StringExp; +import dmd.DotIdExp; +import dmd.DotVarExp; +import dmd.IntegerExp; +import dmd.TupleExp; +import dmd.Type; +import dmd.Dsymbol; +import dmd.DsymbolExp; +import dmd.ScopeDsymbol; +import dmd.FuncDeclaration; +import dmd.ClassDeclaration; +import dmd.TemplateDeclaration; +import dmd.TemplateInstance; +import dmd.TypeClass; +import dmd.Util; +import dmd.expression.Util; + +import core.stdc.string : strcmp; + +/************************************************ + * Delegate to be passed to overloadApply() that looks + * for virtual functions. + */ + +struct Pvirtuals +{ + Expression e1; + Expressions exps; + int fpvirtuals(void* param, FuncDeclaration f) + { Pvirtuals p = *cast(Pvirtuals*)param; + + if (f.isVirtual()) + { Expression e; + + if (p.e1.op == TOK.TOKdotvar) + { DotVarExp dve = cast(DotVarExp)p.e1; + e = new DotVarExp(Loc(0), dve.e1, f); + } + else + e = new DsymbolExp(Loc(0), f); + p.exps.push(cast(void*)e); + } + return 0; + } +} + + + +class TraitsExp : Expression +{ + Identifier ident; + + Objects args; + + this(Loc loc, Identifier ident, Objects args) + { + super(loc, TOK.TOKtraits, this.sizeof); + this.ident = ident; + this.args = args; + } + + override Expression syntaxCopy() + { + return new TraitsExp(loc, ident, TemplateInstance.arraySyntaxCopy(args)); + } + + override Expression semantic(Scope sc) + { + version (LOGSEMANTIC) { + printf("TraitsExp.semantic() %s\n", toChars()); + } + if (ident != Id.compiles && ident != Id.isSame) + TemplateInstance.semanticTiargs(loc, sc, args, 1); + size_t dim = args ? args.dim : 0; + Object o; + FuncDeclaration f; + + string ISTYPE(string cond) + { + return ` + for (size_t i = 0; i < dim; i++) + { Type t = getType(cast(Object)args.data[i]); + if (!t) + goto Lfalse; + if (!(`~cond~`)) + goto Lfalse; + } + if (!dim) + goto Lfalse; + goto Ltrue; + `; + } + + string ISDSYMBOL(string cond) + { + return `for (size_t i = 0; i < dim; i++) + { Dsymbol s = getDsymbol(cast(Object)args.data[i]); + if (!s) + goto Lfalse; + if (!(`~cond~`)) + goto Lfalse; + } + if (!dim) + goto Lfalse; + goto Ltrue;`; + } + + if (ident == Id.isArithmetic) + { + mixin(ISTYPE(`t.isintegral() || t.isfloating()`)); + } + else if (ident == Id.isFloating) + { + mixin(ISTYPE(q{t.isfloating()})); + } + else if (ident == Id.isIntegral) + { + mixin(ISTYPE(q{t.isintegral()})); + } + else if (ident == Id.isScalar) + { + mixin(ISTYPE(q{t.isscalar()})); + } + else if (ident == Id.isUnsigned) + { + mixin(ISTYPE(q{t.isunsigned()})); + } + else if (ident == Id.isAssociativeArray) + { + mixin(ISTYPE(q{t.toBasetype().ty == TY.Taarray})); + } + else if (ident == Id.isStaticArray) + { + mixin(ISTYPE(q{t.toBasetype().ty == TY.Tsarray})); + } + else if (ident == Id.isAbstractClass) + { + mixin(ISTYPE(q{t.toBasetype().ty == TY.Tclass && (cast(TypeClass)t.toBasetype()).sym.isAbstract()})); + } + else if (ident == Id.isFinalClass) + { + mixin(ISTYPE(q{t.toBasetype().ty == TY.Tclass && (cast(TypeClass)t.toBasetype()).sym.storage_class & STC.STCfinal})); + } + else if (ident == Id.isAbstractFunction) + { + mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && f.isAbstract()})); + } + else if (ident == Id.isVirtualFunction) + { + mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && f.isVirtual()})); + } + else if (ident == Id.isFinalFunction) + { + mixin(ISDSYMBOL(q{(f = s.isFuncDeclaration()) !is null && f.isFinal()})); + } + else if (ident == Id.hasMember || + ident == Id.getMember || + ident == Id.getVirtualFunctions) + { + if (dim != 2) + goto Ldimerror; + Object o_ = cast(Object)args.data[0]; + Expression e = isExpression(cast(Object)args.data[1]); + if (!e) + { error("expression expected as second argument of __traits %s", ident.toChars()); + goto Lfalse; + } + e = e.optimize(WANT.WANTvalue | WANT.WANTinterpret); + if (e.op != TOKstring) + { error("string expected as second argument of __traits %s instead of %s", ident.toChars(), e.toChars()); + goto Lfalse; + } + StringExp se = cast(StringExp)e; + se = se.toUTF8(sc); + if (se.sz != 1) + { error("string must be chars"); + goto Lfalse; + } + Identifier id = Lexer.idPool(fromStringz(cast(char*)se.string_)); + + Type t = isType(o_); + e = isExpression(o_); + Dsymbol s = isDsymbol(o_); + if (t) + e = typeDotIdExp(loc, t, id); + else if (e) + e = new DotIdExp(loc, e, id); + else if (s) + { e = new DsymbolExp(loc, s); + e = new DotIdExp(loc, e, id); + } + else + { error("invalid first argument"); + goto Lfalse; + } + + if (ident == Id.hasMember) + { /* Take any errors as meaning it wasn't found + */ + e = e.trySemantic(sc); + if (!e) + { if (global.gag) + global.errors++; + goto Lfalse; + } + else + goto Ltrue; + } + else if (ident == Id.getMember) + { + e = e.semantic(sc); + return e; + } + else if (ident == Id.getVirtualFunctions) + { + uint errors = global.errors; + Expression ex = e; + e = e.semantic(sc); + if (errors < global.errors) + error("%s cannot be resolved", ex.toChars()); + + /* Create tuple of virtual function overloads of e + */ + //e.dump(0); + Expressions exps = new Expressions(); + FuncDeclaration f_; + if (e.op == TOKvar) + { VarExp ve = cast(VarExp)e; + f_ = ve.var.isFuncDeclaration(); + } + else if (e.op == TOKdotvar) + { DotVarExp dve = cast(DotVarExp)e; + f_ = dve.var.isFuncDeclaration(); + } + else + f_ = null; + Pvirtuals p; + p.exps = exps; + p.e1 = e; + overloadApply(f_, &p.fpvirtuals, &p); + + TupleExp tup = new TupleExp(loc, exps); + return tup.semantic(sc); + } + else + assert(0); + } + else if (ident == Id.classInstanceSize) + { + if (dim != 1) + goto Ldimerror; + Object o_ = cast(Object)args.data[0]; + Dsymbol s = getDsymbol(o_); + ClassDeclaration cd; + if (!s || (cd = s.isClassDeclaration()) is null) + { + error("first argument is not a class"); + goto Lfalse; + } + return new IntegerExp(loc, cd.structsize, Type.tsize_t); + } + else if (ident == Id.allMembers || ident == Id.derivedMembers) + { + if (dim != 1) + goto Ldimerror; + Object o_ = cast(Object)args.data[0]; + Dsymbol s = getDsymbol(o_); + ScopeDsymbol sd; + if (!s) + { + error("argument has no members"); + goto Lfalse; + } + if ((sd = s.isScopeDsymbol()) is null) + { + error("%s %s has no members", s.kind(), s.toChars()); + goto Lfalse; + } + Expressions exps = new Expressions; + while (1) + { size_t dim_ = ScopeDsymbol.dim(sd.members); + for (size_t i = 0; i < dim_; i++) + { + Dsymbol sm = ScopeDsymbol.getNth(sd.members, i); + //printf("\t[%i] %s %s\n", i, sm.kind(), sm.toChars()); + if (sm.ident) + { + //printf("\t%s\n", sm.ident.toChars()); + auto str = sm.ident.toChars(); + + /* Skip if already present in exps[] + */ + for (size_t j = 0; j < exps.dim; j++) + { StringExp se2 = cast(StringExp)exps.data[j]; + if (strcmp(toStringz(str), cast(char*)se2.string_) == 0) + goto Lnext; + } + + StringExp se = new StringExp(loc, str); + exps.push(cast(void*)se); + } +Lnext: + ; + } + ClassDeclaration cd = sd.isClassDeclaration(); + if (cd && cd.baseClass && ident == Id.allMembers) + sd = cd.baseClass; // do again with base class + else + break; + } + Expression e = new ArrayLiteralExp(loc, exps); + e = e.semantic(sc); + return e; + } + else if (ident == Id.compiles) + { + /* Determine if all the objects - types, expressions, or symbols - + * compile without error + */ + if (!dim) + goto Lfalse; + + for (size_t i = 0; i < dim; i++) + { Object o_ = cast(Object)args.data[i]; + Expression e; + + uint errors = global.errors; + global.gag++; + + Type t = isType(o_); + if (t) + { Dsymbol s; + t.resolve(loc, sc, &e, &t, &s); + if (t) + t.semantic(loc, sc); + else if (e) + e.semantic(sc); + } + else + { e = isExpression(o); + if (e) + e.semantic(sc); + } + + global.gag--; + if (errors != global.errors) + { if (global.gag == 0) + global.errors = errors; + goto Lfalse; + } + } + goto Ltrue; + } + else if (ident == Id.isSame) + { /* Determine if two symbols are the same + */ + if (dim != 2) + goto Ldimerror; + TemplateInstance.semanticTiargs(loc, sc, args, 0); + Object o1 = cast(Object)args.data[0]; + Object o2 = cast(Object)args.data[1]; + Dsymbol s1 = getDsymbol(o1); + Dsymbol s2 = getDsymbol(o2); + + static if (0) { + printf("o1: %p\n", o1); + printf("o2: %p\n", o2); + if (!s1) + { Expression ea = isExpression(o1); + if (ea) + printf("%s\n", ea.toChars()); + Type ta = isType(o1); + if (ta) + printf("%s\n", ta.toChars()); + goto Lfalse; + } + else + printf("%s %s\n", s1.kind(), s1.toChars()); + } + if (!s1 && !s2) + { Expression ea1 = isExpression(o1); + Expression ea2 = isExpression(o2); + if (ea1 && ea2 && ea1.equals(ea2)) + goto Ltrue; + } + + if (!s1 || !s2) + goto Lfalse; + + s1 = s1.toAlias(); + s2 = s2.toAlias(); + + if (s1 == s2) + goto Ltrue; + else + goto Lfalse; + } + else + { error("unrecognized trait %s", ident.toChars()); + goto Lfalse; + } + + return null; + +Lnottype: + error("%s is not a type", o/*.toChars()*/); // BUG: o is Object, no member toChars() + goto Lfalse; + +Ldimerror: + error("wrong number of arguments %d", dim); + goto Lfalse; + + +Lfalse: + return new IntegerExp(loc, 0, Type.tbool); + +Ltrue: + return new IntegerExp(loc, 1, Type.tbool); + } + + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) + { + buf.writestring("__traits("); + buf.writestring(ident.toChars()); + if (args) + { + for (int i = 0; i < args.dim; i++) + { + buf.writeByte(','); + Object oarg = cast(Object)args.data[i]; + ObjectToCBuffer(buf, hgs, oarg); + } + } + buf.writeByte(')'); + } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TryCatchStatement.d --- a/dmd/TryCatchStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TryCatchStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -33,7 +33,7 @@ this.catches = catches; } - Statement syntaxCopy() + override Statement syntaxCopy() { Array a = new Array(); a.setDim(catches.dim); @@ -49,7 +49,7 @@ return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { body_ = body_.semanticScope(sc, null /*this*/, null); @@ -79,17 +79,17 @@ return this; } - bool hasBreak() + override bool hasBreak() { assert(false); } - bool usesEH() + override bool usesEH() { assert(false); } - BE blockExit() + override BE blockExit() { assert(body_); BE result = body_.blockExit(); @@ -112,7 +112,7 @@ return result | catchresult; } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { if (body_) body_ = body_.inlineScan(iss); @@ -137,7 +137,7 @@ * handler * A try-catch statement. */ - void toIR(IRState *irs) + override void toIR(IRState *irs) { Blockx *blx = irs.blx; @@ -203,10 +203,10 @@ block_next(blx,cast(BC)blx.curblock.BC, breakblock); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - TryCatchStatement isTryCatchStatement() { return this; } -} \ No newline at end of file + override TryCatchStatement isTryCatchStatement() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TryFinallyStatement.d --- a/dmd/TryFinallyStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TryFinallyStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -29,17 +29,17 @@ this.finalbody = finalbody; } - Statement syntaxCopy() + override Statement syntaxCopy() { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { //printf("TryFinallyStatement::semantic()\n"); body_ = body_.semantic(sc); @@ -61,29 +61,29 @@ return this; } - bool hasBreak() + override bool hasBreak() { assert(false); } - bool hasContinue() + override bool hasContinue() { assert(false); } - bool usesEH() + override bool usesEH() { assert(false); } - BE blockExit() + override BE blockExit() { if (body_) return body_.blockExit(); return BE.BEfallthru; } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { if (body_) body_ = body_.inlineScan(iss); @@ -101,7 +101,7 @@ * finalbody * _ret */ - void toIR(IRState* irs) + override void toIR(IRState* irs) { //printf("TryFinallyStatement.toIR()\n"); Blockx* blx = irs.blx; @@ -157,4 +157,4 @@ list_append(&finallyblock.Bsucc, blx.curblock); list_append(&retblock.Bsucc, blx.curblock); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TupleDeclaration.d --- a/dmd/TupleDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TupleDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -31,17 +31,17 @@ this.tupletype = null; } - Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol) { assert(false); } - string kind() + override string kind() { return "tuple"; } - Type getType() + override Type getType() { /* If this tuple represents a type, return that type */ @@ -90,7 +90,7 @@ return tupletype; } - bool needThis() + override bool needThis() { //printf("TupleDeclaration::needThis(%s)\n", toChars()); for (size_t i = 0; i < objects.dim; i++) @@ -112,5 +112,5 @@ return 0; } - TupleDeclaration isTupleDeclaration() { return this; } + override TupleDeclaration isTupleDeclaration() { return this; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TupleExp.d --- a/dmd/TupleExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TupleExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,256 +1,256 @@ -module dmd.TupleExp; - -import dmd.Expression; -import dmd.TupleDeclaration; -import dmd.backend.elem; -import dmd.InterState; -import dmd.WANT; -import dmd.Type; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.InlineCostState; -import dmd.IRState; -import dmd.InlineDoState; -import dmd.HdrGenState; -import dmd.InlineScanState; -import dmd.ArrayTypes; -import dmd.TypeExp; -import dmd.TypeTuple; -import dmd.TOK; -import dmd.TY; -import dmd.Dsymbol; -import dmd.DsymbolExp; -import dmd.DYNCAST; -import dmd.expression.Util; - -/**************************************** - * Expand tuples. - */ -/+ -void expandTuples(Expressions exps) -{ - //printf("expandTuples()\n"); - if (exps) - { - for (size_t i = 0; i < exps.dim; i++) - { Expression arg = cast(Expression)exps.data[i]; - if (!arg) - continue; - - // Look for tuple with 0 members - if (arg.op == TOKtype) - { TypeExp e = cast(TypeExp)arg; - if (e.type.toBasetype().ty == Ttuple) - { TypeTuple tt = cast(TypeTuple)e.type.toBasetype(); - - if (!tt.arguments || tt.arguments.dim == 0) - { - exps.remove(i); - if (i == exps.dim) - return; - i--; - continue; - } - } - } - - // Inline expand all the tuples - while (arg.op == TOKtuple) - { TupleExp te = cast(TupleExp)arg; - - exps.remove(i); // remove arg - exps.insert(i, te.exps); // replace with tuple contents - if (i == exps.dim) - return; // empty tuple, no more arguments - arg = cast(Expression)exps.data[i]; - } - } - } -} -+/ -class TupleExp : Expression -{ - Expressions exps; - - this(Loc loc, Expressions exps) - { - super(loc, TOKtuple, TupleExp.sizeof); - - this.exps = exps; - this.type = null; - } - - this(Loc loc, TupleDeclaration tup) - { - super(loc, TOKtuple, TupleExp.sizeof); - exps = new Expressions(); - type = null; - - exps.reserve(tup.objects.dim); - for (size_t i = 0; i < tup.objects.dim; i++) - { - Object o = cast(Object)tup.objects.data[i]; - if (auto e = cast(Expression)o) - { - e = e.syntaxCopy(); - exps.push(cast(void*)e); - } - else if (auto s = cast(Dsymbol)o) - { - Expression e = new DsymbolExp(loc, s); - exps.push(cast(void*)e); - } - else if (auto t = cast(Type)o) - { - Expression e = new TypeExp(loc, t); - exps.push(cast(void*)e); - } - else - { - error("%s is not an expression", o.toString()); - } - } - } - - Expression syntaxCopy() - { - return new TupleExp(loc, arraySyntaxCopy(exps)); - } - - bool equals(Object o) - { - TupleExp ne; - - if (this == o) - return 1; - if ((cast(Expression)o).op == TOKtuple) - { - TupleExp te = cast(TupleExp)o; - if (exps.dim != te.exps.dim) - return 0; - for (size_t i = 0; i < exps.dim; i++) - { Expression e1 = cast(Expression)exps.data[i]; - Expression e2 = cast(Expression)te.exps.data[i]; - - if (!e1.equals(e2)) - return 0; - } - return 1; - } - return 0; - } - - Expression semantic(Scope sc) - { - version (LOGSEMANTIC) { - printf("+TupleExp::semantic(%s)\n", toChars()); - } - if (type) - return this; - - // Run semantic() on each argument - for (size_t i = 0; i < exps.dim; i++) - { Expression e = cast(Expression)exps.data[i]; - - e = e.semantic(sc); - if (!e.type) - { error("%s has no value", e.toChars()); - e.type = Type.terror; - } - exps.data[i] = cast(void *)e; - } - - expandTuples(exps); - if (0 && exps.dim == 1) - { - return cast(Expression)exps.data[0]; - } - type = new TypeTuple(exps); - type = type.semantic(loc, sc); - //printf("-TupleExp::semantic(%s)\n", toChars()); - return this; - } - - void toCBuffer(OutBuffer buf, HdrGenState* hgs) - { - buf.writestring("tuple("); - argsToCBuffer(buf, exps, hgs); - buf.writeByte(')'); - } - - void scanForNestedRef(Scope sc) - { - assert(false); - } - - void checkEscape() - { - for (size_t i = 0; i < exps.dim; i++) - { Expression e = cast(Expression)exps.data[i]; - e.checkEscape(); - } - } - - bool checkSideEffect(int flag) - { - bool f = false; - - for (int i = 0; i < exps.dim; i++) - { Expression e = cast(Expression)exps.data[i]; - - f |= e.checkSideEffect(2); - } - if (flag == 0 && f == 0) - Expression.checkSideEffect(0); - return f; - } - - Expression optimize(int result) - { - for (size_t i = 0; i < exps.dim; i++) - { - Expression e = cast(Expression)exps.data[i]; - - e = e.optimize(WANTvalue | (result & WANTinterpret)); - exps.data[i] = cast(void*)e; - } - return this; - } - - Expression interpret(InterState istate) - { - assert(false); - } - - Expression castTo(Scope sc, Type t) - { - assert(false); - } - - elem* toElem(IRState* irs) - { - assert(false); - } - - bool canThrow() - { - return arrayExpressionCanThrow(exps); - } - - int inlineCost(InlineCostState* ics) - { - assert(false); - } - - Expression doInline(InlineDoState ids) - { - assert(false); - } - - Expression inlineScan(InlineScanState* iss) - { - assert(false); - } -} - +module dmd.TupleExp; + +import dmd.Expression; +import dmd.TupleDeclaration; +import dmd.backend.elem; +import dmd.InterState; +import dmd.WANT; +import dmd.Type; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.InlineCostState; +import dmd.IRState; +import dmd.InlineDoState; +import dmd.HdrGenState; +import dmd.InlineScanState; +import dmd.ArrayTypes; +import dmd.TypeExp; +import dmd.TypeTuple; +import dmd.TOK; +import dmd.TY; +import dmd.Dsymbol; +import dmd.DsymbolExp; +import dmd.DYNCAST; +import dmd.expression.Util; + +/**************************************** + * Expand tuples. + */ +/+ +void expandTuples(Expressions exps) +{ + //printf("expandTuples()\n"); + if (exps) + { + for (size_t i = 0; i < exps.dim; i++) + { Expression arg = cast(Expression)exps.data[i]; + if (!arg) + continue; + + // Look for tuple with 0 members + if (arg.op == TOKtype) + { TypeExp e = cast(TypeExp)arg; + if (e.type.toBasetype().ty == Ttuple) + { TypeTuple tt = cast(TypeTuple)e.type.toBasetype(); + + if (!tt.arguments || tt.arguments.dim == 0) + { + exps.remove(i); + if (i == exps.dim) + return; + i--; + continue; + } + } + } + + // Inline expand all the tuples + while (arg.op == TOKtuple) + { TupleExp te = cast(TupleExp)arg; + + exps.remove(i); // remove arg + exps.insert(i, te.exps); // replace with tuple contents + if (i == exps.dim) + return; // empty tuple, no more arguments + arg = cast(Expression)exps.data[i]; + } + } + } +} ++/ +class TupleExp : Expression +{ + Expressions exps; + + this(Loc loc, Expressions exps) + { + super(loc, TOKtuple, TupleExp.sizeof); + + this.exps = exps; + this.type = null; + } + + this(Loc loc, TupleDeclaration tup) + { + super(loc, TOKtuple, TupleExp.sizeof); + exps = new Expressions(); + type = null; + + exps.reserve(tup.objects.dim); + for (size_t i = 0; i < tup.objects.dim; i++) + { + Object o = cast(Object)tup.objects.data[i]; + if (auto e = cast(Expression)o) + { + e = e.syntaxCopy(); + exps.push(cast(void*)e); + } + else if (auto s = cast(Dsymbol)o) + { + Expression e = new DsymbolExp(loc, s); + exps.push(cast(void*)e); + } + else if (auto t = cast(Type)o) + { + Expression e = new TypeExp(loc, t); + exps.push(cast(void*)e); + } + else + { + error("%s is not an expression", o.toString()); + } + } + } + + override Expression syntaxCopy() + { + return new TupleExp(loc, arraySyntaxCopy(exps)); + } + + override bool equals(Object o) + { + TupleExp ne; + + if (this == o) + return 1; + if ((cast(Expression)o).op == TOKtuple) + { + TupleExp te = cast(TupleExp)o; + if (exps.dim != te.exps.dim) + return 0; + for (size_t i = 0; i < exps.dim; i++) + { Expression e1 = cast(Expression)exps.data[i]; + Expression e2 = cast(Expression)te.exps.data[i]; + + if (!e1.equals(e2)) + return 0; + } + return 1; + } + return 0; + } + + override Expression semantic(Scope sc) + { + version (LOGSEMANTIC) { + printf("+TupleExp::semantic(%s)\n", toChars()); + } + if (type) + return this; + + // Run semantic() on each argument + for (size_t i = 0; i < exps.dim; i++) + { Expression e = cast(Expression)exps.data[i]; + + e = e.semantic(sc); + if (!e.type) + { error("%s has no value", e.toChars()); + e.type = Type.terror; + } + exps.data[i] = cast(void *)e; + } + + expandTuples(exps); + if (0 && exps.dim == 1) + { + return cast(Expression)exps.data[0]; + } + type = new TypeTuple(exps); + type = type.semantic(loc, sc); + //printf("-TupleExp::semantic(%s)\n", toChars()); + return this; + } + + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) + { + buf.writestring("tuple("); + argsToCBuffer(buf, exps, hgs); + buf.writeByte(')'); + } + + override void scanForNestedRef(Scope sc) + { + assert(false); + } + + override void checkEscape() + { + for (size_t i = 0; i < exps.dim; i++) + { Expression e = cast(Expression)exps.data[i]; + e.checkEscape(); + } + } + + override bool checkSideEffect(int flag) + { + bool f = false; + + for (int i = 0; i < exps.dim; i++) + { Expression e = cast(Expression)exps.data[i]; + + f |= e.checkSideEffect(2); + } + if (flag == 0 && f == 0) + Expression.checkSideEffect(0); + return f; + } + + override Expression optimize(int result) + { + for (size_t i = 0; i < exps.dim; i++) + { + Expression e = cast(Expression)exps.data[i]; + + e = e.optimize(WANTvalue | (result & WANTinterpret)); + exps.data[i] = cast(void*)e; + } + return this; + } + + override Expression interpret(InterState istate) + { + assert(false); + } + + override Expression castTo(Scope sc, Type t) + { + assert(false); + } + + override elem* toElem(IRState* irs) + { + assert(false); + } + + override bool canThrow() + { + return arrayExpressionCanThrow(exps); + } + + override int inlineCost(InlineCostState* ics) + { + assert(false); + } + + override Expression doInline(InlineDoState ids) + { + assert(false); + } + + override Expression inlineScan(InlineScanState* iss) + { + assert(false); + } +} + diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeAArray.d --- a/dmd/TypeAArray.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeAArray.d Sat Aug 28 16:19:48 2010 +0200 @@ -50,7 +50,7 @@ this.index = index; } - Type syntaxCopy() + override Type syntaxCopy() { Type t = next.syntaxCopy(); Type ti = index.syntaxCopy(); @@ -71,12 +71,12 @@ assert(false); } } - ulong size(Loc loc) + override ulong size(Loc loc) { return PTRSIZE /* * 2*/; } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { //printf("TypeAArray::semantic() %s index.ty = %d\n", toChars(), index.ty); @@ -147,7 +147,7 @@ return merge(); } - void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) + override void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) { //printf("TypeAArray.resolve() %s\n", toChars()); @@ -175,14 +175,14 @@ Type.resolve(loc, sc, pe, pt, ps); } - void toDecoBuffer(OutBuffer buf, int flag) + override void toDecoBuffer(OutBuffer buf, int flag) { Type.toDecoBuffer(buf, flag); index.toDecoBuffer(buf); next.toDecoBuffer(buf, (flag & 0x100) ? MOD.MODundefined : mod); } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { if (mod != this.mod) { @@ -195,7 +195,7 @@ buf.writeByte(']'); } - Expression dotExp(Scope sc, Expression e, Identifier ident) + override Expression dotExp(Scope sc, Expression e, Identifier ident) { version (LOGDOTEXP) { printf("TypeAArray.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars()); @@ -267,7 +267,7 @@ return e; } - Expression defaultInit(Loc loc) + override Expression defaultInit(Loc loc) { version (LOGDEFAULTINIT) { printf("TypeAArray.defaultInit() '%s'\n", toChars()); @@ -277,7 +277,7 @@ return e; } - MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) + override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { static if (false) { printf("TypeAArray.deduceType()\n"); @@ -297,27 +297,27 @@ return Type.deduceType(sc, tparam, parameters, dedtypes); } - bool isZeroInit(Loc loc) + override bool isZeroInit(Loc loc) { assert(false); } - bool checkBoolean() + override bool checkBoolean() { assert(false); } - TypeInfoDeclaration getTypeInfoDeclaration() + override TypeInfoDeclaration getTypeInfoDeclaration() { return new TypeInfoAssociativeArrayDeclaration(this); } - bool hasPointers() + override bool hasPointers() { return true; } - MATCH implicitConvTo(Type to) + override MATCH implicitConvTo(Type to) { //printf("TypeAArray.implicitConvTo(to = %s) this = %s\n", to.toChars(), toChars()); if (equals(to)) @@ -347,7 +347,7 @@ return Type.implicitConvTo(to); } - MATCH constConv(Type to) + override MATCH constConv(Type to) { assert(false); } @@ -443,7 +443,7 @@ return s; } - type* toCtype() + override type* toCtype() { type* t; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeArray.d --- a/dmd/TypeArray.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeArray.d Sat Aug 28 16:19:48 2010 +0200 @@ -29,7 +29,7 @@ super(ty, next); } - Expression dotExp(Scope sc, Expression e, Identifier ident) + override Expression dotExp(Scope sc, Expression e, Identifier ident) { Type n = this.next.toBasetype(); // uncover any typedef's @@ -131,4 +131,4 @@ assert(false); } } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeBasic.d --- a/dmd/TypeBasic.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeBasic.d Sat Aug 28 16:19:48 2010 +0200 @@ -143,13 +143,13 @@ assert(false); } } - Type syntaxCopy() + override Type syntaxCopy() { // No semantic analysis done on basic types, no need to copy return this; } - ulong size(Loc loc) + override ulong size(Loc loc) { uint size; @@ -199,7 +199,7 @@ return size; } - uint alignsize() + override uint alignsize() { uint sz; @@ -230,7 +230,7 @@ return sz; } - Expression getProperty(Loc loc, Identifier ident) + override Expression getProperty(Loc loc, Identifier ident) { Expression e; long ivalue; @@ -461,7 +461,7 @@ return e; } - Expression dotExp(Scope sc, Expression e, Identifier ident) + override Expression dotExp(Scope sc, Expression e, Identifier ident) { version (LOGDOTEXP) { printf("TypeBasic.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars()); @@ -534,12 +534,12 @@ return e; } - string toChars() + override string toChars() { return Type.toChars(); } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { //printf("TypeBasic.toCBuffer2(mod = %d, this.mod = %d)\n", mod, this.mod); if (mod != this.mod) @@ -556,7 +556,7 @@ assert(false); } } - bool isintegral() + override bool isintegral() { //printf("TypeBasic.isintegral('%s') x%x\n", toChars(), flags); return (flags & TFLAGS.TFLAGSintegral) != 0; @@ -567,37 +567,37 @@ assert(false); } - bool isfloating() + override bool isfloating() { return (flags & TFLAGS.TFLAGSfloating) != 0; } - bool isreal() + override bool isreal() { return (flags & TFLAGS.TFLAGSreal) != 0; } - bool isimaginary() + override bool isimaginary() { return (flags & TFLAGS.TFLAGSimaginary) != 0; } - bool iscomplex() + override bool iscomplex() { return (flags & TFLAGS.TFLAGScomplex) != 0; } - bool isscalar() + override bool isscalar() { return (flags & (TFLAGS.TFLAGSintegral | TFLAGS.TFLAGSfloating)) != 0; } - bool isunsigned() + override bool isunsigned() { return (flags & TFLAGS.TFLAGSunsigned) != 0; } - MATCH implicitConvTo(Type to) + override MATCH implicitConvTo(Type to) { //printf("TypeBasic.implicitConvTo(%s) from %s\n", to.toChars(), toChars()); if (this is to) @@ -667,7 +667,7 @@ return MATCH.MATCHconvert; } - Expression defaultInit(Loc loc) + override Expression defaultInit(Loc loc) { long value = 0; @@ -738,7 +738,7 @@ return new IntegerExp(loc, value, this); } - bool isZeroInit(Loc loc) + override bool isZeroInit(Loc loc) { switch (ty) { @@ -762,7 +762,7 @@ return true; // yes } - bool builtinTypeInfo() + override bool builtinTypeInfo() { version (DMDV2) { return mod ? false : true; @@ -772,7 +772,7 @@ } // For eliminating dynamic_cast - TypeBasic isTypeBasic() + override TypeBasic isTypeBasic() { return this; } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeClass.d --- a/dmd/TypeClass.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeClass.d Sat Aug 28 16:19:48 2010 +0200 @@ -78,24 +78,24 @@ assert(false); } } - ulong size(Loc loc) + override ulong size(Loc loc) { return PTRSIZE; } - string toChars() + override string toChars() { if (mod) return Type.toChars(); return sym.toPrettyChars(); } - Type syntaxCopy() + override Type syntaxCopy() { assert(false); } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { //printf("TypeClass.semantic(%s)\n", sym.toChars()); if (deco) @@ -104,12 +104,12 @@ return merge(); } - Dsymbol toDsymbol(Scope sc) + override Dsymbol toDsymbol(Scope sc) { return sym; } - void toDecoBuffer(OutBuffer buf, int flag) + override void toDecoBuffer(OutBuffer buf, int flag) { string name = sym.mangle(); //printf("TypeClass.toDecoBuffer('%s' flag=%d mod=%x) = '%s'\n", toChars(), flag, mod, name); @@ -117,7 +117,7 @@ buf.printf("%s", name); } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { if (mod != this.mod) { @@ -127,7 +127,7 @@ buf.writestring(sym.toChars()); } - Expression dotExp(Scope sc, Expression e, Identifier ident) + override Expression dotExp(Scope sc, Expression e, Identifier ident) { uint offset; @@ -459,12 +459,12 @@ return de.semantic(sc); } - ClassDeclaration isClassHandle() + override ClassDeclaration isClassHandle() { return sym; } - bool isBaseOf(Type t, int* poffset) + override bool isBaseOf(Type t, int* poffset) { if (t.ty == Tclass) { @@ -478,7 +478,7 @@ return false; } - MATCH implicitConvTo(Type to) + override MATCH implicitConvTo(Type to) { //printf("TypeClass.implicitConvTo(to = '%s') %s\n", to.toChars(), toChars()); MATCH m = constConv(to); @@ -514,7 +514,7 @@ return m; } - Expression defaultInit(Loc loc) + override Expression defaultInit(Loc loc) { version (LOGDEFAULTINIT) { printf("TypeClass::defaultInit() '%s'\n", toChars()); @@ -524,12 +524,12 @@ return e; } - bool isZeroInit(Loc loc) + override bool isZeroInit(Loc loc) { return true; } - MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) + override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { //printf("TypeClass.deduceType(this = %s)\n", toChars()); @@ -580,17 +580,17 @@ return Type.deduceType(sc, tparam, parameters, dedtypes); } - bool isauto() + override bool isauto() { return sym.isauto; } - bool checkBoolean() + override bool checkBoolean() { return true; } - TypeInfoDeclaration getTypeInfoDeclaration() + override TypeInfoDeclaration getTypeInfoDeclaration() { if (sym.isInterfaceDeclaration()) return new TypeInfoInterfaceDeclaration(this); @@ -598,12 +598,12 @@ return new TypeInfoClassDeclaration(this); } - bool hasPointers() + override bool hasPointers() { return true; } - bool builtinTypeInfo() + override bool builtinTypeInfo() { /* This is statically put out with the ClassInfo, so * claim it is built in so it isn't regenerated by each module. @@ -616,12 +616,12 @@ } version (DMDV2) { - Type toHeadMutable() + override Type toHeadMutable() { assert(false); } - MATCH constConv(Type to) + override MATCH constConv(Type to) { if (equals(to)) return MATCH.MATCHexact; @@ -640,7 +640,7 @@ } } - type* toCtype() + override type* toCtype() { type* t; Symbol* s; @@ -687,8 +687,8 @@ return t; } - Symbol* toSymbol() + override Symbol* toSymbol() { return sym.toSymbol(); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeDArray.d --- a/dmd/TypeDArray.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeDArray.d Sat Aug 28 16:19:48 2010 +0200 @@ -53,7 +53,7 @@ assert(false); } } - Type syntaxCopy() + override Type syntaxCopy() { Type t = next.syntaxCopy(); if (t == next) @@ -66,20 +66,20 @@ return t; } - ulong size(Loc loc) + override ulong size(Loc loc) { //printf("TypeDArray.size()\n"); return PTRSIZE * 2; } - uint alignsize() + override uint alignsize() { // A DArray consists of two ptr-sized values, so align it on pointer size // boundary return PTRSIZE; } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { Type tn = next; @@ -112,14 +112,14 @@ return merge(); } - void toDecoBuffer(OutBuffer buf, int flag) + override void toDecoBuffer(OutBuffer buf, int flag) { Type.toDecoBuffer(buf, flag); if (next) next.toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { if (mod != this.mod) { @@ -130,7 +130,7 @@ buf.writestring("[]"); } - Expression dotExp(Scope sc, Expression e, Identifier ident) + override Expression dotExp(Scope sc, Expression e, Identifier ident) { version (LOGDOTEXP) { printf("TypeDArray.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars()); @@ -159,23 +159,23 @@ return e; } - bool isString() + override bool isString() { TY nty = next.toBasetype().ty; return nty == Tchar || nty == Twchar || nty == Tdchar; } - bool isZeroInit(Loc loc) + override bool isZeroInit(Loc loc) { return true; } - bool checkBoolean() + override bool checkBoolean() { return true; } - MATCH implicitConvTo(Type to) + override MATCH implicitConvTo(Type to) { //printf("TypeDArray.implicitConvTo(to = %s) this = %s\n", to.toChars(), toChars()); if (equals(to)) @@ -237,7 +237,7 @@ return Type.implicitConvTo(to); } - Expression defaultInit(Loc loc) + override Expression defaultInit(Loc loc) { version (LOGDEFAULTINIT) { printf("TypeDArray.defaultInit() '%s'\n", toChars()); @@ -247,7 +247,7 @@ return e; } - bool builtinTypeInfo() + override bool builtinTypeInfo() { version (DMDV2) { return !mod && (next.isTypeBasic() !is null && !next.mod || @@ -258,7 +258,7 @@ } } version (DMDV2) { - MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) + override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { static if (false) { printf("TypeDArray.deduceType()\n"); @@ -271,12 +271,12 @@ return MATCHnomatch; } } - TypeInfoDeclaration getTypeInfoDeclaration() + override TypeInfoDeclaration getTypeInfoDeclaration() { return new TypeInfoArrayDeclaration(this); } - bool hasPointers() + override bool hasPointers() { return true; } @@ -285,7 +285,7 @@ void toCppMangle(OutBuffer buf, CppMangleState* cms); } - type* toCtype() + override type* toCtype() { type *t; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeDelegate.d --- a/dmd/TypeDelegate.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeDelegate.d Sat Aug 28 16:19:48 2010 +0200 @@ -47,7 +47,7 @@ assert(false); } } - Type syntaxCopy() + override Type syntaxCopy() { Type t = next.syntaxCopy(); if (t == next) @@ -60,7 +60,7 @@ return t; } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { if (deco) // if semantic() already run { @@ -72,12 +72,12 @@ return merge(); } - ulong size(Loc loc) + override ulong size(Loc loc) { return PTRSIZE * 2; } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { if (mod != this.mod) { @@ -91,7 +91,7 @@ Argument.argsToCBuffer(buf, hgs, tf.parameters, tf.varargs); } - Expression defaultInit(Loc loc) + override Expression defaultInit(Loc loc) { version (LOGDEFAULTINIT) { printf("TypeDelegate.defaultInit() '%s'\n", toChars()); @@ -102,22 +102,22 @@ return e; } - bool isZeroInit(Loc loc) + override bool isZeroInit(Loc loc) { return true; } - bool checkBoolean() + override bool checkBoolean() { return true; } - TypeInfoDeclaration getTypeInfoDeclaration() + override TypeInfoDeclaration getTypeInfoDeclaration() { return new TypeInfoDelegateDeclaration(this); } - Expression dotExp(Scope sc, Expression e, Identifier ident) + override Expression dotExp(Scope sc, Expression e, Identifier ident) { version (LOGDOTEXP) { printf("TypeDelegate.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars()); @@ -144,7 +144,7 @@ return e; } - bool hasPointers() + override bool hasPointers() { return true; } @@ -156,7 +156,7 @@ } } - type* toCtype() + override type* toCtype() { type* t; @@ -210,4 +210,4 @@ ctype = t; return t; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeEnum.d --- a/dmd/TypeEnum.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeEnum.d Sat Aug 28 16:19:48 2010 +0200 @@ -41,12 +41,12 @@ assert(false); } } - Type syntaxCopy() + override Type syntaxCopy() { assert(false); } - ulong size(Loc loc) + override ulong size(Loc loc) { if (!sym.memtype) { @@ -56,36 +56,36 @@ return sym.memtype.size(loc); } - uint alignsize() + override uint alignsize() { assert(false); } - string toChars() + override string toChars() { assert(false); } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { //printf("TypeEnum::semantic() %s\n", toChars()); //sym.semantic(sc); return merge(); } - Dsymbol toDsymbol(Scope sc) + override Dsymbol toDsymbol(Scope sc) { return sym; } - void toDecoBuffer(OutBuffer buf, int flag) + override void toDecoBuffer(OutBuffer buf, int flag) { string name = sym.mangle(); Type.toDecoBuffer(buf, flag); buf.printf("%s", name); } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { if (mod != this.mod) { @@ -95,7 +95,7 @@ buf.writestring(sym.toChars()); } - Expression dotExp(Scope sc, Expression e, Identifier ident) + override Expression dotExp(Scope sc, Expression e, Identifier ident) { version (LOGDOTEXP) { printf("TypeEnum::dotExp(e = '%s', ident = '%s') '%s'\n", e.toChars(), ident.toChars(), toChars()); @@ -122,33 +122,33 @@ return em; } - Expression getProperty(Loc loc, Identifier ident) + override Expression getProperty(Loc loc, Identifier ident) { assert(false); } - bool isintegral() + override bool isintegral() { return true; } - bool isfloating() + override bool isfloating() { return false; } - bool isscalar() + override bool isscalar() { return true; //return sym.memtype.isscalar(); } - bool isunsigned() + override bool isunsigned() { return sym.memtype.isunsigned(); } - MATCH implicitConvTo(Type to) + override MATCH implicitConvTo(Type to) { MATCH m; @@ -162,12 +162,12 @@ return m; } - MATCH constConv(Type to) + override MATCH constConv(Type to) { assert(false); } - Type toBasetype() + override Type toBasetype() { if (!sym.memtype) { @@ -179,7 +179,7 @@ return sym.memtype.toBasetype(); } - Expression defaultInit(Loc loc) + override Expression defaultInit(Loc loc) { version (LOGDEFAULTINIT) { printf("TypeEnum::defaultInit() '%s'\n", toChars()); @@ -194,7 +194,7 @@ return sym.defaultval; } - bool isZeroInit(Loc loc) + override bool isZeroInit(Loc loc) { if (!sym.defaultval) { @@ -205,17 +205,17 @@ return sym.defaultval.isBool(false); } - MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) + override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { assert(false); } - TypeInfoDeclaration getTypeInfoDeclaration() + override TypeInfoDeclaration getTypeInfoDeclaration() { return new TypeInfoEnumDeclaration(this); } - bool hasPointers() + override bool hasPointers() { return toBasetype().hasPointers(); } @@ -227,8 +227,8 @@ } } - type* toCtype() + override type* toCtype() { return sym.memtype.toCtype(); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeExp.d --- a/dmd/TypeExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,60 +1,60 @@ -module dmd.TypeExp; - -import dmd.Expression; -import dmd.backend.elem; -import dmd.Type; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IRState; -import dmd.HdrGenState; -import dmd.TOK; - +module dmd.TypeExp; + +import dmd.Expression; +import dmd.backend.elem; +import dmd.Type; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IRState; +import dmd.HdrGenState; +import dmd.TOK; + class TypeExp : Expression { this(Loc loc, Type type) { - super(loc, TOK.TOKtype, TypeExp.sizeof); - //printf("TypeExp::TypeExp(%s)\n", type->toChars()); + super(loc, TOK.TOKtype, TypeExp.sizeof); + //printf("TypeExp::TypeExp(%s)\n", type->toChars()); this.type = type; } - -version (DumbClone) { -} else { - Type clone() - { - assert(false); - } + +version (DumbClone) { +} else { + Type clone() + { + assert(false); + } } - Expression syntaxCopy() + override Expression syntaxCopy() { //printf("TypeExp.syntaxCopy()\n"); return new TypeExp(loc, type.syntaxCopy()); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { - //printf("TypeExp::semantic(%s)\n", type->toChars()); - type = type.semantic(loc, sc); + //printf("TypeExp::semantic(%s)\n", type->toChars()); + type = type.semantic(loc, sc); return this; } - void rvalue() + override void rvalue() { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - type.toCBuffer(buf, null, hgs); + type.toCBuffer(buf, null, hgs); } - Expression optimize(int result) + override Expression optimize(int result) { return this; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeFunction.d --- a/dmd/TypeFunction.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeFunction.d Sat Aug 28 16:19:48 2010 +0200 @@ -62,7 +62,7 @@ this.linkage = linkage; } - Type syntaxCopy() + override Type syntaxCopy() { Type treturn = next ? next.syntaxCopy() : null; Arguments params = Argument.arraySyntaxCopy(parameters); @@ -113,7 +113,7 @@ return cloneTo(new TypeFunction(null, next, varargs, linkage)); } } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { if (deco) // if semantic() already run { @@ -222,7 +222,7 @@ return tf; } - void toDecoBuffer(OutBuffer buf, int flag) + override void toDecoBuffer(OutBuffer buf, int flag) { ubyte mc; @@ -270,7 +270,7 @@ inuse--; } - void toCBuffer(OutBuffer buf, Identifier ident, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, Identifier ident, HdrGenState* hgs) { //printf("TypeFunction.toCBuffer() this = %p\n", this); string p = null; @@ -327,7 +327,7 @@ inuse--; } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { //printf("TypeFunction::toCBuffer2() this = %p, ref = %d\n", this, isref); string p; @@ -379,17 +379,17 @@ inuse--; } - MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) + override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { assert(false); } - TypeInfoDeclaration getTypeInfoDeclaration() + override TypeInfoDeclaration getTypeInfoDeclaration() { assert(false); } - Type reliesOnTident() + override Type reliesOnTident() { if (parameters) { @@ -595,7 +595,7 @@ return MATCH.MATCHnomatch; } - type* toCtype() + override type* toCtype() { if (ctype) { return ctype; @@ -690,7 +690,7 @@ return RET.RETregs; } - TYM totym() + override TYM totym() { TYM tyf; diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeIdentifier.d --- a/dmd/TypeIdentifier.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeIdentifier.d Sat Aug 28 16:19:48 2010 +0200 @@ -37,7 +37,7 @@ assert(false); } } - Type syntaxCopy() + override Type syntaxCopy() { TypeIdentifier t = new TypeIdentifier(loc, ident); t.syntaxCopyHelper(this); @@ -48,14 +48,14 @@ //char *toChars(); - void toDecoBuffer(OutBuffer buf, int flag) + override void toDecoBuffer(OutBuffer buf, int flag) { Type.toDecoBuffer(buf, flag); string name = ident.toChars(); buf.printf("%d%s", name.length, name); } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { if (mod != this.mod) { @@ -73,7 +73,7 @@ * if expression, *pe is set * if type, *pt is set */ - void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) + override void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) { Dsymbol scopesym; @@ -88,7 +88,7 @@ * See if type resolves to a symbol, if so, * return that symbol. */ - Dsymbol toDsymbol(Scope sc) + override Dsymbol toDsymbol(Scope sc) { //printf("TypeIdentifier::toDsymbol('%s')\n", toChars()); if (!sc) @@ -114,7 +114,7 @@ return s; } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { Type t; Expression e; @@ -156,7 +156,7 @@ return t; } - MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) + override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { // Extra check if (tparam && tparam.ty == Tident) @@ -175,12 +175,12 @@ return Type.deduceType(sc, tparam, parameters, dedtypes); } - Type reliesOnTident() + override Type reliesOnTident() { return this; } - Expression toExpression() + override Expression toExpression() { Expression e = new IdentifierExp(loc, ident); for (int i = 0; i < idents.dim; i++) @@ -191,4 +191,4 @@ return e; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInfoArrayDeclaration.d --- a/dmd/TypeInfoArrayDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInfoArrayDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,15 +1,15 @@ -module dmd.TypeInfoArrayDeclaration; - -import dmd.Type; +module dmd.TypeInfoArrayDeclaration; + +import dmd.Type; import dmd.TypeInfoDeclaration; import dmd.Type; import dmd.TY; import dmd.TypeDArray; - + import dmd.backend.dt_t; import dmd.backend.Util; -import dmd.backend.TYM; - +import dmd.backend.TYM; + class TypeInfoArrayDeclaration : TypeInfoDeclaration { this(Type tinfo) @@ -17,7 +17,7 @@ super(tinfo, 0); } - void toDt(dt_t** pdt) + override void toDt(dt_t** pdt) { //printf("TypeInfoArrayDeclaration::toDt()\n"); dtxoff(pdt, Type.typeinfoarray.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Array diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInfoAssociativeArrayDeclaration.d --- a/dmd/TypeInfoAssociativeArrayDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInfoAssociativeArrayDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -15,7 +15,7 @@ super(tinfo, 0); } - void toDt(dt_t** pdt) + override void toDt(dt_t** pdt) { //printf("TypeInfoAssociativeArrayDeclaration.toDt()\n"); dtxoff(pdt, Type.typeinfoassociativearray.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInfoClassDeclaration.d --- a/dmd/TypeInfoClassDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInfoClassDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,16 +1,16 @@ -module dmd.TypeInfoClassDeclaration; - -import dmd.Type; +module dmd.TypeInfoClassDeclaration; + +import dmd.Type; import dmd.TypeInfoDeclaration; import dmd.ClassInfoDeclaration; import dmd.TypeClass; import dmd.TY; -import dmd.Util; +import dmd.Util; import dmd.backend.dt_t; import dmd.backend.Util; import dmd.backend.TYM; -import dmd.backend.Symbol; - +import dmd.backend.Symbol; + class TypeInfoClassDeclaration : TypeInfoDeclaration { this(Type tinfo) @@ -18,7 +18,7 @@ super(tinfo, 0); } - void toDt(dt_t** pdt) + override void toDt(dt_t** pdt) { //printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars()); dtxoff(pdt, Type.typeinfoclass.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInfoConstDeclaration.d --- a/dmd/TypeInfoConstDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInfoConstDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,12 +1,12 @@ -module dmd.TypeInfoConstDeclaration; - -import dmd.Type; +module dmd.TypeInfoConstDeclaration; + +import dmd.Type; import dmd.TypeInfoDeclaration; -import dmd.Type; +import dmd.Type; import dmd.backend.dt_t; import dmd.backend.Util; -import dmd.backend.TYM; - +import dmd.backend.TYM; + class TypeInfoConstDeclaration : TypeInfoDeclaration { this(Type tinfo) @@ -14,7 +14,7 @@ super(tinfo, 0); } - void toDt(dt_t** pdt) + override void toDt(dt_t** pdt) { //printf("TypeInfoConstDeclaration.toDt() %s\n", toChars()); dtxoff(pdt, Type.typeinfoconst.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Const diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInfoDeclaration.d --- a/dmd/TypeInfoDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInfoDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -18,7 +18,7 @@ import dmd.backend.glue; import dmd.backend.Util; import dmd.backend.TYPE; - + import core.stdc.stdio; class TypeInfoDeclaration : VarDeclaration @@ -41,28 +41,28 @@ assert(false); } } - Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol) { assert(false); } - void semantic(Scope sc) + override void semantic(Scope sc) { assert(false); } - void emitComment(Scope sc) + override void emitComment(Scope sc) { assert(false); } - Symbol* toSymbol() + override Symbol* toSymbol() { //printf("TypeInfoDeclaration::toSymbol(%s), linkage = %d\n", toChars(), linkage); return VarDeclaration.toSymbol(); } - void toObjFile(int multiobj) // compile to .obj file + override void toObjFile(int multiobj) // compile to .obj file { Symbol* s; uint sz; @@ -112,4 +112,4 @@ { assert(false); } -} +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInfoDelegateDeclaration.d --- a/dmd/TypeInfoDelegateDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInfoDelegateDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,14 +1,14 @@ -module dmd.TypeInfoDelegateDeclaration; - -import dmd.Type; +module dmd.TypeInfoDelegateDeclaration; + +import dmd.Type; import dmd.TypeInfoDeclaration; import dmd.TypeDelegate; import dmd.TY; - + import dmd.backend.dt_t; import dmd.backend.Util; -import dmd.backend.TYM; - +import dmd.backend.TYM; + class TypeInfoDelegateDeclaration : TypeInfoDeclaration { this(Type tinfo) @@ -16,7 +16,7 @@ super(tinfo, 0); } - void toDt(dt_t** pdt) + override void toDt(dt_t** pdt) { //printf("TypeInfoDelegateDeclaration.toDt()\n"); dtxoff(pdt, Type.typeinfodelegate.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Delegate diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInfoEnumDeclaration.d --- a/dmd/TypeInfoEnumDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInfoEnumDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,17 +1,17 @@ -module dmd.TypeInfoEnumDeclaration; +module dmd.TypeInfoEnumDeclaration; -import dmd.TY; +import dmd.TY; import dmd.Type; import dmd.Loc; import dmd.TypeEnum; -import dmd.EnumDeclaration; -import dmd.TypeInfoDeclaration; +import dmd.EnumDeclaration; +import dmd.TypeInfoDeclaration; import dmd.backend.dt_t; import dmd.backend.Util; import dmd.backend.TYM; -import std.string : toStringz; - +import std.string : toStringz; + class TypeInfoEnumDeclaration : TypeInfoDeclaration { this(Type tinfo) @@ -19,7 +19,7 @@ super(tinfo, 0); } - void toDt(dt_t** pdt) + override void toDt(dt_t** pdt) { //printf("TypeInfoEnumDeclaration::toDt()\n"); dtxoff(pdt, Type.typeinfoenum.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInfoInterfaceDeclaration.d --- a/dmd/TypeInfoInterfaceDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInfoInterfaceDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,16 +1,16 @@ -module dmd.TypeInfoInterfaceDeclaration; - -import dmd.Type; +module dmd.TypeInfoInterfaceDeclaration; + +import dmd.Type; import dmd.TypeInfoDeclaration; import dmd.ClassInfoDeclaration; import dmd.TypeClass; import dmd.TY; - + import dmd.backend.dt_t; import dmd.backend.Symbol; import dmd.backend.Util; -import dmd.backend.TYM; - +import dmd.backend.TYM; + class TypeInfoInterfaceDeclaration : TypeInfoDeclaration { this(Type tinfo) @@ -18,7 +18,7 @@ super(tinfo, 0); } - void toDt(dt_t** pdt) + override void toDt(dt_t** pdt) { //printf("TypeInfoInterfaceDeclaration.toDt() %s\n", tinfo.toChars()); dtxoff(pdt, Type.typeinfointerface.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInfoInvariantDeclaration.d --- a/dmd/TypeInfoInvariantDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInfoInvariantDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,11 +1,11 @@ -module dmd.TypeInfoInvariantDeclaration; - -import dmd.Type; -import dmd.TypeInfoDeclaration; +module dmd.TypeInfoInvariantDeclaration; + +import dmd.Type; +import dmd.TypeInfoDeclaration; import dmd.backend.dt_t; import dmd.backend.Util; -import dmd.backend.TYM; - +import dmd.backend.TYM; + class TypeInfoInvariantDeclaration : TypeInfoDeclaration { this(Type tinfo) @@ -13,7 +13,7 @@ super(tinfo, 0); } - void toDt(dt_t** pdt) + override void toDt(dt_t** pdt) { //printf("TypeInfoInvariantDeclaration.toDt() %s\n", toChars()); dtxoff(pdt, Type.typeinfoinvariant.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Invariant diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInfoPointerDeclaration.d --- a/dmd/TypeInfoPointerDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInfoPointerDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,13 +1,13 @@ -module dmd.TypeInfoPointerDeclaration; - -import dmd.Type; +module dmd.TypeInfoPointerDeclaration; + +import dmd.Type; import dmd.TypeInfoDeclaration; import dmd.TypePointer; -import dmd.TY; +import dmd.TY; import dmd.backend.dt_t; import dmd.backend.Util; -import dmd.backend.TYM; - +import dmd.backend.TYM; + class TypeInfoPointerDeclaration : TypeInfoDeclaration { this(Type tinfo) @@ -15,7 +15,7 @@ super(tinfo, 0); } - void toDt(dt_t** pdt) + override void toDt(dt_t** pdt) { //printf("TypeInfoPointerDeclaration::toDt()\n"); dtxoff(pdt, Type.typeinfopointer.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Pointer diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInfoSharedDeclaration.d --- a/dmd/TypeInfoSharedDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInfoSharedDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,18 +1,18 @@ -module dmd.TypeInfoSharedDeclaration; - -import dmd.Type; -import dmd.TypeInfoDeclaration; -import dmd.backend.dt_t; - +module dmd.TypeInfoSharedDeclaration; + +import dmd.Type; +import dmd.TypeInfoDeclaration; +import dmd.backend.dt_t; + class TypeInfoSharedDeclaration : TypeInfoDeclaration { this(Type tinfo) { - assert(false); + assert(false); super(tinfo, 0); } - void toDt(dt_t** pdt) + override void toDt(dt_t** pdt) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInfoStaticArrayDeclaration.d --- a/dmd/TypeInfoStaticArrayDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInfoStaticArrayDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -16,7 +16,7 @@ super(tinfo, 0); } - void toDt(dt_t** pdt) + override void toDt(dt_t** pdt) { //printf("TypeInfoStaticArrayDeclaration.toDt()\n"); dtxoff(pdt, Type.typeinfostaticarray.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray @@ -31,4 +31,4 @@ dtdword(pdt, cast(int)tc.dim.toInteger()); // length } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInfoStructDeclaration.d --- a/dmd/TypeInfoStructDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInfoStructDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,28 +1,28 @@ -module dmd.TypeInfoStructDeclaration; - -import dmd.Type; -import dmd.TY; -import dmd.MOD; -import dmd.Loc; -import dmd.Argument; -import dmd.STC; -import dmd.TypeStruct; -import dmd.TypeFunction; -import dmd.StructDeclaration; -import dmd.FuncDeclaration; -import dmd.Dsymbol; -import dmd.ArrayTypes; -import dmd.Scope; -import dmd.LINK; -import dmd.Id; -import dmd.TypeInfoDeclaration; -import dmd.backend.dt_t; -import dmd.backend.TYM; -import dmd.backend.Util; -import dmd.expression.Util; - -import std.string : toStringz; - +module dmd.TypeInfoStructDeclaration; + +import dmd.Type; +import dmd.TY; +import dmd.MOD; +import dmd.Loc; +import dmd.Argument; +import dmd.STC; +import dmd.TypeStruct; +import dmd.TypeFunction; +import dmd.StructDeclaration; +import dmd.FuncDeclaration; +import dmd.Dsymbol; +import dmd.ArrayTypes; +import dmd.Scope; +import dmd.LINK; +import dmd.Id; +import dmd.TypeInfoDeclaration; +import dmd.backend.dt_t; +import dmd.backend.TYM; +import dmd.backend.Util; +import dmd.expression.Util; + +import std.string : toStringz; + class TypeInfoStructDeclaration : TypeInfoDeclaration { this(Type tinfo) @@ -30,200 +30,200 @@ super(tinfo, 0); } - void toDt(dt_t** pdt) + override void toDt(dt_t** pdt) { - //printf("TypeInfoStructDeclaration.toDt() '%s'\n", toChars()); - - uint offset = Type.typeinfostruct.structsize; - - dtxoff(pdt, Type.typeinfostruct.toVtblSymbol(), 0, TYM.TYnptr); // vtbl for TypeInfo_Struct - dtdword(pdt, 0); // monitor - - assert(tinfo.ty == TY.Tstruct); - - TypeStruct tc = cast(TypeStruct)tinfo; - StructDeclaration sd = tc.sym; - - /* Put out: - * char[] name; - * void[] init; - * hash_t function(in void*) xtoHash; - * bool function(in void*, in void*) xopEquals; - * int function(in void*, in void*) xopCmp; - * string function(const(void)*) xtoString; - * uint m_flags; - * xgetMembers; - * xdtor; - * xpostblit; - * - * name[] - */ - - string name = sd.toPrettyChars(); - size_t namelen = name.length; - dtdword(pdt, namelen); - - //dtabytes(pdt, TYnptr, 0, namelen + 1, name); - dtxoff(pdt, toSymbol(), offset, TYM.TYnptr); - offset += namelen + 1; - - // void[] init; - dtdword(pdt, sd.structsize); // init.length - if (sd.zeroInit) - dtdword(pdt, 0); // null for 0 initialization - else - dtxoff(pdt, sd.toInitializer(), 0, TYM.TYnptr); // init.ptr - FuncDeclaration fd; - FuncDeclaration fdx; - TypeFunction tf; - Type ta; - Dsymbol s; - - static TypeFunction tftohash; - static TypeFunction tftostring; - - if (!tftohash) - { - scope Scope sc = new Scope(); - - tftohash = new TypeFunction(null, Type.thash_t, 0, LINK.LINKd); - tftohash.mod = MOD.MODconst; - tftohash = cast(TypeFunction)tftohash.semantic(Loc(0), sc); - - tftostring = new TypeFunction(null, Type.tchar.invariantOf().arrayOf(), 0, LINK.LINKd); - tftostring = cast(TypeFunction)tftostring.semantic(Loc(0), sc); - } - - TypeFunction tfeqptr; - { - // bool opEqual(const T*) const; - scope Scope sc = new Scope(); - Arguments arguments = new Arguments; - version (STRUCTTHISREF) { - // arg type is ref const T - Argument arg = new Argument(STC.STCref, tc.constOf(), null, null); - } else { - // arg type is const T* - Argument arg = new Argument(STC.STCin, tc.pointerTo(), null, null); - } - - arguments.push(cast(void*)arg); - tfeqptr = new TypeFunction(arguments, Type.tbool, 0, LINK.LINKd); - tfeqptr.mod = MOD.MODconst; - tfeqptr = cast(TypeFunction)tfeqptr.semantic(Loc(0), sc); - } - - TypeFunction tfcmpptr; - { - scope Scope sc = new Scope(); - Arguments arguments = new Arguments; - version (STRUCTTHISREF) { - // arg type is ref const T - Argument arg = new Argument(STC.STCref, tc.constOf(), null, null); - } else { - // arg type is const T* - Argument arg = new Argument(STC.STCin, tc.pointerTo(), null, null); - } - - arguments.push(cast(void*)arg); - tfcmpptr = new TypeFunction(arguments, Type.tint32, 0, LINK.LINKd); - tfcmpptr.mod = MOD.MODconst; - tfcmpptr = cast(TypeFunction)tfcmpptr.semantic(Loc(0), sc); - } - - s = search_function(sd, Id.tohash); - fdx = s ? s.isFuncDeclaration() : null; - if (fdx) - { - fd = fdx.overloadExactMatch(tftohash); - if (fd) - dtxoff(pdt, fd.toSymbol(), 0, TYM.TYnptr); - else - //fdx.error("must be declared as extern (D) uint toHash()"); - dtdword(pdt, 0); - } - else - dtdword(pdt, 0); - - s = search_function(sd, Id.eq); - fdx = s ? s.isFuncDeclaration() : null; - if (fdx) - { - //printf("test1 %s, %s, %s\n", fdx.toChars(), fdx.type.toChars(), tfeqptr.toChars()); - fd = fdx.overloadExactMatch(tfeqptr); - if (fd) - dtxoff(pdt, fd.toSymbol(), 0, TYM.TYnptr); - else - { - fd = fdx.overloadExactMatch(tfcmpptr); - if (fd) - fdx.error("must return bool, not int"); - //fdx.error("must be declared as extern (D) int %s(%s*)", fdx.toChars(), sd.toChars()); - dtdword(pdt, 0); - } - } - else - dtdword(pdt, 0); - - s = search_function(sd, Id.cmp); - fdx = s ? s.isFuncDeclaration() : null; - if (fdx) - { - //printf("test1 %s, %s, %s\n", fdx.toChars(), fdx.type.toChars(), tfeqptr.toChars()); - fd = fdx.overloadExactMatch(tfcmpptr); - if (fd) - { - dtxoff(pdt, fd.toSymbol(), 0, TYM.TYnptr); - //printf("test2\n"); - } - else - //fdx.error("must be declared as extern (D) int %s(%s*)", fdx.toChars(), sd.toChars()); - dtdword(pdt, 0); - } - else - dtdword(pdt, 0); - - s = search_function(sd, Id.tostring); - fdx = s ? s.isFuncDeclaration() : null; - if (fdx) - { - fd = fdx.overloadExactMatch(tftostring); - if (fd) - dtxoff(pdt, fd.toSymbol(), 0, TYM.TYnptr); - else - //fdx.error("must be declared as extern (D) char[] toString()"); - dtdword(pdt, 0); - } - else - dtdword(pdt, 0); - - // uint m_flags; - dtdword(pdt, tc.hasPointers()); - -version (DMDV2) { - // xgetMembers - FuncDeclaration sgetmembers = sd.findGetMembers(); - if (sgetmembers) - dtxoff(pdt, sgetmembers.toSymbol(), 0, TYM.TYnptr); - else - dtdword(pdt, 0); // xgetMembers - - // xdtor - FuncDeclaration sdtor = sd.dtor; - if (sdtor) - dtxoff(pdt, sdtor.toSymbol(), 0, TYM.TYnptr); - else - dtdword(pdt, 0); // xdtor - - // xpostblit - FuncDeclaration spostblit = sd.postblit; - if (spostblit) - dtxoff(pdt, spostblit.toSymbol(), 0, TYM.TYnptr); - else - dtdword(pdt, 0); // xpostblit -} - // name[] - dtnbytes(pdt, namelen + 1, toStringz(name)); + //printf("TypeInfoStructDeclaration.toDt() '%s'\n", toChars()); + + uint offset = Type.typeinfostruct.structsize; + + dtxoff(pdt, Type.typeinfostruct.toVtblSymbol(), 0, TYM.TYnptr); // vtbl for TypeInfo_Struct + dtdword(pdt, 0); // monitor + + assert(tinfo.ty == TY.Tstruct); + + TypeStruct tc = cast(TypeStruct)tinfo; + StructDeclaration sd = tc.sym; + + /* Put out: + * char[] name; + * void[] init; + * hash_t function(in void*) xtoHash; + * bool function(in void*, in void*) xopEquals; + * int function(in void*, in void*) xopCmp; + * string function(const(void)*) xtoString; + * uint m_flags; + * xgetMembers; + * xdtor; + * xpostblit; + * + * name[] + */ + + string name = sd.toPrettyChars(); + size_t namelen = name.length; + dtdword(pdt, namelen); + + //dtabytes(pdt, TYnptr, 0, namelen + 1, name); + dtxoff(pdt, toSymbol(), offset, TYM.TYnptr); + offset += namelen + 1; + + // void[] init; + dtdword(pdt, sd.structsize); // init.length + if (sd.zeroInit) + dtdword(pdt, 0); // null for 0 initialization + else + dtxoff(pdt, sd.toInitializer(), 0, TYM.TYnptr); // init.ptr + FuncDeclaration fd; + FuncDeclaration fdx; + TypeFunction tf; + Type ta; + Dsymbol s; + + static TypeFunction tftohash; + static TypeFunction tftostring; + + if (!tftohash) + { + scope Scope sc = new Scope(); + + tftohash = new TypeFunction(null, Type.thash_t, 0, LINK.LINKd); + tftohash.mod = MOD.MODconst; + tftohash = cast(TypeFunction)tftohash.semantic(Loc(0), sc); + + tftostring = new TypeFunction(null, Type.tchar.invariantOf().arrayOf(), 0, LINK.LINKd); + tftostring = cast(TypeFunction)tftostring.semantic(Loc(0), sc); + } + + TypeFunction tfeqptr; + { + // bool opEqual(const T*) const; + scope Scope sc = new Scope(); + Arguments arguments = new Arguments; + version (STRUCTTHISREF) { + // arg type is ref const T + Argument arg = new Argument(STC.STCref, tc.constOf(), null, null); + } else { + // arg type is const T* + Argument arg = new Argument(STC.STCin, tc.pointerTo(), null, null); + } + + arguments.push(cast(void*)arg); + tfeqptr = new TypeFunction(arguments, Type.tbool, 0, LINK.LINKd); + tfeqptr.mod = MOD.MODconst; + tfeqptr = cast(TypeFunction)tfeqptr.semantic(Loc(0), sc); + } + + TypeFunction tfcmpptr; + { + scope Scope sc = new Scope(); + Arguments arguments = new Arguments; + version (STRUCTTHISREF) { + // arg type is ref const T + Argument arg = new Argument(STC.STCref, tc.constOf(), null, null); + } else { + // arg type is const T* + Argument arg = new Argument(STC.STCin, tc.pointerTo(), null, null); + } + + arguments.push(cast(void*)arg); + tfcmpptr = new TypeFunction(arguments, Type.tint32, 0, LINK.LINKd); + tfcmpptr.mod = MOD.MODconst; + tfcmpptr = cast(TypeFunction)tfcmpptr.semantic(Loc(0), sc); + } + + s = search_function(sd, Id.tohash); + fdx = s ? s.isFuncDeclaration() : null; + if (fdx) + { + fd = fdx.overloadExactMatch(tftohash); + if (fd) + dtxoff(pdt, fd.toSymbol(), 0, TYM.TYnptr); + else + //fdx.error("must be declared as extern (D) uint toHash()"); + dtdword(pdt, 0); + } + else + dtdword(pdt, 0); + + s = search_function(sd, Id.eq); + fdx = s ? s.isFuncDeclaration() : null; + if (fdx) + { + //printf("test1 %s, %s, %s\n", fdx.toChars(), fdx.type.toChars(), tfeqptr.toChars()); + fd = fdx.overloadExactMatch(tfeqptr); + if (fd) + dtxoff(pdt, fd.toSymbol(), 0, TYM.TYnptr); + else + { + fd = fdx.overloadExactMatch(tfcmpptr); + if (fd) + fdx.error("must return bool, not int"); + //fdx.error("must be declared as extern (D) int %s(%s*)", fdx.toChars(), sd.toChars()); + dtdword(pdt, 0); + } + } + else + dtdword(pdt, 0); + + s = search_function(sd, Id.cmp); + fdx = s ? s.isFuncDeclaration() : null; + if (fdx) + { + //printf("test1 %s, %s, %s\n", fdx.toChars(), fdx.type.toChars(), tfeqptr.toChars()); + fd = fdx.overloadExactMatch(tfcmpptr); + if (fd) + { + dtxoff(pdt, fd.toSymbol(), 0, TYM.TYnptr); + //printf("test2\n"); + } + else + //fdx.error("must be declared as extern (D) int %s(%s*)", fdx.toChars(), sd.toChars()); + dtdword(pdt, 0); + } + else + dtdword(pdt, 0); + + s = search_function(sd, Id.tostring); + fdx = s ? s.isFuncDeclaration() : null; + if (fdx) + { + fd = fdx.overloadExactMatch(tftostring); + if (fd) + dtxoff(pdt, fd.toSymbol(), 0, TYM.TYnptr); + else + //fdx.error("must be declared as extern (D) char[] toString()"); + dtdword(pdt, 0); + } + else + dtdword(pdt, 0); + + // uint m_flags; + dtdword(pdt, tc.hasPointers()); + +version (DMDV2) { + // xgetMembers + FuncDeclaration sgetmembers = sd.findGetMembers(); + if (sgetmembers) + dtxoff(pdt, sgetmembers.toSymbol(), 0, TYM.TYnptr); + else + dtdword(pdt, 0); // xgetMembers + + // xdtor + FuncDeclaration sdtor = sd.dtor; + if (sdtor) + dtxoff(pdt, sdtor.toSymbol(), 0, TYM.TYnptr); + else + dtdword(pdt, 0); // xdtor + + // xpostblit + FuncDeclaration spostblit = sd.postblit; + if (spostblit) + dtxoff(pdt, spostblit.toSymbol(), 0, TYM.TYnptr); + else + dtdword(pdt, 0); // xpostblit +} + // name[] + dtnbytes(pdt, namelen + 1, toStringz(name)); } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInfoTupleDeclaration.d --- a/dmd/TypeInfoTupleDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInfoTupleDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -20,7 +20,7 @@ super(tinfo, 0); } - void toDt(dt_t **pdt) + override void toDt(dt_t **pdt) { //printf("TypeInfoTupleDeclaration.toDt() %s\n", tinfo.toChars()); dtxoff(pdt, Type.typeinfotypelist.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface @@ -49,4 +49,4 @@ dtxoff(pdt, s, 0, TYnptr); // elements.ptr } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInfoTypedefDeclaration.d --- a/dmd/TypeInfoTypedefDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInfoTypedefDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,17 +1,17 @@ -module dmd.TypeInfoTypedefDeclaration; - -import dmd.Type; +module dmd.TypeInfoTypedefDeclaration; + +import dmd.Type; import dmd.TypeInfoDeclaration; import dmd.TypedefDeclaration; import dmd.TypeTypedef; import dmd.TY; -import dmd.Loc; +import dmd.Loc; import dmd.backend.dt_t; import dmd.backend.TYM; -import dmd.backend.Util; +import dmd.backend.Util; import std.string; - + class TypeInfoTypedefDeclaration : TypeInfoDeclaration { this(Type tinfo) @@ -19,7 +19,7 @@ super(tinfo, 0); } - void toDt(dt_t** pdt) + override void toDt(dt_t** pdt) { //printf("TypeInfoTypedefDeclaration.toDt() %s\n", toChars()); diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeInstance.d --- a/dmd/TypeInstance.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeInstance.d Sat Aug 28 16:19:48 2010 +0200 @@ -44,7 +44,7 @@ } } - Type syntaxCopy() + override Type syntaxCopy() { //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.dim); TypeInstance t; @@ -59,7 +59,7 @@ //void toDecoBuffer(OutBuffer *buf, int flag); - 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); @@ -69,7 +69,7 @@ toCBuffer2Helper(buf, hgs); } - void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) + override void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) { // Note close similarity to TypeIdentifier::resolve() Dsymbol s; @@ -96,7 +96,7 @@ //printf("pt = '%s'\n", (*pt)->toChars()); } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { Type t; Expression e; @@ -130,7 +130,7 @@ return t; } - Dsymbol toDsymbol(Scope sc) + override Dsymbol toDsymbol(Scope sc) { Type t; Expression e; @@ -160,7 +160,7 @@ return s; } - MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) + override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { static if (0) { printf("TypeInstance::deduceType()\n"); diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeNext.d --- a/dmd/TypeNext.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeNext.d Sat Aug 28 16:19:48 2010 +0200 @@ -31,7 +31,7 @@ return cloneTo(new TypeNext(ty, next)); } } - void toDecoBuffer(OutBuffer buf, int flag) + override void toDecoBuffer(OutBuffer buf, int flag) { super.toDecoBuffer(buf, flag); assert(next !is this); @@ -39,24 +39,24 @@ next.toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); } - void checkDeprecated(Loc loc, Scope sc) + override void checkDeprecated(Loc loc, Scope sc) { Type.checkDeprecated(loc, sc); if (next) // next can be null if TypeFunction and auto return type next.checkDeprecated(loc, sc); } - Type reliesOnTident() + override Type reliesOnTident() { return next.reliesOnTident(); } - Type nextOf() + override Type nextOf() { return next; } - Type makeConst() + override Type makeConst() { //printf("TypeNext::makeConst() %p, %s\n", this, toChars()); if (cto) @@ -79,7 +79,7 @@ return t; } - Type makeInvariant() + override Type makeInvariant() { //printf("TypeNext::makeInvariant() %s\n", toChars()); if (ito) @@ -95,7 +95,7 @@ return t; } - Type makeShared() + override Type makeShared() { //printf("TypeNext::makeShared() %s\n", toChars()); if (sto) @@ -118,12 +118,12 @@ return t; } - Type makeSharedConst() + override Type makeSharedConst() { assert(false); } - MATCH constConv(Type to) + override MATCH constConv(Type to) { MATCH m = Type.constConv(to); @@ -138,4 +138,4 @@ */ next = next.addMod(mod); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypePointer.d --- a/dmd/TypePointer.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypePointer.d Sat Aug 28 16:19:48 2010 +0200 @@ -41,7 +41,7 @@ return cloneTo(new TypePointer(next)); } } - Type syntaxCopy() + override Type syntaxCopy() { Type t = next.syntaxCopy(); if (t == next) @@ -54,7 +54,7 @@ return t; } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { //printf("TypePointer.semantic()\n"); if (deco) @@ -78,12 +78,12 @@ return merge(); } - ulong size(Loc loc) + override ulong size(Loc loc) { return PTRSIZE; } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { //printf("TypePointer::toCBuffer2() next = %d\n", next->ty); if (mod != this.mod) @@ -96,7 +96,7 @@ buf.writeByte('*'); } - MATCH implicitConvTo(Type to) + override MATCH implicitConvTo(Type to) { //printf("TypePointer.implicitConvTo(to = %s) %s\n", to.toChars(), toChars()); @@ -134,12 +134,12 @@ return MATCH.MATCHnomatch; } - bool isscalar() + override bool isscalar() { return true; } - Expression defaultInit(Loc loc) + override Expression defaultInit(Loc loc) { version (LOGDEFAULTINIT) { printf("TypePointer::defaultInit() '%s'\n", toChars()); @@ -149,17 +149,17 @@ return e; } - bool isZeroInit(Loc loc) + override bool isZeroInit(Loc loc) { return true; } - TypeInfoDeclaration getTypeInfoDeclaration() + override TypeInfoDeclaration getTypeInfoDeclaration() { return new TypeInfoPointerDeclaration(this); } - bool hasPointers() + override bool hasPointers() { return true; } @@ -171,7 +171,7 @@ } } - type* toCtype() + override type* toCtype() { type* tn; type* t; @@ -197,4 +197,4 @@ ctype = t; return t; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeQualified.d --- a/dmd/TypeQualified.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeQualified.d Sat Aug 28 16:19:48 2010 +0200 @@ -83,7 +83,7 @@ } } - ulong size(Loc loc) + override ulong size(Loc loc) { assert(false); } @@ -268,4 +268,4 @@ error(loc, "identifier '%s' is not defined", toChars()); } } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeReference.d --- a/dmd/TypeReference.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeReference.d Sat Aug 28 16:19:48 2010 +0200 @@ -28,37 +28,37 @@ } } - Type syntaxCopy() + override Type syntaxCopy() { assert(false); } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { assert(false); } - ulong size(Loc loc) + override ulong size(Loc loc) { assert(false); } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { assert(false); } - Expression dotExp(Scope sc, Expression e, Identifier ident) + override Expression dotExp(Scope sc, Expression e, Identifier ident) { assert(false); } - Expression defaultInit(Loc loc) + override Expression defaultInit(Loc loc) { assert(false); } - bool isZeroInit(Loc loc) + override bool isZeroInit(Loc loc) { assert(false); } @@ -69,4 +69,4 @@ assert(false); } } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeReturn.d --- a/dmd/TypeReturn.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeReturn.d Sat Aug 28 16:19:48 2010 +0200 @@ -26,7 +26,7 @@ } } - Type syntaxCopy() + override Type syntaxCopy() { TypeReturn t = new TypeReturn(loc); t.syntaxCopyHelper(this); @@ -34,7 +34,7 @@ return t; } - Dsymbol toDsymbol(Scope sc) + override Dsymbol toDsymbol(Scope sc) { Type t = semantic(Loc(0), sc); if (t is this) @@ -43,7 +43,7 @@ return t.toDsymbol(sc); } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { Type t; if (!sc.func) @@ -86,8 +86,8 @@ return terror; } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeSArray.d --- a/dmd/TypeSArray.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeSArray.d Sat Aug 28 16:19:48 2010 +0200 @@ -64,7 +64,7 @@ } } - Type syntaxCopy() + override Type syntaxCopy() { Type t = next.syntaxCopy(); Expression e = dim.syntaxCopy(); @@ -73,7 +73,7 @@ return t; } - ulong size(Loc loc) + override ulong size(Loc loc) { if (!dim) return Type.size(loc); @@ -96,12 +96,12 @@ return 1; } - uint alignsize() + override uint alignsize() { return next.alignsize(); } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { //printf("TypeSArray.semantic() %s\n", toChars()); @@ -225,7 +225,7 @@ return merge(); } - void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) + override void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) { //printf("TypeSArray.resolve() %s\n", toChars()); next.resolve(loc, sc, pe, pt, ps); @@ -289,7 +289,7 @@ } } - void toDecoBuffer(OutBuffer buf, int flag) + override void toDecoBuffer(OutBuffer buf, int flag) { Type.toDecoBuffer(buf, flag); if (dim) @@ -304,7 +304,7 @@ next.toDecoBuffer(buf, (flag & 0x100) ? flag : mod); } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { if (mod != this.mod) { @@ -315,7 +315,7 @@ buf.printf("[%s]", dim.toChars()); } - Expression dotExp(Scope sc, Expression e, Identifier ident) + override Expression dotExp(Scope sc, Expression e, Identifier ident) { version (LOGDOTEXP) { printf("TypeSArray.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars()); @@ -335,28 +335,28 @@ return e; } - bool isString() + override bool isString() { TY nty = next.toBasetype().ty; return nty == Tchar || nty == Twchar || nty == Tdchar; } - bool isZeroInit(Loc loc) + override bool isZeroInit(Loc loc) { return next.isZeroInit(loc); } - uint memalign(uint salign) + override uint memalign(uint salign) { return next.memalign(salign); } - MATCH constConv(Type to) + override MATCH constConv(Type to) { assert(false); } - MATCH implicitConvTo(Type to) + override MATCH implicitConvTo(Type to) { //printf("TypeSArray.implicitConvTo(to = %s) this = %s\n", to.toChars(), toChars()); @@ -417,7 +417,7 @@ return MATCHnomatch; } - Expression defaultInit(Loc loc) + override Expression defaultInit(Loc loc) { version (LOGDEFAULTINIT) { printf("TypeSArray.defaultInit() '%s'\n", toChars()); @@ -425,7 +425,7 @@ return next.defaultInit(loc); } - dt_t** toDt(dt_t** pdt) + override dt_t** toDt(dt_t** pdt) { return toDtElem(pdt, null); } @@ -486,7 +486,7 @@ return pdt; } - MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) + override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { static if (false) { printf("TypeSArray.deduceType()\n"); @@ -581,17 +581,17 @@ return MATCHnomatch; } - TypeInfoDeclaration getTypeInfoDeclaration() + override TypeInfoDeclaration getTypeInfoDeclaration() { return new TypeInfoStaticArrayDeclaration(this); } - Expression toExpression() + override Expression toExpression() { assert(false); } - bool hasPointers() + override bool hasPointers() { return next.hasPointers(); } @@ -603,7 +603,7 @@ } } - type* toCtype() + override type* toCtype() { if (!ctype) { @@ -615,9 +615,9 @@ return ctype; } - type* toCParamtype() + override type* toCParamtype() { // arrays are passed as pointers return next.pointerTo().toCtype(); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeSlice.d --- a/dmd/TypeSlice.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeSlice.d Sat Aug 28 16:19:48 2010 +0200 @@ -42,14 +42,14 @@ } } - Type syntaxCopy() + override Type syntaxCopy() { Type t = new TypeSlice(next.syntaxCopy(), lwr.syntaxCopy(), upr.syntaxCopy()); t.mod = mod; return t; } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { //printf("TypeSlice.semantic() %s\n", toChars()); next = next.semantic(loc, sc); @@ -89,7 +89,7 @@ return new TypeTuple(args); } - void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) + override void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) { next.resolve(loc, sc, pe, pt, ps); if (*pe) @@ -155,8 +155,8 @@ } } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeStruct.d --- a/dmd/TypeStruct.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeStruct.d Sat Aug 28 16:19:48 2010 +0200 @@ -82,12 +82,12 @@ return cloneTo(new TypeStruct(sym)); } } - ulong size(Loc loc) + override ulong size(Loc loc) { return sym.size(loc); } - uint alignsize() + override uint alignsize() { uint sz; @@ -98,7 +98,7 @@ return sz; } - string toChars() + override string toChars() { //printf("sym.parent: %s, deco = %s\n", sym.parent.toChars(), deco); if (mod) @@ -111,12 +111,12 @@ return sym.toChars(); } - Type syntaxCopy() + override Type syntaxCopy() { assert(false); } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { //printf("TypeStruct.semantic('%s')\n", sym.toChars()); @@ -128,12 +128,12 @@ return merge(); } - Dsymbol toDsymbol(Scope sc) + override Dsymbol toDsymbol(Scope sc) { return sym; } - void toDecoBuffer(OutBuffer buf, int flag) + override void toDecoBuffer(OutBuffer buf, int flag) { string name = sym.mangle(); //printf("TypeStruct.toDecoBuffer('%s') = '%s'\n", toChars(), name); @@ -141,7 +141,7 @@ buf.printf("%s", name); } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { if (mod != this.mod) { @@ -155,7 +155,7 @@ buf.writestring(sym.toChars()); } - Expression dotExp(Scope sc, Expression e, Identifier ident) + override Expression dotExp(Scope sc, Expression e, Identifier ident) { uint offset; @@ -402,13 +402,13 @@ return de.semantic(sc); } - uint memalign(uint salign) + override uint memalign(uint salign) { sym.size(Loc(0)); // give error for forward references return sym.structalign; } - Expression defaultInit(Loc loc) + override Expression defaultInit(Loc loc) { Symbol* s; Declaration d; @@ -423,12 +423,12 @@ return new VarExp(sym.loc, d); } - bool isZeroInit(Loc loc) + override bool isZeroInit(Loc loc) { return sym.zeroInit; } - int isAssignable() + override int isAssignable() { /* If any of the fields are const or invariant, * then one cannot assign this struct. @@ -442,18 +442,18 @@ return true; } - bool checkBoolean() + override bool checkBoolean() { return false; } - dt_t** toDt(dt_t** pdt) + override dt_t** toDt(dt_t** pdt) { sym.toDt(pdt); return pdt; } - MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) + override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { //printf("TypeStruct.deduceType()\n"); //printf("\tthis.parent = %s, ", sym.parent.toChars()); print(); @@ -506,12 +506,12 @@ return Type.deduceType(sc, tparam, parameters, dedtypes); } - TypeInfoDeclaration getTypeInfoDeclaration() + override TypeInfoDeclaration getTypeInfoDeclaration() { return new TypeInfoStructDeclaration(this); } - bool hasPointers() + override bool hasPointers() { StructDeclaration s = sym; @@ -527,7 +527,7 @@ return false; } - MATCH implicitConvTo(Type to) + override MATCH implicitConvTo(Type to) { MATCH m; @@ -579,7 +579,7 @@ return m; } - MATCH constConv(Type to) + override MATCH constConv(Type to) { if (equals(to)) return MATCHexact; @@ -588,7 +588,7 @@ return MATCHnomatch; } - Type toHeadMutable() + override Type toHeadMutable() { assert(false); } @@ -600,7 +600,7 @@ } } - type* toCtype() + override type* toCtype() { type* t; Symbol* s; @@ -644,4 +644,4 @@ //printf("t = %p, Tflags = x%x\n", t, t.Tflags); return t; } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeTuple.d --- a/dmd/TypeTuple.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeTuple.d Sat Aug 28 16:19:48 2010 +0200 @@ -70,7 +70,7 @@ this.arguments = arguments; } - Type syntaxCopy() + override Type syntaxCopy() { Arguments args = Argument.arraySyntaxCopy(arguments); Type t = new TypeTuple(args); @@ -78,7 +78,7 @@ return t; } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { //printf("TypeTuple::semantic(this = %p)\n", this); //printf("TypeTuple::semantic() %s\n", toChars()); @@ -91,7 +91,7 @@ return this; } - bool equals(Object o) + override bool equals(Object o) { Type t; @@ -119,7 +119,7 @@ return 0; } - Type reliesOnTident() + override Type reliesOnTident() { if (arguments) { @@ -134,12 +134,12 @@ return null; } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { Argument.argsToCBuffer(buf, hgs, arguments, 0); } - void toDecoBuffer(OutBuffer buf, int flag) + override void toDecoBuffer(OutBuffer buf, int flag) { //printf("TypeTuple::toDecoBuffer() this = %p, %s\n", this, toChars()); Type.toDecoBuffer(buf, flag); @@ -150,7 +150,7 @@ buf.printf("%d%s", len, buf2.extractString()); } - Expression getProperty(Loc loc, Identifier ident) + override Expression getProperty(Loc loc, Identifier ident) { Expression e; @@ -169,7 +169,7 @@ return e; } - TypeInfoDeclaration getTypeInfoDeclaration() + override TypeInfoDeclaration getTypeInfoDeclaration() { return new TypeInfoTupleDeclaration(this); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeTypedef.d --- a/dmd/TypeTypedef.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeTypedef.d Sat Aug 28 16:19:48 2010 +0200 @@ -40,46 +40,46 @@ } } - Type syntaxCopy() + override Type syntaxCopy() { assert(false); } - ulong size(Loc loc) + override ulong size(Loc loc) { return sym.basetype.size(loc); } - uint alignsize() + override uint alignsize() { assert(false); } - string toChars() + override string toChars() { assert(false); } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { //printf("TypeTypedef::semantic(%s), sem = %d\n", toChars(), sym->sem); sym.semantic(sc); return merge(); } - Dsymbol toDsymbol(Scope sc) + override Dsymbol toDsymbol(Scope sc) { return sym; } - void toDecoBuffer(OutBuffer buf, int flag) + override void toDecoBuffer(OutBuffer buf, int flag) { Type.toDecoBuffer(buf, flag); string name = sym.mangle(); buf.printf("%s", name); } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { //printf("TypeTypedef.toCBuffer2() '%s'\n", sym.toChars()); if (mod != this.mod) @@ -91,7 +91,7 @@ buf.writestring(sym.toChars()); } - Expression dotExp(Scope sc, Expression e, Identifier ident) + override Expression dotExp(Scope sc, Expression e, Identifier ident) { version (LOGDOTEXP) { printf("TypeTypedef.dotExp(e = '%s', ident = '%s') '%s'\n", e.toChars(), ident.toChars(), toChars()); @@ -103,7 +103,7 @@ return sym.basetype.dotExp(sc, e, ident); } - Expression getProperty(Loc loc, Identifier ident) + override Expression getProperty(Loc loc, Identifier ident) { version (LOGDOTEXP) { printf("TypeTypedef.getProperty(ident = '%s') '%s'\n", ident.toChars(), toChars()); @@ -120,7 +120,7 @@ assert(false); } - bool isintegral() + override bool isintegral() { //printf("TypeTypedef::isintegral()\n"); //printf("sym = '%s'\n", sym->toChars()); @@ -128,47 +128,47 @@ return sym.basetype.isintegral(); } - bool isfloating() + override bool isfloating() { return sym.basetype.isfloating(); } - bool isreal() + override bool isreal() { return sym.basetype.isreal(); } - bool isimaginary() + override bool isimaginary() { return sym.basetype.isimaginary(); } - bool iscomplex() + override bool iscomplex() { return sym.basetype.iscomplex(); } - bool isscalar() + override bool isscalar() { return sym.basetype.isscalar(); } - bool isunsigned() + override bool isunsigned() { return sym.basetype.isunsigned(); } - bool checkBoolean() + override bool checkBoolean() { return sym.basetype.checkBoolean(); } - int isAssignable() + override int isAssignable() { return sym.basetype.isAssignable(); } - Type toBasetype() + override Type toBasetype() { if (sym.inuse) { @@ -183,7 +183,7 @@ return t; } - MATCH implicitConvTo(Type to) + override MATCH implicitConvTo(Type to) { MATCH m; @@ -201,7 +201,7 @@ return m; } - MATCH constConv(Type to) + override MATCH constConv(Type to) { if (equals(to)) return MATCHexact; @@ -210,7 +210,7 @@ return MATCHnomatch; } - Expression defaultInit(Loc loc) + override Expression defaultInit(Loc loc) { Expression e; Type bt; @@ -235,7 +235,7 @@ return e; } - bool isZeroInit(Loc loc) + override bool isZeroInit(Loc loc) { if (sym.init) { @@ -259,7 +259,7 @@ return result; } - dt_t** toDt(dt_t** pdt) + override dt_t** toDt(dt_t** pdt) { if (sym.init) { @@ -275,7 +275,7 @@ return pdt; } - MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) + override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { // Extra check if (tparam && tparam.ty == Ttypedef) @@ -288,17 +288,17 @@ return Type.deduceType(sc, tparam, parameters, dedtypes); } - TypeInfoDeclaration getTypeInfoDeclaration() + override TypeInfoDeclaration getTypeInfoDeclaration() { return new TypeInfoTypedefDeclaration(this); } - bool hasPointers() + override bool hasPointers() { return toBasetype().hasPointers(); } - Type toHeadMutable() + override Type toHeadMutable() { assert(false); } @@ -310,13 +310,13 @@ } } - type* toCtype() + override type* toCtype() { return sym.basetype.toCtype(); } - type* toCParamtype() + override type* toCParamtype() { return sym.basetype.toCParamtype(); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeTypeof.d --- a/dmd/TypeTypeof.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeTypeof.d Sat Aug 28 16:19:48 2010 +0200 @@ -32,7 +32,7 @@ } } - Type syntaxCopy() + override Type syntaxCopy() { //printf("TypeTypeof.syntaxCopy() %s\n", toChars()); TypeTypeof t; @@ -43,7 +43,7 @@ return t; } - Dsymbol toDsymbol(Scope sc) + override Dsymbol toDsymbol(Scope sc) { Type t = semantic(loc, sc); if (t is this) @@ -52,7 +52,7 @@ return t.toDsymbol(sc); } - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { if (mod != this.mod) { @@ -65,7 +65,7 @@ toCBuffer2Helper(buf, hgs); } - Type semantic(Loc loc, Scope sc) + override Type semantic(Loc loc, Scope sc) { Expression e; Type t; @@ -174,8 +174,8 @@ return tvoid; } - ulong size(Loc loc) + override ulong size(Loc loc) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypedefDeclaration.d --- a/dmd/TypedefDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypedefDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -57,12 +57,12 @@ assert(false); } } - Dsymbol syntaxCopy(Dsymbol) + override Dsymbol syntaxCopy(Dsymbol) { assert(false); } - void semantic(Scope sc) + override void semantic(Scope sc) { //printf("TypedefDeclaration::semantic(%s) sem = %d\n", toChars(), sem); if (sem == 0) @@ -81,7 +81,7 @@ } } - void semantic2(Scope sc) + override void semantic2(Scope sc) { //printf("TypedefDeclaration::semantic2(%s) sem = %d\n", toChars(), sem); if (sem == 2) @@ -101,23 +101,23 @@ } } - string mangle() + override string mangle() { //printf("TypedefDeclaration::mangle() '%s'\n", toChars()); return Dsymbol.mangle(); } - string kind() + override string kind() { assert(false); } - Type getType() + override Type getType() { return type; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } @@ -127,12 +127,12 @@ Type hbasetype; } - void toDocBuffer(OutBuffer buf) + override void toDocBuffer(OutBuffer buf) { assert(false); } - void toObjFile(int multiobj) // compile to .obj file + override void toObjFile(int multiobj) // compile to .obj file { //printf("TypedefDeclaration::toObjFile('%s')\n", toChars()); if (global.params.symdebug) @@ -170,12 +170,12 @@ assert(false); } - int cvMember(ubyte* p) + override int cvMember(ubyte* p) { assert(false); } - TypedefDeclaration isTypedefDeclaration() { return this; } + override TypedefDeclaration isTypedefDeclaration() { return this; } Symbol* sinit; Symbol* toInitializer() diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/TypeidExp.d --- a/dmd/TypeidExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/TypeidExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,13 +1,13 @@ -module dmd.TypeidExp; - -import dmd.Expression; -import dmd.Type; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.HdrGenState; -import dmd.TOK; - +module dmd.TypeidExp; + +import dmd.Expression; +import dmd.Type; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.HdrGenState; +import dmd.TOK; + class TypeidExp : Expression { Type typeidType; @@ -17,20 +17,20 @@ super(loc, TOK.TOKtypeid, TypeidExp.sizeof); this.typeidType = typeidType; } - -version (DumbClone) { -} else { - Type clone() - { - assert(false); - } + +version (DumbClone) { +} else { + Type clone() + { + assert(false); + } } - Expression syntaxCopy() + override Expression syntaxCopy() { return new TypeidExp(loc, typeidType.syntaxCopy()); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -44,7 +44,7 @@ return e; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/UAddExp.d --- a/dmd/UAddExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/UAddExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,39 +1,39 @@ -module dmd.UAddExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.UnaExp; -import dmd.Loc; -import dmd.Scope; -import dmd.TOK; - -class UAddExp : UnaExp -{ - this(Loc loc, Expression e) - { - super(loc, TOK.TOKuadd, this.sizeof, e); - } - - Expression semantic(Scope sc) - { - Expression e; - - version (LOGSEMANTIC) { - printf("UAddExp.semantic('%s')\n", toChars()); - } - assert(!type); - UnaExp.semantic(sc); - e1 = resolveProperties(sc, e1); - e = op_overload(sc); - if (e) - return e; - e1.checkNoBool(); - e1.checkArithmetic(); - return e1; - } - - Identifier opId() - { - assert(false); - } -} +module dmd.UAddExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.UnaExp; +import dmd.Loc; +import dmd.Scope; +import dmd.TOK; + +class UAddExp : UnaExp +{ + this(Loc loc, Expression e) + { + super(loc, TOK.TOKuadd, this.sizeof, e); + } + + override Expression semantic(Scope sc) + { + Expression e; + + version (LOGSEMANTIC) { + printf("UAddExp.semantic('%s')\n", toChars()); + } + assert(!type); + UnaExp.semantic(sc); + e1 = resolveProperties(sc, e1); + e = op_overload(sc); + if (e) + return e; + e1.checkNoBool(); + e1.checkArithmetic(); + return e1; + } + + override Identifier opId() + { + assert(false); + } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/UnaExp.d --- a/dmd/UnaExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/UnaExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,76 +1,76 @@ -module dmd.UnaExp; - -import dmd.Expression; -import dmd.InterState; -import dmd.TY; -import dmd.TypeClass; -import dmd.TypeStruct; -import dmd.Dsymbol; -import dmd.AggregateDeclaration; -import dmd.Type; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.TOK; -import dmd.Scope; -import dmd.InlineCostState; -import dmd.InlineDoState; -import dmd.HdrGenState; -import dmd.InlineScanState; -import dmd.DotIdExp; -import dmd.ArrayExp; -import dmd.CallExp; -import dmd.PREC; -import dmd.Token; -import dmd.expression.Util; - +module dmd.UnaExp; + +import dmd.Expression; +import dmd.InterState; +import dmd.TY; +import dmd.TypeClass; +import dmd.TypeStruct; +import dmd.Dsymbol; +import dmd.AggregateDeclaration; +import dmd.Type; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.TOK; +import dmd.Scope; +import dmd.InlineCostState; +import dmd.InlineDoState; +import dmd.HdrGenState; +import dmd.InlineScanState; +import dmd.DotIdExp; +import dmd.ArrayExp; +import dmd.CallExp; +import dmd.PREC; +import dmd.Token; +import dmd.expression.Util; + class UnaExp : Expression { Expression e1; this(Loc loc, TOK op, int size, Expression e1) { - super(loc, op, size); + super(loc, op, size); this.e1 = e1; } - Expression syntaxCopy() + override Expression syntaxCopy() { - UnaExp e = cast(UnaExp)copy(); - e.type = null; - e.e1 = e.e1.syntaxCopy(); - + UnaExp e = cast(UnaExp)copy(); + e.type = null; + e.e1 = e.e1.syntaxCopy(); + return e; } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { -version (LOGSEMANTIC) { - writef("UnaExp.semantic('%s')\n", toChars()); -} - e1 = e1.semantic(sc); - // if (!e1.type) - // error("%s has no value", e1.toChars()); +version (LOGSEMANTIC) { + writef("UnaExp.semantic('%s')\n", toChars()); +} + e1 = e1.semantic(sc); + // if (!e1.type) + // error("%s has no value", e1.toChars()); return this; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - buf.writestring(Token.toChars(op)); + buf.writestring(Token.toChars(op)); expToCBuffer(buf, hgs, e1, precedence[op]); } - Expression optimize(int result) + override Expression optimize(int result) { - e1 = e1.optimize(result); + e1 = e1.optimize(result); return this; } - void dump(int indent) + override void dump(int indent) { assert(false); } - void scanForNestedRef(Scope sc) + override void scanForNestedRef(Scope sc) { e1.scanForNestedRef(sc); } @@ -80,89 +80,89 @@ assert(false); } - bool canThrow() + override bool canThrow() { return e1.canThrow(); } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { return 1 + e1.inlineCost(ics); } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { - UnaExp ue = cast(UnaExp)copy(); - - ue.e1 = e1.doInline(ids); + UnaExp ue = cast(UnaExp)copy(); + + ue.e1 = e1.doInline(ids); return ue; } - Expression inlineScan(InlineScanState* iss) + override Expression inlineScan(InlineScanState* iss) { - e1 = e1.inlineScan(iss); + e1 = e1.inlineScan(iss); return this; - } - - /************************************ - * Operator overload. - * Check for operator overload, if so, replace - * with function call. - * Return null if not an operator overload. + } + + /************************************ + * Operator overload. + * Check for operator overload, if so, replace + * with function call. + * Return null if not an operator overload. */ Expression op_overload(Scope sc) { - //printf("UnaExp.op_overload() (%s)\n", toChars()); - AggregateDeclaration ad; - Dsymbol fd; - Type t1 = e1.type.toBasetype(); - - if (t1.ty == TY.Tclass) - { - ad = (cast(TypeClass)t1).sym; - goto L1; - } - else if (t1.ty == TY.Tstruct) - { - ad = (cast(TypeStruct)t1).sym; - - L1: - fd = search_function(ad, opId()); - if (fd) - { - if (op == TOK.TOKarray) - { - /* Rewrite op e1[arguments] as: - * e1.fd(arguments) - */ - Expression e = new DotIdExp(loc, e1, fd.ident); - ArrayExp ae = cast(ArrayExp)this; - e = new CallExp(loc, e, ae.arguments); - e = e.semantic(sc); - return e; - } - else - { - // Rewrite +e1 as e1.add() - return build_overload(loc, sc, e1, null, fd.ident); - } - } - -version (DMDV2) { - // Didn't find it. Forward to aliasthis - if (ad.aliasthis) - { - /* Rewrite op(e1) as: - * op(e1.aliasthis) - */ - Expression e1 = new DotIdExp(loc, this.e1, ad.aliasthis.ident); - Expression e = copy(); - (cast(UnaExp)e).e1 = e1; - e = e.semantic(sc); - return e; - } -} - } + //printf("UnaExp.op_overload() (%s)\n", toChars()); + AggregateDeclaration ad; + Dsymbol fd; + Type t1 = e1.type.toBasetype(); + + if (t1.ty == TY.Tclass) + { + ad = (cast(TypeClass)t1).sym; + goto L1; + } + else if (t1.ty == TY.Tstruct) + { + ad = (cast(TypeStruct)t1).sym; + + L1: + fd = search_function(ad, opId()); + if (fd) + { + if (op == TOK.TOKarray) + { + /* Rewrite op e1[arguments] as: + * e1.fd(arguments) + */ + Expression e = new DotIdExp(loc, e1, fd.ident); + ArrayExp ae = cast(ArrayExp)this; + e = new CallExp(loc, e, ae.arguments); + e = e.semantic(sc); + return e; + } + else + { + // Rewrite +e1 as e1.add() + return build_overload(loc, sc, e1, null, fd.ident); + } + } + +version (DMDV2) { + // Didn't find it. Forward to aliasthis + if (ad.aliasthis) + { + /* Rewrite op(e1) as: + * op(e1.aliasthis) + */ + Expression e1 = new DotIdExp(loc, this.e1, ad.aliasthis.ident); + Expression e = copy(); + (cast(UnaExp)e).e1 = e1; + e = e.semantic(sc); + return e; + } +} + } return null; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/UnionDeclaration.d --- a/dmd/UnionDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/UnionDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -12,7 +12,7 @@ super(loc, id); } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { UnionDeclaration ud; @@ -24,10 +24,10 @@ return ud; } - string kind() + override string kind() { return "union"; } - UnionDeclaration isUnionDeclaration() { return this; } + override UnionDeclaration isUnionDeclaration() { return this; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/UnitTestDeclaration.d --- a/dmd/UnitTestDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/UnitTestDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -32,7 +32,7 @@ super(loc, endloc, unitTestId(), STC.STCundefined, null); } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { UnitTestDeclaration utd; @@ -42,7 +42,7 @@ return FuncDeclaration.syntaxCopy(utd); } - void semantic(Scope sc) + override void semantic(Scope sc) { if (global.params.useUnitTests) { @@ -63,30 +63,30 @@ m.needmoduleinfo = 1; } - AggregateDeclaration isThis() + override AggregateDeclaration isThis() { return null; } - bool isVirtual() + override bool isVirtual() { return false; } - bool addPreInvariant() + override bool addPreInvariant() { return false; } - bool addPostInvariant() + override bool addPostInvariant() { return false; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - UnitTestDeclaration isUnitTestDeclaration() { return this; } -} \ No newline at end of file + override UnitTestDeclaration isUnitTestDeclaration() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/UnrolledLoopStatement.d --- a/dmd/UnrolledLoopStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/UnrolledLoopStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,156 +1,156 @@ -module dmd.UnrolledLoopStatement; - -import dmd.Expression; -import dmd.Statement; -import dmd.InterState; -import dmd.ArrayTypes; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.InlineCostState; -import dmd.InlineDoState; -import dmd.IRState; -import dmd.HdrGenState; +module dmd.UnrolledLoopStatement; + +import dmd.Expression; +import dmd.Statement; +import dmd.InterState; +import dmd.ArrayTypes; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.InlineCostState; +import dmd.InlineDoState; +import dmd.IRState; +import dmd.HdrGenState; import dmd.InlineScanState; -import dmd.BE; - -import dmd.backend.BC; -import dmd.backend.Blockx; -import dmd.backend.block; -import dmd.backend.Util; - +import dmd.BE; + +import dmd.backend.BC; +import dmd.backend.Blockx; +import dmd.backend.block; +import dmd.backend.Util; + class UnrolledLoopStatement : Statement { Statements statements; this(Loc loc, Statements s) { - super(loc); + super(loc); statements = s; } - Statement syntaxCopy() + override Statement syntaxCopy() { assert(false); } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { - //printf("UnrolledLoopStatement.semantic(this = %p, sc = %p)\n", this, sc); - - sc.noctor++; - Scope scd = sc.push(); - scd.sbreak = this; - scd.scontinue = this; - - for (size_t i = 0; i < statements.dim; i++) - { - Statement s = cast(Statement) statements.data[i]; - if (s) - { - s = s.semantic(scd); - statements.data[i] = cast(void*)s; - } - } - - scd.pop(); - sc.noctor--; + //printf("UnrolledLoopStatement.semantic(this = %p, sc = %p)\n", this, sc); + + sc.noctor++; + Scope scd = sc.push(); + scd.sbreak = this; + scd.scontinue = this; + + for (size_t i = 0; i < statements.dim; i++) + { + Statement s = cast(Statement) statements.data[i]; + if (s) + { + s = s.semantic(scd); + statements.data[i] = cast(void*)s; + } + } + + scd.pop(); + sc.noctor--; return this; } - bool hasBreak() + override bool hasBreak() { assert(false); } - bool hasContinue() + override bool hasContinue() { assert(false); } - bool usesEH() + override bool usesEH() { assert(false); } - BE blockExit() + override BE blockExit() { - BE result = BEfallthru; - for (size_t i = 0; i < statements.dim; i++) - { - Statement s = cast(Statement) statements.data[i]; - if (s) - { - int r = s.blockExit(); - result |= r & ~(BEbreak | BEcontinue); - } - } + BE result = BEfallthru; + for (size_t i = 0; i < statements.dim; i++) + { + Statement s = cast(Statement) statements.data[i]; + if (s) + { + int r = s.blockExit(); + result |= r & ~(BEbreak | BEcontinue); + } + } return result; } - bool comeFrom() + override bool comeFrom() { assert(false); } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { assert(false); } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { assert(false); } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { assert(false); } - void toIR(IRState* irs) + override void toIR(IRState* irs) { - Blockx* blx = irs.blx; - - IRState mystate = IRState(irs, this); - mystate.breakBlock = block_calloc(blx); - - block* bpre = blx.curblock; - block_next(blx, BCgoto, null); - - block* bdo = blx.curblock; - list_append(&bpre.Bsucc, bdo); - - block* bdox; - - size_t dim = statements.dim; - for (size_t i = 0 ; i < dim ; i++) - { - Statement s = cast(Statement)statements.data[i]; - if (s !is null) - { - mystate.contBlock = block_calloc(blx); - - s.toIR(&mystate); - - bdox = blx.curblock; - block_next(blx, BCgoto, mystate.contBlock); - list_append(&bdox.Bsucc, mystate.contBlock); - } - } - - bdox = blx.curblock; - block_next(blx, BCgoto, mystate.breakBlock); + Blockx* blx = irs.blx; + + IRState mystate = IRState(irs, this); + mystate.breakBlock = block_calloc(blx); + + block* bpre = blx.curblock; + block_next(blx, BCgoto, null); + + block* bdo = blx.curblock; + list_append(&bpre.Bsucc, bdo); + + block* bdox; + + size_t dim = statements.dim; + for (size_t i = 0 ; i < dim ; i++) + { + Statement s = cast(Statement)statements.data[i]; + if (s !is null) + { + mystate.contBlock = block_calloc(blx); + + s.toIR(&mystate); + + bdox = blx.curblock; + block_next(blx, BCgoto, mystate.contBlock); + list_append(&bdox.Bsucc, mystate.contBlock); + } + } + + bdox = blx.curblock; + block_next(blx, BCgoto, mystate.breakBlock); list_append(&bdox.Bsucc, mystate.breakBlock); } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/UshrAssignExp.d --- a/dmd/UshrAssignExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/UshrAssignExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -20,7 +20,7 @@ super(loc, TOK.TOKushrass, UshrAssignExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -42,18 +42,18 @@ return this; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - Identifier opId() /* For operator overloading */ + override Identifier opId() /* For operator overloading */ { return Id.ushrass; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/UshrExp.d --- a/dmd/UshrExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/UshrExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,25 +1,25 @@ -module dmd.UshrExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.InterState; -import dmd.Loc; +module dmd.UshrExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.InterState; +import dmd.Loc; import dmd.Scope; -import dmd.Id; -import dmd.IntRange; -import dmd.IRState; -import dmd.BinExp; +import dmd.Id; +import dmd.IntRange; +import dmd.IRState; +import dmd.BinExp; import dmd.TOK; -import dmd.Type; - +import dmd.Type; + import dmd.backend.elem; import dmd.backend.OPER; import dmd.backend.TYFL; import dmd.backend.Util; import dmd.expression.Util; import dmd.expression.Ushr; -import dmd.expression.shift_optimize; - +import dmd.expression.shift_optimize; + class UshrExp : BinExp { this(Loc loc, Expression e1, Expression e2) @@ -27,7 +27,7 @@ super(loc, TOK.TOKushr, UshrExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -46,33 +46,33 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { //printf("UshrExp.optimize(result = %d) %s\n", result, toChars()); return shift_optimize(result, this, &Ushr); } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - IntRange getIntRange() + override IntRange getIntRange() { assert(false); } - Identifier opId() + override Identifier opId() { return Id.ushr; } - Identifier opId_r() + override Identifier opId_r() { return Id.ushr_r; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { elem *eleft = e1.toElem(irs); eleft.Ety = touns(eleft.Ety); diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/VarDeclaration.d --- a/dmd/VarDeclaration.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/VarDeclaration.d Sat Aug 28 16:19:48 2010 +0200 @@ -108,7 +108,7 @@ nestedrefs = new FuncDeclarations(); } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { //printf("VarDeclaration.syntaxCopy(%s)\n", toChars()); @@ -156,7 +156,7 @@ return sv; } - void semantic(Scope sc) + override void semantic(Scope sc) { static if (false) { printf("VarDeclaration.semantic('%s', parent = '%s')\n", toChars(), sc.parent.toChars()); @@ -648,7 +648,7 @@ } } - void semantic2(Scope sc) + override void semantic2(Scope sc) { //printf("VarDeclaration.semantic2('%s')\n", toChars()); if (init && !toParent().isFuncDeclaration()) @@ -667,12 +667,12 @@ } } - string kind() + override string kind() { return "variable"; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { StorageClassDeclaration.stcToCBuffer(buf, storage_class); @@ -702,13 +702,13 @@ Type htype; Initializer hinit; } - bool needThis() + override bool needThis() { //printf("VarDeclaration.needThis(%s, x%x)\n", toChars(), storage_class); return (storage_class & STC.STCfield) != 0; } - bool isImportedSymbol() + override bool isImportedSymbol() { if (protection == PROT.PROTexport && !init && (storage_class & STC.STCstatic || parent.isModule())) return true; @@ -716,7 +716,7 @@ return false; } - bool isDataseg() + override bool isDataseg() { static if (false) { printf("VarDeclaration.isDataseg(%p, '%s')\n", this, toChars()); @@ -737,7 +737,7 @@ return canTakeAddressOf() && (storage_class & (STC.STCstatic | STC.STCextern | STC.STCtls | STC.STCgshared) || toParent().isModule() || toParent().isTemplateInstance()); } - bool isThreadlocal() + override bool isThreadlocal() { //printf("VarDeclaration.isThreadlocal(%p, '%s')\n", this, toChars()); static if (false) { /// || TARGET_OSX @@ -755,7 +755,7 @@ } } - bool hasPointers() + override bool hasPointers() { //printf("VarDeclaration.hasPointers() %s, ty = %d\n", toChars(), type.ty); return (!isDataseg() && type.hasPointers()); @@ -927,7 +927,7 @@ return null; } - void checkCtorConstInit() + override void checkCtorConstInit() { static if (false) { /* doesn't work if more than one static ctor */ if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield)) @@ -978,14 +978,14 @@ } } - Dsymbol toAlias() + override Dsymbol toAlias() { //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym); assert(this !is aliassym); return aliassym ? aliassym.toAlias() : this; } - Symbol* toSymbol() + override Symbol* toSymbol() { //printf("VarDeclaration.toSymbol(%s)\n", toChars()); //if (needThis()) *(char*)0=0; @@ -1097,7 +1097,7 @@ return csym; } - void toObjFile(int multiobj) // compile to .obj file + override void toObjFile(int multiobj) // compile to .obj file { Symbol* s; uint sz; @@ -1231,11 +1231,11 @@ } } - int cvMember(ubyte* p) + override int cvMember(ubyte* p) { assert(false); } // Eliminate need for dynamic_cast - VarDeclaration isVarDeclaration() { return this; } + override VarDeclaration isVarDeclaration() { return this; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/VarExp.d --- a/dmd/VarExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/VarExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,264 +1,264 @@ -module dmd.VarExp; - -import dmd.Expression; -import dmd.Declaration; -import dmd.InterState; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.InlineCostState; -import dmd.FuncLiteralDeclaration; -import dmd.VarDeclaration; -import dmd.Dsymbol; -import dmd.FuncDeclaration; -import dmd.InlineDoState; -import dmd.HdrGenState; -import dmd.TOK; -import dmd.TY; -import dmd.STC; -import dmd.SymbolExp; -import dmd.Type; -import dmd.interpret.Util; -import dmd.backend.dt_t; -import dmd.expression.Util; - -// Variable - +module dmd.VarExp; + +import dmd.Expression; +import dmd.Declaration; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.InlineCostState; +import dmd.FuncLiteralDeclaration; +import dmd.VarDeclaration; +import dmd.Dsymbol; +import dmd.FuncDeclaration; +import dmd.InlineDoState; +import dmd.HdrGenState; +import dmd.TOK; +import dmd.TY; +import dmd.STC; +import dmd.SymbolExp; +import dmd.Type; +import dmd.interpret.Util; +import dmd.backend.dt_t; +import dmd.expression.Util; + +// Variable + class VarExp : SymbolExp { this(Loc loc, Declaration var, int hasOverloads = 0) { - super(loc, TOK.TOKvar, VarExp.sizeof, var, hasOverloads); - - //printf("VarExp(this = %p, '%s', loc = %s)\n", this, var.toChars(), loc.toChars()); - //if (strcmp(var.ident.toChars(), "func") == 0) halt(); + super(loc, TOK.TOKvar, VarExp.sizeof, var, hasOverloads); + + //printf("VarExp(this = %p, '%s', loc = %s)\n", this, var.toChars(), loc.toChars()); + //if (strcmp(var.ident.toChars(), "func") == 0) halt(); this.type = var.type; } - bool equals(Object o) + override bool equals(Object o) { assert(false); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { - FuncLiteralDeclaration fd; - - version (LOGSEMANTIC) { - printf("VarExp.semantic(%s)\n", toChars()); - } - if (!type) - { - type = var.type; -static if (false) { - if (var.storage_class & STC.STClazy) - { - TypeFunction tf = new TypeFunction(null, type, 0, LINK.LINKd); - type = new TypeDelegate(tf); - type = type.semantic(loc, sc); - } -} - } - - /* Fix for 1161 doesn't work because it causes protection - * problems when instantiating imported templates passing private - * variables as alias template parameters. - */ - //accessCheck(loc, sc, null, var); - - VarDeclaration v = var.isVarDeclaration(); - if (v) - { -static if (false) { - if ((v.isConst() || v.isInvariant()) && type.toBasetype().ty != TY.Tsarray && v.init) - { - ExpInitializer ei = v.init.isExpInitializer(); - if (ei) - { - //ei.exp.implicitCastTo(sc, type).print(); - return ei.exp.implicitCastTo(sc, type); - } - } -} - v.checkNestedReference(sc, loc); -version (DMDV2) { - static if (true) { - if (sc.func) - { - /* Determine if sc.func is pure or if any function that - * encloses it is also pure. - */ - bool hasPureParent = false; - for (FuncDeclaration outerfunc = sc.func; outerfunc;) - { - if (outerfunc.isPure()) - { - hasPureParent = true; - break; - } - Dsymbol parent = outerfunc.toParent2(); - if (!parent) - break; - outerfunc = parent.isFuncDeclaration(); - } - - /* If ANY of its enclosing functions are pure, - * it cannot do anything impure. - * If it is pure, it cannot access any mutable variables other - * than those inside itself - */ - if (hasPureParent && !sc.intypeof && v.isDataseg() && !v.isInvariant()) - { - error("pure function '%s' cannot access mutable static data '%s'", - sc.func.toChars(), v.toChars()); - } - else if (sc.func.isPure() && sc.parent != v.parent && !sc.intypeof && !v.isInvariant() && !(v.storage_class & STC.STCmanifest)) - { - error("pure nested function '%s' cannot access mutable data '%s'", sc.func.toChars(), v.toChars()); - if (v.isEnumDeclaration()) - error("enum"); - } - } - } else { - if (sc.func && sc.func.isPure() && !sc.intypeof) - { - if (v.isDataseg() && !v.isInvariant()) - error("pure function '%s' cannot access mutable static data '%s'", sc.func.toChars(), v.toChars()); - } - } -} - } - else - { -static if (false) { - if ((fd = var.isFuncLiteralDeclaration()) !is null) - { - Expression e = new FuncExp(loc, fd); - e.type = type; - return e; - } -} - } - + FuncLiteralDeclaration fd; + + version (LOGSEMANTIC) { + printf("VarExp.semantic(%s)\n", toChars()); + } + if (!type) + { + type = var.type; +static if (false) { + if (var.storage_class & STC.STClazy) + { + TypeFunction tf = new TypeFunction(null, type, 0, LINK.LINKd); + type = new TypeDelegate(tf); + type = type.semantic(loc, sc); + } +} + } + + /* Fix for 1161 doesn't work because it causes protection + * problems when instantiating imported templates passing private + * variables as alias template parameters. + */ + //accessCheck(loc, sc, null, var); + + VarDeclaration v = var.isVarDeclaration(); + if (v) + { +static if (false) { + if ((v.isConst() || v.isInvariant()) && type.toBasetype().ty != TY.Tsarray && v.init) + { + ExpInitializer ei = v.init.isExpInitializer(); + if (ei) + { + //ei.exp.implicitCastTo(sc, type).print(); + return ei.exp.implicitCastTo(sc, type); + } + } +} + v.checkNestedReference(sc, loc); +version (DMDV2) { + static if (true) { + if (sc.func) + { + /* Determine if sc.func is pure or if any function that + * encloses it is also pure. + */ + bool hasPureParent = false; + for (FuncDeclaration outerfunc = sc.func; outerfunc;) + { + if (outerfunc.isPure()) + { + hasPureParent = true; + break; + } + Dsymbol parent = outerfunc.toParent2(); + if (!parent) + break; + outerfunc = parent.isFuncDeclaration(); + } + + /* If ANY of its enclosing functions are pure, + * it cannot do anything impure. + * If it is pure, it cannot access any mutable variables other + * than those inside itself + */ + if (hasPureParent && !sc.intypeof && v.isDataseg() && !v.isInvariant()) + { + error("pure function '%s' cannot access mutable static data '%s'", + sc.func.toChars(), v.toChars()); + } + else if (sc.func.isPure() && sc.parent != v.parent && !sc.intypeof && !v.isInvariant() && !(v.storage_class & STC.STCmanifest)) + { + error("pure nested function '%s' cannot access mutable data '%s'", sc.func.toChars(), v.toChars()); + if (v.isEnumDeclaration()) + error("enum"); + } + } + } else { + if (sc.func && sc.func.isPure() && !sc.intypeof) + { + if (v.isDataseg() && !v.isInvariant()) + error("pure function '%s' cannot access mutable static data '%s'", sc.func.toChars(), v.toChars()); + } + } +} + } + else + { +static if (false) { + if ((fd = var.isFuncLiteralDeclaration()) !is null) + { + Expression e = new FuncExp(loc, fd); + e.type = type; + return e; + } +} + } + return this; } - Expression optimize(int result) + override Expression optimize(int result) { return fromConstInitializer(result, this); } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { -version (LOG) { - printf("VarExp.interpret() %.*s\n", toChars()); -} +version (LOG) { + printf("VarExp.interpret() %.*s\n", toChars()); +} return getVarExp(loc, istate, var); } - void dump(int indent) + override void dump(int indent) { assert(false); } - string toChars() + override string toChars() { return var.toChars(); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { buf.writestring(var.toChars()); } - void checkEscape() + override void checkEscape() { - VarDeclaration v = var.isVarDeclaration(); - if (v) - { - Type tb = v.type.toBasetype(); - // if reference type - if (tb.ty == TY.Tarray || tb.ty == TY.Tsarray || tb.ty == TY.Tclass) - { - if ((v.isAuto() || v.isScope()) && !v.noauto) - error("escaping reference to scope local %s", v.toChars()); - else if (v.storage_class & STC.STCvariadic) - error("escaping reference to variadic parameter %s", v.toChars()); - } + VarDeclaration v = var.isVarDeclaration(); + if (v) + { + Type tb = v.type.toBasetype(); + // if reference type + if (tb.ty == TY.Tarray || tb.ty == TY.Tsarray || tb.ty == TY.Tclass) + { + if ((v.isAuto() || v.isScope()) && !v.noauto) + error("escaping reference to scope local %s", v.toChars()); + else if (v.storage_class & STC.STCvariadic) + error("escaping reference to variadic parameter %s", v.toChars()); + } } } - + version (DMDV2) { - int isLvalue() + override int isLvalue() { - if (var.storage_class & STClazy) - return 0; + if (var.storage_class & STClazy) + return 0; return 1; } } - Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression e) { -static if (false) { - tym = tybasic(e1.ET.Tty); - if (!(tyscalar(tym) || - tym == TYM.TYstruct || - tym == TYM.TYarray && e.Eoper == TOK.TOKaddr)) - { - synerr(EM_lvalue); // lvalue expected - } -} - if (var.storage_class & STC.STClazy) - error("lazy variables cannot be lvalues"); - +static if (false) { + tym = tybasic(e1.ET.Tty); + if (!(tyscalar(tym) || + tym == TYM.TYstruct || + tym == TYM.TYarray && e.Eoper == TOK.TOKaddr)) + { + synerr(EM_lvalue); // lvalue expected + } +} + if (var.storage_class & STC.STClazy) + error("lazy variables cannot be lvalues"); + return this; } - Expression modifiableLvalue(Scope sc, Expression e) + 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()); - - var.checkModify(loc, sc, type); - - // See if this expression is a modifiable lvalue (i.e. not const) + //printf("VarExp::modifiableLvalue('%s')\n", var.toChars()); + if (type && type.toBasetype().ty == TY.Tsarray) + error("cannot change reference to static array '%s'", var.toChars()); + + var.checkModify(loc, sc, type); + + // See if this expression is a modifiable lvalue (i.e. not const) return toLvalue(sc, e); } - dt_t** toDt(dt_t** pdt) + override dt_t** toDt(dt_t** pdt) { assert(false); } - void scanForNestedRef(Scope sc) + override void scanForNestedRef(Scope sc) { - //printf("VarExp.scanForNestedRef(%s)\n", toChars()); - VarDeclaration v = var.isVarDeclaration(); - if (v) + //printf("VarExp.scanForNestedRef(%s)\n", toChars()); + VarDeclaration v = var.isVarDeclaration(); + if (v) v.checkNestedReference(sc, Loc(0)); } - int inlineCost(InlineCostState* ics) + override int inlineCost(InlineCostState* ics) { - //printf("VarExp.inlineCost() %s\n", toChars()); + //printf("VarExp.inlineCost() %s\n", toChars()); return 1; } - Expression doInline(InlineDoState ids) + override Expression doInline(InlineDoState ids) { - int i; - - //printf("VarExp.doInline(%s)\n", toChars()); - for (i = 0; i < ids.from.dim; i++) - { - if (var == cast(Declaration)ids.from.data[i]) - { - VarExp ve = cast(VarExp)copy(); - - ve.var = cast(Declaration)ids.to.data[i]; - return ve; - } - } + int i; + + //printf("VarExp.doInline(%s)\n", toChars()); + for (i = 0; i < ids.from.dim; i++) + { + if (var == cast(Declaration)ids.from.data[i]) + { + VarExp ve = cast(VarExp)copy(); + + ve.var = cast(Declaration)ids.to.data[i]; + return ve; + } + } return this; } } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/VersionCondition.d --- a/dmd/VersionCondition.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/VersionCondition.d Sat Aug 28 16:19:48 2010 +0200 @@ -104,7 +104,7 @@ super(mod, level, ident); } - final bool include(Scope sc, ScopeDsymbol s) + override final bool include(Scope sc, ScopeDsymbol s) { //printf("VersionCondition::include() level = %d, versionlevel = %d\n", level, global.params.versionlevel); //if (ident) printf("\tident = '%s'\n", ident->toChars()); @@ -129,7 +129,7 @@ return (inc == 1); } - final void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override final void toCBuffer(OutBuffer buf, HdrGenState* hgs) { if (ident !is null) { buf.printf("version (%s)", ident.toChars()); @@ -137,4 +137,4 @@ buf.printf("version (%u)", level); } } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/VersionSymbol.d --- a/dmd/VersionSymbol.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/VersionSymbol.d Sat Aug 28 16:19:48 2010 +0200 @@ -34,12 +34,12 @@ this.loc = loc; } - Dsymbol syntaxCopy(Dsymbol s) + override Dsymbol syntaxCopy(Dsymbol s) { assert(false); } - bool addMember(Scope sc, ScopeDsymbol s, bool memnum) + override bool addMember(Scope sc, ScopeDsymbol s, bool memnum) { //printf("VersionSymbol::addMember('%s') %s\n", sd->toChars(), toChars()); @@ -71,17 +71,17 @@ return false; } - void semantic(Scope sc) + override void semantic(Scope sc) { } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - string kind() + override string kind() { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/VoidInitializer.d --- a/dmd/VoidInitializer.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/VoidInitializer.d Sat Aug 28 16:19:48 2010 +0200 @@ -20,29 +20,29 @@ super(loc); } - Initializer syntaxCopy() + override Initializer syntaxCopy() { return new VoidInitializer(loc); } - Initializer semantic(Scope sc, Type t) + override Initializer semantic(Scope sc, Type t) { //printf("VoidInitializer.semantic(t = %p)\n", t); type = t; return this; } - Expression toExpression() + override Expression toExpression() { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - dt_t* toDt() + override dt_t* toDt() { /* Void initializers are set to 0, just because we need something * to set them to in the static data segment. @@ -53,5 +53,5 @@ return dt; } - VoidInitializer isVoidInitializer() { return this; } -} \ No newline at end of file + override VoidInitializer isVoidInitializer() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/VolatileStatement.d --- a/dmd/VolatileStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/VolatileStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -26,19 +26,19 @@ this.statement = statement; } - Statement syntaxCopy() + override Statement syntaxCopy() { assert(false); } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { if (statement) statement = statement.semantic(sc); return this; } - Statements flatten(Scope sc) + override Statements flatten(Scope sc) { Statements a = statement ? statement.flatten(sc) : null; if (a) @@ -55,24 +55,24 @@ return a; } - BE blockExit() + override BE blockExit() { return statement ? statement.blockExit() : BE.BEfallthru; } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { if (statement) statement = statement.inlineScan(iss); return this; } - void toIR(IRState* irs) + override void toIR(IRState* irs) { block* b; @@ -96,4 +96,4 @@ } } } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/WhileStatement.d --- a/dmd/WhileStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/WhileStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -24,13 +24,13 @@ body_ = b; } - Statement syntaxCopy() + override Statement syntaxCopy() { WhileStatement s = new WhileStatement(loc, condition.syntaxCopy(), body_ ? body_.syntaxCopy() : null); return s; } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { /* Rewrite as a for(;condition;) loop */ @@ -40,48 +40,48 @@ return s; } - bool hasBreak() + override bool hasBreak() { return true; } - bool hasContinue() + override bool hasContinue() { assert(false); } - bool usesEH() + override bool usesEH() { assert(false); } - BE blockExit() + override BE blockExit() { assert(false); } - bool comeFrom() + override bool comeFrom() { assert(false); } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { assert(false); } - void toIR(IRState* irs) + override void toIR(IRState* irs) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/WithScopeSymbol.d --- a/dmd/WithScopeSymbol.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/WithScopeSymbol.d Sat Aug 28 16:19:48 2010 +0200 @@ -15,10 +15,10 @@ assert(false); } - Dsymbol search(Loc loc, Identifier ident, int flags) + override Dsymbol search(Loc loc, Identifier ident, int flags) { assert(false); } - WithScopeSymbol isWithScopeSymbol() { return this; } -} \ No newline at end of file + override WithScopeSymbol isWithScopeSymbol() { return this; } +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/WithStatement.d --- a/dmd/WithStatement.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/WithStatement.d Sat Aug 28 16:19:48 2010 +0200 @@ -25,38 +25,38 @@ wthis = null; } - Statement syntaxCopy() + override Statement syntaxCopy() { assert(false); } - Statement semantic(Scope sc) + override Statement semantic(Scope sc) { assert(false); } - void toCBuffer(OutBuffer buf, HdrGenState* hgs) + override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } - bool usesEH() + override bool usesEH() { assert(false); } - BE blockExit() + override BE blockExit() { assert(false); } - Statement inlineScan(InlineScanState* iss) + override Statement inlineScan(InlineScanState* iss) { assert(false); } - void toIR(IRState* irs) + override void toIR(IRState* irs) { assert(false); } -} \ No newline at end of file +} diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/XorAssignExp.d --- a/dmd/XorAssignExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/XorAssignExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -21,32 +21,32 @@ super(loc, TOK.TOKxorass, this.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { return commonSemanticAssignIntegral(sc); } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { AssignExp_buildArrayIdent(buf, arguments, "Xor"); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { assert(false); } - Identifier opId() /* For operator overloading */ + override Identifier opId() /* For operator overloading */ { return Id.xorass; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs,OPxorass); } diff -r 8e24ef1dd139 -r 2e2a5c3f943a dmd/XorExp.d --- a/dmd/XorExp.d Sat Aug 28 16:14:07 2010 +0200 +++ b/dmd/XorExp.d Sat Aug 28 16:19:48 2010 +0200 @@ -1,26 +1,26 @@ -module dmd.XorExp; - -import dmd.Expression; -import dmd.Identifier; -import dmd.InterState; +module dmd.XorExp; + +import dmd.Expression; +import dmd.Identifier; +import dmd.InterState; import dmd.MATCH; -import dmd.Id; -import dmd.Type; -import dmd.OutBuffer; -import dmd.Loc; -import dmd.Scope; -import dmd.IntRange; -import dmd.IRState; -import dmd.ArrayTypes; -import dmd.BinExp; +import dmd.Id; +import dmd.Type; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.IntRange; +import dmd.IRState; +import dmd.ArrayTypes; +import dmd.BinExp; import dmd.TOK; -import dmd.TY; - -import dmd.backend.elem; +import dmd.TY; + +import dmd.backend.elem; import dmd.backend.OPER; import dmd.expression.Util; -import dmd.expression.Xor; - +import dmd.expression.Xor; + class XorExp : BinExp { this(Loc loc, Expression e1, Expression e2) @@ -28,7 +28,7 @@ super(loc, TOK.TOKxor, XorExp.sizeof, e1, e2); } - Expression semantic(Scope sc) + override Expression semantic(Scope sc) { Expression e; @@ -57,7 +57,7 @@ return this; } - Expression optimize(int result) + override Expression optimize(int result) { Expression e; @@ -71,62 +71,62 @@ return e; } - Expression interpret(InterState istate) + override Expression interpret(InterState istate) { assert(false); } - void buildArrayIdent(OutBuffer buf, Expressions arguments) + override void buildArrayIdent(OutBuffer buf, Expressions arguments) { Exp_buildArrayIdent(buf, arguments, "Xor"); } - Expression buildArrayLoop(Arguments fparams) + override Expression buildArrayLoop(Arguments fparams) { - /* Evaluate assign expressions left to right - */ - Expression ex1 = e1.buildArrayLoop(fparams); - Expression ex2 = e2.buildArrayLoop(fparams); - Expression e = new XorExp(Loc(0), ex1, ex2); + /* Evaluate assign expressions left to right + */ + Expression ex1 = e1.buildArrayLoop(fparams); + Expression ex2 = e2.buildArrayLoop(fparams); + Expression e = new XorExp(Loc(0), ex1, ex2); return e; } - MATCH implicitConvTo(Type t) + override MATCH implicitConvTo(Type t) { - MATCH result = Expression.implicitConvTo(t); - - if (result == MATCHnomatch) - { - MATCH m1 = e1.implicitConvTo(t); - MATCH m2 = e2.implicitConvTo(t); - - // Pick the worst match - result = (m1 < m2) ? m1 : m2; - } + MATCH result = Expression.implicitConvTo(t); + + if (result == MATCHnomatch) + { + MATCH m1 = e1.implicitConvTo(t); + MATCH m2 = e2.implicitConvTo(t); + + // Pick the worst match + result = (m1 < m2) ? m1 : m2; + } return result; } - IntRange getIntRange() + override IntRange getIntRange() { assert(false); } - bool isCommutative() + override bool isCommutative() { return true; } - Identifier opId() + override Identifier opId() { return Id.ixor; } - Identifier opId_r() + override Identifier opId_r() { return Id.ixor_r; } - elem* toElem(IRState* irs) + override elem* toElem(IRState* irs) { return toElemBin(irs,OPxor); }