sammccall planned changes to this revision. sammccall added a comment. No, this patch is busted, and the tests were too simple go catch it.
The issue is that with no exclusivity check, given `{{{ MACRO }}}` all the enclosing blocks get to count themselves selected. We need an exclusivity check on the expanded token stream first. This will yield a sequence of slices of tokens not yet claimed. Then each slice gets partitioned by FileID, each partition gets mapped to spelled tokens and checked as in this patch. I suspect the exclusivity/claiming at the spelled token level is no longer needed. ================ Comment at: clang-tools-extra/clangd/Selection.cpp:49 + Result = New; + else if (Result != New) + Result = SelectionTree::Partial; ---------------- hokein wrote: > I might be missing something, I don't understand why we set Partial if > `Result != New`. Added a brief comment and an assertion. Intuitive explanation: Consider `Complete` = black, `Unselected` = white, `Partial` = grey. White + White -> white, Black + Black -> black, every other mixture is grey. (But honestly I wrote up the state transition table first and then extracted the logic by staring at it) ================ Comment at: clang-tools-extra/clangd/Selection.cpp:446 + // Consider the macro expansion FLAG(x) -> int x = 0; + // Neither S.getBegin() nor S.getEnd() are arg expansions, but x is. + // The selection FLAG([[x]]) must partially select the VarDecl. ---------------- hokein wrote: > what's S for this case? S is the function parameter, the implication is that it's the range of the vardecl in the example. Expanded the comment a bit. ================ Comment at: clang-tools-extra/clangd/Selection.cpp:496 + // Check if the macro name is selected, don't claim it exclusively. + auto Expansion = SM.getDecomposedExpansionLoc(S.getBegin()); + if (Expansion.first == SelFile) ---------------- hokein wrote: > not sure what's the rational behavior, but I think for the following case, we > just have the TUDecl in the selection tree, maybe use the whole macro range? > > ``` > #define M() 123 > > int d = M(^); // now we only have the TUDecl in the selection tree. > ``` This is definitely better, but isn't trivial to do, and isn't a very important case. Added a FIXME rather than clutter/delay this patch with it. ================ Comment at: clang/lib/Tooling/Syntax/Tokens.cpp:125 + return {}; + const Token *Begin = + llvm::partition_point(expandedTokens(), [&](const syntax::Token &T) { ---------------- hokein wrote: > nit: for code readability, I'd use `llvm::ArrayRef<syntax::Token>::iterator` > type here. I think that hurts readability on two counts: - it obscures the actual type: a pointer is concrete and familiar, so it's easier to realize that e.g. `>` is well-defined here - it makes it harder to understand `return {Begin, End}` which relies on the fact that the actual type here is Token* Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70512/new/ https://reviews.llvm.org/D70512 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits