@@ -680,20 +680,21 @@ class ModuleWriter {
680680 // Sort top level functions with the same C++ name by their location to
681681 // have stable sorting that depends on users source but not on the
682682 // 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.
683686 if ((*rhs)->getLoc ().isValid () && (*lhs)->getLoc ().isValid ()) {
684- std::string rhsLoc, lhsLoc;
685- auto getLocText = [](const AbstractFunctionDecl *afd) {
687+ auto getLocText = [](const Decl *afd) {
686688 std::string res;
687689 llvm::raw_string_ostream os (res);
688690 afd->getLoc ().print (os, afd->getASTContext ().SourceMgr );
689691 return std::move (os.str ());
690692 };
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 ;
695697 }
696- return result;
697698 }
698699
699700 // A function and a global variable can have the same name in C++,
@@ -705,12 +706,35 @@ class ModuleWriter {
705706 return -1 ;
706707
707708 // Prefer value decls to extensions.
708- assert (!(isa<ValueDecl>(*lhs) && isa<ValueDecl>(*rhs)));
709709 if (isa<ValueDecl>(*lhs) && !isa<ValueDecl>(*rhs))
710710 return Descending;
711711 if (!isa<ValueDecl>(*lhs) && isa<ValueDecl>(*rhs))
712712 return Ascending;
713713
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+
714738 // Break ties in extensions by putting smaller extensions last (in reverse
715739 // order).
716740 // FIXME: This will end up taking linear time.
@@ -731,16 +755,48 @@ class ModuleWriter {
731755
732756 // If that fails, arbitrarily pick the extension whose protocols are
733757 // 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;
744800 });
745801
746802 assert (declsToWrite.empty ());
0 commit comments