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 {