Changeset c5cb943d in mainline for uspace/app/sbi/src/stype.c
- Timestamp:
- 2010-06-09T19:01:08Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1113c9e
- Parents:
- 051bc69a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/sbi/src/stype.c
r051bc69a rc5cb943d 63 63 static void stype_fun_body(stype_t *stype, stree_fun_t *fun); 64 64 static void stype_block(stype_t *stype, stree_block_t *block); 65 66 static void stype_class_impl_check(stype_t *stype, stree_csi_t *csi); 67 static void stype_class_impl_check_if(stype_t *stype, stree_csi_t *csi, 68 tdata_item_t *iface_ti); 69 static void stype_class_impl_check_mbr(stype_t *stype, stree_csi_t *csi, 70 tdata_tvv_t *if_tvv, stree_csimbr_t *ifmbr); 71 static void stype_class_impl_check_fun(stype_t *stype, 72 stree_symbol_t *cfun_sym, tdata_tvv_t *if_tvv, stree_symbol_t *ifun_sym); 73 static void stype_class_impl_check_prop(stype_t *stype, 74 stree_symbol_t *cprop_sym, tdata_tvv_t *if_tvv, stree_symbol_t *iprop_sym); 65 75 66 76 static void stype_vdecl(stype_t *stype, stree_vdecl_t *vdecl_s); … … 90 100 static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr, 91 101 tdata_item_t *dest); 92 static void stype_convert_failure(stype_t *stype, stree_expr_t *expr,93 tdata_item_t *dest);94 102 95 103 static bool_t stype_fun_sig_equal(stype_t *stype, tdata_fun_sig_t *asig, … … 168 176 } 169 177 178 if (csi->cc == csi_class) 179 stype_class_impl_check(stype, csi); 180 170 181 stype->current_csi = prev_ctx; 171 182 } … … 310 321 311 322 enum_d->titem = titem; 312 } else {313 titem = enum_d->titem;314 323 } 315 324 } … … 453 462 assert(stype->proc_vr == NULL); 454 463 455 /* Builtin functions do not have a body. */464 /* Declarations and builtin functions do not have a body. */ 456 465 if (fun->proc->body == NULL) 457 466 return; … … 475 484 { 476 485 tdata_item_t *titem; 477 478 (void) stype;479 (void) var;480 486 481 487 run_texpr(stype->program, stype->current_csi, var->type, … … 484 490 /* An error occured. */ 485 491 stype_note_error(stype); 486 return;487 492 } 488 493 } … … 500 505 printf("'.\n"); 501 506 #endif 507 if (prop->titem == NULL) 508 stype_prop_header(stype, prop); 509 502 510 stype->proc_vr = stype_proc_vr_new(); 503 511 list_init(&stype->proc_vr->block_vr); 504 512 505 if (prop->getter != NULL) { 513 /* Property declarations do not have a getter body. */ 514 if (prop->getter != NULL && prop->getter->body != NULL) { 506 515 stype->proc_vr->proc = prop->getter; 507 516 stype_block(stype, prop->getter->body); 508 517 } 509 518 510 if (prop->setter != NULL) { 519 /* Property declarations do not have a setter body. */ 520 if (prop->setter != NULL && prop->setter->body != NULL) { 511 521 stype->proc_vr->proc = prop->setter; 512 522 stype_block(stype, prop->setter->body); … … 515 525 free(stype->proc_vr); 516 526 stype->proc_vr = NULL; 527 } 528 529 /** Type property header. 530 * 531 * @param stype Static typing object 532 * @param prop Property 533 */ 534 void stype_prop_header(stype_t *stype, stree_prop_t *prop) 535 { 536 tdata_item_t *titem; 537 538 #ifdef DEBUG_TYPE_TRACE 539 printf("Type property '"); 540 symbol_print_fqn(prop_to_symbol(prop)); 541 printf("' header.\n"); 542 #endif 543 run_texpr(stype->program, stype->current_csi, prop->type, 544 &titem); 545 if (titem->tic == tic_ignore) { 546 /* An error occured. */ 547 stype_note_error(stype); 548 return; 549 } 550 551 prop->titem = titem; 517 552 } 518 553 … … 552 587 assert(list_node_data(bvr_n, stype_block_vr_t *) == block_vr); 553 588 list_remove(&stype->proc_vr->block_vr, bvr_n); 589 } 590 591 /** Verify that class fully implements all interfaces as it claims. 592 * 593 * @param stype Static typing object 594 * @param csi CSI to check 595 */ 596 static void stype_class_impl_check(stype_t *stype, stree_csi_t *csi) 597 { 598 list_node_t *pred_n; 599 stree_texpr_t *pred_te; 600 tdata_item_t *pred_ti; 601 602 #ifdef DEBUG_TYPE_TRACE 603 printf("Verify that class implements all interfaces.\n"); 604 #endif 605 assert(csi->cc == csi_class); 606 607 pred_n = list_first(&csi->inherit); 608 while (pred_n != NULL) { 609 pred_te = list_node_data(pred_n, stree_texpr_t *); 610 run_texpr(stype->program, csi, pred_te, &pred_ti); 611 612 assert(pred_ti->tic == tic_tobject); 613 switch (pred_ti->u.tobject->csi->cc) { 614 case csi_class: 615 break; 616 case csi_struct: 617 assert(b_false); 618 case csi_interface: 619 /* Store to impl_if_ti for later use. */ 620 list_append(&csi->impl_if_ti, pred_ti); 621 622 /* Check implementation of this interface. */ 623 stype_class_impl_check_if(stype, csi, pred_ti); 624 break; 625 } 626 627 pred_n = list_next(&csi->inherit, pred_n); 628 } 629 } 630 631 /** Verify that class fully implements an interface. 632 * 633 * @param stype Static typing object 634 * @param csi CSI to check 635 * @param iface Interface that must be fully implemented 636 */ 637 static void stype_class_impl_check_if(stype_t *stype, stree_csi_t *csi, 638 tdata_item_t *iface_ti) 639 { 640 tdata_tvv_t *iface_tvv; 641 list_node_t *pred_n; 642 tdata_item_t *pred_ti; 643 tdata_item_t *pred_sti; 644 645 stree_csi_t *iface; 646 list_node_t *ifmbr_n; 647 stree_csimbr_t *ifmbr; 648 649 assert(csi->cc == csi_class); 650 651 assert(iface_ti->tic == tic_tobject); 652 iface = iface_ti->u.tobject->csi; 653 assert(iface->cc = csi_interface); 654 655 #ifdef DEBUG_TYPE_TRACE 656 printf("Verify that class fully implements interface.\n"); 657 #endif 658 /* Compute TVV for this interface reference. */ 659 stype_titem_to_tvv(stype, iface_ti, &iface_tvv); 660 661 /* 662 * Recurse to accumulated interfaces. 663 */ 664 pred_n = list_first(&iface->impl_if_ti); 665 while (pred_n != NULL) { 666 pred_ti = list_node_data(pred_n, tdata_item_t *); 667 assert(pred_ti->tic == tic_tobject); 668 assert(pred_ti->u.tobject->csi->cc == csi_interface); 669 670 /* Substitute real type parameters to predecessor reference. */ 671 tdata_item_subst(pred_ti, iface_tvv, &pred_sti); 672 673 /* Check accumulated interface. */ 674 stype_class_impl_check_if(stype, csi, pred_sti); 675 676 pred_n = list_next(&iface->impl_if_ti, pred_n); 677 } 678 679 /* 680 * Check all interface members. 681 */ 682 ifmbr_n = list_first(&iface->members); 683 while (ifmbr_n != NULL) { 684 ifmbr = list_node_data(ifmbr_n, stree_csimbr_t *); 685 stype_class_impl_check_mbr(stype, csi, iface_tvv, ifmbr); 686 687 ifmbr_n = list_next(&iface->members, ifmbr_n); 688 } 689 } 690 691 /** Verify that class fully implements an interface member. 692 * 693 * @param stype Static typing object 694 * @param csi CSI to check 695 * @param if_tvv TVV for @a ifmbr 696 * @param ifmbr Interface that must be fully implemented 697 */ 698 static void stype_class_impl_check_mbr(stype_t *stype, stree_csi_t *csi, 699 tdata_tvv_t *if_tvv, stree_csimbr_t *ifmbr) 700 { 701 stree_symbol_t *cmbr_sym; 702 stree_symbol_t *ifmbr_sym; 703 stree_ident_t *ifmbr_name; 704 705 assert(csi->cc == csi_class); 706 707 #ifdef DEBUG_TYPE_TRACE 708 printf("Verify that class implements interface member.\n"); 709 #endif 710 ifmbr_name = stree_csimbr_get_name(ifmbr); 711 712 cmbr_sym = symbol_search_csi(stype->program, csi, ifmbr_name); 713 if (cmbr_sym == NULL) { 714 printf("Error: CSI '"); 715 symbol_print_fqn(csi_to_symbol(csi)); 716 printf("' should implement '"); 717 symbol_print_fqn(csimbr_to_symbol(ifmbr)); 718 printf("' but it does not.\n"); 719 stype_note_error(stype); 720 return; 721 } 722 723 ifmbr_sym = csimbr_to_symbol(ifmbr); 724 if (cmbr_sym->sc != ifmbr_sym->sc) { 725 printf("Error: CSI '"); 726 symbol_print_fqn(csi_to_symbol(csi)); 727 printf("' implements '"); 728 symbol_print_fqn(csimbr_to_symbol(ifmbr)); 729 printf("' as a different kind of symbol.\n"); 730 stype_note_error(stype); 731 } 732 733 switch (cmbr_sym->sc) { 734 case sc_csi: 735 case sc_ctor: 736 case sc_deleg: 737 case sc_enum: 738 /* 739 * Checked at parse time. Interface should not have these 740 * member types. 741 */ 742 assert(b_false); 743 case sc_fun: 744 stype_class_impl_check_fun(stype, cmbr_sym, if_tvv, ifmbr_sym); 745 break; 746 case sc_var: 747 /* 748 * Checked at parse time. Interface should not have these 749 * member types. 750 */ 751 assert(b_false); 752 case sc_prop: 753 stype_class_impl_check_prop(stype, cmbr_sym, if_tvv, ifmbr_sym); 754 break; 755 } 756 } 757 758 /** Verify that class properly implements a function from an interface. 759 * 760 * @param stype Static typing object 761 * @param cfun_sym Function symbol in class 762 * @param if_tvv TVV for @a ifun_sym 763 * @param ifun_sym Function declaration symbol in interface 764 */ 765 static void stype_class_impl_check_fun(stype_t *stype, 766 stree_symbol_t *cfun_sym, tdata_tvv_t *if_tvv, stree_symbol_t *ifun_sym) 767 { 768 stree_fun_t *cfun; 769 tdata_fun_t *tcfun; 770 stree_fun_t *ifun; 771 tdata_item_t *sifun_ti; 772 tdata_fun_t *tifun; 773 774 #ifdef DEBUG_TYPE_TRACE 775 printf("Verify that class '"); 776 symbol_print_fqn(csi_to_symbol(cfun_sym->outer_csi)); 777 printf("' implements function '"); 778 symbol_print_fqn(ifun_sym); 779 printf("' properly.\n"); 780 #endif 781 assert(cfun_sym->sc == sc_fun); 782 cfun = cfun_sym->u.fun; 783 784 assert(ifun_sym->sc == sc_fun); 785 ifun = ifun_sym->u.fun; 786 787 assert(cfun->titem->tic == tic_tfun); 788 tcfun = cfun->titem->u.tfun; 789 790 tdata_item_subst(ifun->titem, if_tvv, &sifun_ti); 791 assert(sifun_ti->tic == tic_tfun); 792 tifun = sifun_ti->u.tfun; 793 794 if (!stype_fun_sig_equal(stype, tcfun->tsig, tifun->tsig)) { 795 cspan_print(cfun->name->cspan); 796 printf(" Error: Type of function '"); 797 symbol_print_fqn(cfun_sym); 798 printf("' ("); 799 tdata_item_print(cfun->titem); 800 printf(") does not match type of '"); 801 symbol_print_fqn(ifun_sym); 802 printf("' ("); 803 tdata_item_print(sifun_ti); 804 printf(") which it should implement.\n"); 805 stype_note_error(stype); 806 } 807 } 808 809 /** Verify that class properly implements a function from an interface. 810 * 811 * @param stype Static typing object 812 * @param cprop_sym Property symbol in class 813 * @param if_tvv TVV for @a ifun_sym 814 * @param iprop_sym Property declaration symbol in interface 815 */ 816 static void stype_class_impl_check_prop(stype_t *stype, 817 stree_symbol_t *cprop_sym, tdata_tvv_t *if_tvv, stree_symbol_t *iprop_sym) 818 { 819 stree_prop_t *cprop; 820 stree_prop_t *iprop; 821 tdata_item_t *siprop_ti; 822 823 #ifdef DEBUG_TYPE_TRACE 824 printf("Verify that class '"); 825 symbol_print_fqn(csi_to_symbol(cprop_sym->outer_csi)); 826 printf("' implements property '"); 827 symbol_print_fqn(iprop_sym); 828 printf("' properly.\n"); 829 #endif 830 assert(cprop_sym->sc == sc_prop); 831 cprop = cprop_sym->u.prop; 832 833 assert(iprop_sym->sc == sc_prop); 834 iprop = iprop_sym->u.prop; 835 836 tdata_item_subst(iprop->titem, if_tvv, &siprop_ti); 837 838 if (!tdata_item_equal(cprop->titem, siprop_ti)) { 839 cspan_print(cprop->name->cspan); 840 printf(" Error: Type of property '"); 841 symbol_print_fqn(cprop_sym); 842 printf("' ("); 843 tdata_item_print(cprop->titem); 844 printf(") does not match type of '"); 845 symbol_print_fqn(iprop_sym); 846 printf("' ("); 847 tdata_item_print(siprop_ti); 848 printf(") which it should implement.\n"); 849 stype_note_error(stype); 850 } 851 852 if (iprop->getter != NULL && cprop->getter == NULL) { 853 cspan_print(cprop->name->cspan); 854 printf(" Error: Property '"); 855 symbol_print_fqn(cprop_sym); 856 printf("' is missing a getter, which is required by '"); 857 symbol_print_fqn(iprop_sym); 858 printf("'.\n"); 859 stype_note_error(stype); 860 } 861 862 if (iprop->setter != NULL && cprop->setter == NULL) { 863 cspan_print(cprop->name->cspan); 864 printf(" Error: Property '"); 865 symbol_print_fqn(cprop_sym); 866 printf("' is missing a setter, which is required by '"); 867 symbol_print_fqn(iprop_sym); 868 printf("'.\n"); 869 stype_note_error(stype); 870 } 554 871 } 555 872 … … 824 1141 stype_expr(stype, exp_s->expr); 825 1142 826 if (want_value == b_false && exp_s->expr->titem != NULL) 827 printf("Warning: Expression value ignored.\n"); 1143 if (want_value == b_false && exp_s->expr->titem != NULL) { 1144 cspan_print(exp_s->expr->cspan); 1145 printf(" Warning: Expression value ignored.\n"); 1146 } 828 1147 } 829 1148 … … 925 1244 926 1245 if (src->tic == tic_tebase) { 927 stype_convert_failure(stype, expr, dest);1246 stype_convert_failure(stype, convc_implicit, expr, dest); 928 1247 printf("Invalid use of reference to enum type in " 929 1248 "expression.\n"); … … 932 1251 933 1252 if (src->tic != dest->tic) { 934 stype_convert_failure(stype, expr, dest);1253 stype_convert_failure(stype, convc_implicit, expr, dest); 935 1254 return expr; 936 1255 } … … 987 1306 /* Check if both have the same tprimitive class. */ 988 1307 if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc) 989 stype_convert_failure(stype, expr, dest);1308 stype_convert_failure(stype, convc_implicit, expr, dest); 990 1309 991 1310 return expr; … … 1020 1339 bi = stype->program->builtin; 1021 1340 csi_sym = csi_to_symbol(dest->u.tobject->csi); 1341 1342 /* Make compiler happy. */ 1343 bp_sym = NULL; 1022 1344 1023 1345 switch (src->u.tprimitive->tpc) { … … 1028 1350 case tpc_string: bp_sym = bi->boxed_string; break; 1029 1351 case tpc_resource: 1030 stype_convert_failure(stype, expr, dest);1352 stype_convert_failure(stype, convc_implicit, expr, dest); 1031 1353 return expr; 1032 1354 } … … 1034 1356 /* Target type must be boxed @a src or Object */ 1035 1357 if (csi_sym != bp_sym && csi_sym != bi->gf_class) 1036 stype_convert_failure(stype, expr, dest);1358 stype_convert_failure(stype, convc_implicit, expr, dest); 1037 1359 1038 1360 /* Patch the code to box the primitive value */ … … 1058 1380 { 1059 1381 tdata_item_t *src; 1060 tdata_item_t *cur; 1061 stree_csi_t *cur_csi; 1062 tdata_tvv_t *tvv; 1063 tdata_item_t *b_ti, *bs_ti; 1382 tdata_item_t *pred_ti; 1064 1383 1065 1384 #ifdef DEBUG_TYPE_TRACE 1066 1385 printf("Convert object type.\n"); 1067 1386 #endif 1068 list_node_t *ca_n, *da_n;1069 tdata_item_t *carg, *darg;1070 1071 1387 src = expr->titem; 1072 1388 assert(src->tic == tic_tobject); 1073 1389 assert(dest->tic == tic_tobject); 1074 1390 1075 cur = src; 1076 1077 while (cur->u.tobject->csi != dest->u.tobject->csi) { 1078 1079 cur_csi = cur->u.tobject->csi; 1080 stype_titem_to_tvv(stype, cur, &tvv); 1081 1082 if (cur_csi->base_csi_ref != NULL) { 1083 run_texpr(stype->program, cur_csi, cur_csi->base_csi_ref, &b_ti); 1084 if (b_ti->tic == tic_ignore) { 1085 /* An error occured. */ 1086 stype_note_error(stype); 1087 return expr; 1088 } 1089 1090 tdata_item_subst(b_ti, tvv, &bs_ti); 1091 cur = bs_ti; 1092 assert(cur->tic == tic_tobject); 1093 1094 } else if (cur_csi->base_csi != NULL) { 1095 /* No explicit reference. Use grandfather class. */ 1096 cur = tdata_item_new(tic_tobject); 1097 cur->u.tobject = tdata_object_new(); 1098 cur->u.tobject->csi = cur_csi->base_csi; 1099 cur->u.tobject->static_ref = b_false; 1100 1101 list_init(&cur->u.tobject->targs); 1102 } else { 1103 /* No match */ 1104 stype_convert_failure(stype, expr, dest); 1105 return expr; 1106 } 1107 } 1108 1109 /* Verify that type arguments match */ 1110 ca_n = list_first(&cur->u.tobject->targs); 1111 da_n = list_first(&dest->u.tobject->targs); 1112 1113 while (ca_n != NULL && da_n != NULL) { 1114 carg = list_node_data(ca_n, tdata_item_t *); 1115 darg = list_node_data(da_n, tdata_item_t *); 1116 1117 if (tdata_item_equal(carg, darg) != b_true) { 1118 /* Diferent argument type */ 1119 stype_convert_failure(stype, expr, dest); 1120 printf("Different argument type '"); 1121 tdata_item_print(carg); 1122 printf("' vs. '"); 1123 tdata_item_print(darg); 1124 printf("'.\n"); 1125 return expr; 1126 } 1127 1128 ca_n = list_next(&cur->u.tobject->targs, ca_n); 1129 da_n = list_next(&dest->u.tobject->targs, da_n); 1130 } 1131 1132 if (ca_n != NULL || da_n != NULL) { 1133 /* Diferent number of arguments */ 1134 stype_convert_failure(stype, expr, dest); 1135 printf("Different number of arguments.\n"); 1391 /* 1392 * Find predecessor of the right type. This determines the 1393 * type arguments that the destination type should have. 1394 */ 1395 pred_ti = stype_tobject_find_pred(stype, src, dest); 1396 if (pred_ti == NULL) { 1397 stype_convert_failure(stype, convc_implicit, expr, dest); 1398 printf("Not a base class or implemented or accumulated " 1399 "interface.\n"); 1400 return expr; 1401 } 1402 1403 /* 1404 * Verify that type arguments match with those specified for 1405 * conversion destination. 1406 */ 1407 if (stype_targs_check_equal(stype, pred_ti, dest) != EOK) { 1408 stype_convert_failure(stype, convc_implicit, expr, dest); 1136 1409 return expr; 1137 1410 } … … 1160 1433 /* Compare rank and base type. */ 1161 1434 if (src->u.tarray->rank != dest->u.tarray->rank) { 1162 stype_convert_failure(stype, expr, dest);1435 stype_convert_failure(stype, convc_implicit, expr, dest); 1163 1436 return expr; 1164 1437 } … … 1167 1440 if (tdata_item_equal(src->u.tarray->base_ti, 1168 1441 dest->u.tarray->base_ti) != b_true) { 1169 stype_convert_failure(stype, expr, dest);1442 stype_convert_failure(stype, convc_implicit, expr, dest); 1170 1443 } 1171 1444 … … 1205 1478 /* Both must be the same delegate. */ 1206 1479 if (sdeleg->deleg != ddeleg->deleg) { 1207 stype_convert_failure(stype, expr, dest);1480 stype_convert_failure(stype, convc_implicit, expr, dest); 1208 1481 return expr; 1209 1482 } … … 1240 1513 /* Both must be of the same enum type (with the same declaration). */ 1241 1514 if (senum->enum_d != denum->enum_d) { 1242 stype_convert_failure(stype, expr, dest);1515 stype_convert_failure(stype, convc_implicit, expr, dest); 1243 1516 return expr; 1244 1517 } … … 1279 1552 1280 1553 if (!stype_fun_sig_equal(stype, ssig, dsig)) { 1281 stype_convert_failure(stype, expr, dest);1554 stype_convert_failure(stype, convc_implicit, expr, dest); 1282 1555 return expr; 1283 1556 } … … 1311 1584 /* Currently only allow if both types are the same. */ 1312 1585 if (src->u.tvref->targ != dest->u.tvref->targ) { 1313 stype_convert_failure(stype, expr, dest);1586 stype_convert_failure(stype, convc_implicit, expr, dest); 1314 1587 return expr; 1315 1588 } … … 1324 1597 * @param dest Destination type 1325 1598 */ 1326 static void stype_convert_failure(stype_t *stype, stree_expr_t *expr,1327 tdata_item_t *dest)1599 void stype_convert_failure(stype_t *stype, stype_conv_class_t convc, 1600 stree_expr_t *expr, tdata_item_t *dest) 1328 1601 { 1329 1602 cspan_print(expr->cspan); 1330 printf(" Error: Cannot convert "); 1603 printf(" Error: "); 1604 switch (convc) { 1605 case convc_implicit: printf("Cannot implicitly convert '"); break; 1606 case convc_as: printf("Cannot use 'as' to convert '"); break; 1607 } 1608 1331 1609 tdata_item_print(expr->titem); 1332 1610 printf(" to "); … … 1397 1675 } 1398 1676 1677 /** Find predecessor CSI and return its type item. 1678 * 1679 * Looks for predecessor of CSI type @a src that matches @a dest. 1680 * The type maches if they use the same generic CSI definition, type 1681 * arguments are ignored. If found, returns the type arguments that 1682 * @a dest should have in order to be a true predecessor of @a src. 1683 * 1684 * @param stype Static typing object 1685 * @param src Source type 1686 * @param dest Destination type 1687 * @return Type matching @a dest with correct type arguments 1688 */ 1689 tdata_item_t *stype_tobject_find_pred(stype_t *stype, tdata_item_t *src, 1690 tdata_item_t *dest) 1691 { 1692 stree_csi_t *src_csi; 1693 tdata_tvv_t *tvv; 1694 tdata_item_t *b_ti, *bs_ti; 1695 1696 list_node_t *pred_n; 1697 stree_texpr_t *pred_te; 1698 1699 tdata_item_t *res_ti; 1700 1701 #ifdef DEBUG_TYPE_TRACE 1702 printf("Find CSI predecessor.\n"); 1703 #endif 1704 assert(src->tic == tic_tobject); 1705 assert(dest->tic == tic_tobject); 1706 1707 if (src->u.tobject->csi == dest->u.tobject->csi) 1708 return src; 1709 1710 src_csi = src->u.tobject->csi; 1711 stype_titem_to_tvv(stype, src, &tvv); 1712 1713 res_ti = NULL; 1714 1715 switch (dest->u.tobject->csi->cc) { 1716 case csi_class: 1717 /* Destination is a class. Look at base class. */ 1718 pred_te = symbol_get_base_class_ref(stype->program, 1719 src_csi); 1720 if (pred_te != NULL) { 1721 run_texpr(stype->program, src_csi, pred_te, 1722 &b_ti); 1723 } else if (src_csi->base_csi != NULL && 1724 src->u.tobject->csi->cc == csi_class) { 1725 /* No explicit reference. Use grandfather class. */ 1726 b_ti = tdata_item_new(tic_tobject); 1727 b_ti->u.tobject = tdata_object_new(); 1728 b_ti->u.tobject->csi = src_csi->base_csi; 1729 b_ti->u.tobject->static_ref = sn_nonstatic; 1730 1731 list_init(&b_ti->u.tobject->targs); 1732 } else { 1733 /* No match */ 1734 return NULL; 1735 } 1736 1737 /* Substitute type variables to get predecessor type. */ 1738 tdata_item_subst(b_ti, tvv, &bs_ti); 1739 assert(bs_ti->tic == tic_tobject); 1740 1741 /* Recurse to compute the rest of the path. */ 1742 res_ti = stype_tobject_find_pred(stype, bs_ti, dest); 1743 if (b_ti->tic == tic_ignore) { 1744 /* An error occured. */ 1745 return NULL; 1746 } 1747 break; 1748 case csi_struct: 1749 assert(b_false); 1750 case csi_interface: 1751 /* 1752 * Destination is an interface. Look at implemented 1753 * or accumulated interfaces. 1754 */ 1755 pred_n = list_first(&src_csi->inherit); 1756 while (pred_n != NULL) { 1757 pred_te = list_node_data(pred_n, stree_texpr_t *); 1758 run_texpr(stype->program, src_csi, pred_te, 1759 &b_ti); 1760 1761 /* Substitute type variables to get predecessor type. */ 1762 tdata_item_subst(b_ti, tvv, &bs_ti); 1763 assert(bs_ti->tic == tic_tobject); 1764 1765 /* Recurse to compute the rest of the path. */ 1766 res_ti = stype_tobject_find_pred(stype, bs_ti, dest); 1767 if (res_ti != NULL) 1768 break; 1769 1770 pred_n = list_next(&src_csi->inherit, pred_n); 1771 } 1772 break; 1773 } 1774 1775 return res_ti; 1776 } 1777 1778 /** Check whether type arguments of expression type and another type are equal. 1779 * 1780 * Compare type arguments of the type of @a expr and of type @a b_ti. 1781 * @a convc denotes the type of conversion for which we perform this check 1782 * (for sake of error reporting). 1783 * 1784 * If the type arguments are not equal a typing error and a conversion error 1785 * message is generated. 1786 * 1787 * @param stype Static typing object 1788 * @param expr Expression 1789 * @param b_ti b_tiination type 1790 * @return EOK if equal, EINVAL if not. 1791 */ 1792 int stype_targs_check_equal(stype_t *stype, tdata_item_t *a_ti, 1793 tdata_item_t *b_ti) 1794 { 1795 list_node_t *arg_a_n, *arg_b_n; 1796 tdata_item_t *arg_a, *arg_b; 1797 1798 (void) stype; 1799 1800 #ifdef DEBUG_TYPE_TRACE 1801 printf("Check if type arguments match.\n"); 1802 #endif 1803 assert(a_ti->tic == tic_tobject); 1804 assert(b_ti->tic == tic_tobject); 1805 1806 /* 1807 * Verify that type arguments match with those specified for 1808 * conversion b_tiination. 1809 */ 1810 arg_a_n = list_first(&a_ti->u.tobject->targs); 1811 arg_b_n = list_first(&b_ti->u.tobject->targs); 1812 1813 while (arg_a_n != NULL && arg_b_n != NULL) { 1814 arg_a = list_node_data(arg_a_n, tdata_item_t *); 1815 arg_b = list_node_data(arg_b_n, tdata_item_t *); 1816 1817 if (tdata_item_equal(arg_a, arg_b) != b_true) { 1818 /* Diferent argument type */ 1819 printf("Different argument type '"); 1820 tdata_item_print(arg_a); 1821 printf("' vs. '"); 1822 tdata_item_print(arg_b); 1823 printf("'.\n"); 1824 return EINVAL; 1825 } 1826 1827 arg_a_n = list_next(&a_ti->u.tobject->targs, arg_a_n); 1828 arg_b_n = list_next(&b_ti->u.tobject->targs, arg_b_n); 1829 } 1830 1831 if (arg_a_n != NULL || arg_b_n != NULL) { 1832 /* Diferent number of arguments */ 1833 printf("Different number of arguments.\n"); 1834 return EINVAL; 1835 } 1836 1837 return EOK; 1838 } 1399 1839 1400 1840 … … 1448 1888 1449 1889 /* Compare return type */ 1450 if (!tdata_item_equal(asig->rtype, bsig->rtype)) 1451 return b_false; 1890 1891 if (asig->rtype != NULL || bsig->rtype != NULL) { 1892 if (asig->rtype == NULL || 1893 bsig->rtype == NULL) { 1894 return b_false; 1895 } 1896 1897 if (!tdata_item_equal(asig->rtype, bsig->rtype)) { 1898 return b_false; 1899 } 1900 } 1452 1901 1453 1902 return b_true;
Note:
See TracChangeset
for help on using the changeset viewer.