@@ -58,6 +58,7 @@ void recordMetrics(const SelectionTree &S, const LangOptions &Lang) {
58
58
SelectionUsedRecovery.record (0 , LanguageLabel); // unused.
59
59
}
60
60
61
+ // Return the range covering a node and all its children.
61
62
SourceRange getSourceRange (const DynTypedNode &N) {
62
63
// MemberExprs to implicitly access anonymous fields should not claim any
63
64
// tokens for themselves. Given:
@@ -702,7 +703,7 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
702
703
void pop () {
703
704
Node &N = *Stack.top ();
704
705
dlog (" {1}pop: {0}" , printNodeToString (N.ASTNode , PrintPolicy), indent (-1 ));
705
- claimRange ( getSourceRange ( N.ASTNode ) , N.Selected );
706
+ claimTokensFor ( N.ASTNode , N.Selected );
706
707
if (N.Selected == NoTokens)
707
708
N.Selected = SelectionTree::Unselected;
708
709
if (N.Selected || !N.Children .empty ()) {
@@ -744,6 +745,28 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
744
745
return SourceRange ();
745
746
}
746
747
748
+ // Claim tokens for N, after processing its children.
749
+ // By default this claims all unclaimed tokens in getSourceRange().
750
+ // We override this if we want to claim fewer tokens (e.g. there are gaps).
751
+ void claimTokensFor (const DynTypedNode &N, SelectionTree::Selection &Result) {
752
+ if (const auto *TL = N.get <TypeLoc>()) {
753
+ // e.g. EltType Foo[OuterSize][InnerSize];
754
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ArrayTypeLoc (Outer)
755
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |-ArrayTypeLoc (Inner)
756
+ // ~~~~~~~ | |-RecordType
757
+ // ~~~~~~~~~ | `-Expr (InnerSize)
758
+ // ~~~~~~~~~ `-Expr (OuterSize)
759
+ // Inner ATL must not claim its whole SourceRange, or it clobbers Outer.
760
+ if (TL->getAs <ArrayTypeLoc>()) {
761
+ claimRange (TL->getLocalSourceRange (), Result);
762
+ return ;
763
+ }
764
+ // FIXME: maybe LocalSourceRange is a better default for TypeLocs.
765
+ // It doesn't seem to be usable for FunctionTypeLocs.
766
+ }
767
+ claimRange (getSourceRange (N), Result);
768
+ }
769
+
747
770
// Perform hit-testing of a complete Node against the selection.
748
771
// This runs for every node in the AST, and must be fast in common cases.
749
772
// This is usually called from pop(), so we can take children into account.
0 commit comments