Mercurial > projects > ddmd
comparison 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 |
comparison
equal
deleted
inserted
replaced
134:4251f96733f4 | 135:af1bebfd96a4 |
---|---|
592 * 1. implicitly convert argument to the corresponding parameter type | 592 * 1. implicitly convert argument to the corresponding parameter type |
593 * 2. add default arguments for any missing arguments | 593 * 2. add default arguments for any missing arguments |
594 * 3. do default promotions on arguments corresponding to ... | 594 * 3. do default promotions on arguments corresponding to ... |
595 * 4. add hidden _arguments[] argument | 595 * 4. add hidden _arguments[] argument |
596 * 5. call copy constructor for struct value arguments | 596 * 5. call copy constructor for struct value arguments |
597 */ | 597 * Returns: |
598 | 598 * return type from function |
599 void functionParameters(Loc loc, Scope sc, TypeFunction tf, Expressions arguments) | 599 */ |
600 { | 600 |
601 uint n; | 601 Type functionParameters(Loc loc, Scope sc, TypeFunction tf, Expressions arguments) |
602 | 602 { |
603 //printf("functionParameters()\n"); | 603 //printf("functionParameters()\n"); |
604 assert(arguments); | 604 assert(arguments); |
605 size_t nargs = arguments ? arguments.dim : 0; | 605 size_t nargs = arguments ? arguments.dim : 0; |
606 size_t nparams = Parameter.dim(tf.parameters); | 606 size_t nparams = Parameter.dim(tf.parameters); |
607 | 607 |
608 if (nargs > nparams && tf.varargs == 0) | 608 if (nargs > nparams && tf.varargs == 0) |
609 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()); |
610 | 610 |
611 n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) | 611 uint n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) |
612 | 612 |
613 uint wildmatch = 0; | |
614 | |
613 int done = 0; | 615 int done = 0; |
614 for (size_t i = 0; i < n; i++) | 616 for (size_t i = 0; i < n; i++) |
615 { | 617 { |
616 Expression arg; | 618 Expression arg; |
617 | 619 |
632 { | 634 { |
633 if (tf.varargs == 2 && i + 1 == nparams) | 635 if (tf.varargs == 2 && i + 1 == nparams) |
634 goto L2; | 636 goto L2; |
635 | 637 |
636 error(loc, "expected %d function arguments, not %d", nparams, nargs); | 638 error(loc, "expected %d function arguments, not %d", nparams, nargs); |
637 return; | 639 return tf.next; |
638 } | 640 } |
639 arg = p.defaultArg; | 641 arg = p.defaultArg; |
640 arg = arg.copy(); | 642 arg = arg.copy(); |
641 version (DMDV2) | 643 version (DMDV2) |
642 { | 644 { |
652 if (arg.implicitConvTo(p.type)) | 654 if (arg.implicitConvTo(p.type)) |
653 { | 655 { |
654 if (nargs != nparams) | 656 if (nargs != nparams) |
655 { | 657 { |
656 error(loc, "expected %zu function arguments, not %zu", nparams, nargs); | 658 error(loc, "expected %zu function arguments, not %zu", nparams, nargs); |
657 return; | 659 return tf.next; |
658 } | 660 } |
659 goto L1; | 661 goto L1; |
660 } | 662 } |
661 L2: | 663 L2: |
662 tb = p.type.toBasetype(); /// | 664 tb = p.type.toBasetype(); /// |
678 } | 680 } |
679 Identifier id = Lexer.uniqueId("__arrayArg"); | 681 Identifier id = Lexer.uniqueId("__arrayArg"); |
680 Type t = new TypeSArray((cast(TypeArray)tb).next, new IntegerExp(nargs - i)); | 682 Type t = new TypeSArray((cast(TypeArray)tb).next, new IntegerExp(nargs - i)); |
681 t = t.semantic(loc, sc); | 683 t = t.semantic(loc, sc); |
682 VarDeclaration v = new VarDeclaration(loc, t, id, new VoidInitializer(loc)); | 684 VarDeclaration v = new VarDeclaration(loc, t, id, new VoidInitializer(loc)); |
685 v.storage_class |= STCctfe; | |
683 v.semantic(sc); | 686 v.semantic(sc); |
684 v.parent = sc.parent; | 687 v.parent = sc.parent; |
685 //sc.insert(v); | 688 //sc.insert(v); |
686 | 689 |
687 Expression c = new DeclarationExp(Loc(0), v); | 690 Expression c = new DeclarationExp(Loc(0), v); |
727 | 730 |
728 default: | 731 default: |
729 if (!arg) | 732 if (!arg) |
730 { | 733 { |
731 error(loc, "not enough arguments"); | 734 error(loc, "not enough arguments"); |
732 return; | 735 return tf.next; |
733 } | 736 } |
734 break; | 737 break; |
735 } | 738 } |
736 | 739 |
737 arg = arg.semantic(sc); | 740 arg = arg.semantic(sc); |
746 if (p.type != arg.type) | 749 if (p.type != arg.type) |
747 { | 750 { |
748 //printf("arg.type = %s, p.type = %s\n", arg.type.toChars(), p.type.toChars()); | 751 //printf("arg.type = %s, p.type = %s\n", arg.type.toChars(), p.type.toChars()); |
749 if (arg.op == TOKtype) | 752 if (arg.op == TOKtype) |
750 arg.error("cannot pass type %s as function argument", arg.toChars()); | 753 arg.error("cannot pass type %s as function argument", arg.toChars()); |
751 arg = arg.implicitCastTo(sc, p.type); | 754 if (p.type.isWild() && tf.next.isWild()) |
755 { | |
756 Type t = p.type; | |
757 MATCH m = arg.implicitConvTo(t); | |
758 if (m == MATCH.MATCHnomatch) | |
759 { | |
760 t = t.constOf(); | |
761 m = arg.implicitConvTo(t); | |
762 if (m == MATCHnomatch) | |
763 { | |
764 t = t.sharedConstOf(); | |
765 m = arg.implicitConvTo(t); | |
766 } | |
767 wildmatch |= p.type.wildMatch(arg.type); | |
768 } | |
769 arg = arg.implicitCastTo(sc, t); | |
770 } | |
771 else | |
772 arg = arg.implicitCastTo(sc, p.type); | |
752 arg = arg.optimize(WANT.WANTvalue); | 773 arg = arg.optimize(WANT.WANTvalue); |
753 } | 774 } |
754 } | 775 } |
755 if (p.storageClass & STC.STCref) | 776 if (p.storageClass & STC.STCref) |
756 { | 777 { |
846 if (tb.ty == TY.Tsarray) | 867 if (tb.ty == TY.Tsarray) |
847 { | 868 { |
848 TypeSArray ts = cast(TypeSArray)tb; | 869 TypeSArray ts = cast(TypeSArray)tb; |
849 Type ta = ts.next.arrayOf(); | 870 Type ta = ts.next.arrayOf(); |
850 if (ts.size(arg.loc) == 0) | 871 if (ts.size(arg.loc) == 0) |
851 { | 872 arg = new NullExp(arg.loc, ta); |
852 arg = new NullExp(arg.loc); | |
853 arg.type = ta; | |
854 } | |
855 else | 873 else |
856 { | |
857 arg = arg.castTo(sc, ta); | 874 arg = arg.castTo(sc, ta); |
858 } | |
859 } | 875 } |
860 version (DMDV2) { | 876 version (DMDV2) { |
861 if (tb.ty == Tstruct) | 877 if (tb.ty == Tstruct) |
862 { | 878 { |
863 arg = callCpCtor(loc, sc, arg); | 879 arg = callCpCtor(loc, sc, arg); |
891 { | 907 { |
892 assert(arguments.dim >= nparams); | 908 assert(arguments.dim >= nparams); |
893 auto e = createTypeInfoArray(sc, &arguments[nparams], arguments.dim - nparams); | 909 auto e = createTypeInfoArray(sc, &arguments[nparams], arguments.dim - nparams); |
894 arguments.insert(0, e); | 910 arguments.insert(0, e); |
895 } | 911 } |
912 | |
913 Type tret = tf.next; | |
914 if (wildmatch) | |
915 { /* Adjust function return type based on wildmatch | |
916 */ | |
917 //printf("wildmatch = x%x\n", wildmatch); | |
918 assert(tret.isWild()); | |
919 if (wildmatch & MOD.MODconst || wildmatch & (wildmatch - 1)) | |
920 tret = tret.constOf(); | |
921 else if (wildmatch & MOD.MODimmutable) | |
922 tret = tret.invariantOf(); | |
923 else | |
924 { | |
925 assert(wildmatch & MOD.MODmutable); | |
926 tret = tret.mutableOf(); | |
927 } | |
928 } | |
929 return tret; | |
896 } | 930 } |
897 | 931 |
898 /****************************** | 932 /****************************** |
899 * Perform canThrow() on an array of Expressions. | 933 * Perform canThrow() on an array of Expressions. |
900 */ | 934 */ |
1254 | 1288 |
1255 Expression e = null; | 1289 Expression e = null; |
1256 if (!v) | 1290 if (!v) |
1257 return e; | 1291 return e; |
1258 | 1292 |
1259 if (v.isConst() || v.isInvariant() || v.storage_class & STC.STCmanifest) | 1293 if (v.isConst() || v.isImmutable() || v.storage_class & STC.STCmanifest) |
1260 { | 1294 { |
1261 if (!v.type) | 1295 if (!v.type) |
1262 { | 1296 { |
1263 //error("ICE"); | 1297 //error("ICE"); |
1264 return e; | 1298 return e; |
1401 auto arg = arguments[u]; | 1435 auto arg = arguments[u]; |
1402 if (!arg.type) | 1436 if (!arg.type) |
1403 break; | 1437 break; |
1404 } | 1438 } |
1405 | 1439 |
1440 Dsymbol s; | |
1406 AggregateDeclaration ad; | 1441 AggregateDeclaration ad; |
1407 | 1442 |
1408 auto arg = arguments[0]; | 1443 auto arg = arguments[0]; |
1409 Type taggr = aggr.type; | 1444 Type taggr = aggr.type; |
1410 if (!taggr) | 1445 if (!taggr) |
1447 case TY.Tstruct: | 1482 case TY.Tstruct: |
1448 ad = (cast(TypeStruct)tab).sym; | 1483 ad = (cast(TypeStruct)tab).sym; |
1449 goto Laggr; | 1484 goto Laggr; |
1450 | 1485 |
1451 Laggr: | 1486 Laggr: |
1487 s = search_function(ad, (op == TOKforeach_reverse) ? Id.applyReverse : Id.apply); | |
1488 if (s) | |
1489 goto Lapply; // prefer opApply | |
1490 | |
1452 if (arguments.dim == 1) | 1491 if (arguments.dim == 1) |
1453 { | 1492 { |
1454 if (!arg.type) | 1493 if (!arg.type) |
1455 { | 1494 { |
1456 /* Look for a head() or rear() overload | 1495 /* Look for a head() or rear() overload |
1457 */ | 1496 */ |
1458 Identifier id = (op == TOK.TOKforeach) ? Id.Fhead : Id.Ftoe; | 1497 Identifier id = (op == TOK.TOKforeach) ? Id.Fhead : Id.Ftoe; |
1459 Dsymbol s = search_function(ad, id); | 1498 Dsymbol s1 = search_function(ad, id); |
1460 FuncDeclaration fd = s ? s.isFuncDeclaration() : null; | 1499 FuncDeclaration fd = s1 ? s1.isFuncDeclaration() : null; |
1461 if (!fd) | 1500 if (!fd) |
1462 { | 1501 { |
1463 if (s && s.isTemplateDeclaration()) | 1502 if (s1 && s1.isTemplateDeclaration()) |
1464 break; | 1503 break; |
1465 goto Lapply; | 1504 goto Lapply; |
1466 } | 1505 } |
1467 arg.type = fd.type.nextOf(); | 1506 arg.type = fd.type.nextOf(); |
1468 } | 1507 } |
1472 Lapply: | 1511 Lapply: |
1473 { /* Look for an | 1512 { /* Look for an |
1474 * int opApply(int delegate(ref Type [, ...]) dg); | 1513 * int opApply(int delegate(ref Type [, ...]) dg); |
1475 * overload | 1514 * overload |
1476 */ | 1515 */ |
1477 Dsymbol s = search_function(ad, (op == TOK.TOKforeach_reverse) ? Id.applyReverse : Id.apply); | |
1478 if (s) | 1516 if (s) |
1479 { | 1517 { |
1480 FuncDeclaration fd = s.isFuncDeclaration(); | 1518 FuncDeclaration fd = s.isFuncDeclaration(); |
1481 if (fd) | 1519 if (fd) |
1482 { | 1520 { |