Skip to content

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

Open
tieo wants to merge 1 commit 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 1 commit 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


this.disposables.push(vscode.languages.registerHoverProvider(util.documentSelector, instrument(this.copilotHoverProvider)));
this.disposables.push(vscode.languages.registerHoverProvider(util.documentSelector, instrument(this.hoverProvider)));
this.disposables.push(vscode.languages.registerEvaluatableExpressionProvider(util.documentSelector, instrument(new EvaluatableExpressionProvider())));

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.

I think this belongs in vscode-cpptools\Extension\src\Debugger\extension.ts

@@ -0,0 +1,51 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved.

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.

I think this belongs under vscode-cpptools\Extension\src\Debugger. vscode-cpptools\Extension\src\LanguageServer is for the non-debugger IntelliSense features.

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.

...just for organization and not a technical API reason, since we split up the debugger and language server features separately.

@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 on lines +44 to +47
const exprStart: number = tokenStart + leading[0].length;
if (clipEnd >= tokenEnd || clipEnd <= exprStart) {
return undefined;
}
@sean-mcmanus sean-mcmanus added this to the 1.33.2 milestone Jun 23, 2026
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