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)