Mercurial > projects > ddmd
diff dmd/ForeachStatement.d @ 135:af1bebfd96a4 dmd2037
dmd 2.038
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Mon, 13 Sep 2010 22:19:42 +0100 |
parents | 60bb0fe4563e |
children | 94b6033c07f3 |
line wrap: on
line diff
--- a/dmd/ForeachStatement.d Sat Sep 11 13:03:39 2010 +0100 +++ b/dmd/ForeachStatement.d Mon Sep 13 22:19:42 2010 +0100 @@ -115,6 +115,7 @@ Statement s = this; size_t dim = arguments.dim; TypeAArray taa = null; + Dsymbol sapply = null; Type tn = null; Type tnv = null; @@ -255,6 +256,9 @@ sc.noctor++; Lagain: + Identifier idapply = (op == TOK.TOKforeach_reverse) + ? Id.applyReverse : Id.apply; + sapply = null; switch (tab.ty) { case TY.Tarray: @@ -445,6 +449,15 @@ case TY.Tclass: case TY.Tstruct: version (DMDV2) { + /* Prefer using opApply, if it exists + */ + if (dim != 1) // only one argument allowed with ranges + goto Lapply; + + sapply = search_function(cast(AggregateDeclaration)tab.toDsymbol(sc), idapply); + if (sapply) + goto Lapply; + { /* Look for range iteration, i.e. the properties * .empty, .next, .retreat, .head and .rear * foreach (e; aggr) { ... } @@ -454,9 +467,6 @@ * ... * } */ - if (dim != 1) // only one argument allowed with ranges - goto Lapply; - AggregateDeclaration ad = (tab.ty == TY.Tclass) ? cast(AggregateDeclaration)(cast(TypeClass)tab).sym : cast(AggregateDeclaration)(cast(TypeStruct)tab).sym; @@ -531,16 +541,9 @@ case TY.Tdelegate: Lapply: { - FuncDeclaration fdapply; - Parameters args; Expression ec; Expression e; - FuncLiteralDeclaration fld; Parameter a; - Type t; - Expression flde; - Identifier id; - Type tret; if (!checkForArgTypes()) { @@ -548,7 +551,7 @@ return this; } - tret = func.type.nextOf(); + Type tret = func.type.nextOf(); // Need a variable to hold value from any return statements in body. if (!sc.func.vresult && tret && tret != Type.tvoid) @@ -566,10 +569,11 @@ /* Turn body into the function literal: * int delegate(ref T arg) { body } */ - args = new Parameters(); + auto args = new Parameters(); for (size_t i = 0; i < dim; i++) { auto arg = arguments[i]; + Identifier id; arg.type = arg.type.semantic(loc, sc); if (arg.storageClass & STC.STCref) @@ -577,28 +581,25 @@ else { // Make a copy of the ref argument so it isn't // a reference. - VarDeclaration v; - Initializer ie; - id = Lexer.uniqueId("__applyArg", i); - ie = new ExpInitializer(Loc(0), new IdentifierExp(Loc(0), id)); - v = new VarDeclaration(Loc(0), arg.type, arg.ident, ie); + Initializer ie = new ExpInitializer(Loc(0), new IdentifierExp(Loc(0), id)); + auto v = new VarDeclaration(Loc(0), arg.type, arg.ident, ie); s = new DeclarationStatement(Loc(0), v); body_ = new CompoundStatement(loc, s, body_); } a = new Parameter(STC.STCref, arg.type, id, null); args.push(a); } - t = new TypeFunction(args, Type.tint32, 0, LINK.LINKd); - fld = new FuncLiteralDeclaration(loc, Loc(0), t, TOK.TOKdelegate, this); + Type t = new TypeFunction(args, Type.tint32, 0, LINK.LINKd); + FuncLiteralDeclaration fld = new FuncLiteralDeclaration(loc, Loc(0), t, TOK.TOKdelegate, this); fld.fbody = body_; - flde = new FuncExp(loc, fld); + Expression flde = new FuncExp(loc, fld); flde = flde.semantic(sc); fld.tookAddressOf = 0; // Resolve any forward referenced goto's - for (int i = 0; i < gotos.dim; i++) + for (size_t i = 0; i < gotos.dim; i++) { auto cs = cast(CompoundStatement)gotos.data[i]; auto gs = cast(GotoStatement)cs.statements[0]; @@ -631,6 +632,7 @@ /* Call: * _aaApply(aggr, keysize, flde) */ + FuncDeclaration fdapply; if (dim == 2) fdapply = FuncDeclaration.genCfunc(Type.tindex, "_aaApply2"); else @@ -674,7 +676,7 @@ string r = (op == TOK.TOKforeach_reverse) ? "R" : ""; int j = sprintf(fdname.ptr, "_aApply%.*s%.*s%zd".ptr, r, 2, fntab[flag].ptr, dim); assert(j < fdname.sizeof); - fdapply = FuncDeclaration.genCfunc(Type.tindex, fdname[0..j].idup); + FuncDeclaration fdapply = FuncDeclaration.genCfunc(Type.tindex, fdname[0..j].idup); ec = new VarExp(Loc(0), fdapply); auto exps = new Expressions(); @@ -700,10 +702,9 @@ else { assert(tab.ty == TY.Tstruct || tab.ty == TY.Tclass); - Identifier idapply = (op == TOK.TOKforeach_reverse) - ? Id.applyReverse : Id.apply; - Dsymbol sapply = search_function(cast(AggregateDeclaration)tab.toDsymbol(sc), idapply); - Expressions exps = new Expressions(); + auto exps = new Expressions(); + if (!sapply) + sapply = search_function(cast(AggregateDeclaration)tab.toDsymbol(sc), idapply); static if (false) { TemplateDeclaration td; if (sapply && (td = sapply.isTemplateDeclaration()) !is null)