@@ -764,10 +764,33 @@ ArrayRef<Decl *> IterableDeclContext::getSemanticMembers() const {
764764 ArrayRef<Decl *>());
765765}
766766
767+ void IterableDeclContext::addMemberPreservingSourceOrder (Decl *member) {
768+ auto &SM = getASTContext ().SourceMgr ;
769+
770+ SourceLoc start = member->getStartLoc ();
771+ Decl *hint = nullptr ;
772+
773+ for (auto *existingMember : getMembers ()) {
774+ if (existingMember->isImplicit ())
775+ continue ;
776+
777+ if (isa<EnumCaseDecl>(existingMember) ||
778+ isa<IfConfigDecl>(existingMember))
779+ continue ;
780+
781+ if (!SM.isBeforeInBuffer (existingMember->getEndLoc (), start))
782+ break ;
783+
784+ hint = existingMember;
785+ }
786+
787+ addMember (member, hint, /* insertAtHead=*/ hint == nullptr );
788+ }
789+
767790// / Add a member to this context.
768- void IterableDeclContext::addMember (Decl *member, Decl *Hint ) {
791+ void IterableDeclContext::addMember (Decl *member, Decl *hint, bool insertAtHead ) {
769792 // Add the member to the list of declarations without notification.
770- addMemberSilently (member, Hint );
793+ addMemberSilently (member, hint, insertAtHead );
771794
772795 // Notify our parent declaration that we have added the member, which can
773796 // be used to update the lookup tables.
@@ -790,29 +813,83 @@ void IterableDeclContext::addMember(Decl *member, Decl *Hint) {
790813 }
791814}
792815
793- void IterableDeclContext::addMemberSilently (Decl *member, Decl *hint) const {
816+ void IterableDeclContext::addMemberSilently (Decl *member, Decl *hint,
817+ bool insertAtHead) const {
794818 assert (!isa<AccessorDecl>(member) && " Accessors should not be added here" );
795819 assert (!member->NextDecl && " Already added to a container" );
796820
797- // If there is a hint decl that specifies where to add this, just
798- // link into the chain immediately following it.
799- if (hint) {
821+ #ifndef NDEBUG
822+ auto checkSourceRange = [&](Decl *prev, Decl *next) {
823+ if (!member->getDeclContext ()->getParentSourceFile ())
824+ return ;
825+
826+ auto shouldSkip = [](Decl *d) {
827+ if (isa<VarDecl>(d) || isa<EnumElementDecl>(d) || isa<IfConfigDecl>(d))
828+ return true ;
829+
830+ if (d->isImplicit ())
831+ return true ;
832+
833+ return false ;
834+ };
835+
836+ if (shouldSkip (prev) || shouldSkip (next))
837+ return ;
838+
839+ SourceLoc prevEnd = prev->getEndLoc ();
840+ SourceLoc nextStart = next->getStartLoc ();
841+
842+ if (!prevEnd.isValid () || !nextStart.isValid ())
843+ return ;
844+
845+ if (getASTContext ().SourceMgr .isBeforeInBuffer (prevEnd, nextStart))
846+ return ;
847+
848+ llvm::errs () << " Source ranges out of order in addMember():\n " ;
849+ prev->dump (llvm::errs ());
850+ next->dump (llvm::errs ());
851+ abort ();
852+ };
853+ #endif
854+
855+ // Empty list.
856+ if (!FirstDeclAndLazyMembers.getPointer ()) {
857+ assert (hint == nullptr );
858+
859+ FirstDeclAndLazyMembers.setPointer (member);
860+ LastDeclAndKind.setPointer (member);
861+
862+ // Insertion at the head.
863+ } else if (insertAtHead) {
864+ assert (hint == nullptr );
865+
866+ member->NextDecl = FirstDeclAndLazyMembers.getPointer ();
867+ FirstDeclAndLazyMembers.setPointer (member);
868+
869+ // Insertion at the tail.
870+ } else if (hint == nullptr ) {
871+ auto *last = LastDeclAndKind.getPointer ();
872+
873+ #ifndef NDEBUG
874+ checkSourceRange (last, member);
875+ #endif
876+
877+ last->NextDecl = member;
878+ LastDeclAndKind.setPointer (member);
879+
880+ // Insertion after 'hint' (which may be the tail).
881+ } else {
882+ #ifndef NDEBUG
883+ checkSourceRange (hint, member);
884+ #endif
885+
800886 member->NextDecl = hint->NextDecl ;
801887 hint->NextDecl = member;
802888
803- // If the hint was the last in the parent context's chain, update it .
889+ // Handle case where the 'hint' is the tail .
804890 if (LastDeclAndKind.getPointer () == hint)
805891 LastDeclAndKind.setPointer (member);
806- return ;
807- }
808-
809- if (auto last = LastDeclAndKind.getPointer ()) {
810- last->NextDecl = member;
811- assert (last != member && " Simple cycle in decl list" );
812- } else {
813- FirstDeclAndLazyMembers.setPointer (member);
814892 }
815- LastDeclAndKind.setPointer (member);
816893}
817894
818895void IterableDeclContext::setMemberLoader (LazyMemberLoader *loader,
0 commit comments