Mercurial > projects > ddmd
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();