@@ -691,20 +691,21 @@ class ModuleWriter {
691691 // Sort top level functions with the same C++ name by their location to
692692 // have stable sorting that depends on users source but not on the
693693 // 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.
694697 if ((*rhs)->getLoc ().isValid () && (*lhs)->getLoc ().isValid ()) {
695- std::string rhsLoc, lhsLoc;
696- auto getLocText = [](const AbstractFunctionDecl *afd) {
698+ auto getLocText = [](const Decl *afd) {
697699 std::string res;
698700 llvm::raw_string_ostream os (res);
699701 afd->getLoc ().print (os, afd->getASTContext ().SourceMgr );
700702 return std::move (os.str ());
701703 };
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 ;
706708 }
707- return result;
708709 }
709710
710711 // A function and a global variable can have the same name in C++,
@@ -716,12 +717,35 @@ class ModuleWriter {
716717 return Ascending;
717718
718719 // Prefer value decls to extensions.
719- assert (!(isa<ValueDecl>(*lhs) && isa<ValueDecl>(*rhs)));
720720 if (isa<ValueDecl>(*lhs) && !isa<ValueDecl>(*rhs))
721721 return Descending;
722722 if (!isa<ValueDecl>(*lhs) && isa<ValueDecl>(*rhs))
723723 return Ascending;
724724
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+
725749 // Break ties in extensions by putting smaller extensions last (in reverse
726750 // order).
727751 // FIXME: This will end up taking linear time.
@@ -742,16 +766,48 @@ class ModuleWriter {
742766
743767 // If that fails, arbitrarily pick the extension whose protocols are
744768 // 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;
755811 });
756812
757813 assert (declsToWrite.empty ());
0 commit comments