Skip to content

Fix C/C++ debug hover on intermediate members of a dereferenced expression#14540

Open
tieo wants to merge 2 commits into
microsoft:mainfrom
tieo:cpp-debug-hover-leading-deref
Open

Fix C/C++ debug hover on intermediate members of a dereferenced expression#14540
tieo wants to merge 2 commits into
microsoft:mainfrom
tieo:cpp-debug-hover-leading-deref

Conversation

@tieo

@tieo tieo commented Jun 23, 2026

Copy link
Copy Markdown

Problem

On a line that begins an expression with */& (e.g. if (*a.b.c == X) where a.b is a
struct), hovering an intermediate member (a or b) while debugging shows no value.
Without the leading operator it works fine; Watch/Variables are unaffected.

Cause

No EvaluatableExpressionProvider is registered for C/C++, so VS Code's default is used. It keeps
the leading * and clips on the right, so hovering b sends *a.b to the debug adapter — a
dereference of the non-pointer member a.b — which errors.

Fix

Register an EvaluatableExpressionProvider that, only for an intermediate member of a
*/&-prefixed chain, returns the expression without the leading operator (a.b). Every other
case returns undefined, so the default behavior (./->/::, and legitimate *ptr derefs on
the 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.

…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.
@tieo tieo requested a review from a team as a code owner June 23, 2026 10:35
@github-project-automation github-project-automation Bot moved this to Pull Request in cpptools Jun 23, 2026
@tieo

tieo commented Jun 23, 2026

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

Comment thread Extension/src/LanguageServer/client.ts Outdated
Comment thread Extension/src/LanguageServer/Providers/evaluatableExpressionProvider.ts Outdated

@sean-mcmanus sean-mcmanus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...see my other comments.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 EvaluatableExpressionProvider implementation 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.

Comment thread Extension/src/LanguageServer/Providers/evaluatableExpressionProvider.ts Outdated
@sean-mcmanus sean-mcmanus added this to the 1.33.2 milestone Jun 23, 2026
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.
@tieo

tieo commented Jun 25, 2026

Copy link
Copy Markdown
Author

Addressed the review feedback in the latest commit:

  • Moved the provider to Extension/src/Debugger/ and register it during debugger activation in Debugger/extension.ts instead of the language client.

On the Copilot suggestion to gate with line.charAt(clipEnd) === '.': I went a different way. The problem with that gate is it leaves *ptr->member doing what the default does, but that's already broken — -> has higher precedence than the unary *, so the expression is really *(ptr->member), and when you hover ptr you want to see ptr, not *ptr.

What it does now is keep the leading */& only when you're hovering the last segment of the chain, and drop it everywhere in the middle. That ends up being right whether the chain uses ., ->, or []. I also had to keep subscripts in the token because the default detection stops at the [, which is why hovering something like the c in a.b[i].c gave you nothing before. Function calls never get pulled in, so there's no risk of evaluating something with side effects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Pull Request

Development

Successfully merging this pull request may close these issues.

3 participants