This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Handle declarators more consistently in Selection.
ClosedPublic

Authored by sammccall on Jan 4 2022, 3:20 PM.

Details

Summary

Because declarators nest inside-out, we logically need to claim tokens for
parent declarators logically before child ones.
This is the ultimate reason we had problems with DeclaratorDecl, ArrayType etc.

However actually changing the order of traversal is hard, especially for nodes
that have both declarator and non-declarator children.
Since there's only a few TypeLocs corresponding to declarators, we just
have them claim the exact tokens rather than rely on nesting.

This fixes handling of complex declarators, like
int (*Fun(OuterT^ype))(InnerType);.

This avoids the need for the DeclaratorDecl early-claim hack, which is
removed.
Unfortunately the DeclaratorDecl early-claims were covering up an AST
anomaly around CXXConstructExpr, so we need to fix that up too.

Based on D116623 and D116618

Diff Detail

Event Timeline

sammccall created this revision.Jan 4 2022, 3:20 PM
sammccall requested review of this revision.Jan 4 2022, 3:20 PM
hokein accepted this revision.Jan 5 2022, 5:18 AM

Thanks, this looks better!

clang-tools-extra/clangd/Selection.cpp
757

I'd prefer to keep this comment, while we have some high-level and abstract comment in the new patch, I think it is still useful to give us some details (otherwise, I'd probably forget everything when coming back to read the code a few months later).

I also want to add the example int (*Fun(OuterType))(InnerType); from D116618 here, I understand it might be too verbose (personally, I find it useful to understand this part of code), up to you.

777

nit: FTL.getLParenLoc().

clang-tools-extra/clangd/unittests/SelectionTests.cpp
209–212

Maybe a FIXME for "CXXConstructExpr is better", but I don't come up with a good fix.

This revision is now accepted and ready to land.Jan 5 2022, 5:18 AM
sammccall marked 3 inline comments as done.Jan 5 2022, 6:34 AM
sammccall added inline comments.
clang-tools-extra/clangd/Selection.cpp
757

Yeah, the example is useful.
My problem was that the examples were showing how each declarator type combined with itself, which was both confusing (as you have to describe which you're talking about) and didn't cover the general case.

I've added a new example, which uses multiple different types of declarators and also shows nontrivial non-declarator types for comparison.

clang-tools-extra/clangd/unittests/SelectionTests.cpp
209–212

I actually like the way we treat CXXConstructExpr, which is that it owns the brackets and nothing else.
And having VarDecl consistently own the = is nice too.

This is a divergence from the AST so I've left a comment, but I think it's actually good.

(As mentioned offline: the CXXConstructExpr in this case isn't actually the interesting constructor, it's the elidable move construction, so this doesn't really hurt go-to-definition etc)

This revision was automatically updated to reflect the committed changes.
sammccall marked 2 inline comments as done.
nridge added a subscriber: nridge.Jan 12 2022, 8:53 PM