Fix C/C++ debug hover on intermediate members of a dereferenced expression#14540
Fix C/C++ debug hover on intermediate members of a dereferenced expression#14540tieo wants to merge 2 commits into
Conversation
…enced members VS Code's default debug data-tip keeps a leading `*`/`&` and clips on the right, so hovering an intermediate member of e.g. `*a.b.c` evaluates `*a.b` (a dereference of the struct `a.b`) and shows no value. Register an EvaluatableExpressionProvider that, only for that case, returns the expression without the leading operator. Every other expression returns undefined so the default behavior is unchanged.
|
@microsoft-github-policy-service agree |
There was a problem hiding this comment.
Pull request overview
Registers a C/C++ EvaluatableExpressionProvider so debug hover evaluates the correct sub-expression when the hovered identifier is an intermediate member inside a */&-prefixed access chain (e.g. avoiding *a.b when hovering b in *a.b.c).
Changes:
- Added
EvaluatableExpressionProviderimplementation that conditionally strips leading*/&for intermediate member hovers. - Registered the provider during language server client initialization for the C/C++ document selector.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| Extension/src/LanguageServer/Providers/evaluatableExpressionProvider.ts | Adds a custom evaluatable-expression computation to override VS Code’s default behavior in a narrow case. |
| Extension/src/LanguageServer/client.ts | Registers the new evaluatable expression provider for C/C++ documents. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Register the EvaluatableExpressionProvider during debugger activation instead of through the language client, so it also works when IntelliSense is disabled, and move it next to the other debugger code. Registering a provider replaces VS Code's built-in data-tip expression detection entirely, so reproduce that for ordinary tokens and additionally handle two cases the built-in detection gets wrong for C/C++: - A leading * or & binds to the whole access chain, not an interior member (the postfix operators bind tighter), so it is dropped on an interior member, where e.g. *a.b would dereference the struct a.b, and kept on the final segment. Cases like *ptr->member are handled accordingly. - Array subscripts are part of the chain, so [...] is kept (including nesting) rather than ending the token, and hovering an index evaluates the index on its own. Members accessed after a subscript such as a.b[i].c now resolve instead of producing a broken fragment.
|
Addressed the review feedback in the latest commit:
On the Copilot suggestion to gate with What it does now is keep the leading |
Problem
On a line that begins an expression with
*/&(e.g.if (*a.b.c == X)wherea.bis astruct), hovering an intermediate member (
aorb) while debugging shows no value.Without the leading operator it works fine; Watch/Variables are unaffected.
Cause
No
EvaluatableExpressionProvideris registered for C/C++, so VS Code's default is used. It keepsthe leading
*and clips on the right, so hoveringbsends*a.bto the debug adapter — adereference of the non-pointer member
a.b— which errors.Fix
Register an
EvaluatableExpressionProviderthat, only for an intermediate member of a*/&-prefixed chain, returns the expression without the leading operator (a.b). Every othercase returns
undefined, so the default behavior (./->/::, and legitimate*ptrderefs onthe final segment) is unchanged.
Note: I created the code in this PR using the LLM Opus 4.8, as well as the text above which was proofread by it.
I tested it manually in VS Code.