@@ -815,12 +815,33 @@ struct RangeResolver::Implementation {
815
815
analyzeDecl (D);
816
816
auto &DCInfo = getCurrentDC ();
817
817
818
- auto NodeRange = Node.getSourceRange ();
819
-
820
818
// Widen the node's source range to include all attributes to get a range
821
819
// match if a function with its attributes has been selected.
822
- if (auto D = Node.dyn_cast <Decl *>())
823
- NodeRange = D->getSourceRangeIncludingAttrs ();
820
+ auto getSourceRangeIncludingAttrs = [](ASTNode N) -> SourceRange {
821
+ if (auto D = N.dyn_cast <Decl *>()) {
822
+ return D->getSourceRangeIncludingAttrs ();
823
+ } else {
824
+ return N.getSourceRange ();
825
+ }
826
+ };
827
+
828
+ auto NodeRange = getSourceRangeIncludingAttrs (Node);
829
+
830
+ // SemaAnnotator walks the AST in source order, but considers source order
831
+ // for declarations to be defined by their range *excluding* attributes.
832
+ // In RangeResolver, we attributes as belonging to their decl (see comment
833
+ // on getSourceRAngeIncludingAttrs above).
834
+ // Thus, for the purpose RangeResolver, we need to assume that SemaAnnotator
835
+ // hands us the nodes in arbitrary order.
836
+ //
837
+ // Remove any nodes that are contained by the newly added one.
838
+ auto removeIterator = std::remove_if (
839
+ ContainedASTNodes.begin (), ContainedASTNodes.end (),
840
+ [&](ASTNode ContainedNode) {
841
+ return SM.rangeContains (NodeRange,
842
+ getSourceRangeIncludingAttrs (ContainedNode));
843
+ });
844
+ ContainedASTNodes.erase (removeIterator, ContainedASTNodes.end ());
824
845
825
846
switch (getRangeMatchKind (NodeRange)) {
826
847
case RangeMatchKind::NoneMatch: {
@@ -848,11 +869,16 @@ struct RangeResolver::Implementation {
848
869
849
870
// If no parent is considered as a contained node; this node should be
850
871
// a top-level contained node.
872
+ // If a node that contains this one is later discovered, this node will be
873
+ // removed from ContainedASTNodes again.
851
874
if (std::none_of (ContainedASTNodes.begin (), ContainedASTNodes.end (),
852
- [&](ASTNode N) { return SM.rangeContains (N.getSourceRange (),
853
- Node.getSourceRange ()); })) {
854
- ContainedASTNodes.push_back (Node);
855
- }
875
+ [&](ASTNode ContainedNode) {
876
+ return SM.rangeContains (
877
+ getSourceRangeIncludingAttrs (ContainedNode),
878
+ NodeRange);
879
+ })) {
880
+ ContainedASTNodes.push_back (Node);
881
+ }
856
882
857
883
if (DCInfo.isMultiStatement ()) {
858
884
postAnalysis (DCInfo.EndMatches .back ());
0 commit comments