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