Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Unit tests: pass. 61162 tests passed, 0 failed and 728 were skipped.
clang-tidy: pass.
clang-format: pass.
Build artifacts: diff.json, clang-tidy.txt, clang-format.patch, CMakeCache.txt, console-log.txt, test-results.xml
I like the goal here, a few high-level comments:
- it seems unfortunate to solve this mostly in xrefs rather than mostly in SelectionTree. All the other clients potentially want this behavior.
- the allSelectedNodes API on SelectionTree feels non-orthogonal: it's only meaningful here because the input happened to be a point and thus touches a single token and therefore node. If the input was a range, then this API doesn't help, because it loses the sense of "topmost" node.
- maybe the function we want walks down the tree as if finding the common ancestor, but may descend to return the roots of multiple subtrees if they are located in distinct expansions of the same macro arg
- or maybe we just want to treat non-first expansions as not-selected? That would about this issue I think
(BTW, Haojian is out the first few weeks of Jan. I'm still technically OOO, back later this week)
Good point!
- maybe the function we want walks down the tree as if finding the common ancestor, but may descend to return the roots of multiple subtrees if they are located in distinct expansions of the same macro arg
- or maybe we just want to treat non-first expansions as not-selected? That would about this issue I think
I'm thinking of going with the second suggestion, because it doesn't require changes to the SelectionTree API, and therefore addresses this concern:
- it seems unfortunate to solve this mostly in xrefs rather than mostly in SelectionTree. All the other clients potentially want this behavior.
without touching all the clients of SelectionTree.
Unit tests: pass. 61848 tests passed, 0 failed and 781 were skipped.
clang-tidy: unknown.
clang-format: pass.
Build artifacts: diff.json, clang-format.patch, CMakeCache.txt, console-log.txt, test-results.xml
Thanks for fixing this. I think it could maybe use a further tweak, LMK if I'm missing something as my intuition around macros is pretty bad.
clang-tools-extra/clangd/Selection.cpp | ||
---|---|---|
259 | Given the following program: #define SQUARE(x) x * x; int four = [[SQUARE(2)]]; We're going to now report the binary operator and one of the operands as selected and not the other, which doesn't seem desirable. I think we want to accept macro-selected || arg-selected, so probably doing the current "non-argument macro expansion" first unconditionally or factoring it out into a function. This will change the behavior of int four = [[SQUARE]](2) to consider the literal children selected too, I think this is fine. | |
259 | I don't think it's a good idea to add hidden state and side-effects to testChunk() - it breaks a lot of assumptions that help reason about the code, and using mutable hides the violation of them. Instead I think you can do this statelessly: from the top-level spelling location, walk down with SM.getMacroArgExpandedLocation until you hit the target FileID (this is the first-expansion of first-expansion of first-expansion...) or the FileID stops changing (you've reached the innermost macro invocation, and your target location was on a different branch). | |
clang-tools-extra/clangd/Selection.h | ||
58 | Worth mentioning the new behavior here, IMO. e.g. When a macro argument is specifically selected, only its first expansion is selected in the AST. (Returning a selection forest is unreasonably difficult for callers to handle correctly). |
clang-tools-extra/clangd/Selection.cpp | ||
---|---|---|
259 | I agree that adding state is not great. I thought it was icky as I was writing it, I just couldn't think of an alternative. Thank you for suggesting one! I implemented what you suggested, and it seems to work. I did want to ask a clarifying question to make sure I understand correctly: when an argument occurs multiple times in a macro exapnsion, the occurrences will have distinct FileIDs (as opposed just different offsets in the same macro FileID)? |
Awesome, thanks for fixing this!
clang-tools-extra/clangd/Selection.cpp | ||
---|---|---|
160 | nit: return false directly? | |
259 | That's right. My mental model is:
One of the things I really like about the syntax::TokenBuffer API is that it exposes this structure. | |
259 | when false is the fallthrough to handling as if part of the macro body deliberate? Thinking about it I suppose either that or returning NoTokens works, but please document it, e.g. } else { /* fall through and treat as part of the macro body */} |
clang-tools-extra/clangd/Selection.cpp | ||
---|---|---|
259 | It is deliberate. In fact, it is intended to address this previous comment. Please let me know if I've misunderstood and the solution doesn't match the request. I'll add a comment as you suggested. |
clang-tools-extra/clangd/Selection.cpp | ||
---|---|---|
259 | Yeah I think the behavior is great, as is the implementation :-) just a little surprising. |
Worth mentioning the new behavior here, IMO. e.g.