@@ -764,10 +764,33 @@ ArrayRef<Decl *> IterableDeclContext::getSemanticMembers() const {
764
764
ArrayRef<Decl *>());
765
765
}
766
766
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
+
767
790
// / Add a member to this context.
768
- void IterableDeclContext::addMember (Decl *member, Decl *Hint ) {
791
+ void IterableDeclContext::addMember (Decl *member, Decl *hint, bool insertAtHead ) {
769
792
// Add the member to the list of declarations without notification.
770
- addMemberSilently (member, Hint );
793
+ addMemberSilently (member, hint, insertAtHead );
771
794
772
795
// Notify our parent declaration that we have added the member, which can
773
796
// be used to update the lookup tables.
@@ -790,29 +813,83 @@ void IterableDeclContext::addMember(Decl *member, Decl *Hint) {
790
813
}
791
814
}
792
815
793
- void IterableDeclContext::addMemberSilently (Decl *member, Decl *hint) const {
816
+ void IterableDeclContext::addMemberSilently (Decl *member, Decl *hint,
817
+ bool insertAtHead) const {
794
818
assert (!isa<AccessorDecl>(member) && " Accessors should not be added here" );
795
819
assert (!member->NextDecl && " Already added to a container" );
796
820
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
+
800
886
member->NextDecl = hint->NextDecl ;
801
887
hint->NextDecl = member;
802
888
803
- // If the hint was the last in the parent context's chain, update it .
889
+ // Handle case where the 'hint' is the tail .
804
890
if (LastDeclAndKind.getPointer () == hint)
805
891
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);
814
892
}
815
- LastDeclAndKind.setPointer (member);
816
893
}
817
894
818
895
void IterableDeclContext::setMemberLoader (LazyMemberLoader *loader,
0 commit comments