Rollup merge of #145218 - nilptr:nilptr/feat/lldb-enum-pretty-printer, r=Mark-Simulacrum
[Debuginfo] improve enum value formatting in LLDB for better readability > TL;DR: When debugging with CodeLLDB, I noticed enum values were often hard to read because LLDB lists every possible variant, resulting in a verbose and cluttered view, even though only one variant is actually valid. Interestingly, raw enum types display nicely. After some investigation, I found that `&enum` values get classified as `Other`, so it falls back to `DefaultSyntheticProvider`, which causes this verbose output. ## What does this PR do? This PR contains 2 commits: 1. change the enum value formatting from showing 2 separate fields (`value` for attached data and `$discr$` for the discriminator) to a concise `<readable variant name>: <attached data>` format 2. dereference pointer types in `classify_rust_type` so that it can return more accurate type for reference type ## Self-test proof Before: <img width="1706" height="799" alt="before" src="https://github.com/user-attachments/assets/b66c7e22-990a-4da5-9036-34e3f9f62367" /> After: <img width="1541" height="678" alt="after" src="https://github.com/user-attachments/assets/36db32e2-f822-4883-8f17-cb8067e509f6" />
This commit is contained in:
commit
5cfdbd6c08
3 changed files with 23 additions and 21 deletions
|
|
@ -10,6 +10,9 @@ def is_hashbrown_hashmap(hash_map: lldb.SBValue) -> bool:
|
|||
|
||||
|
||||
def classify_rust_type(type: lldb.SBType) -> str:
|
||||
if type.IsPointerType():
|
||||
type = type.GetPointeeType()
|
||||
|
||||
type_class = type.GetTypeClass()
|
||||
if type_class == lldb.eTypeClassStruct:
|
||||
return classify_struct(type.name, type.fields)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from __future__ import annotations
|
||||
import re
|
||||
import sys
|
||||
from typing import List, TYPE_CHECKING
|
||||
|
||||
|
|
@ -410,6 +411,16 @@ class MSVCStrSyntheticProvider:
|
|||
return "&str"
|
||||
|
||||
|
||||
def _getVariantName(variant) -> str:
|
||||
"""
|
||||
Since the enum variant's type name is in the form `TheEnumName::TheVariantName$Variant`,
|
||||
we can extract `TheVariantName` from it for display purpose.
|
||||
"""
|
||||
s = variant.GetType().GetName()
|
||||
match = re.search(r"::([^:]+)\$Variant$", s)
|
||||
return match.group(1) if match else ""
|
||||
|
||||
|
||||
class ClangEncodedEnumProvider:
|
||||
"""Pretty-printer for 'clang-encoded' enums support implemented in LLDB"""
|
||||
|
||||
|
|
@ -424,37 +435,25 @@ class ClangEncodedEnumProvider:
|
|||
return True
|
||||
|
||||
def num_children(self) -> int:
|
||||
if self.is_default:
|
||||
return 1
|
||||
return 2
|
||||
return 1
|
||||
|
||||
def get_child_index(self, name: str) -> int:
|
||||
if name == ClangEncodedEnumProvider.VALUE_MEMBER_NAME:
|
||||
return 0
|
||||
if name == ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME:
|
||||
return 1
|
||||
def get_child_index(self, _name: str) -> int:
|
||||
return -1
|
||||
|
||||
def get_child_at_index(self, index: int) -> SBValue:
|
||||
if index == 0:
|
||||
return self.variant.GetChildMemberWithName(
|
||||
value = self.variant.GetChildMemberWithName(
|
||||
ClangEncodedEnumProvider.VALUE_MEMBER_NAME
|
||||
)
|
||||
if index == 1:
|
||||
return self.variant.GetChildMemberWithName(
|
||||
ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME
|
||||
return value.CreateChildAtOffset(
|
||||
_getVariantName(self.variant), 0, value.GetType()
|
||||
)
|
||||
return None
|
||||
|
||||
def update(self):
|
||||
all_variants = self.valobj.GetChildAtIndex(0)
|
||||
index = self._getCurrentVariantIndex(all_variants)
|
||||
self.variant = all_variants.GetChildAtIndex(index)
|
||||
self.is_default = (
|
||||
self.variant.GetIndexOfChildWithName(
|
||||
ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME
|
||||
)
|
||||
== -1
|
||||
)
|
||||
|
||||
def _getCurrentVariantIndex(self, all_variants: SBValue) -> int:
|
||||
default_index = 0
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@
|
|||
// lldb-command:run
|
||||
|
||||
// lldb-command:v *the_a_ref
|
||||
// lldb-check:(borrowed_enum::ABC) *the_a_ref = { value = { x = 0 y = 8970181431921507452 } $discr$ = 0 }
|
||||
// lldb-check:(borrowed_enum::ABC) *the_a_ref = { TheA = { x = 0 y = 8970181431921507452 } }
|
||||
// lldb-command:v *the_b_ref
|
||||
// lldb-check:(borrowed_enum::ABC) *the_b_ref = { value = { 0 = 0 1 = 286331153 2 = 286331153 } $discr$ = 1 }
|
||||
// lldb-check:(borrowed_enum::ABC) *the_b_ref = { TheB = { 0 = 0 1 = 286331153 2 = 286331153 } }
|
||||
// lldb-command:v *univariant_ref
|
||||
// lldb-check:(borrowed_enum::Univariant) *univariant_ref = { value = { 0 = 4820353753753434 } }
|
||||
// lldb-check:(borrowed_enum::Univariant) *univariant_ref = { TheOnlyCase = { 0 = 4820353753753434 } }
|
||||
|
||||
#![allow(unused_variables)]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue