comparison dmd/expression/Util.d @ 130:60bb0fe4563e

dmdfe 2.037 first main iteration
author Eldar Insafutdinov <e.insafutdinov@gmail.com>
date Thu, 09 Sep 2010 22:51:44 +0100
parents 010eb8f0e18d
children af1bebfd96a4
comparison
equal deleted inserted replaced
129:010eb8f0e18d 130:60bb0fe4563e
22 import dmd.STC; 22 import dmd.STC;
23 import dmd.WANT; 23 import dmd.WANT;
24 import dmd.IndexExp; 24 import dmd.IndexExp;
25 import dmd.AssignExp; 25 import dmd.AssignExp;
26 import dmd.CommaExp; 26 import dmd.CommaExp;
27 import dmd.Argument; 27 import dmd.CondExp;
28 import dmd.Parameter;
28 import dmd.DefaultInitExp; 29 import dmd.DefaultInitExp;
29 import dmd.Identifier; 30 import dmd.Identifier;
30 import dmd.Dsymbol; 31 import dmd.Dsymbol;
31 import dmd.Global; 32 import dmd.Global;
32 import dmd.ScopeDsymbol; 33 import dmd.ScopeDsymbol;
62 import dmd.PREC; 63 import dmd.PREC;
63 import dmd.Util; 64 import dmd.Util;
64 import dmd.TypeAArray; 65 import dmd.TypeAArray;
65 import dmd.Id; 66 import dmd.Id;
66 import dmd.PtrExp; 67 import dmd.PtrExp;
68 import dmd.ErrorExp;
67 69
68 import std.stdio : writef; 70 import std.stdio : writef;
69 71
70 import core.stdc.math; 72 import core.stdc.math;
71 import core.stdc.string; 73 import core.stdc.string;
186 */ 188 */
187 189
188 struct Param2 190 struct Param2
189 { 191 {
190 Match* m; 192 Match* m;
193 version(DMDV2) {
191 Expression ethis; 194 Expression ethis;
195 int property; // 0: unintialized
196 // 1: seen @property
197 // 2: not @property
198 }
192 Expressions arguments; 199 Expressions arguments;
193 200
194 int fp2(void*, FuncDeclaration f) 201 int fp2(void* param, FuncDeclaration f)
195 { 202 {
203 auto p = cast(Param2*)param;
196 MATCH match; 204 MATCH match;
197 205
198 if (f != m.lastf) // skip duplicates 206 if (f != m.lastf) // skip duplicates
199 { 207 {
200 m.anyf = f; 208 m.anyf = f;
201 TypeFunction tf = cast(TypeFunction)f.type; 209 TypeFunction tf = cast(TypeFunction)f.type;
210
211 int property = (tf.isproperty) ? 1 : 2;
212 if (p.property == 0)
213 p.property = property;
214 else if (p.property != property)
215 error(f.loc, "cannot overload both property and non-property functions");
216
202 match = tf.callMatch(f.needThis() ? ethis : null, arguments); 217 match = tf.callMatch(f.needThis() ? ethis : null, arguments);
203 //printf("test: match = %d\n", match); 218 //printf("test: match = %d\n", match);
204 if (match != MATCH.MATCHnomatch) 219 if (match != MATCH.MATCHnomatch)
205 { 220 {
206 if (match > m.last) 221 if (match > m.last)
214 if (m.lastf.overrides(f)) 229 if (m.lastf.overrides(f))
215 goto LlastIsBetter; 230 goto LlastIsBetter;
216 else if (f.overrides(m.lastf)) 231 else if (f.overrides(m.lastf))
217 goto LfIsBetter; 232 goto LfIsBetter;
218 233
234 version(DMDV2) {
219 /* Try to disambiguate using template-style partial ordering rules. 235 /* Try to disambiguate using template-style partial ordering rules.
220 * In essence, if f() and g() are ambiguous, if f() can call g(), 236 * In essence, if f() and g() are ambiguous, if f() can call g(),
221 * but g() cannot call f(), then pick f(). 237 * but g() cannot call f(), then pick f().
222 * This is because f() is "more specialized." 238 * This is because f() is "more specialized."
223 */ 239 */
228 if (c1 > c2) 244 if (c1 > c2)
229 goto LfIsBetter; 245 goto LfIsBetter;
230 if (c1 < c2) 246 if (c1 < c2)
231 goto LlastIsBetter; 247 goto LlastIsBetter;
232 } 248 }
249 }
233 250
234 Lambiguous: 251 Lambiguous:
235 m.nextf = f; 252 m.nextf = f;
236 m.count++; 253 m.count++;
237 return 0; 254 return 0;
262 this.f = f; 279 this.f = f;
263 return 1; 280 return 1;
264 } 281 }
265 282
266 version (DMDV2) { 283 version (DMDV2) {
267 /* Allow covariant matches, if it's just a const conversion 284 /* Allow covariant matches, as long as the return type
268 * of the return type 285 * is just a const conversion.
269 */ 286 * This allows things like pure functions to match with an impure function type.
287 */
270 if (t.ty == Tfunction) 288 if (t.ty == Tfunction)
271 { 289 {
272 TypeFunction tf = cast(TypeFunction)f.type; 290 TypeFunction tf = cast(TypeFunction)f.type;
273 if (tf.covariant(t) == 1 && 291 if (tf.covariant(t) == 1 &&
274 tf.nextOf().implicitConvTo(t.nextOf()) >= MATCHconst) 292 tf.nextOf().implicitConvTo(t.nextOf()) >= MATCHconst)
285 void overloadResolveX(Match* m, FuncDeclaration fstart, Expression ethis, Expressions arguments) 303 void overloadResolveX(Match* m, FuncDeclaration fstart, Expression ethis, Expressions arguments)
286 { 304 {
287 Param2 p; 305 Param2 p;
288 p.m = m; 306 p.m = m;
289 p.ethis = ethis; 307 p.ethis = ethis;
308 p.property = 0;
290 p.arguments = arguments; 309 p.arguments = arguments;
291 overloadApply(fstart, &p.fp2, &p); 310 overloadApply(fstart, &p.fp2, &p);
292 } 311 }
293 312
294 void templateResolve(Match* m, TemplateDeclaration td, Scope sc, Loc loc, Objects targsi, Expression ethis, Expressions arguments) 313 void templateResolve(Match* m, TemplateDeclaration td, Scope sc, Loc loc, Objects targsi, Expression ethis, Expressions arguments)
326 e = e.semantic(sc); 345 e = e.semantic(sc);
327 } 346 }
328 } 347 }
329 } 348 }
330 349
350 Expressions arrayExpressionToCommonType(Scope sc, Expressions exps, Type *pt)
351 {
352 //version(DMDV1) {
353 // /* The first element sets the type
354 // */
355 // Type *t0 = NULL;
356 // for (size_t i = 0; i < exps->dim; i++)
357 // { Expression *e = (Expression *)exps->data[i];
358 //
359 // if (!e->type)
360 // { error("%s has no value", e->toChars());
361 // e = new ErrorExp();
362 // }
363 // e = resolveProperties(sc, e);
364 //
365 // if (!t0)
366 // t0 = e->type;
367 // else
368 // e = e->implicitCastTo(sc, t0);
369 // exps->data[i] = (void *)e;
370 // }
371 //
372 // if (!t0)
373 // t0 = Type::tvoid;
374 // if (pt)
375 // *pt = t0;
376 //
377 // // Eventually, we want to make this copy-on-write
378 // return exps;
379 //}
380 version(DMDV2) {
381 /* The type is determined by applying ?: to each pair.
382 */
383 /* Still have a problem with:
384 * ubyte[][] = [ cast(ubyte[])"hello", [1]];
385 * which works if the array literal is initialized top down with the ubyte[][]
386 * type, but fails with this function doing bottom up typing.
387 */
388 //printf("arrayExpressionToCommonType()\n");
389 scope integerexp = new IntegerExp(0);
390 scope condexp = new CondExp(Loc(0), integerexp, null, null);
391
392 Type t0;
393 Expression e0;
394 int j0;
395 foreach (size_t i, Expression e; exps)
396 {
397 e = resolveProperties(sc, e);
398 if (!e.type)
399 { error("%s has no value", e.toChars());
400 e = new ErrorExp();
401 }
402
403 if (t0)
404 {
405 if (t0 != e.type)
406 {
407 /* This applies ?: to merge the types. It's backwards;
408 * ?: should call this function to merge types.
409 */
410 condexp.type = null;
411 condexp.e1 = e0;
412 condexp.e2 = e;
413 condexp.semantic(sc);
414 exps[j0] = condexp.e1;
415 e = condexp.e2;
416 j0 = i;
417 e0 = e;
418 t0 = e0.type;
419 }
420 }
421 else
422 {
423 j0 = i;
424 e0 = e;
425 t0 = e.type;
426 }
427 exps[i] = e;
428 }
429
430 if (t0)
431 {
432 foreach (ref Expression e; exps)
433 {
434 e = e.implicitCastTo(sc, t0);
435 }
436 }
437 else
438 t0 = Type.tvoid; // [] is typed as void[]
439 if (pt)
440 *pt = t0;
441
442 // Eventually, we want to make this copy-on-write
443 return exps;
444 }
445 }
446
331 /**************************************** 447 /****************************************
332 * Preprocess arguments to function. 448 * Preprocess arguments to function.
333 */ 449 */
334 450
335 void preFunctionArguments(Loc loc, Scope sc, Expressions exps) 451 void preFunctionParameters(Loc loc, Scope sc, Expressions exps)
336 { 452 {
337 if (exps) 453 if (exps)
338 { 454 {
339 expandTuples(exps); 455 expandTuples(exps);
340 456
478 * 3. do default promotions on arguments corresponding to ... 594 * 3. do default promotions on arguments corresponding to ...
479 * 4. add hidden _arguments[] argument 595 * 4. add hidden _arguments[] argument
480 * 5. call copy constructor for struct value arguments 596 * 5. call copy constructor for struct value arguments
481 */ 597 */
482 598
483 void functionArguments(Loc loc, Scope sc, TypeFunction tf, Expressions arguments) 599 void functionParameters(Loc loc, Scope sc, TypeFunction tf, Expressions arguments)
484 { 600 {
485 uint n; 601 uint n;
486 602
487 //printf("functionArguments()\n"); 603 //printf("functionParameters()\n");
488 assert(arguments); 604 assert(arguments);
489 size_t nargs = arguments ? arguments.dim : 0; 605 size_t nargs = arguments ? arguments.dim : 0;
490 size_t nparams = Argument.dim(tf.parameters); 606 size_t nparams = Parameter.dim(tf.parameters);
491 607
492 if (nargs > nparams && tf.varargs == 0) 608 if (nargs > nparams && tf.varargs == 0)
493 error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf.toChars()); 609 error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf.toChars());
494 610
495 n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) 611 n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams)
506 622
507 Type tb; 623 Type tb;
508 624
509 if (i < nparams) 625 if (i < nparams)
510 { 626 {
511 auto p = Argument.getNth(tf.parameters, i); 627 auto p = Parameter.getNth(tf.parameters, i);
512 628
513 if (!arg) 629 if (!arg)
514 { 630 {
515 if (!p.defaultArg) 631 if (!p.defaultArg)
516 { 632 {
517 if (tf.varargs == 2 && i + 1 == nparams) 633 if (tf.varargs == 2 && i + 1 == nparams)
518 goto L2; 634 goto L2;
519 635
520 error(loc, "expected %d function arguments, not %d", nparams, nargs); 636 error(loc, "expected %d function arguments, not %d", nparams, nargs);
521 break; 637 return;
522 } 638 }
523 arg = p.defaultArg; 639 arg = p.defaultArg;
524 version (DMDV2) {
525 if (arg.op == TOK.TOKdefault)
526 {
527 DefaultInitExp de = cast(DefaultInitExp)arg;
528 arg = de.resolve(loc, sc);
529 }
530 else
531 {
532 arg = arg.copy();
533 }
534 } else {
535 arg = arg.copy(); 640 arg = arg.copy();
641 version (DMDV2)
642 {
643 arg = arg.resolveLoc(loc, sc); // __FILE__ and __LINE__
536 } 644 }
537 arguments.push(arg); 645 arguments.push(arg);
538 nargs++; 646 nargs++;
539 } 647 }
540 648
542 { 650 {
543 //printf("\t\tvarargs == 2, p.type = '%s'\n", p.type.toChars()); 651 //printf("\t\tvarargs == 2, p.type = '%s'\n", p.type.toChars());
544 if (arg.implicitConvTo(p.type)) 652 if (arg.implicitConvTo(p.type))
545 { 653 {
546 if (nargs != nparams) 654 if (nargs != nparams)
655 {
547 error(loc, "expected %zu function arguments, not %zu", nparams, nargs); 656 error(loc, "expected %zu function arguments, not %zu", nparams, nargs);
657 return;
658 }
548 goto L1; 659 goto L1;
549 } 660 }
550 L2: 661 L2:
551 tb = p.type.toBasetype(); /// 662 tb = p.type.toBasetype(); ///
552 Type tret = p.isLazyArray(); 663 Type tret = p.isLazyArray();
776 } 887 }
777 888
778 // If D linkage and variadic, add _arguments[] as first argument 889 // If D linkage and variadic, add _arguments[] as first argument
779 if (tf.linkage == LINK.LINKd && tf.varargs == 1) 890 if (tf.linkage == LINK.LINKd && tf.varargs == 1)
780 { 891 {
892 assert(arguments.dim >= nparams);
781 auto e = createTypeInfoArray(sc, &arguments[nparams], arguments.dim - nparams); 893 auto e = createTypeInfoArray(sc, &arguments[nparams], arguments.dim - nparams);
782 arguments.insert(0, e); 894 arguments.insert(0, e);
783 } 895 }
784 } 896 }
785 897
952 * point at its elements[]. 1064 * point at its elements[].
953 */ 1065 */
954 1066
955 /* Create the TypeTuple corresponding to the types of args[] 1067 /* Create the TypeTuple corresponding to the types of args[]
956 */ 1068 */
957 Arguments args = new Arguments; 1069 auto args = new Parameters;
958 args.setDim(dim); 1070 args.setDim(dim);
959 for (size_t i = 0; i < dim; i++) 1071 for (size_t i = 0; i < dim; i++)
960 { 1072 {
961 Argument arg = new Argument(STCin, exps[i].type, null, null); 1073 auto arg = new Parameter(STCin, exps[i].type, null, null);
962 args[i] = arg; 1074 args[i] = arg;
963 } 1075 }
964 TypeTuple tup = new TypeTuple(args); 1076 TypeTuple tup = new TypeTuple(args);
965 Expression e = tup.getTypeInfo(sc); 1077 Expression e = tup.getTypeInfo(sc);
966 e = e.optimize(WANTvalue); 1078 e = e.optimize(WANTvalue);
1272 * Given array of arguments and an aggregate type, 1384 * Given array of arguments and an aggregate type,
1273 * if any of the argument types are missing, attempt to infer 1385 * if any of the argument types are missing, attempt to infer
1274 * them from the aggregate type. 1386 * them from the aggregate type.
1275 */ 1387 */
1276 1388
1277 void inferApplyArgTypes(TOK op, Arguments arguments, Expression aggr) 1389 void inferApplyArgTypes(TOK op, Parameters arguments, Expression aggr)
1278 { 1390 {
1279 if (!arguments || !arguments.dim) 1391 if (!arguments || !arguments.dim)
1280 return; 1392 return;
1281 1393
1282 /* Return if no arguments need types. 1394 /* Return if no arguments need types.
1284 for (size_t u = 0; 1; u++) 1396 for (size_t u = 0; 1; u++)
1285 { 1397 {
1286 if (u == arguments.dim) 1398 if (u == arguments.dim)
1287 return; 1399 return;
1288 1400
1289 Argument arg = arguments[u]; 1401 auto arg = arguments[u];
1290 if (!arg.type) 1402 if (!arg.type)
1291 break; 1403 break;
1292 } 1404 }
1293 1405
1294 AggregateDeclaration ad; 1406 AggregateDeclaration ad;
1295 1407
1296 Argument arg = arguments[0]; 1408 auto arg = arguments[0];
1297 Type taggr = aggr.type; 1409 Type taggr = aggr.type;
1298 if (!taggr) 1410 if (!taggr)
1299 return; 1411 return;
1300 Type tab = taggr.toBasetype(); 1412 Type tab = taggr.toBasetype();
1301 switch (tab.ty) 1413 switch (tab.ty)
1313 arg.type = tab.nextOf(); // value type 1425 arg.type = tab.nextOf(); // value type
1314 break; 1426 break;
1315 1427
1316 case TY.Taarray: 1428 case TY.Taarray:
1317 { 1429 {
1318 TypeAArray taa = cast(TypeAArray)tab; 1430 auto taa = cast(TypeAArray)tab;
1319 1431
1320 if (arguments.dim == 2) 1432 if (arguments.dim == 2)
1321 { 1433 {
1322 if (!arg.type) 1434 if (!arg.type)
1323 arg.type = taa.index; // key type 1435 arg.type = taa.index; // key type
1412 * analogous to func.overloadResolveX(). 1524 * analogous to func.overloadResolveX().
1413 */ 1525 */
1414 1526
1415 int fp3(void*, FuncDeclaration f) 1527 int fp3(void*, FuncDeclaration f)
1416 { 1528 {
1417 TypeFunction tf = cast(TypeFunction)f.type; 1529 auto tf = cast(TypeFunction)f.type;
1418 if (inferApplyArgTypesY(tf, arguments) == 1) 1530 if (inferApplyArgTypesY(tf, arguments) == 1)
1419 return 0; 1531 return 0;
1420 1532
1421 if (arguments.dim == 0) 1533 if (arguments.dim == 0)
1422 return 1; 1534 return 1;
1423 1535
1424 return 0; 1536 return 0;
1425 } 1537 }
1426 1538
1427 Arguments arguments; 1539 Parameters arguments;
1428 } 1540 }
1429 1541
1430 void inferApplyArgTypesX(FuncDeclaration fstart, Arguments arguments) 1542 void inferApplyArgTypesX(FuncDeclaration fstart, Parameters arguments)
1431 { 1543 {
1432 Param3 p3; 1544 Param3 p3;
1433 p3.arguments = arguments; 1545 p3.arguments = arguments;
1434 overloadApply(fstart, &p3.fp3, cast(void*)arguments); 1546 overloadApply(fstart, &p3.fp3, cast(void*)arguments);
1435 } 1547 }
1439 * Returns: 1551 * Returns:
1440 * 0 match for this function 1552 * 0 match for this function
1441 * 1 no match for this function 1553 * 1 no match for this function
1442 */ 1554 */
1443 1555
1444 int inferApplyArgTypesY(TypeFunction tf, Arguments arguments) 1556 int inferApplyArgTypesY(TypeFunction tf, Parameters arguments)
1445 { 1557 {
1446 size_t nparams; 1558 size_t nparams;
1447 Argument p; 1559 Parameter p;
1448 1560
1449 if (Argument.dim(tf.parameters) != 1) 1561 if (Parameter.dim(tf.parameters) != 1)
1450 goto Lnomatch; 1562 goto Lnomatch;
1451 1563
1452 p = Argument.getNth(tf.parameters, 0); 1564 p = Parameter.getNth(tf.parameters, 0);
1453 if (p.type.ty != TY.Tdelegate) 1565 if (p.type.ty != TY.Tdelegate)
1454 goto Lnomatch; 1566 goto Lnomatch;
1455 1567
1456 tf = cast(TypeFunction)p.type.nextOf(); 1568 tf = cast(TypeFunction)p.type.nextOf();
1457 assert(tf.ty == TY.Tfunction); 1569 assert(tf.ty == TY.Tfunction);
1458 1570
1459 /* We now have tf, the type of the delegate. Match it against 1571 /* We now have tf, the type of the delegate. Match it against
1460 * the arguments, filling in missing argument types. 1572 * the arguments, filling in missing argument types.
1461 */ 1573 */
1462 nparams = Argument.dim(tf.parameters); 1574 nparams = Parameter.dim(tf.parameters);
1463 if (nparams == 0 || tf.varargs) 1575 if (nparams == 0 || tf.varargs)
1464 goto Lnomatch; // not enough parameters 1576 goto Lnomatch; // not enough parameters
1465 if (arguments.dim != nparams) 1577 if (arguments.dim != nparams)
1466 goto Lnomatch; // not enough parameters 1578 goto Lnomatch; // not enough parameters
1467 1579
1468 for (size_t u = 0; u < nparams; u++) 1580 for (size_t u = 0; u < nparams; u++)
1469 { 1581 {
1470 Argument arg = arguments[u]; 1582 auto arg = arguments[u];
1471 Argument param = Argument.getNth(tf.parameters, u); 1583 auto param = Parameter.getNth(tf.parameters, u);
1472 if (arg.type) 1584 if (arg.type)
1473 { 1585 {
1474 if (!arg.type.equals(param.type)) 1586 if (!arg.type.equals(param.type))
1475 { 1587 {
1476 /* Cannot resolve argument types. Indicate an 1588 /* Cannot resolve argument types. Indicate an