diff dmd/expression/Util.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 ea6325d0edd9
line wrap: on
line diff
--- a/dmd/expression/Util.d	Sat Sep 11 13:03:39 2010 +0100
+++ b/dmd/expression/Util.d	Mon Sep 13 22:19:42 2010 +0100
@@ -594,12 +594,12 @@
  *	3. do default promotions on arguments corresponding to ...
  *	4. add hidden _arguments[] argument
  *	5. call copy constructor for struct value arguments
+ * Returns:
+ *	return type from function
  */
 
-void functionParameters(Loc loc, Scope sc, TypeFunction tf, Expressions arguments)
+Type functionParameters(Loc loc, Scope sc, TypeFunction tf, Expressions arguments)
 {
-	uint n;
-
     //printf("functionParameters()\n");
     assert(arguments);
     size_t nargs = arguments ? arguments.dim : 0;
@@ -608,8 +608,10 @@
     if (nargs > nparams && tf.varargs == 0)
 	error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf.toChars());
 
-    n = (nargs > nparams) ? nargs : nparams;	// n = max(nargs, nparams)
+    uint n = (nargs > nparams) ? nargs : nparams;	// n = max(nargs, nparams)
 
+    uint wildmatch = 0;
+    
     int done = 0;
     for (size_t i = 0; i < n; i++)
     {
@@ -634,7 +636,7 @@
 						goto L2;
 
 					error(loc, "expected %d function arguments, not %d", nparams, nargs);
-					return;
+					return tf.next;
 				}
 				arg = p.defaultArg;
 				arg = arg.copy();
@@ -654,7 +656,7 @@
 					if (nargs != nparams)
 					{
 						error(loc, "expected %zu function arguments, not %zu", nparams, nargs);
-						return;
+						return tf.next;
 					}
 					goto L1;
 				}
@@ -680,6 +682,7 @@
 						Type t = new TypeSArray((cast(TypeArray)tb).next, new IntegerExp(nargs - i));
 						t = t.semantic(loc, sc);
 						VarDeclaration v = new VarDeclaration(loc, t, id, new VoidInitializer(loc));
+			            v.storage_class |= STCctfe;
 						v.semantic(sc);
 						v.parent = sc.parent;
 						//sc.insert(v);
@@ -729,7 +732,7 @@
 						if (!arg)
 						{   
 							error(loc, "not enough arguments");
-							return;
+							return tf.next;
 						}
 						break;
 				}
@@ -748,7 +751,25 @@
 					//printf("arg.type = %s, p.type = %s\n", arg.type.toChars(), p.type.toChars());
 					if (arg.op == TOKtype)
 						arg.error("cannot pass type %s as function argument", arg.toChars());
-					arg = arg.implicitCastTo(sc, p.type);
+		            if (p.type.isWild() && tf.next.isWild())
+		            {	
+                        Type t = p.type;
+			            MATCH m = arg.implicitConvTo(t);
+			            if (m == MATCH.MATCHnomatch)
+			            {
+                            t = t.constOf();
+			                m = arg.implicitConvTo(t);
+			                if (m == MATCHnomatch)
+			                {
+                                t = t.sharedConstOf();
+				                m = arg.implicitConvTo(t);
+			                }
+			                wildmatch |= p.type.wildMatch(arg.type);
+			            }
+			            arg = arg.implicitCastTo(sc, t);
+		            }
+		            else
+    					arg = arg.implicitCastTo(sc, p.type);
 					arg = arg.optimize(WANT.WANTvalue);
 				}
 			}
@@ -848,14 +869,9 @@
 				TypeSArray ts = cast(TypeSArray)tb;
 				Type ta = ts.next.arrayOf();
 				if (ts.size(arg.loc) == 0)
-				{   
-					arg = new NullExp(arg.loc);
-					arg.type = ta;
-				}
+					arg = new NullExp(arg.loc, ta);
 				else
-				{
 					arg = arg.castTo(sc, ta);
-				}
 			}
 version (DMDV2) {
 			if (tb.ty == Tstruct)
@@ -893,6 +909,24 @@
 		auto e = createTypeInfoArray(sc, &arguments[nparams], arguments.dim - nparams);
 		arguments.insert(0, e);
     }
+    
+    Type tret = tf.next;
+    if (wildmatch)
+    {	/* Adjust function return type based on wildmatch
+	 */
+	    //printf("wildmatch = x%x\n", wildmatch);
+	    assert(tret.isWild());
+	    if (wildmatch & MOD.MODconst || wildmatch & (wildmatch - 1))
+	        tret = tret.constOf();
+	    else if (wildmatch & MOD.MODimmutable)
+	        tret = tret.invariantOf();
+	    else
+	    {
+            assert(wildmatch & MOD.MODmutable);
+	        tret = tret.mutableOf();
+	    }
+    }
+    return tret;
 }
 
 /******************************
@@ -1256,7 +1290,7 @@
     if (!v)
 		return e;
 
-    if (v.isConst() || v.isInvariant() || v.storage_class & STC.STCmanifest)
+    if (v.isConst() || v.isImmutable() || v.storage_class & STC.STCmanifest)
     {
 		if (!v.type)
 		{
@@ -1403,6 +1437,7 @@
 			break;
     }
 
+    Dsymbol s;
     AggregateDeclaration ad;
 
     auto arg = arguments[0];
@@ -1449,6 +1484,10 @@
 			goto Laggr;
 
 		Laggr:
+	        s = search_function(ad, (op == TOKforeach_reverse) ? Id.applyReverse : Id.apply);
+	        if (s)
+		        goto Lapply;			// prefer opApply
+
 			if (arguments.dim == 1)
 			{
 				if (!arg.type)
@@ -1456,11 +1495,11 @@
 					/* Look for a head() or rear() overload
 					 */
 					Identifier id = (op == TOK.TOKforeach) ? Id.Fhead : Id.Ftoe;
-					Dsymbol s = search_function(ad, id);
-					FuncDeclaration fd = s ? s.isFuncDeclaration() : null;
+					Dsymbol s1 = search_function(ad, id);
+					FuncDeclaration fd = s1 ? s1.isFuncDeclaration() : null;
 					if (!fd)
 					{	
-						if (s && s.isTemplateDeclaration())
+						if (s1 && s1.isTemplateDeclaration())
 							break;
 						goto Lapply;
 					}
@@ -1474,7 +1513,6 @@
 			 *	int opApply(int delegate(ref Type [, ...]) dg);
 			 * overload
 			 */
-			Dsymbol s = search_function(ad, (op == TOK.TOKforeach_reverse) ? Id.applyReverse : Id.apply);
 			if (s)
 			{
 				FuncDeclaration fd = s.isFuncDeclaration();