@@ -360,16 +360,6 @@ Collect_export_references::type(Type* type)
360
360
if (type->is_abstract ())
361
361
return TRAVERSE_SKIP_COMPONENTS;
362
362
363
- // For interfaces make sure that embedded methods are sorted, since the
364
- // comparison function we use for indexing types relies on it (this call has
365
- // to happen before the record_type call below).
366
- if (type->classification () == Type::TYPE_INTERFACE)
367
- {
368
- Interface_type* it = type->interface_type ();
369
- if (it != NULL )
370
- it->sort_embedded ();
371
- }
372
-
373
363
if (!this ->exp_ ->record_type (type))
374
364
{
375
365
// We've already seen this type.
@@ -501,6 +491,11 @@ should_export(Named_object* no)
501
491
return true ;
502
492
}
503
493
494
+ // Compare Typed_identifier_list's.
495
+
496
+ static int
497
+ compare_til (const Typed_identifier_list*, const Typed_identifier_list*);
498
+
504
499
// A functor to sort Named_object pointers by name.
505
500
506
501
struct Sort_bindings
@@ -514,10 +509,57 @@ struct Sort_bindings
514
509
return true ;
515
510
if (n2->package () == NULL )
516
511
return false ;
517
- return n1->package ()->pkgpath () < n2->package ()->pkgpath ();
512
+
513
+ // Make sure we don't see the same pkgpath twice.
514
+ const std::string& p1 (n1->package ()->pkgpath ());
515
+ const std::string& p2 (n2->package ()->pkgpath ());
516
+ go_assert (p1 != p2);
517
+
518
+ return p1 < p2;
518
519
}
519
520
520
- return n1->name () < n2->name ();
521
+ if (n1->name () != n2->name ())
522
+ return n1->name () < n2->name ();
523
+
524
+ // We shouldn't see the same name twice, but it can happen for
525
+ // nested type names.
526
+
527
+ go_assert (n1->is_type () && n2->is_type ());
528
+
529
+ unsigned int ind1;
530
+ const Named_object* g1 = n1->type_value ()->in_function (&ind1);
531
+ unsigned int ind2;
532
+ const Named_object* g2 = n2->type_value ()->in_function (&ind2);
533
+
534
+ if (g1 == NULL )
535
+ {
536
+ go_assert (g2 != NULL );
537
+ return true ;
538
+ }
539
+ else if (g2 == NULL )
540
+ return false ;
541
+ else if (g1 == g2)
542
+ {
543
+ go_assert (ind1 != ind2);
544
+ return ind1 < ind2;
545
+ }
546
+ else if ((g1->package () != g2->package ()) || (g1->name () != g2->name ()))
547
+ return Sort_bindings ()(g1, g2);
548
+ else
549
+ {
550
+ // This case can happen if g1 or g2 is a method.
551
+ if (g1 != NULL && g1->func_value ()->is_method ())
552
+ {
553
+ const Typed_identifier* r = g1->func_value ()->type ()->receiver ();
554
+ g1 = r->type ()->named_type ()->named_object ();
555
+ }
556
+ if (g2 != NULL && g2->func_value ()->is_method ())
557
+ {
558
+ const Typed_identifier* r = g2->func_value ()->type ()->receiver ();
559
+ g2 = r->type ()->named_type ()->named_object ();
560
+ }
561
+ return Sort_bindings ()(g1, g2);
562
+ }
521
563
}
522
564
};
523
565
@@ -528,17 +570,20 @@ struct Sort_types
528
570
bool
529
571
operator ()(const Type* t1, const Type* t2) const
530
572
{
573
+ t1 = t1->forwarded ();
574
+ t2 = t2->forwarded ();
575
+
531
576
const Named_type* nt1 = t1->named_type ();
532
577
const Named_type* nt2 = t2->named_type ();
533
578
if (nt1 != NULL )
534
579
{
535
- if (nt2 != NULL )
536
- {
537
- Sort_bindings sb;
538
- return sb (nt1->named_object (), nt2->named_object ());
539
- }
540
- else
541
- return true ;
580
+ if (nt2 != NULL )
581
+ {
582
+ Sort_bindings sb;
583
+ return sb (nt1->named_object (), nt2->named_object ());
584
+ }
585
+ else
586
+ return true ;
542
587
}
543
588
else if (nt2 != NULL )
544
589
return false ;
@@ -549,10 +594,218 @@ struct Sort_types
549
594
gogo->type_descriptor_backend_name (t1, NULL , &b1);
550
595
Backend_name b2;
551
596
gogo->type_descriptor_backend_name (t2, NULL , &b2);
552
- return b1.name () < b2.name ();
597
+
598
+ std::string n1 = b1.name ();
599
+ std::string n2 = b2.name ();
600
+ if (n1 != n2)
601
+ return n1 < n2;
602
+
603
+ // We should never see equal types here. If we do, we may not
604
+ // generate an identical output file for identical input. But the
605
+ // backend names can be equal because we want to treat aliases
606
+ // differently while type_descriptor_backend_name does not. In
607
+ // that case we need to traverse the type elements.
608
+
609
+ // t1 == t2 in case std::sort compares elements to themselves.
610
+ if (t1 == t2)
611
+ return false ;
612
+
613
+ Sort_types sort;
614
+ Type_alias_identical identical;
615
+ go_assert (!identical (t1, t2));
616
+
617
+ switch (t1->classification ())
618
+ {
619
+ case Type::TYPE_ERROR:
620
+ return false ;
621
+
622
+ case Type::TYPE_VOID:
623
+ case Type::TYPE_BOOLEAN:
624
+ case Type::TYPE_INTEGER:
625
+ case Type::TYPE_FLOAT:
626
+ case Type::TYPE_COMPLEX:
627
+ case Type::TYPE_STRING:
628
+ case Type::TYPE_SINK:
629
+ case Type::TYPE_NIL:
630
+ case Type::TYPE_CALL_MULTIPLE_RESULT:
631
+ case Type::TYPE_NAMED:
632
+ case Type::TYPE_FORWARD:
633
+ default :
634
+ go_unreachable ();
635
+
636
+ case Type::TYPE_FUNCTION:
637
+ {
638
+ const Function_type* ft1 = t1->function_type ();
639
+ const Function_type* ft2 = t2->function_type ();
640
+ const Typed_identifier* r1 = ft1->receiver ();
641
+ const Typed_identifier* r2 = ft2->receiver ();
642
+ if (r1 == NULL )
643
+ go_assert (r2 == NULL );
644
+ else
645
+ {
646
+ go_assert (r2 != NULL );
647
+ const Type* rt1 = r1->type ()->forwarded ();
648
+ const Type* rt2 = r2->type ()->forwarded ();
649
+ if (!identical (rt1, rt2))
650
+ return sort (rt1, rt2);
651
+ }
652
+
653
+ const Typed_identifier_list* p1 = ft1->parameters ();
654
+ const Typed_identifier_list* p2 = ft2->parameters ();
655
+ if (p1 == NULL || p1->empty ())
656
+ go_assert (p2 == NULL || p2->empty ());
657
+ else
658
+ {
659
+ go_assert (p2 != NULL && !p2->empty ());
660
+ int i = compare_til (p1, p2);
661
+ if (i < 0 )
662
+ return false ;
663
+ else if (i > 0 )
664
+ return true ;
665
+ }
666
+
667
+ p1 = ft1->results ();
668
+ p2 = ft2->results ();
669
+ if (p1 == NULL || p1->empty ())
670
+ go_assert (p2 == NULL || p2->empty ());
671
+ else
672
+ {
673
+ go_assert (p2 != NULL && !p2->empty ());
674
+ int i = compare_til (p1, p2);
675
+ if (i < 0 )
676
+ return false ;
677
+ else if (i > 0 )
678
+ return true ;
679
+ }
680
+
681
+ go_unreachable ();
682
+ }
683
+
684
+ case Type::TYPE_POINTER:
685
+ {
686
+ const Type* p1 = t1->points_to ()->forwarded ();
687
+ const Type* p2 = t2->points_to ()->forwarded ();
688
+ go_assert (!identical (p1, p2));
689
+ return sort (p1, p2);
690
+ }
691
+
692
+ case Type::TYPE_STRUCT:
693
+ {
694
+ const Struct_type* s1 = t1->struct_type ();
695
+ const Struct_type* s2 = t2->struct_type ();
696
+ const Struct_field_list* f1 = s1->fields ();
697
+ const Struct_field_list* f2 = s2->fields ();
698
+ go_assert (f1 != NULL && f2 != NULL );
699
+ Struct_field_list::const_iterator p1 = f1->begin ();
700
+ Struct_field_list::const_iterator p2 = f2->begin ();
701
+ for (; p2 != f2->end (); ++p1, ++p2)
702
+ {
703
+ go_assert (p1 != f1->end ());
704
+ go_assert (p1->field_name () == p2->field_name ());
705
+ go_assert (p1->is_anonymous () == p2->is_anonymous ());
706
+ const Type* ft1 = p1->type ()->forwarded ();
707
+ const Type* ft2 = p2->type ()->forwarded ();
708
+ if (!identical (ft1, ft2))
709
+ return sort (ft1, ft2);
710
+ }
711
+ go_assert (p1 == f1->end ());
712
+ go_unreachable ();
713
+ }
714
+
715
+ case Type::TYPE_ARRAY:
716
+ {
717
+ const Type* e1 = t1->array_type ()->element_type ()->forwarded ();
718
+ const Type* e2 = t2->array_type ()->element_type ()->forwarded ();
719
+ go_assert (!identical (e1 , e2 ));
720
+ return sort (e1 , e2 );
721
+ }
722
+
723
+ case Type::TYPE_MAP:
724
+ {
725
+ const Map_type* m1 = t1->map_type ();
726
+ const Map_type* m2 = t2->map_type ();
727
+ const Type* k1 = m1->key_type ()->forwarded ();
728
+ const Type* k2 = m2->key_type ()->forwarded ();
729
+ if (!identical (k1, k2))
730
+ return sort (k1, k2);
731
+ const Type* v1 = m1->val_type ()->forwarded ();
732
+ const Type* v2 = m2->val_type ()->forwarded ();
733
+ go_assert (!identical (v1, v2));
734
+ return sort (v1, v2);
735
+ }
736
+
737
+ case Type::TYPE_CHANNEL:
738
+ {
739
+ const Type* e1 = t1->channel_type ()->element_type ()->forwarded ();
740
+ const Type* e2 = t2->channel_type ()->element_type ()->forwarded ();
741
+ go_assert (!identical (e1 , e2 ));
742
+ return sort (e1 , e2 );
743
+ }
744
+
745
+ case Type::TYPE_INTERFACE:
746
+ {
747
+ const Interface_type* it1 = t1->interface_type ();
748
+ const Interface_type* it2 = t2->interface_type ();
749
+ const Typed_identifier_list* m1 = it1->local_methods ();
750
+ const Typed_identifier_list* m2 = it2->local_methods ();
751
+
752
+ // We know the full method lists are the same, because the
753
+ // mangled type names were the same, but here we are looking
754
+ // at the local method lists, which include embedded
755
+ // interfaces, and we can have an embedded empty interface.
756
+ if (m1 == NULL || m1->empty ())
757
+ {
758
+ go_assert (m2 != NULL && !m2->empty ());
759
+ return true ;
760
+ }
761
+ else if (m2 == NULL || m2->empty ())
762
+ {
763
+ go_assert (m1 != NULL && !m1->empty ());
764
+ return false ;
765
+ }
766
+
767
+ int i = compare_til (m1, m2);
768
+ if (i < 0 )
769
+ return false ;
770
+ else if (i > 0 )
771
+ return true ;
772
+ else
773
+ go_unreachable ();
774
+ }
775
+ }
553
776
}
554
777
};
555
778
779
+ // Compare Typed_identifier_list's with Sort_types, returning -1, 0, +1.
780
+
781
+ static int
782
+ compare_til (
783
+ const Typed_identifier_list* til1,
784
+ const Typed_identifier_list* til2)
785
+ {
786
+ Type_alias_identical identical;
787
+ Sort_types sort;
788
+ Typed_identifier_list::const_iterator p1 = til1->begin ();
789
+ Typed_identifier_list::const_iterator p2 = til2->begin ();
790
+ for (; p2 != til2->end (); ++p1, ++p2)
791
+ {
792
+ if (p1 == til1->end ())
793
+ return -1 ;
794
+ const Type* t1 = p1->type ()->forwarded ();
795
+ const Type* t2 = p2->type ()->forwarded ();
796
+ if (!identical (t1, t2))
797
+ {
798
+ if (sort (t1, t2))
799
+ return -1 ;
800
+ else
801
+ return +1 ;
802
+ }
803
+ }
804
+ if (p1 != til1->end ())
805
+ return +1 ;
806
+ return 0 ;
807
+ }
808
+
556
809
// Export those identifiers marked for exporting.
557
810
558
811
void
@@ -714,17 +967,9 @@ bool
714
967
Export::record_type (Type* type)
715
968
{
716
969
type = type->forwarded ();
717
-
718
970
std::pair<Type_refs::iterator, bool > ins =
719
971
this ->impl_ ->type_refs .insert (std::make_pair (type, 0 ));
720
- if (!ins.second )
721
- {
722
- // We've already seen this type.
723
- return false ;
724
- }
725
- ins.first ->second = 0 ;
726
-
727
- return true ;
972
+ return ins.second ;
728
973
}
729
974
730
975
// Assign the specified type an index.
@@ -733,13 +978,12 @@ void
733
978
Export::set_type_index (const Type* type)
734
979
{
735
980
type = type->forwarded ();
736
- std::pair<Type_refs::iterator, bool > ins =
737
- this ->impl_ ->type_refs .insert (std::make_pair (type, 0 ));
738
- go_assert (!ins.second );
981
+ Type_refs::iterator p = this ->impl_ ->type_refs .find (type);
982
+ go_assert (p != this ->impl_ ->type_refs .end ());
739
983
int index = this ->type_index_ ;
740
984
++this ->type_index_ ;
741
- go_assert (ins. first ->second == 0 );
742
- ins. first ->second = index ;
985
+ go_assert (p ->second == 0 );
986
+ p ->second = index ;
743
987
}
744
988
745
989
// This helper assigns type indices to all types mentioned directly or
@@ -758,9 +1002,6 @@ Export::assign_type_indices(const std::vector<Named_object*>& sorted_exports)
758
1002
{
759
1003
if (!(*p)->is_type ())
760
1004
continue ;
761
- Interface_type* it = (*p)->type_value ()->interface_type ();
762
- if (it != NULL )
763
- it->sort_embedded ();
764
1005
this ->record_type ((*p)->type_value ());
765
1006
this ->set_type_index ((*p)->type_value ());
766
1007
}
0 commit comments