@@ -680,20 +680,21 @@ class ModuleWriter {
680
680
// Sort top level functions with the same C++ name by their location to
681
681
// have stable sorting that depends on users source but not on the
682
682
// compiler invocation.
683
+ // FIXME: This is pretty suspect; PrintAsClang sometimes operates on
684
+ // serialized modules which don't have SourceLocs, so this sort
685
+ // rule may be applied in some steps of a build but not others.
683
686
if ((*rhs)->getLoc ().isValid () && (*lhs)->getLoc ().isValid ()) {
684
- std::string rhsLoc, lhsLoc;
685
- auto getLocText = [](const AbstractFunctionDecl *afd) {
687
+ auto getLocText = [](const Decl *afd) {
686
688
std::string res;
687
689
llvm::raw_string_ostream os (res);
688
690
afd->getLoc ().print (os, afd->getASTContext ().SourceMgr );
689
691
return std::move (os.str ());
690
692
};
691
- if ( getLocText (cast<AbstractFunctionDecl>(*lhs)) <
692
- getLocText (cast<AbstractFunctionDecl>( *rhs)))
693
- return Descending;
694
- return Ascending ;
693
+
694
+ result = getLocText (*rhs). compare ( getLocText (*lhs));
695
+ if (result != 0 )
696
+ return result ;
695
697
}
696
- return result;
697
698
}
698
699
699
700
// A function and a global variable can have the same name in C++,
@@ -705,12 +706,35 @@ class ModuleWriter {
705
706
return -1 ;
706
707
707
708
// Prefer value decls to extensions.
708
- assert (!(isa<ValueDecl>(*lhs) && isa<ValueDecl>(*rhs)));
709
709
if (isa<ValueDecl>(*lhs) && !isa<ValueDecl>(*rhs))
710
710
return Descending;
711
711
if (!isa<ValueDecl>(*lhs) && isa<ValueDecl>(*rhs))
712
712
return Ascending;
713
713
714
+ // Last-ditch ValueDecl tiebreaker: Compare mangled names. This captures
715
+ // *tons* of context and detail missed by the previous checks, but the
716
+ // resulting sort makes little sense to humans.
717
+ // FIXME: It'd be nice to share the mangler or even memoize mangled names,
718
+ // but we'd have to stop using `llvm::array_pod_sort()` so that we
719
+ // could capture some outside state.
720
+ Mangle::ASTMangler mangler;
721
+ auto getMangledName = [&](const Decl *D) {
722
+ auto VD = dyn_cast<ValueDecl>(D);
723
+ if (!VD && isa<ExtensionDecl>(D))
724
+ VD = cast<ExtensionDecl>(D)->getExtendedNominal ();
725
+ if (!VD)
726
+ return std::string ();
727
+ return mangler.mangleAnyDecl (VD, /* prefix=*/ true ,
728
+ /* respectOriginallyDefinedIn=*/ true );
729
+ };
730
+ result = getMangledName (*rhs).compare (getMangledName (*lhs));
731
+ if (result != 0 )
732
+ return result;
733
+
734
+ // Mangled names ought to distinguish all value decls, leaving only
735
+ // extensions of the same nominal type beyond this point.
736
+ assert (isa<ExtensionDecl>(*lhs) && isa<ExtensionDecl>(*rhs));
737
+
714
738
// Break ties in extensions by putting smaller extensions last (in reverse
715
739
// order).
716
740
// FIXME: This will end up taking linear time.
@@ -731,16 +755,48 @@ class ModuleWriter {
731
755
732
756
// If that fails, arbitrarily pick the extension whose protocols are
733
757
// alphabetically first.
734
- auto mismatch =
735
- std::mismatch (lhsProtos.begin (), lhsProtos.end (), rhsProtos.begin (),
736
- [] (const ProtocolDecl *nextLHSProto,
737
- const ProtocolDecl *nextRHSProto) {
738
- return nextLHSProto->getName () != nextRHSProto->getName ();
739
- });
740
- if (mismatch.first == lhsProtos.end ())
741
- return Equivalent;
742
- StringRef lhsProtoName = (*mismatch.first )->getName ().str ();
743
- return lhsProtoName.compare ((*mismatch.second )->getName ().str ());
758
+ {
759
+ auto mismatch =
760
+ std::mismatch (lhsProtos.begin (), lhsProtos.end (), rhsProtos.begin (),
761
+ [] (const ProtocolDecl *nextLHSProto,
762
+ const ProtocolDecl *nextRHSProto) {
763
+ return nextLHSProto->getName () != nextRHSProto->getName ();
764
+ });
765
+ if (mismatch.first != lhsProtos.end ()) {
766
+ StringRef lhsProtoName = (*mismatch.first )->getName ().str ();
767
+ return lhsProtoName.compare ((*mismatch.second )->getName ().str ());
768
+ }
769
+ }
770
+
771
+ // Still nothing? Fine, we'll pick the one with the alphabetically first
772
+ // member instead.
773
+ {
774
+ auto mismatch =
775
+ std::mismatch (cast<ExtensionDecl>(*lhs)->getMembers ().begin (),
776
+ cast<ExtensionDecl>(*lhs)->getMembers ().end (),
777
+ cast<ExtensionDecl>(*rhs)->getMembers ().begin (),
778
+ [] (const Decl *nextLHSDecl, const Decl *nextRHSDecl) {
779
+ if (isa<ValueDecl>(nextLHSDecl) && isa<ValueDecl>(nextRHSDecl)) {
780
+ return cast<ValueDecl>(nextLHSDecl)->getName () !=
781
+ cast<ValueDecl>(nextRHSDecl)->getName ();
782
+ }
783
+ return isa<ValueDecl>(nextLHSDecl) != isa<ValueDecl>(nextRHSDecl);
784
+ });
785
+ if (mismatch.first != cast<ExtensionDecl>(*lhs)->getMembers ().end ()) {
786
+ auto *lhsMember = dyn_cast<ValueDecl>(*mismatch.first ),
787
+ *rhsMember = dyn_cast<ValueDecl>(*mismatch.second );
788
+ if (!rhsMember && lhsMember)
789
+ return Descending;
790
+ if (lhsMember && !rhsMember)
791
+ return Ascending;
792
+ if (lhsMember && rhsMember)
793
+ return rhsMember->getName ().compare (lhsMember->getName ());
794
+ }
795
+ }
796
+
797
+ // Hopefully two extensions with identical conformances and member names
798
+ // will be interchangeable enough not to matter.
799
+ return Equivalent;
744
800
});
745
801
746
802
assert (declsToWrite.empty ());
0 commit comments