Mercurial > hg > CbC > CbC_gcc
comparison gcc/go/gofrontend/types.cc @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
101 const Forward_declaration_type* ftype = t->forward_declaration_type(); | 101 const Forward_declaration_type* ftype = t->forward_declaration_type(); |
102 while (ftype != NULL && ftype->is_defined()) | 102 while (ftype != NULL && ftype->is_defined()) |
103 { | 103 { |
104 t = ftype->real_type(); | 104 t = ftype->real_type(); |
105 ftype = t->forward_declaration_type(); | 105 ftype = t->forward_declaration_type(); |
106 } | |
107 return t; | |
108 } | |
109 | |
110 // Skip alias definitions. | |
111 | |
112 Type* | |
113 Type::unalias() | |
114 { | |
115 Type* t = this->forwarded(); | |
116 Named_type* nt = t->named_type(); | |
117 while (nt != NULL && nt->is_alias()) | |
118 { | |
119 t = nt->real_type()->forwarded(); | |
120 nt = t->named_type(); | |
121 } | |
122 return t; | |
123 } | |
124 | |
125 const Type* | |
126 Type::unalias() const | |
127 { | |
128 const Type* t = this->forwarded(); | |
129 const Named_type* nt = t->named_type(); | |
130 while (nt != NULL && nt->is_alias()) | |
131 { | |
132 t = nt->real_type()->forwarded(); | |
133 nt = t->named_type(); | |
106 } | 134 } |
107 return t; | 135 return t; |
108 } | 136 } |
109 | 137 |
110 // If this is a named type, return it. Otherwise, return NULL. | 138 // If this is a named type, return it. Otherwise, return NULL. |
306 Type::do_traverse(Traverse*) | 334 Type::do_traverse(Traverse*) |
307 { | 335 { |
308 return TRAVERSE_CONTINUE; | 336 return TRAVERSE_CONTINUE; |
309 } | 337 } |
310 | 338 |
311 // Return whether two types are identical. If ERRORS_ARE_IDENTICAL, | 339 // Return whether two types are identical. If REASON is not NULL, |
312 // then return true for all erroneous types; this is used to avoid | 340 // optionally set *REASON to the reason the types are not identical. |
313 // cascading errors. If REASON is not NULL, optionally set *REASON to | |
314 // the reason the types are not identical. | |
315 | 341 |
316 bool | 342 bool |
317 Type::are_identical(const Type* t1, const Type* t2, bool errors_are_identical, | 343 Type::are_identical(const Type* t1, const Type* t2, int flags, |
318 std::string* reason) | 344 std::string* reason) |
319 { | 345 { |
320 return Type::are_identical_cmp_tags(t1, t2, COMPARE_TAGS, | |
321 errors_are_identical, reason); | |
322 } | |
323 | |
324 // Like are_identical, but with a CMP_TAGS parameter. | |
325 | |
326 bool | |
327 Type::are_identical_cmp_tags(const Type* t1, const Type* t2, Cmp_tags cmp_tags, | |
328 bool errors_are_identical, std::string* reason) | |
329 { | |
330 if (t1 == NULL || t2 == NULL) | 346 if (t1 == NULL || t2 == NULL) |
331 { | 347 { |
332 // Something is wrong. | 348 // Something is wrong. |
333 return errors_are_identical ? true : t1 == t2; | 349 return (flags & COMPARE_ERRORS) == 0 ? true : t1 == t2; |
334 } | 350 } |
335 | 351 |
336 // Skip defined forward declarations. | 352 // Skip defined forward declarations. |
337 t1 = t1->forwarded(); | 353 t1 = t1->forwarded(); |
338 t2 = t2->forwarded(); | 354 t2 = t2->forwarded(); |
339 | 355 |
340 // Ignore aliases for purposes of type identity. | 356 if ((flags & COMPARE_ALIASES) == 0) |
341 while (t1->named_type() != NULL && t1->named_type()->is_alias()) | 357 { |
342 t1 = t1->named_type()->real_type()->forwarded(); | 358 // Ignore aliases. |
343 while (t2->named_type() != NULL && t2->named_type()->is_alias()) | 359 t1 = t1->unalias(); |
344 t2 = t2->named_type()->real_type()->forwarded(); | 360 t2 = t2->unalias(); |
361 } | |
345 | 362 |
346 if (t1 == t2) | 363 if (t1 == t2) |
347 return true; | 364 return true; |
348 | 365 |
349 // An undefined forward declaration is an error. | 366 // An undefined forward declaration is an error. |
350 if (t1->forward_declaration_type() != NULL | 367 if (t1->forward_declaration_type() != NULL |
351 || t2->forward_declaration_type() != NULL) | 368 || t2->forward_declaration_type() != NULL) |
352 return errors_are_identical; | 369 return (flags & COMPARE_ERRORS) == 0; |
353 | 370 |
354 // Avoid cascading errors with error types. | 371 // Avoid cascading errors with error types. |
355 if (t1->is_error_type() || t2->is_error_type()) | 372 if (t1->is_error_type() || t2->is_error_type()) |
356 { | 373 { |
357 if (errors_are_identical) | 374 if ((flags & COMPARE_ERRORS) == 0) |
358 return true; | 375 return true; |
359 return t1->is_error_type() && t2->is_error_type(); | 376 return t1->is_error_type() && t2->is_error_type(); |
360 } | 377 } |
361 | 378 |
362 // Get a good reason for the sink type. Note that the sink type on | 379 // Get a good reason for the sink type. Note that the sink type on |
394 case TYPE_COMPLEX: | 411 case TYPE_COMPLEX: |
395 return t1->complex_type()->is_identical(t2->complex_type()); | 412 return t1->complex_type()->is_identical(t2->complex_type()); |
396 | 413 |
397 case TYPE_FUNCTION: | 414 case TYPE_FUNCTION: |
398 return t1->function_type()->is_identical(t2->function_type(), | 415 return t1->function_type()->is_identical(t2->function_type(), |
399 false, | 416 false, flags, reason); |
400 cmp_tags, | |
401 errors_are_identical, | |
402 reason); | |
403 | 417 |
404 case TYPE_POINTER: | 418 case TYPE_POINTER: |
405 return Type::are_identical_cmp_tags(t1->points_to(), t2->points_to(), | 419 return Type::are_identical(t1->points_to(), t2->points_to(), flags, |
406 cmp_tags, errors_are_identical, | 420 reason); |
407 reason); | |
408 | 421 |
409 case TYPE_STRUCT: | 422 case TYPE_STRUCT: |
410 return t1->struct_type()->is_identical(t2->struct_type(), cmp_tags, | 423 return t1->struct_type()->is_identical(t2->struct_type(), flags); |
411 errors_are_identical); | |
412 | 424 |
413 case TYPE_ARRAY: | 425 case TYPE_ARRAY: |
414 return t1->array_type()->is_identical(t2->array_type(), cmp_tags, | 426 return t1->array_type()->is_identical(t2->array_type(), flags); |
415 errors_are_identical); | |
416 | 427 |
417 case TYPE_MAP: | 428 case TYPE_MAP: |
418 return t1->map_type()->is_identical(t2->map_type(), cmp_tags, | 429 return t1->map_type()->is_identical(t2->map_type(), flags); |
419 errors_are_identical); | |
420 | 430 |
421 case TYPE_CHANNEL: | 431 case TYPE_CHANNEL: |
422 return t1->channel_type()->is_identical(t2->channel_type(), cmp_tags, | 432 return t1->channel_type()->is_identical(t2->channel_type(), flags); |
423 errors_are_identical); | |
424 | 433 |
425 case TYPE_INTERFACE: | 434 case TYPE_INTERFACE: |
426 return t1->interface_type()->is_identical(t2->interface_type(), cmp_tags, | 435 return t1->interface_type()->is_identical(t2->interface_type(), flags); |
427 errors_are_identical); | |
428 | 436 |
429 case TYPE_CALL_MULTIPLE_RESULT: | 437 case TYPE_CALL_MULTIPLE_RESULT: |
430 if (reason != NULL) | 438 if (reason != NULL) |
431 *reason = "invalid use of multiple-value function call"; | 439 *reason = "invalid use of multiple-value function call"; |
432 return false; | 440 return false; |
440 // and RHS. This is not used for shifts or comparisons. | 448 // and RHS. This is not used for shifts or comparisons. |
441 | 449 |
442 bool | 450 bool |
443 Type::are_compatible_for_binop(const Type* lhs, const Type* rhs) | 451 Type::are_compatible_for_binop(const Type* lhs, const Type* rhs) |
444 { | 452 { |
445 if (Type::are_identical(lhs, rhs, true, NULL)) | 453 if (Type::are_identical(lhs, rhs, Type::COMPARE_TAGS, NULL)) |
446 return true; | 454 return true; |
447 | 455 |
448 // A constant of abstract bool type may be mixed with any bool type. | 456 // A constant of abstract bool type may be mixed with any bool type. |
449 if ((rhs->is_abstract_boolean_type() && lhs->is_boolean_type()) | 457 if ((rhs->is_abstract_boolean_type() && lhs->is_boolean_type()) |
450 || (lhs->is_abstract_boolean_type() && rhs->is_boolean_type())) | 458 || (lhs->is_abstract_boolean_type() && rhs->is_boolean_type())) |
573 if (reason != NULL) | 581 if (reason != NULL) |
574 *reason = _("invalid comparison of non-comparable type"); | 582 *reason = _("invalid comparison of non-comparable type"); |
575 return false; | 583 return false; |
576 } | 584 } |
577 | 585 |
578 if (t1->named_type() != NULL) | 586 if (t1->unalias()->named_type() != NULL) |
579 return t1->named_type()->named_type_is_comparable(reason); | 587 return t1->unalias()->named_type()->named_type_is_comparable(reason); |
580 else if (t2->named_type() != NULL) | 588 else if (t2->unalias()->named_type() != NULL) |
581 return t2->named_type()->named_type_is_comparable(reason); | 589 return t2->unalias()->named_type()->named_type_is_comparable(reason); |
582 else if (t1->struct_type() != NULL) | 590 else if (t1->struct_type() != NULL) |
583 { | 591 { |
584 if (t1->struct_type()->is_struct_incomparable()) | 592 if (t1->struct_type()->is_struct_incomparable()) |
585 { | 593 { |
586 if (reason != NULL) | 594 if (reason != NULL) |
651 && !lhs->is_undefined() | 659 && !lhs->is_undefined() |
652 && lhs->is_sink_type()) | 660 && lhs->is_sink_type()) |
653 return true; | 661 return true; |
654 | 662 |
655 // Identical types are assignable. | 663 // Identical types are assignable. |
656 if (Type::are_identical(lhs, rhs, true, reason)) | 664 if (Type::are_identical(lhs, rhs, Type::COMPARE_TAGS, reason)) |
657 return true; | 665 return true; |
666 | |
667 // Ignore aliases, except for error messages. | |
668 const Type* lhs_orig = lhs; | |
669 const Type* rhs_orig = rhs; | |
670 lhs = lhs->unalias(); | |
671 rhs = rhs->unalias(); | |
658 | 672 |
659 // The types are assignable if they have identical underlying types | 673 // The types are assignable if they have identical underlying types |
660 // and either LHS or RHS is not a named type. | 674 // and either LHS or RHS is not a named type. |
661 if (((lhs->named_type() != NULL && rhs->named_type() == NULL) | 675 if (((lhs->named_type() != NULL && rhs->named_type() == NULL) |
662 || (rhs->named_type() != NULL && lhs->named_type() == NULL)) | 676 || (rhs->named_type() != NULL && lhs->named_type() == NULL)) |
663 && Type::are_identical(lhs->base(), rhs->base(), true, reason)) | 677 && Type::are_identical(lhs->base(), rhs->base(), Type::COMPARE_TAGS, |
678 reason)) | |
664 return true; | 679 return true; |
665 | 680 |
666 // The types are assignable if LHS is an interface type and RHS | 681 // The types are assignable if LHS is an interface type and RHS |
667 // implements the required methods. | 682 // implements the required methods. |
668 const Interface_type* lhs_interface_type = lhs->interface_type(); | 683 const Interface_type* lhs_interface_type = lhs->interface_type(); |
685 && rhs->channel_type()->may_send() | 700 && rhs->channel_type()->may_send() |
686 && rhs->channel_type()->may_receive() | 701 && rhs->channel_type()->may_receive() |
687 && (lhs->named_type() == NULL || rhs->named_type() == NULL) | 702 && (lhs->named_type() == NULL || rhs->named_type() == NULL) |
688 && Type::are_identical(lhs->channel_type()->element_type(), | 703 && Type::are_identical(lhs->channel_type()->element_type(), |
689 rhs->channel_type()->element_type(), | 704 rhs->channel_type()->element_type(), |
690 true, | 705 Type::COMPARE_TAGS, |
691 reason)) | 706 reason)) |
692 return true; | 707 return true; |
693 | 708 |
694 // The nil type may be assigned to a pointer, function, slice, map, | 709 // The nil type may be assigned to a pointer, function, slice, map, |
695 // channel, or interface type. | 710 // channel, or interface type. |
716 // Give some better error messages. | 731 // Give some better error messages. |
717 if (reason != NULL && reason->empty()) | 732 if (reason != NULL && reason->empty()) |
718 { | 733 { |
719 if (rhs->interface_type() != NULL) | 734 if (rhs->interface_type() != NULL) |
720 reason->assign(_("need explicit conversion")); | 735 reason->assign(_("need explicit conversion")); |
721 else if (lhs->named_type() != NULL && rhs->named_type() != NULL) | 736 else if (lhs_orig->named_type() != NULL |
722 { | 737 && rhs_orig->named_type() != NULL) |
723 size_t len = (lhs->named_type()->name().length() | 738 { |
724 + rhs->named_type()->name().length() | 739 size_t len = (lhs_orig->named_type()->name().length() |
740 + rhs_orig->named_type()->name().length() | |
725 + 100); | 741 + 100); |
726 char* buf = new char[len]; | 742 char* buf = new char[len]; |
727 snprintf(buf, len, _("cannot use type %s as type %s"), | 743 snprintf(buf, len, _("cannot use type %s as type %s"), |
728 rhs->named_type()->message_name().c_str(), | 744 rhs_orig->named_type()->message_name().c_str(), |
729 lhs->named_type()->message_name().c_str()); | 745 lhs_orig->named_type()->message_name().c_str()); |
730 reason->assign(buf); | 746 reason->assign(buf); |
731 delete[] buf; | 747 delete[] buf; |
732 } | 748 } |
733 } | 749 } |
734 | 750 |
743 Type::are_convertible(const Type* lhs, const Type* rhs, std::string* reason) | 759 Type::are_convertible(const Type* lhs, const Type* rhs, std::string* reason) |
744 { | 760 { |
745 // The types are convertible if they are assignable. | 761 // The types are convertible if they are assignable. |
746 if (Type::are_assignable(lhs, rhs, reason)) | 762 if (Type::are_assignable(lhs, rhs, reason)) |
747 return true; | 763 return true; |
764 | |
765 // Ignore aliases. | |
766 lhs = lhs->unalias(); | |
767 rhs = rhs->unalias(); | |
748 | 768 |
749 // A pointer to a regular type may not be converted to a pointer to | 769 // A pointer to a regular type may not be converted to a pointer to |
750 // a type that may not live in the heap, except when converting from | 770 // a type that may not live in the heap, except when converting from |
751 // unsafe.Pointer. | 771 // unsafe.Pointer. |
752 if (lhs->points_to() != NULL | 772 if (lhs->points_to() != NULL |
761 } | 781 } |
762 | 782 |
763 // The types are convertible if they have identical underlying | 783 // The types are convertible if they have identical underlying |
764 // types, ignoring struct field tags. | 784 // types, ignoring struct field tags. |
765 if ((lhs->named_type() != NULL || rhs->named_type() != NULL) | 785 if ((lhs->named_type() != NULL || rhs->named_type() != NULL) |
766 && Type::are_identical_cmp_tags(lhs->base(), rhs->base(), IGNORE_TAGS, | 786 && Type::are_identical(lhs->base(), rhs->base(), 0, reason)) |
767 true, reason)) | |
768 return true; | 787 return true; |
769 | 788 |
770 // The types are convertible if they are both unnamed pointer types | 789 // The types are convertible if they are both unnamed pointer types |
771 // and their pointer base types have identical underlying types, | 790 // and their pointer base types have identical underlying types, |
772 // ignoring struct field tags. | 791 // ignoring struct field tags. |
774 && rhs->named_type() == NULL | 793 && rhs->named_type() == NULL |
775 && lhs->points_to() != NULL | 794 && lhs->points_to() != NULL |
776 && rhs->points_to() != NULL | 795 && rhs->points_to() != NULL |
777 && (lhs->points_to()->named_type() != NULL | 796 && (lhs->points_to()->named_type() != NULL |
778 || rhs->points_to()->named_type() != NULL) | 797 || rhs->points_to()->named_type() != NULL) |
779 && Type::are_identical_cmp_tags(lhs->points_to()->base(), | 798 && Type::are_identical(lhs->points_to()->base(), |
780 rhs->points_to()->base(), | 799 rhs->points_to()->base(), |
781 IGNORE_TAGS, | 800 0, reason)) |
782 true, | |
783 reason)) | |
784 return true; | 801 return true; |
785 | 802 |
786 // Integer and floating point types are convertible to each other. | 803 // Integer and floating point types are convertible to each other. |
787 if ((lhs->integer_type() != NULL || lhs->float_type() != NULL) | 804 if ((lhs->integer_type() != NULL || lhs->float_type() != NULL) |
788 && (rhs->integer_type() != NULL || rhs->float_type() != NULL)) | 805 && (rhs->integer_type() != NULL || rhs->float_type() != NULL)) |
844 } | 861 } |
845 | 862 |
846 return false; | 863 return false; |
847 } | 864 } |
848 | 865 |
866 // Copy expressions if it may change the size. | |
867 // | |
868 // The only type that has an expression is an array type. The only | |
869 // types whose size can be changed by the size of an array type are an | |
870 // array type itself, or a struct type with an array field. | |
871 Type* | |
872 Type::copy_expressions() | |
873 { | |
874 // This is run during parsing, so types may not be valid yet. | |
875 // We only have to worry about array type literals. | |
876 switch (this->classification_) | |
877 { | |
878 default: | |
879 return this; | |
880 | |
881 case TYPE_ARRAY: | |
882 { | |
883 Array_type* at = this->array_type(); | |
884 if (at->length() == NULL) | |
885 return this; | |
886 Expression* len = at->length()->copy(); | |
887 if (at->length() == len) | |
888 return this; | |
889 return Type::make_array_type(at->element_type(), len); | |
890 } | |
891 | |
892 case TYPE_STRUCT: | |
893 { | |
894 Struct_type* st = this->struct_type(); | |
895 const Struct_field_list* sfl = st->fields(); | |
896 if (sfl == NULL) | |
897 return this; | |
898 bool changed = false; | |
899 Struct_field_list *nsfl = new Struct_field_list(); | |
900 for (Struct_field_list::const_iterator pf = sfl->begin(); | |
901 pf != sfl->end(); | |
902 ++pf) | |
903 { | |
904 Type* ft = pf->type()->copy_expressions(); | |
905 Struct_field nf(Typed_identifier((pf->is_anonymous() | |
906 ? "" | |
907 : pf->field_name()), | |
908 ft, | |
909 pf->location())); | |
910 if (pf->has_tag()) | |
911 nf.set_tag(pf->tag()); | |
912 nsfl->push_back(nf); | |
913 if (ft != pf->type()) | |
914 changed = true; | |
915 } | |
916 if (!changed) | |
917 { | |
918 delete(nsfl); | |
919 return this; | |
920 } | |
921 return Type::make_struct_type(nsfl, st->location()); | |
922 } | |
923 } | |
924 | |
925 go_unreachable(); | |
926 } | |
927 | |
849 // Return a hash code for the type to be used for method lookup. | 928 // Return a hash code for the type to be used for method lookup. |
850 | 929 |
851 unsigned int | 930 unsigned int |
852 Type::hash_for_method(Gogo* gogo) const | 931 Type::hash_for_method(Gogo* gogo, int flags) const |
853 { | 932 { |
854 if (this->named_type() != NULL && this->named_type()->is_alias()) | 933 const Type* t = this->forwarded(); |
855 return this->named_type()->real_type()->hash_for_method(gogo); | 934 if (t->named_type() != NULL && t->named_type()->is_alias()) |
856 unsigned int ret = 0; | 935 { |
857 if (this->classification_ != TYPE_FORWARD) | 936 unsigned int r = |
858 ret += this->classification_; | 937 t->named_type()->real_type()->hash_for_method(gogo, flags); |
859 return ret + this->do_hash_for_method(gogo); | 938 if ((flags & Type::COMPARE_ALIASES) != 0) |
939 r += TYPE_FORWARD; | |
940 return r; | |
941 } | |
942 unsigned int ret = t->classification_; | |
943 return ret + t->do_hash_for_method(gogo, flags); | |
860 } | 944 } |
861 | 945 |
862 // Default implementation of do_hash_for_method. This is appropriate | 946 // Default implementation of do_hash_for_method. This is appropriate |
863 // for types with no subfields. | 947 // for types with no subfields. |
864 | 948 |
865 unsigned int | 949 unsigned int |
866 Type::do_hash_for_method(Gogo*) const | 950 Type::do_hash_for_method(Gogo*, int) const |
867 { | 951 { |
868 return 0; | 952 return 0; |
869 } | 953 } |
870 | 954 |
871 // Return a hash code for a string, given a starting hash. | 955 // Return a hash code for a string, given a starting hash. |
893 Btype* | 977 Btype* |
894 Type::get_backend(Gogo* gogo) | 978 Type::get_backend(Gogo* gogo) |
895 { | 979 { |
896 if (this->btype_ != NULL) | 980 if (this->btype_ != NULL) |
897 return this->btype_; | 981 return this->btype_; |
982 | |
983 if (this->named_type() != NULL && this->named_type()->is_alias()) { | |
984 Btype* bt = this->unalias()->get_backend(gogo); | |
985 if (gogo != NULL && gogo->named_types_are_converted()) | |
986 this->btype_ = bt; | |
987 return bt; | |
988 } | |
898 | 989 |
899 if (this->forward_declaration_type() != NULL | 990 if (this->forward_declaration_type() != NULL |
900 || this->named_type() != NULL) | 991 || this->named_type() != NULL) |
901 return this->get_btype_without_hash(gogo); | 992 return this->get_btype_without_hash(gogo); |
902 | 993 |
1021 | 1112 |
1022 case TYPE_NAMED: | 1113 case TYPE_NAMED: |
1023 case TYPE_FORWARD: | 1114 case TYPE_FORWARD: |
1024 // Named types keep track of their own dependencies and manage | 1115 // Named types keep track of their own dependencies and manage |
1025 // their own placeholders. | 1116 // their own placeholders. |
1117 if (this->named_type() != NULL && this->named_type()->is_alias()) | |
1118 return this->unalias()->get_backend_placeholder(gogo); | |
1026 return this->get_backend(gogo); | 1119 return this->get_backend(gogo); |
1027 | 1120 |
1028 case TYPE_INTERFACE: | 1121 case TYPE_INTERFACE: |
1029 if (this->interface_type()->is_empty()) | 1122 if (this->interface_type()->is_empty()) |
1030 return Interface_type::get_backend_empty_interface_type(gogo); | 1123 return Interface_type::get_backend_empty_interface_type(gogo); |
1195 // Return a pointer to the type descriptor for this type. | 1288 // Return a pointer to the type descriptor for this type. |
1196 | 1289 |
1197 Bexpression* | 1290 Bexpression* |
1198 Type::type_descriptor_pointer(Gogo* gogo, Location location) | 1291 Type::type_descriptor_pointer(Gogo* gogo, Location location) |
1199 { | 1292 { |
1200 Type* t = this->forwarded(); | 1293 Type* t = this->unalias(); |
1201 while (t->named_type() != NULL && t->named_type()->is_alias()) | |
1202 t = t->named_type()->real_type()->forwarded(); | |
1203 if (t->type_descriptor_var_ == NULL) | 1294 if (t->type_descriptor_var_ == NULL) |
1204 { | 1295 { |
1205 t->make_type_descriptor_var(gogo); | 1296 t->make_type_descriptor_var(gogo); |
1206 go_assert(t->type_descriptor_var_ != NULL); | 1297 go_assert(t->type_descriptor_var_ != NULL); |
1207 } | 1298 } |
1208 Bexpression* var_expr = | 1299 Bexpression* var_expr = |
1209 gogo->backend()->var_expression(t->type_descriptor_var_, | 1300 gogo->backend()->var_expression(t->type_descriptor_var_, location); |
1210 VE_rvalue, location); | |
1211 Bexpression* var_addr = | 1301 Bexpression* var_addr = |
1212 gogo->backend()->address_expression(var_expr, location); | 1302 gogo->backend()->address_expression(var_expr, location); |
1213 Type* td_type = Type::make_type_descriptor_type(); | 1303 Type* td_type = Type::make_type_descriptor_type(); |
1214 Btype* td_btype = td_type->get_backend(gogo); | 1304 Btype* td_btype = td_type->get_backend(gogo); |
1215 Btype* ptd_btype = gogo->backend()->pointer_type(td_btype); | 1305 Btype* ptd_btype = gogo->backend()->pointer_type(td_btype); |
1647 void | 1737 void |
1648 Type::type_functions(Gogo* gogo, Named_type* name, Function_type* hash_fntype, | 1738 Type::type_functions(Gogo* gogo, Named_type* name, Function_type* hash_fntype, |
1649 Function_type* equal_fntype, Named_object** hash_fn, | 1739 Function_type* equal_fntype, Named_object** hash_fn, |
1650 Named_object** equal_fn) | 1740 Named_object** equal_fn) |
1651 { | 1741 { |
1652 // If this loop leaves NAME as NULL, then the type does not have a | 1742 // If the unaliased type is not a named type, then the type does not |
1653 // name after all. | 1743 // have a name after all. |
1654 while (name != NULL && name->is_alias()) | 1744 if (name != NULL) |
1655 name = name->real_type()->named_type(); | 1745 name = name->unalias()->named_type(); |
1656 | 1746 |
1657 if (!this->is_comparable()) | 1747 if (!this->is_comparable()) |
1658 { | 1748 { |
1659 *hash_fn = NULL; | 1749 *hash_fn = NULL; |
1660 *equal_fn = NULL; | 1750 *equal_fn = NULL; |
2214 Temporary_statement* p2 = Statement::make_temporary(pt, ref, bloc); | 2304 Temporary_statement* p2 = Statement::make_temporary(pt, ref, bloc); |
2215 gogo->add_statement(p2); | 2305 gogo->add_statement(p2); |
2216 | 2306 |
2217 // Compare the values for equality. | 2307 // Compare the values for equality. |
2218 Expression* t1 = Expression::make_temporary_reference(p1, bloc); | 2308 Expression* t1 = Expression::make_temporary_reference(p1, bloc); |
2219 t1 = Expression::make_unary(OPERATOR_MULT, t1, bloc); | 2309 t1 = Expression::make_dereference(t1, Expression::NIL_CHECK_NOT_NEEDED, bloc); |
2220 | 2310 |
2221 Expression* t2 = Expression::make_temporary_reference(p2, bloc); | 2311 Expression* t2 = Expression::make_temporary_reference(p2, bloc); |
2222 t2 = Expression::make_unary(OPERATOR_MULT, t2, bloc); | 2312 t2 = Expression::make_dereference(t2, Expression::NIL_CHECK_NOT_NEEDED, bloc); |
2223 | 2313 |
2224 Expression* cond = Expression::make_binary(OPERATOR_EQEQ, t1, t2, bloc); | 2314 Expression* cond = Expression::make_binary(OPERATOR_EQEQ, t1, t2, bloc); |
2225 | 2315 |
2226 // Return the equality comparison. | 2316 // Return the equality comparison. |
2227 Expression_list* vals = new Expression_list(); | 2317 Expression_list* vals = new Expression_list(); |
2267 | 2357 |
2268 ++p; | 2358 ++p; |
2269 go_assert(p->is_field_name("hash")); | 2359 go_assert(p->is_field_name("hash")); |
2270 unsigned int h; | 2360 unsigned int h; |
2271 if (name != NULL) | 2361 if (name != NULL) |
2272 h = name->hash_for_method(gogo); | 2362 h = name->hash_for_method(gogo, Type::COMPARE_TAGS); |
2273 else | 2363 else |
2274 h = this->hash_for_method(gogo); | 2364 h = this->hash_for_method(gogo, Type::COMPARE_TAGS); |
2275 vals->push_back(Expression::make_integer_ul(h, p->type(), bloc)); | 2365 vals->push_back(Expression::make_integer_ul(h, p->type(), bloc)); |
2276 | 2366 |
2277 ++p; | 2367 ++p; |
2278 go_assert(p->is_field_name("kind")); | 2368 go_assert(p->is_field_name("kind")); |
2279 vals->push_back(Expression::make_integer_ul(runtime_type_kind, p->type(), | 2369 vals->push_back(Expression::make_integer_ul(runtime_type_kind, p->type(), |
2369 // Return a pointer to the Garbage Collection information for this type. | 2459 // Return a pointer to the Garbage Collection information for this type. |
2370 | 2460 |
2371 Bexpression* | 2461 Bexpression* |
2372 Type::gc_symbol_pointer(Gogo* gogo) | 2462 Type::gc_symbol_pointer(Gogo* gogo) |
2373 { | 2463 { |
2374 Type* t = this->forwarded(); | 2464 Type* t = this->unalias(); |
2375 while (t->named_type() != NULL && t->named_type()->is_alias()) | |
2376 t = t->named_type()->real_type()->forwarded(); | |
2377 | 2465 |
2378 if (!t->has_pointer()) | 2466 if (!t->has_pointer()) |
2379 return gogo->backend()->nil_pointer_expression(); | 2467 return gogo->backend()->nil_pointer_expression(); |
2380 | 2468 |
2381 if (t->gc_symbol_var_ == NULL) | 2469 if (t->gc_symbol_var_ == NULL) |
2383 t->make_gc_symbol_var(gogo); | 2471 t->make_gc_symbol_var(gogo); |
2384 go_assert(t->gc_symbol_var_ != NULL); | 2472 go_assert(t->gc_symbol_var_ != NULL); |
2385 } | 2473 } |
2386 Location bloc = Linemap::predeclared_location(); | 2474 Location bloc = Linemap::predeclared_location(); |
2387 Bexpression* var_expr = | 2475 Bexpression* var_expr = |
2388 gogo->backend()->var_expression(t->gc_symbol_var_, VE_rvalue, bloc); | 2476 gogo->backend()->var_expression(t->gc_symbol_var_, bloc); |
2389 Bexpression* addr_expr = | 2477 Bexpression* addr_expr = |
2390 gogo->backend()->address_expression(var_expr, bloc); | 2478 gogo->backend()->address_expression(var_expr, bloc); |
2391 | 2479 |
2392 Type* uint8_type = Type::lookup_integer_type("uint8"); | 2480 Type* uint8_type = Type::lookup_integer_type("uint8"); |
2393 Type* pointer_uint8_type = Type::make_pointer_type(uint8_type); | 2481 Type* pointer_uint8_type = Type::make_pointer_type(uint8_type); |
2653 } | 2741 } |
2654 | 2742 |
2655 // Return a symbol name for this ptrmask. This is used to coalesce | 2743 // Return a symbol name for this ptrmask. This is used to coalesce |
2656 // identical ptrmasks, which are common. The symbol name must use | 2744 // identical ptrmasks, which are common. The symbol name must use |
2657 // only characters that are valid in symbols. It's nice if it's | 2745 // only characters that are valid in symbols. It's nice if it's |
2658 // short. We convert it to a base64 string. | 2746 // short. We convert it to a string that uses only 32 characters, |
2747 // avoiding digits and u and U. | |
2659 | 2748 |
2660 std::string | 2749 std::string |
2661 Ptrmask::symname() const | 2750 Ptrmask::symname() const |
2662 { | 2751 { |
2663 const char chars[65] = | 2752 const char chars[33] = "abcdefghijklmnopqrstvwxyzABCDEFG"; |
2664 "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_."; | 2753 go_assert(chars[32] == '\0'); |
2665 go_assert(chars[64] == '\0'); | |
2666 std::string ret; | 2754 std::string ret; |
2667 unsigned int b = 0; | 2755 unsigned int b = 0; |
2668 int remaining = 0; | 2756 int remaining = 0; |
2669 for (std::vector<unsigned char>::const_iterator p = this->bits_.begin(); | 2757 for (std::vector<unsigned char>::const_iterator p = this->bits_.begin(); |
2670 p != this->bits_.end(); | 2758 p != this->bits_.end(); |
2671 ++p) | 2759 ++p) |
2672 { | 2760 { |
2673 b |= *p << remaining; | 2761 b |= *p << remaining; |
2674 remaining += 8; | 2762 remaining += 8; |
2675 while (remaining >= 6) | 2763 while (remaining >= 5) |
2676 { | 2764 { |
2677 ret += chars[b & 0x3f]; | 2765 ret += chars[b & 0x1f]; |
2678 b >>= 6; | 2766 b >>= 5; |
2679 remaining -= 6; | 2767 remaining -= 5; |
2680 } | 2768 } |
2681 } | 2769 } |
2682 while (remaining > 0) | 2770 while (remaining > 0) |
2683 { | 2771 { |
2684 ret += chars[b & 0x3f]; | 2772 ret += chars[b & 0x1f]; |
2685 b >>= 6; | 2773 b >>= 5; |
2686 remaining -= 6; | 2774 remaining -= 5; |
2687 } | 2775 } |
2688 return ret; | 2776 return ret; |
2689 } | 2777 } |
2690 | 2778 |
2691 // Return a constructor for this ptrmask. This will be used to | 2779 // Return a constructor for this ptrmask. This will be used to |
3879 } | 3967 } |
3880 | 3968 |
3881 // Hash code. | 3969 // Hash code. |
3882 | 3970 |
3883 unsigned int | 3971 unsigned int |
3884 Integer_type::do_hash_for_method(Gogo*) const | 3972 Integer_type::do_hash_for_method(Gogo*, int) const |
3885 { | 3973 { |
3886 return ((this->bits_ << 4) | 3974 return ((this->bits_ << 4) |
3887 + ((this->is_unsigned_ ? 1 : 0) << 8) | 3975 + ((this->is_unsigned_ ? 1 : 0) << 8) |
3888 + ((this->is_abstract_ ? 1 : 0) << 9)); | 3976 + ((this->is_abstract_ ? 1 : 0) << 9)); |
3889 } | 3977 } |
4009 } | 4097 } |
4010 | 4098 |
4011 // Hash code. | 4099 // Hash code. |
4012 | 4100 |
4013 unsigned int | 4101 unsigned int |
4014 Float_type::do_hash_for_method(Gogo*) const | 4102 Float_type::do_hash_for_method(Gogo*, int) const |
4015 { | 4103 { |
4016 return (this->bits_ << 4) + ((this->is_abstract_ ? 1 : 0) << 8); | 4104 return (this->bits_ << 4) + ((this->is_abstract_ ? 1 : 0) << 8); |
4017 } | 4105 } |
4018 | 4106 |
4019 // Convert to the backend representation. | 4107 // Convert to the backend representation. |
4123 } | 4211 } |
4124 | 4212 |
4125 // Hash code. | 4213 // Hash code. |
4126 | 4214 |
4127 unsigned int | 4215 unsigned int |
4128 Complex_type::do_hash_for_method(Gogo*) const | 4216 Complex_type::do_hash_for_method(Gogo*, int) const |
4129 { | 4217 { |
4130 return (this->bits_ << 4) + ((this->is_abstract_ ? 1 : 0) << 8); | 4218 return (this->bits_ << 4) + ((this->is_abstract_ ? 1 : 0) << 8); |
4131 } | 4219 } |
4132 | 4220 |
4133 // Convert to the backend representation. | 4221 // Convert to the backend representation. |
4342 | 4430 |
4343 bool | 4431 bool |
4344 Function_type::is_valid_redeclaration(const Function_type* t, | 4432 Function_type::is_valid_redeclaration(const Function_type* t, |
4345 std::string* reason) const | 4433 std::string* reason) const |
4346 { | 4434 { |
4347 if (!this->is_identical(t, false, COMPARE_TAGS, true, reason)) | 4435 if (!this->is_identical(t, false, COMPARE_TAGS, reason)) |
4348 return false; | 4436 return false; |
4349 | 4437 |
4350 // A redeclaration of a function is required to use the same names | 4438 // A redeclaration of a function is required to use the same names |
4351 // for the receiver and parameters. | 4439 // for the receiver and parameters. |
4352 if (this->receiver() != NULL | 4440 if (this->receiver() != NULL |
4420 | 4508 |
4421 // Check whether T is the same as this type. | 4509 // Check whether T is the same as this type. |
4422 | 4510 |
4423 bool | 4511 bool |
4424 Function_type::is_identical(const Function_type* t, bool ignore_receiver, | 4512 Function_type::is_identical(const Function_type* t, bool ignore_receiver, |
4425 Cmp_tags cmp_tags, bool errors_are_identical, | 4513 int flags, std::string* reason) const |
4426 std::string* reason) const | 4514 { |
4427 { | 4515 if (this->is_backend_function_type() != t->is_backend_function_type()) |
4516 return false; | |
4517 | |
4428 if (!ignore_receiver) | 4518 if (!ignore_receiver) |
4429 { | 4519 { |
4430 const Typed_identifier* r1 = this->receiver(); | 4520 const Typed_identifier* r1 = this->receiver(); |
4431 const Typed_identifier* r2 = t->receiver(); | 4521 const Typed_identifier* r2 = t->receiver(); |
4432 if ((r1 != NULL) != (r2 != NULL)) | 4522 if ((r1 != NULL) != (r2 != NULL)) |
4435 *reason = _("different receiver types"); | 4525 *reason = _("different receiver types"); |
4436 return false; | 4526 return false; |
4437 } | 4527 } |
4438 if (r1 != NULL) | 4528 if (r1 != NULL) |
4439 { | 4529 { |
4440 if (!Type::are_identical_cmp_tags(r1->type(), r2->type(), cmp_tags, | 4530 if (!Type::are_identical(r1->type(), r2->type(), flags, reason)) |
4441 errors_are_identical, reason)) | |
4442 { | 4531 { |
4443 if (reason != NULL && !reason->empty()) | 4532 if (reason != NULL && !reason->empty()) |
4444 *reason = "receiver: " + *reason; | 4533 *reason = "receiver: " + *reason; |
4445 return false; | 4534 return false; |
4446 } | 4535 } |
4447 } | 4536 } |
4448 } | 4537 } |
4449 | 4538 |
4450 const Typed_identifier_list* parms1 = this->parameters(); | 4539 const Typed_identifier_list* parms1 = this->parameters(); |
4540 if (parms1 != NULL && parms1->empty()) | |
4541 parms1 = NULL; | |
4451 const Typed_identifier_list* parms2 = t->parameters(); | 4542 const Typed_identifier_list* parms2 = t->parameters(); |
4543 if (parms2 != NULL && parms2->empty()) | |
4544 parms2 = NULL; | |
4452 if ((parms1 != NULL) != (parms2 != NULL)) | 4545 if ((parms1 != NULL) != (parms2 != NULL)) |
4453 { | 4546 { |
4454 if (reason != NULL) | 4547 if (reason != NULL) |
4455 *reason = _("different number of parameters"); | 4548 *reason = _("different number of parameters"); |
4456 return false; | 4549 return false; |
4467 if (reason != NULL) | 4560 if (reason != NULL) |
4468 *reason = _("different number of parameters"); | 4561 *reason = _("different number of parameters"); |
4469 return false; | 4562 return false; |
4470 } | 4563 } |
4471 | 4564 |
4472 if (!Type::are_identical_cmp_tags(p1->type(), p2->type(), cmp_tags, | 4565 if (!Type::are_identical(p1->type(), p2->type(), flags, NULL)) |
4473 errors_are_identical, NULL)) | |
4474 { | 4566 { |
4475 if (reason != NULL) | 4567 if (reason != NULL) |
4476 *reason = _("different parameter types"); | 4568 *reason = _("different parameter types"); |
4477 return false; | 4569 return false; |
4478 } | 4570 } |
4491 *reason = _("different varargs"); | 4583 *reason = _("different varargs"); |
4492 return false; | 4584 return false; |
4493 } | 4585 } |
4494 | 4586 |
4495 const Typed_identifier_list* results1 = this->results(); | 4587 const Typed_identifier_list* results1 = this->results(); |
4588 if (results1 != NULL && results1->empty()) | |
4589 results1 = NULL; | |
4496 const Typed_identifier_list* results2 = t->results(); | 4590 const Typed_identifier_list* results2 = t->results(); |
4591 if (results2 != NULL && results2->empty()) | |
4592 results2 = NULL; | |
4497 if ((results1 != NULL) != (results2 != NULL)) | 4593 if ((results1 != NULL) != (results2 != NULL)) |
4498 { | 4594 { |
4499 if (reason != NULL) | 4595 if (reason != NULL) |
4500 *reason = _("different number of results"); | 4596 *reason = _("different number of results"); |
4501 return false; | 4597 return false; |
4512 if (reason != NULL) | 4608 if (reason != NULL) |
4513 *reason = _("different number of results"); | 4609 *reason = _("different number of results"); |
4514 return false; | 4610 return false; |
4515 } | 4611 } |
4516 | 4612 |
4517 if (!Type::are_identical_cmp_tags(res1->type(), res2->type(), | 4613 if (!Type::are_identical(res1->type(), res2->type(), flags, NULL)) |
4518 cmp_tags, errors_are_identical, | |
4519 NULL)) | |
4520 { | 4614 { |
4521 if (reason != NULL) | 4615 if (reason != NULL) |
4522 *reason = _("different result types"); | 4616 *reason = _("different result types"); |
4523 return false; | 4617 return false; |
4524 } | 4618 } |
4535 } | 4629 } |
4536 | 4630 |
4537 // Hash code. | 4631 // Hash code. |
4538 | 4632 |
4539 unsigned int | 4633 unsigned int |
4540 Function_type::do_hash_for_method(Gogo* gogo) const | 4634 Function_type::do_hash_for_method(Gogo* gogo, int flags) const |
4541 { | 4635 { |
4542 unsigned int ret = 0; | 4636 unsigned int ret = 0; |
4543 // We ignore the receiver type for hash codes, because we need to | 4637 // We ignore the receiver type for hash codes, because we need to |
4544 // get the same hash code for a method in an interface and a method | 4638 // get the same hash code for a method in an interface and a method |
4545 // declared for a type. The former will not have a receiver. | 4639 // declared for a type. The former will not have a receiver. |
4547 { | 4641 { |
4548 int shift = 1; | 4642 int shift = 1; |
4549 for (Typed_identifier_list::const_iterator p = this->parameters_->begin(); | 4643 for (Typed_identifier_list::const_iterator p = this->parameters_->begin(); |
4550 p != this->parameters_->end(); | 4644 p != this->parameters_->end(); |
4551 ++p, ++shift) | 4645 ++p, ++shift) |
4552 ret += p->type()->hash_for_method(gogo) << shift; | 4646 ret += p->type()->hash_for_method(gogo, flags) << shift; |
4553 } | 4647 } |
4554 if (this->results_ != NULL) | 4648 if (this->results_ != NULL) |
4555 { | 4649 { |
4556 int shift = 2; | 4650 int shift = 2; |
4557 for (Typed_identifier_list::const_iterator p = this->results_->begin(); | 4651 for (Typed_identifier_list::const_iterator p = this->results_->begin(); |
4558 p != this->results_->end(); | 4652 p != this->results_->end(); |
4559 ++p, ++shift) | 4653 ++p, ++shift) |
4560 ret += p->type()->hash_for_method(gogo) << shift; | 4654 ret += p->type()->hash_for_method(gogo, flags) << shift; |
4561 } | 4655 } |
4562 if (this->is_varargs_) | 4656 if (this->is_varargs_) |
4563 ret += 1; | 4657 ret += 1; |
4564 ret <<= 4; | 4658 ret <<= 4; |
4565 return ret; | 4659 return ret; |
4575 p != t->end(); | 4669 p != t->end(); |
4576 ++p) | 4670 ++p) |
4577 { | 4671 { |
4578 hash <<= 2; | 4672 hash <<= 2; |
4579 hash = Type::hash_string(p->name(), hash); | 4673 hash = Type::hash_string(p->name(), hash); |
4580 hash += p->type()->hash_for_method(NULL); | 4674 hash += p->type()->hash_for_method(NULL, Type::COMPARE_TAGS); |
4581 } | 4675 } |
4582 return hash; | 4676 return hash; |
4583 } | 4677 } |
4584 | 4678 |
4585 // Compare result parameters so that can map identical result | 4679 // Compare result parameters so that can map identical result |
4595 for (Typed_identifier_list::const_iterator pb = b->begin(); | 4689 for (Typed_identifier_list::const_iterator pb = b->begin(); |
4596 pb != b->end(); | 4690 pb != b->end(); |
4597 ++pa, ++pb) | 4691 ++pa, ++pb) |
4598 { | 4692 { |
4599 if (pa->name() != pb->name() | 4693 if (pa->name() != pb->name() |
4600 || !Type::are_identical(pa->type(), pb->type(), true, NULL)) | 4694 || !Type::are_identical(pa->type(), pb->type(), Type::COMPARE_TAGS, |
4695 NULL)) | |
4601 return false; | 4696 return false; |
4602 } | 4697 } |
4603 return true; | 4698 return true; |
4604 } | 4699 } |
4605 | 4700 |
5157 } | 5252 } |
5158 | 5253 |
5159 // Hash code. | 5254 // Hash code. |
5160 | 5255 |
5161 unsigned int | 5256 unsigned int |
5162 Pointer_type::do_hash_for_method(Gogo* gogo) const | 5257 Pointer_type::do_hash_for_method(Gogo* gogo, int flags) const |
5163 { | 5258 { |
5164 return this->to_type_->hash_for_method(gogo) << 4; | 5259 return this->to_type_->hash_for_method(gogo, flags) << 4; |
5165 } | 5260 } |
5166 | 5261 |
5167 // Get the backend representation for a pointer type. | 5262 // Get the backend representation for a pointer type. |
5168 | 5263 |
5169 Btype* | 5264 Btype* |
5616 } | 5711 } |
5617 | 5712 |
5618 // Whether this type is identical to T. | 5713 // Whether this type is identical to T. |
5619 | 5714 |
5620 bool | 5715 bool |
5621 Struct_type::is_identical(const Struct_type* t, Cmp_tags cmp_tags, | 5716 Struct_type::is_identical(const Struct_type* t, int flags) const |
5622 bool errors_are_identical) const | |
5623 { | 5717 { |
5624 if (this->is_struct_incomparable_ != t->is_struct_incomparable_) | 5718 if (this->is_struct_incomparable_ != t->is_struct_incomparable_) |
5625 return false; | 5719 return false; |
5626 const Struct_field_list* fields1 = this->fields(); | 5720 const Struct_field_list* fields1 = this->fields(); |
5627 const Struct_field_list* fields2 = t->fields(); | 5721 const Struct_field_list* fields2 = t->fields(); |
5635 if (pf2 == fields2->end()) | 5729 if (pf2 == fields2->end()) |
5636 return false; | 5730 return false; |
5637 if (pf1->field_name() != pf2->field_name()) | 5731 if (pf1->field_name() != pf2->field_name()) |
5638 return false; | 5732 return false; |
5639 if (pf1->is_anonymous() != pf2->is_anonymous() | 5733 if (pf1->is_anonymous() != pf2->is_anonymous() |
5640 || !Type::are_identical_cmp_tags(pf1->type(), pf2->type(), cmp_tags, | 5734 || !Type::are_identical(pf1->type(), pf2->type(), flags, NULL)) |
5641 errors_are_identical, NULL)) | |
5642 return false; | 5735 return false; |
5643 if (cmp_tags == COMPARE_TAGS) | 5736 if ((flags & Type::COMPARE_TAGS) != 0) |
5644 { | 5737 { |
5645 if (!pf1->has_tag()) | 5738 if (!pf1->has_tag()) |
5646 { | 5739 { |
5647 if (pf2->has_tag()) | 5740 if (pf2->has_tag()) |
5648 return false; | 5741 return false; |
5769 // Build identity and hash functions for this struct. | 5862 // Build identity and hash functions for this struct. |
5770 | 5863 |
5771 // Hash code. | 5864 // Hash code. |
5772 | 5865 |
5773 unsigned int | 5866 unsigned int |
5774 Struct_type::do_hash_for_method(Gogo* gogo) const | 5867 Struct_type::do_hash_for_method(Gogo* gogo, int flags) const |
5775 { | 5868 { |
5776 unsigned int ret = 0; | 5869 unsigned int ret = 0; |
5777 if (this->fields() != NULL) | 5870 if (this->fields() != NULL) |
5778 { | 5871 { |
5779 for (Struct_field_list::const_iterator pf = this->fields()->begin(); | 5872 for (Struct_field_list::const_iterator pf = this->fields()->begin(); |
5780 pf != this->fields()->end(); | 5873 pf != this->fields()->end(); |
5781 ++pf) | 5874 ++pf) |
5782 ret = (ret << 1) + pf->type()->hash_for_method(gogo); | 5875 ret = (ret << 1) + pf->type()->hash_for_method(gogo, flags); |
5783 } | 5876 } |
5784 ret <<= 2; | 5877 ret <<= 2; |
5785 if (this->is_struct_incomparable_) | 5878 if (this->is_struct_incomparable_) |
5786 ret <<= 1; | 5879 ret <<= 1; |
5787 return ret; | 5880 return ret; |
5910 ret = sub; | 6003 ret = sub; |
5911 found_depth = subdepth; | 6004 found_depth = subdepth; |
5912 Expression* here = Expression::make_field_reference(struct_expr, i, | 6005 Expression* here = Expression::make_field_reference(struct_expr, i, |
5913 location); | 6006 location); |
5914 if (pf->type()->points_to() != NULL) | 6007 if (pf->type()->points_to() != NULL) |
5915 here = Expression::make_unary(OPERATOR_MULT, here, location); | 6008 here = Expression::make_dereference(here, |
6009 Expression::NIL_CHECK_DEFAULT, | |
6010 location); | |
5916 while (sub->expr() != NULL) | 6011 while (sub->expr() != NULL) |
5917 { | 6012 { |
5918 sub = sub->expr()->deref()->field_reference_expression(); | 6013 sub = sub->expr()->deref()->field_reference_expression(); |
5919 go_assert(sub != NULL); | 6014 go_assert(sub != NULL); |
5920 } | 6015 } |
6341 if (Gogo::is_sink_name(pf->field_name())) | 6436 if (Gogo::is_sink_name(pf->field_name())) |
6342 continue; | 6437 continue; |
6343 | 6438 |
6344 // Compare one field in both P1 and P2. | 6439 // Compare one field in both P1 and P2. |
6345 Expression* f1 = Expression::make_temporary_reference(p1, bloc); | 6440 Expression* f1 = Expression::make_temporary_reference(p1, bloc); |
6346 f1 = Expression::make_unary(OPERATOR_MULT, f1, bloc); | 6441 f1 = Expression::make_dereference(f1, Expression::NIL_CHECK_DEFAULT, |
6442 bloc); | |
6347 f1 = Expression::make_field_reference(f1, field_index, bloc); | 6443 f1 = Expression::make_field_reference(f1, field_index, bloc); |
6348 | 6444 |
6349 Expression* f2 = Expression::make_temporary_reference(p2, bloc); | 6445 Expression* f2 = Expression::make_temporary_reference(p2, bloc); |
6350 f2 = Expression::make_unary(OPERATOR_MULT, f2, bloc); | 6446 f2 = Expression::make_dereference(f2, Expression::NIL_CHECK_DEFAULT, |
6447 bloc); | |
6351 f2 = Expression::make_field_reference(f2, field_index, bloc); | 6448 f2 = Expression::make_field_reference(f2, field_index, bloc); |
6352 | 6449 |
6353 Expression* cond = Expression::make_binary(OPERATOR_NOTEQ, f1, f2, bloc); | 6450 Expression* cond = Expression::make_binary(OPERATOR_NOTEQ, f1, f2, bloc); |
6354 | 6451 |
6355 // If the values are not equal, return false. | 6452 // If the values are not equal, return false. |
6383 ++p) | 6480 ++p) |
6384 { | 6481 { |
6385 if (p != this->fields_->begin()) | 6482 if (p != this->fields_->begin()) |
6386 ret->push_back(';'); | 6483 ret->push_back(';'); |
6387 ret->push_back(' '); | 6484 ret->push_back(' '); |
6388 if (p->is_anonymous()) | 6485 if (!p->is_anonymous()) |
6389 ret->push_back('?'); | 6486 { |
6390 else | 6487 ret->append(Gogo::unpack_hidden_name(p->field_name())); |
6391 ret->append(Gogo::unpack_hidden_name(p->field_name())); | 6488 ret->push_back(' '); |
6392 ret->push_back(' '); | 6489 } |
6393 if (p->is_anonymous() | 6490 if (p->is_anonymous() |
6394 && p->type()->named_type() != NULL | 6491 && p->type()->named_type() != NULL |
6395 && p->type()->named_type()->is_alias()) | 6492 && p->type()->named_type()->is_alias()) |
6396 p->type()->named_type()->append_reflection_type_name(gogo, true, ret); | 6493 p->type()->named_type()->append_reflection_type_name(gogo, true, ret); |
6397 else | 6494 else |
6829 } | 6926 } |
6830 | 6927 |
6831 // Whether two array types are identical. | 6928 // Whether two array types are identical. |
6832 | 6929 |
6833 bool | 6930 bool |
6834 Array_type::is_identical(const Array_type* t, Cmp_tags cmp_tags, | 6931 Array_type::is_identical(const Array_type* t, int flags) const |
6835 bool errors_are_identical) const | 6932 { |
6836 { | 6933 if (!Type::are_identical(this->element_type(), t->element_type(), |
6837 if (!Type::are_identical_cmp_tags(this->element_type(), t->element_type(), | 6934 flags, NULL)) |
6838 cmp_tags, errors_are_identical, NULL)) | |
6839 return false; | 6935 return false; |
6840 | 6936 |
6841 if (this->is_array_incomparable_ != t->is_array_incomparable_) | 6937 if (this->is_array_incomparable_ != t->is_array_incomparable_) |
6842 return false; | 6938 return false; |
6843 | 6939 |
6906 this->length_->determine_type(&context); | 7002 this->length_->determine_type(&context); |
6907 | 7003 |
6908 if (!this->length_->is_constant()) | 7004 if (!this->length_->is_constant()) |
6909 { | 7005 { |
6910 go_error_at(this->length_->location(), "array bound is not constant"); | 7006 go_error_at(this->length_->location(), "array bound is not constant"); |
7007 return false; | |
7008 } | |
7009 | |
7010 // For array types, the length expression can be an untyped constant | |
7011 // representable as an int, but we don't allow explicitly non-integer | |
7012 // values such as "float64(10)". See issues #13485 and #13486. | |
7013 if (this->length_->type()->integer_type() == NULL | |
7014 && !this->length_->type()->is_error_type()) | |
7015 { | |
7016 go_error_at(this->length_->location(), "invalid array bound"); | |
6911 return false; | 7017 return false; |
6912 } | 7018 } |
6913 | 7019 |
6914 Numeric_constant nc; | 7020 Numeric_constant nc; |
6915 if (!this->length_->numeric_constant_value(&nc)) | 7021 if (!this->length_->numeric_constant_value(&nc)) |
7033 } | 7139 } |
7034 | 7140 |
7035 // Array type hash code. | 7141 // Array type hash code. |
7036 | 7142 |
7037 unsigned int | 7143 unsigned int |
7038 Array_type::do_hash_for_method(Gogo* gogo) const | 7144 Array_type::do_hash_for_method(Gogo* gogo, int flags) const |
7039 { | 7145 { |
7040 unsigned int ret; | 7146 unsigned int ret; |
7041 | 7147 |
7042 // There is no very convenient way to get a hash code for the | 7148 // There is no very convenient way to get a hash code for the |
7043 // length. | 7149 // length. |
7044 ret = this->element_type_->hash_for_method(gogo) + 1; | 7150 ret = this->element_type_->hash_for_method(gogo, flags) + 1; |
7045 if (this->is_array_incomparable_) | 7151 if (this->is_array_incomparable_) |
7046 ret <<= 1; | 7152 ret <<= 1; |
7047 return ret; | 7153 return ret; |
7048 } | 7154 } |
7049 | 7155 |
7192 | 7298 |
7193 gogo->start_block(bloc); | 7299 gogo->start_block(bloc); |
7194 | 7300 |
7195 // Compare element in P1 and P2. | 7301 // Compare element in P1 and P2. |
7196 Expression* e1 = Expression::make_temporary_reference(p1, bloc); | 7302 Expression* e1 = Expression::make_temporary_reference(p1, bloc); |
7197 e1 = Expression::make_unary(OPERATOR_MULT, e1, bloc); | 7303 e1 = Expression::make_dereference(e1, Expression::NIL_CHECK_DEFAULT, bloc); |
7198 ref = Expression::make_temporary_reference(index, bloc); | 7304 ref = Expression::make_temporary_reference(index, bloc); |
7199 e1 = Expression::make_array_index(e1, ref, NULL, NULL, bloc); | 7305 e1 = Expression::make_array_index(e1, ref, NULL, NULL, bloc); |
7200 | 7306 |
7201 Expression* e2 = Expression::make_temporary_reference(p2, bloc); | 7307 Expression* e2 = Expression::make_temporary_reference(p2, bloc); |
7202 e2 = Expression::make_unary(OPERATOR_MULT, e2, bloc); | 7308 e2 = Expression::make_dereference(e2, Expression::NIL_CHECK_DEFAULT, bloc); |
7203 ref = Expression::make_temporary_reference(index, bloc); | 7309 ref = Expression::make_temporary_reference(index, bloc); |
7204 e2 = Expression::make_array_index(e2, ref, NULL, NULL, bloc); | 7310 e2 = Expression::make_array_index(e2, ref, NULL, NULL, bloc); |
7205 | 7311 |
7206 Expression* cond = Expression::make_binary(OPERATOR_NOTEQ, e1, e2, bloc); | 7312 Expression* cond = Expression::make_binary(OPERATOR_NOTEQ, e1, e2, bloc); |
7207 | 7313 |
7393 array = tref; | 7499 array = tref; |
7394 } | 7500 } |
7395 else if (ve != NULL) | 7501 else if (ve != NULL) |
7396 { | 7502 { |
7397 ve = new Var_expression(ve->named_object(), ve->location()); | 7503 ve = new Var_expression(ve->named_object(), ve->location()); |
7398 ve->set_in_lvalue_pos(); | |
7399 array = ve; | 7504 array = ve; |
7400 } | 7505 } |
7401 } | 7506 } |
7402 | 7507 |
7403 return Expression::make_slice_info(array, | 7508 return Expression::make_slice_info(array, |
7717 | 7822 |
7718 std::string zname = Map_type::zero_value->name(); | 7823 std::string zname = Map_type::zero_value->name(); |
7719 std::string asm_name(go_selectively_encode_id(zname)); | 7824 std::string asm_name(go_selectively_encode_id(zname)); |
7720 Bvariable* zvar = | 7825 Bvariable* zvar = |
7721 gogo->backend()->implicit_variable(zname, asm_name, | 7826 gogo->backend()->implicit_variable(zname, asm_name, |
7722 barray_type, false, true, true, | 7827 barray_type, false, false, true, |
7723 Map_type::zero_value_align); | 7828 Map_type::zero_value_align); |
7724 gogo->backend()->implicit_variable_set_init(zvar, zname, barray_type, | 7829 gogo->backend()->implicit_variable_set_init(zvar, zname, barray_type, |
7725 false, true, true, NULL); | 7830 false, false, true, NULL); |
7726 return zvar; | 7831 return zvar; |
7727 } | 7832 } |
7728 | 7833 |
7729 // Traversal. | 7834 // Traversal. |
7730 | 7835 |
7753 } | 7858 } |
7754 | 7859 |
7755 // Whether two map types are identical. | 7860 // Whether two map types are identical. |
7756 | 7861 |
7757 bool | 7862 bool |
7758 Map_type::is_identical(const Map_type* t, Cmp_tags cmp_tags, | 7863 Map_type::is_identical(const Map_type* t, int flags) const |
7759 bool errors_are_identical) const | 7864 { |
7760 { | 7865 return (Type::are_identical(this->key_type(), t->key_type(), flags, NULL) |
7761 return (Type::are_identical_cmp_tags(this->key_type(), t->key_type(), | 7866 && Type::are_identical(this->val_type(), t->val_type(), flags, |
7762 cmp_tags, errors_are_identical, NULL) | 7867 NULL)); |
7763 && Type::are_identical_cmp_tags(this->val_type(), t->val_type(), | |
7764 cmp_tags, errors_are_identical, | |
7765 NULL)); | |
7766 } | 7868 } |
7767 | 7869 |
7768 // Hash code. | 7870 // Hash code. |
7769 | 7871 |
7770 unsigned int | 7872 unsigned int |
7771 Map_type::do_hash_for_method(Gogo* gogo) const | 7873 Map_type::do_hash_for_method(Gogo* gogo, int flags) const |
7772 { | 7874 { |
7773 return (this->key_type_->hash_for_method(gogo) | 7875 return (this->key_type_->hash_for_method(gogo, flags) |
7774 + this->val_type_->hash_for_method(gogo) | 7876 + this->val_type_->hash_for_method(gogo, flags) |
7775 + 2); | 7877 + 2); |
7776 } | 7878 } |
7777 | 7879 |
7778 // Get the backend representation for a map type. A map type is | 7880 // Get the backend representation for a map type. A map type is |
7779 // represented as a pointer to a struct. The struct is hmap in | 7881 // represented as a pointer to a struct. The struct is hmap in |
7826 Type* uintptr_type = Type::lookup_integer_type("uintptr"); | 7928 Type* uintptr_type = Type::lookup_integer_type("uintptr"); |
7827 bfields[7].name = "nevacuate"; | 7929 bfields[7].name = "nevacuate"; |
7828 bfields[7].btype = uintptr_type->get_backend(gogo); | 7930 bfields[7].btype = uintptr_type->get_backend(gogo); |
7829 bfields[7].location = bloc; | 7931 bfields[7].location = bloc; |
7830 | 7932 |
7831 bfields[8].name = "overflow"; | 7933 bfields[8].name = "extra"; |
7832 bfields[8].btype = bpvt; | 7934 bfields[8].btype = bpvt; |
7833 bfields[8].location = bloc; | 7935 bfields[8].location = bloc; |
7834 | 7936 |
7835 Btype *bt = gogo->backend()->struct_type(bfields); | 7937 Btype *bt = gogo->backend()->struct_type(bfields); |
7836 bt = gogo->backend()->named_type("runtime.hmap", bt, bloc); | 7938 bt = gogo->backend()->named_type("runtime.hmap", bt, bloc); |
7852 Type* uint8_type = Type::lookup_integer_type("uint8"); | 7954 Type* uint8_type = Type::lookup_integer_type("uint8"); |
7853 Type* uint16_type = Type::lookup_integer_type("uint16"); | 7955 Type* uint16_type = Type::lookup_integer_type("uint16"); |
7854 Type* bool_type = Type::lookup_bool_type(); | 7956 Type* bool_type = Type::lookup_bool_type(); |
7855 | 7957 |
7856 Struct_type* sf = | 7958 Struct_type* sf = |
7857 Type::make_builtin_struct_type(12, | 7959 Type::make_builtin_struct_type(11, |
7858 "", tdt, | 7960 "", tdt, |
7859 "key", ptdt, | 7961 "key", ptdt, |
7860 "elem", ptdt, | 7962 "elem", ptdt, |
7861 "bucket", ptdt, | 7963 "bucket", ptdt, |
7862 "hmap", ptdt, | |
7863 "keysize", uint8_type, | 7964 "keysize", uint8_type, |
7864 "indirectkey", bool_type, | 7965 "indirectkey", bool_type, |
7865 "valuesize", uint8_type, | 7966 "valuesize", uint8_type, |
7866 "indirectvalue", bool_type, | 7967 "indirectvalue", bool_type, |
7867 "bucketsize", uint16_type, | 7968 "bucketsize", uint16_type, |
7940 vals->push_back(Expression::make_type_descriptor(this->val_type_, bloc)); | 8041 vals->push_back(Expression::make_type_descriptor(this->val_type_, bloc)); |
7941 | 8042 |
7942 ++p; | 8043 ++p; |
7943 go_assert(p->is_field_name("bucket")); | 8044 go_assert(p->is_field_name("bucket")); |
7944 vals->push_back(Expression::make_type_descriptor(bucket_type, bloc)); | 8045 vals->push_back(Expression::make_type_descriptor(bucket_type, bloc)); |
7945 | |
7946 ++p; | |
7947 go_assert(p->is_field_name("hmap")); | |
7948 Type* hmap_type = this->hmap_type(bucket_type); | |
7949 vals->push_back(Expression::make_type_descriptor(hmap_type, bloc)); | |
7950 | 8046 |
7951 ++p; | 8047 ++p; |
7952 go_assert(p->is_field_name("keysize")); | 8048 go_assert(p->is_field_name("keysize")); |
7953 if (keysize > Map_type::max_key_size) | 8049 if (keysize > Map_type::max_key_size) |
7954 vals->push_back(Expression::make_integer_int64(ptrsize, uint8_type, bloc)); | 8050 vals->push_back(Expression::make_integer_int64(ptrsize, uint8_type, bloc)); |
8140 if (this->hmap_type_ != NULL) | 8236 if (this->hmap_type_ != NULL) |
8141 return this->hmap_type_; | 8237 return this->hmap_type_; |
8142 | 8238 |
8143 Type* int_type = Type::lookup_integer_type("int"); | 8239 Type* int_type = Type::lookup_integer_type("int"); |
8144 Type* uint8_type = Type::lookup_integer_type("uint8"); | 8240 Type* uint8_type = Type::lookup_integer_type("uint8"); |
8241 Type* uint16_type = Type::lookup_integer_type("uint16"); | |
8145 Type* uint32_type = Type::lookup_integer_type("uint32"); | 8242 Type* uint32_type = Type::lookup_integer_type("uint32"); |
8146 Type* uintptr_type = Type::lookup_integer_type("uintptr"); | 8243 Type* uintptr_type = Type::lookup_integer_type("uintptr"); |
8147 Type* void_ptr_type = Type::make_pointer_type(Type::make_void_type()); | 8244 Type* void_ptr_type = Type::make_pointer_type(Type::make_void_type()); |
8148 | 8245 |
8149 Type* ptr_bucket_type = Type::make_pointer_type(bucket_type); | 8246 Type* ptr_bucket_type = Type::make_pointer_type(bucket_type); |
8150 | 8247 |
8151 Struct_type* ret = make_builtin_struct_type(8, | 8248 Struct_type* ret = make_builtin_struct_type(9, |
8152 "count", int_type, | 8249 "count", int_type, |
8153 "flags", uint8_type, | 8250 "flags", uint8_type, |
8154 "B", uint8_type, | 8251 "B", uint8_type, |
8252 "noverflow", uint16_type, | |
8155 "hash0", uint32_type, | 8253 "hash0", uint32_type, |
8156 "buckets", ptr_bucket_type, | 8254 "buckets", ptr_bucket_type, |
8157 "oldbuckets", ptr_bucket_type, | 8255 "oldbuckets", ptr_bucket_type, |
8158 "nevacuate", uintptr_type, | 8256 "nevacuate", uintptr_type, |
8159 "overflow", void_ptr_type); | 8257 "extra", void_ptr_type); |
8160 ret->set_is_struct_incomparable(); | 8258 ret->set_is_struct_incomparable(); |
8161 this->hmap_type_ = ret; | 8259 this->hmap_type_ = ret; |
8162 return ret; | 8260 return ret; |
8163 } | 8261 } |
8164 | 8262 |
8187 Type* bucket_type = this->bucket_type(gogo, keysize, valsize); | 8285 Type* bucket_type = this->bucket_type(gogo, keysize, valsize); |
8188 Type* bucket_ptr_type = Type::make_pointer_type(bucket_type); | 8286 Type* bucket_ptr_type = Type::make_pointer_type(bucket_type); |
8189 Type* hmap_type = this->hmap_type(bucket_type); | 8287 Type* hmap_type = this->hmap_type(bucket_type); |
8190 Type* hmap_ptr_type = Type::make_pointer_type(hmap_type); | 8288 Type* hmap_ptr_type = Type::make_pointer_type(hmap_type); |
8191 Type* void_ptr_type = Type::make_pointer_type(Type::make_void_type()); | 8289 Type* void_ptr_type = Type::make_pointer_type(Type::make_void_type()); |
8192 | 8290 Type* bool_type = Type::lookup_bool_type(); |
8193 Struct_type* ret = make_builtin_struct_type(12, | 8291 |
8292 Struct_type* ret = make_builtin_struct_type(15, | |
8194 "key", key_ptr_type, | 8293 "key", key_ptr_type, |
8195 "val", val_ptr_type, | 8294 "val", val_ptr_type, |
8196 "t", uint8_ptr_type, | 8295 "t", uint8_ptr_type, |
8197 "h", hmap_ptr_type, | 8296 "h", hmap_ptr_type, |
8198 "buckets", bucket_ptr_type, | 8297 "buckets", bucket_ptr_type, |
8199 "bptr", bucket_ptr_type, | 8298 "bptr", bucket_ptr_type, |
8200 "overflow0", void_ptr_type, | 8299 "overflow", void_ptr_type, |
8201 "overflow1", void_ptr_type, | 8300 "oldoverflow", void_ptr_type, |
8202 "startBucket", uintptr_type, | 8301 "startBucket", uintptr_type, |
8203 "stuff", uintptr_type, | 8302 "offset", uint8_type, |
8303 "wrapped", bool_type, | |
8304 "B", uint8_type, | |
8305 "i", uint8_type, | |
8204 "bucket", uintptr_type, | 8306 "bucket", uintptr_type, |
8205 "checkBucket", uintptr_type); | 8307 "checkBucket", uintptr_type); |
8206 ret->set_is_struct_incomparable(); | 8308 ret->set_is_struct_incomparable(); |
8207 this->hiter_type_ = ret; | 8309 this->hiter_type_ = ret; |
8208 return ret; | 8310 return ret; |
8266 } | 8368 } |
8267 | 8369 |
8268 // Hash code. | 8370 // Hash code. |
8269 | 8371 |
8270 unsigned int | 8372 unsigned int |
8271 Channel_type::do_hash_for_method(Gogo* gogo) const | 8373 Channel_type::do_hash_for_method(Gogo* gogo, int flags) const |
8272 { | 8374 { |
8273 unsigned int ret = 0; | 8375 unsigned int ret = 0; |
8274 if (this->may_send_) | 8376 if (this->may_send_) |
8275 ret += 1; | 8377 ret += 1; |
8276 if (this->may_receive_) | 8378 if (this->may_receive_) |
8277 ret += 2; | 8379 ret += 2; |
8278 if (this->element_type_ != NULL) | 8380 if (this->element_type_ != NULL) |
8279 ret += this->element_type_->hash_for_method(gogo) << 2; | 8381 ret += this->element_type_->hash_for_method(gogo, flags) << 2; |
8280 return ret << 3; | 8382 return ret << 3; |
8281 } | 8383 } |
8282 | 8384 |
8283 // Whether this type is the same as T. | 8385 // Whether this type is the same as T. |
8284 | 8386 |
8285 bool | 8387 bool |
8286 Channel_type::is_identical(const Channel_type* t, Cmp_tags cmp_tags, | 8388 Channel_type::is_identical(const Channel_type* t, int flags) const |
8287 bool errors_are_identical) const | 8389 { |
8288 { | 8390 if (!Type::are_identical(this->element_type(), t->element_type(), flags, |
8289 if (!Type::are_identical_cmp_tags(this->element_type(), t->element_type(), | 8391 NULL)) |
8290 cmp_tags, errors_are_identical, NULL)) | |
8291 return false; | 8392 return false; |
8292 return (this->may_send_ == t->may_send_ | 8393 return (this->may_send_ == t->may_send_ |
8293 && this->may_receive_ == t->may_receive_); | 8394 && this->may_receive_ == t->may_receive_); |
8294 } | 8395 } |
8295 | 8396 |
8434 Type* element_type = imp->read_type(); | 8535 Type* element_type = imp->read_type(); |
8435 | 8536 |
8436 return Type::make_channel_type(may_send, may_receive, element_type); | 8537 return Type::make_channel_type(may_send, may_receive, element_type); |
8437 } | 8538 } |
8438 | 8539 |
8439 // Return the type to manage a select statement with ncases case | 8540 // Return the type that the runtime package uses for one case of a |
8440 // statements. A value of this type is allocated on the stack. This | 8541 // select statement. An array of values of this type is allocated on |
8441 // must match the type hselect in libgo/go/runtime/select.go. | 8542 // the stack. This must match scase in libgo/go/runtime/select.go. |
8442 | 8543 |
8443 Type* | 8544 Type* |
8444 Channel_type::select_type(int ncases) | 8545 Channel_type::select_case_type() |
8445 { | 8546 { |
8446 Type* unsafe_pointer_type = Type::make_pointer_type(Type::make_void_type()); | |
8447 Type* uint16_type = Type::lookup_integer_type("uint16"); | |
8448 | |
8449 static Struct_type* scase_type; | 8547 static Struct_type* scase_type; |
8450 if (scase_type == NULL) | 8548 if (scase_type == NULL) |
8451 { | 8549 { |
8452 Type* uintptr_type = Type::lookup_integer_type("uintptr"); | 8550 Type* unsafe_pointer_type = |
8453 Type* uint64_type = Type::lookup_integer_type("uint64"); | 8551 Type::make_pointer_type(Type::make_void_type()); |
8552 Type* uint16_type = Type::lookup_integer_type("uint16"); | |
8553 Type* int64_type = Type::lookup_integer_type("int64"); | |
8454 scase_type = | 8554 scase_type = |
8455 Type::make_builtin_struct_type(7, | 8555 Type::make_builtin_struct_type(4, |
8556 "c", unsafe_pointer_type, | |
8456 "elem", unsafe_pointer_type, | 8557 "elem", unsafe_pointer_type, |
8457 "chan", unsafe_pointer_type, | |
8458 "pc", uintptr_type, | |
8459 "kind", uint16_type, | 8558 "kind", uint16_type, |
8460 "index", uint16_type, | 8559 "releasetime", int64_type); |
8461 "receivedp", unsafe_pointer_type, | |
8462 "releasetime", uint64_type); | |
8463 scase_type->set_is_struct_incomparable(); | 8560 scase_type->set_is_struct_incomparable(); |
8464 } | 8561 } |
8465 | 8562 return scase_type; |
8466 Expression* ncases_expr = | |
8467 Expression::make_integer_ul(ncases, NULL, Linemap::predeclared_location()); | |
8468 Array_type* scases = Type::make_array_type(scase_type, ncases_expr); | |
8469 scases->set_is_array_incomparable(); | |
8470 Array_type* order = Type::make_array_type(uint16_type, ncases_expr); | |
8471 order->set_is_array_incomparable(); | |
8472 | |
8473 Struct_type* ret = | |
8474 Type::make_builtin_struct_type(7, | |
8475 "tcase", uint16_type, | |
8476 "ncase", uint16_type, | |
8477 "pollorder", unsafe_pointer_type, | |
8478 "lockorder", unsafe_pointer_type, | |
8479 "scase", scases, | |
8480 "lockorderarr", order, | |
8481 "pollorderarr", order); | |
8482 ret->set_is_struct_incomparable(); | |
8483 return ret; | |
8484 } | 8563 } |
8485 | 8564 |
8486 // Make a new channel type. | 8565 // Make a new channel type. |
8487 | 8566 |
8488 Channel_type* | 8567 Channel_type* |
8677 } | 8756 } |
8678 | 8757 |
8679 // Whether this type is identical with T. | 8758 // Whether this type is identical with T. |
8680 | 8759 |
8681 bool | 8760 bool |
8682 Interface_type::is_identical(const Interface_type* t, Cmp_tags cmp_tags, | 8761 Interface_type::is_identical(const Interface_type* t, int flags) const |
8683 bool errors_are_identical) const | |
8684 { | 8762 { |
8685 // If methods have not been finalized, then we are asking whether | 8763 // If methods have not been finalized, then we are asking whether |
8686 // func redeclarations are the same. This is an error, so for | 8764 // func redeclarations are the same. This is an error, so for |
8687 // simplicity we say they are never the same. | 8765 // simplicity we say they are never the same. |
8688 if (!this->methods_are_finalized_ || !t->methods_are_finalized_) | 8766 if (!this->methods_are_finalized_ || !t->methods_are_finalized_) |
8708 for (p2 = t->all_methods_->begin(); p2 != t->all_methods_->end(); ++p1, ++p2) | 8786 for (p2 = t->all_methods_->begin(); p2 != t->all_methods_->end(); ++p1, ++p2) |
8709 { | 8787 { |
8710 if (p1 == this->all_methods_->end()) | 8788 if (p1 == this->all_methods_->end()) |
8711 break; | 8789 break; |
8712 if (p1->name() != p2->name() | 8790 if (p1->name() != p2->name() |
8713 || !Type::are_identical_cmp_tags(p1->type(), p2->type(), cmp_tags, | 8791 || !Type::are_identical(p1->type(), p2->type(), flags, NULL)) |
8714 errors_are_identical, NULL)) | |
8715 break; | 8792 break; |
8716 } | 8793 } |
8717 | 8794 |
8718 this->assume_identical_ = hold_ai; | 8795 this->assume_identical_ = hold_ai; |
8719 | 8796 |
8765 } | 8842 } |
8766 return false; | 8843 return false; |
8767 } | 8844 } |
8768 | 8845 |
8769 std::string subreason; | 8846 std::string subreason; |
8770 if (!Type::are_identical(p->type(), m->type(), true, &subreason)) | 8847 if (!Type::are_identical(p->type(), m->type(), Type::COMPARE_TAGS, |
8848 &subreason)) | |
8771 { | 8849 { |
8772 if (reason != NULL) | 8850 if (reason != NULL) |
8773 { | 8851 { |
8774 std::string n = Gogo::message_name(p->name()); | 8852 std::string n = Gogo::message_name(p->name()); |
8775 size_t len = 100 + n.length() + subreason.length(); | 8853 size_t len = 100 + n.length() + subreason.length(); |
8793 } | 8871 } |
8794 | 8872 |
8795 // Hash code. | 8873 // Hash code. |
8796 | 8874 |
8797 unsigned int | 8875 unsigned int |
8798 Interface_type::do_hash_for_method(Gogo*) const | 8876 Interface_type::do_hash_for_method(Gogo*, int) const |
8799 { | 8877 { |
8800 go_assert(this->methods_are_finalized_); | 8878 go_assert(this->methods_are_finalized_); |
8801 unsigned int ret = 0; | 8879 unsigned int ret = 0; |
8802 if (this->all_methods_ != NULL) | 8880 if (this->all_methods_ != NULL) |
8803 { | 8881 { |
8907 | 8985 |
8908 Function_type *p_fn_type = p->type()->function_type(); | 8986 Function_type *p_fn_type = p->type()->function_type(); |
8909 Function_type* m_fn_type = m->type()->function_type(); | 8987 Function_type* m_fn_type = m->type()->function_type(); |
8910 go_assert(p_fn_type != NULL && m_fn_type != NULL); | 8988 go_assert(p_fn_type != NULL && m_fn_type != NULL); |
8911 std::string subreason; | 8989 std::string subreason; |
8912 if (!p_fn_type->is_identical(m_fn_type, true, COMPARE_TAGS, true, | 8990 if (!p_fn_type->is_identical(m_fn_type, true, Type::COMPARE_TAGS, |
8913 &subreason)) | 8991 &subreason)) |
8914 { | 8992 { |
8915 if (reason != NULL) | 8993 if (reason != NULL) |
8916 { | 8994 { |
8917 std::string n = Gogo::message_name(p->name()); | 8995 std::string n = Gogo::message_name(p->name()); |
8995 empty_interface_type = gogo->backend()->struct_type(bfields); | 9073 empty_interface_type = gogo->backend()->struct_type(bfields); |
8996 } | 9074 } |
8997 return empty_interface_type; | 9075 return empty_interface_type; |
8998 } | 9076 } |
8999 | 9077 |
9078 Interface_type::Bmethods_map Interface_type::bmethods_map; | |
9079 | |
9000 // Return a pointer to the backend representation of the method table. | 9080 // Return a pointer to the backend representation of the method table. |
9001 | 9081 |
9002 Btype* | 9082 Btype* |
9003 Interface_type::get_backend_methods(Gogo* gogo) | 9083 Interface_type::get_backend_methods(Gogo* gogo) |
9004 { | 9084 { |
9005 if (this->bmethods_ != NULL && !this->bmethods_is_placeholder_) | 9085 if (this->bmethods_ != NULL && !this->bmethods_is_placeholder_) |
9006 return this->bmethods_; | 9086 return this->bmethods_; |
9087 | |
9088 std::pair<Interface_type*, Bmethods_map_entry> val; | |
9089 val.first = this; | |
9090 val.second.btype = NULL; | |
9091 val.second.is_placeholder = false; | |
9092 std::pair<Bmethods_map::iterator, bool> ins = | |
9093 Interface_type::bmethods_map.insert(val); | |
9094 if (!ins.second | |
9095 && ins.first->second.btype != NULL | |
9096 && !ins.first->second.is_placeholder) | |
9097 { | |
9098 this->bmethods_ = ins.first->second.btype; | |
9099 this->bmethods_is_placeholder_ = false; | |
9100 return this->bmethods_; | |
9101 } | |
9007 | 9102 |
9008 Location loc = this->location(); | 9103 Location loc = this->location(); |
9009 | 9104 |
9010 std::vector<Backend::Btyped_identifier> | 9105 std::vector<Backend::Btyped_identifier> |
9011 mfields(this->all_methods_->size() + 1); | 9106 mfields(this->all_methods_->size() + 1); |
9059 } | 9154 } |
9060 | 9155 |
9061 Btype* st = gogo->backend()->struct_type(mfields); | 9156 Btype* st = gogo->backend()->struct_type(mfields); |
9062 Btype* ret = gogo->backend()->pointer_type(st); | 9157 Btype* ret = gogo->backend()->pointer_type(st); |
9063 | 9158 |
9064 if (this->bmethods_ != NULL && this->bmethods_is_placeholder_) | 9159 if (ins.first->second.btype != NULL |
9065 gogo->backend()->set_placeholder_pointer_type(this->bmethods_, ret); | 9160 && ins.first->second.is_placeholder) |
9161 gogo->backend()->set_placeholder_pointer_type(ins.first->second.btype, | |
9162 ret); | |
9066 this->bmethods_ = ret; | 9163 this->bmethods_ = ret; |
9164 ins.first->second.btype = ret; | |
9067 this->bmethods_is_placeholder_ = false; | 9165 this->bmethods_is_placeholder_ = false; |
9166 ins.first->second.is_placeholder = false; | |
9068 return ret; | 9167 return ret; |
9069 } | 9168 } |
9070 | 9169 |
9071 // Return a placeholder for the pointer to the backend methods table. | 9170 // Return a placeholder for the pointer to the backend methods table. |
9072 | 9171 |
9073 Btype* | 9172 Btype* |
9074 Interface_type::get_backend_methods_placeholder(Gogo* gogo) | 9173 Interface_type::get_backend_methods_placeholder(Gogo* gogo) |
9075 { | 9174 { |
9076 if (this->bmethods_ == NULL) | 9175 if (this->bmethods_ == NULL) |
9077 { | 9176 { |
9177 std::pair<Interface_type*, Bmethods_map_entry> val; | |
9178 val.first = this; | |
9179 val.second.btype = NULL; | |
9180 val.second.is_placeholder = false; | |
9181 std::pair<Bmethods_map::iterator, bool> ins = | |
9182 Interface_type::bmethods_map.insert(val); | |
9183 if (!ins.second && ins.first->second.btype != NULL) | |
9184 { | |
9185 this->bmethods_ = ins.first->second.btype; | |
9186 this->bmethods_is_placeholder_ = ins.first->second.is_placeholder; | |
9187 return this->bmethods_; | |
9188 } | |
9189 | |
9078 Location loc = this->location(); | 9190 Location loc = this->location(); |
9079 this->bmethods_ = gogo->backend()->placeholder_pointer_type("", loc, | 9191 Btype* bt = gogo->backend()->placeholder_pointer_type("", loc, false); |
9080 false); | 9192 this->bmethods_ = bt; |
9193 ins.first->second.btype = bt; | |
9081 this->bmethods_is_placeholder_ = true; | 9194 this->bmethods_is_placeholder_ = true; |
9195 ins.first->second.is_placeholder = true; | |
9082 } | 9196 } |
9083 return this->bmethods_; | 9197 return this->bmethods_; |
9084 } | 9198 } |
9085 | 9199 |
9086 // Return the fields of a non-empty interface type. This is not | 9200 // Return the fields of a non-empty interface type. This is not |
9605 | 9719 |
9606 bool | 9720 bool |
9607 Named_method::do_nointerface() const | 9721 Named_method::do_nointerface() const |
9608 { | 9722 { |
9609 Named_object* no = this->named_object_; | 9723 Named_object* no = this->named_object_; |
9610 return no->is_function() && no->func_value()->nointerface(); | 9724 if (no->is_function()) |
9725 return no->func_value()->nointerface(); | |
9726 else if (no->is_function_declaration()) | |
9727 return no->func_declaration_value()->nointerface(); | |
9728 else | |
9729 go_unreachable(); | |
9611 } | 9730 } |
9612 | 9731 |
9613 // Class Interface_method. | 9732 // Class Interface_method. |
9614 | 9733 |
9615 // Bind a method to an object. | 9734 // Bind a method to an object. |
10288 | 10407 |
10289 // Return a hash code. This is used for method lookup. We simply | 10408 // Return a hash code. This is used for method lookup. We simply |
10290 // hash on the name itself. | 10409 // hash on the name itself. |
10291 | 10410 |
10292 unsigned int | 10411 unsigned int |
10293 Named_type::do_hash_for_method(Gogo* gogo) const | 10412 Named_type::do_hash_for_method(Gogo* gogo, int) const |
10294 { | 10413 { |
10295 if (this->is_error_) | 10414 if (this->is_error_) |
10296 return 0; | 10415 return 0; |
10297 | 10416 |
10298 // Aliases are handled in Type::hash_for_method. | 10417 // Aliases are handled in Type::hash_for_method. |
10618 | 10737 |
10619 case TYPE_FUNCTION: | 10738 case TYPE_FUNCTION: |
10620 // Don't build a circular data structure. GENERIC can't handle | 10739 // Don't build a circular data structure. GENERIC can't handle |
10621 // it. | 10740 // it. |
10622 if (this->seen_in_get_backend_) | 10741 if (this->seen_in_get_backend_) |
10623 { | 10742 return gogo->backend()->circular_pointer_type(bt, true); |
10624 this->is_circular_ = true; | |
10625 return gogo->backend()->circular_pointer_type(bt, true); | |
10626 } | |
10627 this->seen_in_get_backend_ = true; | 10743 this->seen_in_get_backend_ = true; |
10628 bt1 = Type::get_named_base_btype(gogo, base); | 10744 bt1 = Type::get_named_base_btype(gogo, base); |
10629 this->seen_in_get_backend_ = false; | 10745 this->seen_in_get_backend_ = false; |
10630 if (this->is_circular_) | |
10631 bt1 = gogo->backend()->circular_pointer_type(bt, true); | |
10632 if (!gogo->backend()->set_placeholder_pointer_type(bt, bt1)) | 10746 if (!gogo->backend()->set_placeholder_pointer_type(bt, bt1)) |
10633 bt = gogo->backend()->error_type(); | 10747 bt = gogo->backend()->error_type(); |
10634 return bt; | 10748 return bt; |
10635 | 10749 |
10636 case TYPE_POINTER: | 10750 case TYPE_POINTER: |
10637 // Don't build a circular data structure. GENERIC can't handle | 10751 // Don't build a circular data structure. GENERIC can't handle |
10638 // it. | 10752 // it. |
10639 if (this->seen_in_get_backend_) | 10753 if (this->seen_in_get_backend_) |
10640 { | 10754 return gogo->backend()->circular_pointer_type(bt, false); |
10641 this->is_circular_ = true; | |
10642 return gogo->backend()->circular_pointer_type(bt, false); | |
10643 } | |
10644 this->seen_in_get_backend_ = true; | 10755 this->seen_in_get_backend_ = true; |
10645 bt1 = Type::get_named_base_btype(gogo, base); | 10756 bt1 = Type::get_named_base_btype(gogo, base); |
10646 this->seen_in_get_backend_ = false; | 10757 this->seen_in_get_backend_ = false; |
10647 if (this->is_circular_) | |
10648 bt1 = gogo->backend()->circular_pointer_type(bt, false); | |
10649 if (!gogo->backend()->set_placeholder_pointer_type(bt, bt1)) | 10758 if (!gogo->backend()->set_placeholder_pointer_type(bt, bt1)) |
10650 bt = gogo->backend()->error_type(); | 10759 bt = gogo->backend()->error_type(); |
10651 return bt; | 10760 return bt; |
10652 | 10761 |
10653 default: | 10762 default: |
10754 ret->push_back('\t'); | 10863 ret->push_back('\t'); |
10755 } | 10864 } |
10756 ret->append(Gogo::unpack_hidden_name(this->named_object_->name())); | 10865 ret->append(Gogo::unpack_hidden_name(this->named_object_->name())); |
10757 } | 10866 } |
10758 | 10867 |
10759 // Export the type. This is called to export a global type. | 10868 // Import a named type. This is only used for export format versions |
10760 | 10869 // before version 3. |
10761 void | |
10762 Named_type::export_named_type(Export* exp, const std::string&) const | |
10763 { | |
10764 // We don't need to write the name of the type here, because it will | |
10765 // be written by Export::write_type anyhow. | |
10766 exp->write_c_string("type "); | |
10767 exp->write_type(this); | |
10768 exp->write_c_string(";\n"); | |
10769 } | |
10770 | |
10771 // Import a named type. | |
10772 | 10870 |
10773 void | 10871 void |
10774 Named_type::import_named_type(Import* imp, Named_type** ptype) | 10872 Named_type::import_named_type(Import* imp, Named_type** ptype) |
10775 { | 10873 { |
10776 imp->require_c_string("type "); | 10874 imp->require_c_string("type "); |
10777 Type *type = imp->read_type(); | 10875 Type *type = imp->read_type(); |
10778 *ptype = type->named_type(); | 10876 *ptype = type->named_type(); |
10779 go_assert(*ptype != NULL); | 10877 go_assert(*ptype != NULL); |
10780 imp->require_c_string(";\n"); | 10878 imp->require_semicolon_if_old_version(); |
10879 imp->require_c_string("\n"); | |
10781 } | 10880 } |
10782 | 10881 |
10783 // Export the type when it is referenced by another type. In this | 10882 // Export the type when it is referenced by another type. In this |
10784 // case Export::export_type will already have issued the name. | 10883 // case Export::export_type will already have issued the name. The |
10884 // output always ends with a newline, since that is convenient if | |
10885 // there are methods. | |
10785 | 10886 |
10786 void | 10887 void |
10787 Named_type::do_export(Export* exp) const | 10888 Named_type::do_export(Export* exp) const |
10788 { | 10889 { |
10789 exp->write_type(this->type_); | 10890 exp->write_type(this->type_); |
10891 exp->write_c_string("\n"); | |
10790 | 10892 |
10791 // To save space, we only export the methods directly attached to | 10893 // To save space, we only export the methods directly attached to |
10792 // this type. | 10894 // this type. |
10793 Bindings* methods = this->local_methods_; | 10895 Bindings* methods = this->local_methods_; |
10794 if (methods == NULL) | 10896 if (methods == NULL) |
10795 return; | 10897 return; |
10796 | 10898 |
10797 exp->write_c_string("\n"); | |
10798 for (Bindings::const_definitions_iterator p = methods->begin_definitions(); | 10899 for (Bindings::const_definitions_iterator p = methods->begin_definitions(); |
10799 p != methods->end_definitions(); | 10900 p != methods->end_definitions(); |
10800 ++p) | 10901 ++p) |
10801 { | 10902 { |
10802 exp->write_c_string(" "); | 10903 exp->write_c_string(" "); |
11134 const Package* package; | 11235 const Package* package; |
11135 if (type->named_type() == NULL) | 11236 if (type->named_type() == NULL) |
11136 package = NULL; | 11237 package = NULL; |
11137 else | 11238 else |
11138 package = type->named_type()->named_object()->package(); | 11239 package = type->named_type()->named_object()->package(); |
11139 std::string stub_name = gogo->stub_method_name(name); | 11240 std::string stub_name = gogo->stub_method_name(package, name); |
11140 Named_object* stub; | 11241 Named_object* stub; |
11141 if (package != NULL) | 11242 if (package != NULL) |
11142 stub = Named_object::make_function_declaration(stub_name, package, | 11243 stub = Named_object::make_function_declaration(stub_name, package, |
11143 stub_type, location); | 11244 stub_type, location); |
11144 else | 11245 else |
11219 go_assert(stype != NULL | 11320 go_assert(stype != NULL |
11220 && field_indexes->field_index < stype->field_count()); | 11321 && field_indexes->field_index < stype->field_count()); |
11221 if (expr->type()->struct_type() == NULL) | 11322 if (expr->type()->struct_type() == NULL) |
11222 { | 11323 { |
11223 go_assert(expr->type()->points_to() != NULL); | 11324 go_assert(expr->type()->points_to() != NULL); |
11224 expr = Expression::make_unary(OPERATOR_MULT, expr, location); | 11325 expr = Expression::make_dereference(expr, Expression::NIL_CHECK_DEFAULT, |
11326 location); | |
11225 go_assert(expr->type()->struct_type() == stype); | 11327 go_assert(expr->type()->struct_type() == stype); |
11226 } | 11328 } |
11227 return Expression::make_field_reference(expr, field_indexes->field_index, | 11329 return Expression::make_field_reference(expr, field_indexes->field_index, |
11228 location); | 11330 location); |
11229 } | 11331 } |
11323 && st == NULL | 11425 && st == NULL |
11324 && it == NULL | 11426 && it == NULL |
11325 && type->points_to() != NULL | 11427 && type->points_to() != NULL |
11326 && type->points_to()->points_to() != NULL) | 11428 && type->points_to()->points_to() != NULL) |
11327 { | 11429 { |
11328 expr = Expression::make_unary(OPERATOR_MULT, expr, location); | 11430 expr = Expression::make_dereference(expr, Expression::NIL_CHECK_DEFAULT, |
11431 location); | |
11329 type = type->points_to(); | 11432 type = type->points_to(); |
11330 if (type->deref()->is_error_type()) | 11433 if (type->deref()->is_error_type()) |
11331 return Expression::make_error(location); | 11434 return Expression::make_error(location); |
11332 nt = type->points_to()->named_type(); | 11435 nt = type->points_to()->named_type(); |
11333 st = type->points_to()->struct_type(); | 11436 st = type->points_to()->struct_type(); |
11356 go_error_at(location, "pointer type has no field %qs", | 11459 go_error_at(location, "pointer type has no field %qs", |
11357 Gogo::message_name(name).c_str()); | 11460 Gogo::message_name(name).c_str()); |
11358 return Expression::make_error(location); | 11461 return Expression::make_error(location); |
11359 } | 11462 } |
11360 go_assert(type->points_to() != NULL); | 11463 go_assert(type->points_to() != NULL); |
11361 expr = Expression::make_unary(OPERATOR_MULT, expr, | 11464 expr = Expression::make_dereference(expr, |
11362 location); | 11465 Expression::NIL_CHECK_DEFAULT, |
11466 location); | |
11363 go_assert(expr->type()->struct_type() == st); | 11467 go_assert(expr->type()->struct_type() == st); |
11364 } | 11468 } |
11365 ret = st->field_reference(expr, name, location); | 11469 ret = st->field_reference(expr, name, location); |
11366 if (ret == NULL) | 11470 if (ret == NULL) |
11367 { | 11471 { |
11473 bool* found_pointer_method, | 11577 bool* found_pointer_method, |
11474 std::string* ambig1, | 11578 std::string* ambig1, |
11475 std::string* ambig2) | 11579 std::string* ambig2) |
11476 { | 11580 { |
11477 // Named types can have locally defined methods. | 11581 // Named types can have locally defined methods. |
11478 const Named_type* nt = type->named_type(); | 11582 const Named_type* nt = type->unalias()->named_type(); |
11479 if (nt == NULL && type->points_to() != NULL) | 11583 if (nt == NULL && type->points_to() != NULL) |
11480 nt = type->points_to()->named_type(); | 11584 nt = type->points_to()->unalias()->named_type(); |
11481 if (nt != NULL) | 11585 if (nt != NULL) |
11482 { | 11586 { |
11483 Named_object* no = nt->find_local_method(name); | 11587 Named_object* no = nt->find_local_method(name); |
11484 if (no != NULL) | 11588 if (no != NULL) |
11485 { | 11589 { |
12010 } | 12114 } |
12011 | 12115 |
12012 // Traverse types. | 12116 // Traverse types. |
12013 | 12117 |
12014 int | 12118 int |
12015 Typed_identifier_list::traverse(Traverse* traverse) | 12119 Typed_identifier_list::traverse(Traverse* traverse) const |
12016 { | 12120 { |
12017 for (Typed_identifier_list::const_iterator p = this->begin(); | 12121 for (Typed_identifier_list::const_iterator p = this->begin(); |
12018 p != this->end(); | 12122 p != this->end(); |
12019 ++p) | 12123 ++p) |
12020 { | 12124 { |