11from __future__ import annotations
2- import re
32import sys
4- from typing import List , TYPE_CHECKING
3+ from typing import Generator , List , TYPE_CHECKING
54
65from lldb import (
76 SBData ,
1211 eFormatChar ,
1312)
1413
14+ from rust_types import is_tuple_fields
15+
1516if TYPE_CHECKING :
1617 from lldb import SBValue , SBType , SBTypeStaticField
1718
@@ -133,7 +134,7 @@ def has_children(self) -> bool:
133134 return False
134135
135136
136- def get_template_args (type_name : str ) -> list [str ]:
137+ def get_template_args (type_name : str ) -> List [str ]:
137138 """
138139 Takes a type name `T<A, tuple$<B, C>, D>` and returns a list of its generic args
139140 `["A", "tuple$<B, C>", "D"]`.
@@ -163,6 +164,34 @@ def get_template_args(type_name: str) -> list[str]:
163164 return params
164165
165166
167+ def StructSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
168+ # structs need the field name before the field value
169+ output = (
170+ f"{ valobj .GetChildAtIndex (i ).GetName ()} :{ child } "
171+ for i , child in enumerate (aggregate_field_summary (valobj , _dict ))
172+ )
173+
174+ return "{" + ", " .join (output ) + "}"
175+
176+
177+ def TupleSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ):
178+ return "(" + ", " .join (aggregate_field_summary (valobj , _dict )) + ")"
179+
180+
181+ def aggregate_field_summary (valobj : SBValue , _dict ) -> Generator [str , None , None ]:
182+ for i in range (0 , valobj .GetNumChildren ()):
183+ child : SBValue = valobj .GetChildAtIndex (i )
184+ summary = child .summary
185+ if summary is None :
186+ summary = child .value
187+ if summary is None :
188+ if is_tuple_fields (child ):
189+ summary = TupleSummaryProvider (child , _dict )
190+ else :
191+ summary = StructSummaryProvider (child , _dict )
192+ yield summary
193+
194+
166195def SizeSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
167196 return "size=" + str (valobj .GetNumChildren ())
168197
@@ -411,49 +440,55 @@ def get_type_name(self):
411440 return "&str"
412441
413442
414- def _getVariantName (variant ) -> str :
443+ def _getVariantName (variant : SBValue ) -> str :
415444 """
416445 Since the enum variant's type name is in the form `TheEnumName::TheVariantName$Variant`,
417446 we can extract `TheVariantName` from it for display purpose.
418447 """
419448 s = variant .GetType ().GetName ()
420- match = re .search (r"::([^:]+)\$Variant$" , s )
421- return match .group (1 ) if match else ""
449+ if not s .endswith ("$Variant" ):
450+ return ""
451+
452+ # trim off path and "$Variant"
453+ # len("$Variant") == 8
454+ return s .rsplit ("::" , 1 )[1 ][:- 8 ]
422455
423456
424457class ClangEncodedEnumProvider :
425458 """Pretty-printer for 'clang-encoded' enums support implemented in LLDB"""
426459
460+ valobj : SBValue
461+ variant : SBValue
462+ value : SBValue
463+
427464 DISCRIMINANT_MEMBER_NAME = "$discr$"
428465 VALUE_MEMBER_NAME = "value"
429466
467+ __slots__ = ("valobj" , "variant" , "value" )
468+
430469 def __init__ (self , valobj : SBValue , _dict : LLDBOpaque ):
431470 self .valobj = valobj
432471 self .update ()
433472
434473 def has_children (self ) -> bool :
435- return True
474+ return self . value . MightHaveChildren ()
436475
437476 def num_children (self ) -> int :
438- return 1
477+ return self . value . GetNumChildren ()
439478
440- def get_child_index (self , _name : str ) -> int :
441- return - 1
479+ def get_child_index (self , name : str ) -> int :
480+ return self . value . GetIndexOfChildWithName ( name )
442481
443482 def get_child_at_index (self , index : int ) -> SBValue :
444- if index == 0 :
445- value = self .variant .GetChildMemberWithName (
446- ClangEncodedEnumProvider .VALUE_MEMBER_NAME
447- )
448- return value .CreateChildAtOffset (
449- _getVariantName (self .variant ), 0 , value .GetType ()
450- )
451- return None
483+ return self .value .GetChildAtIndex (index )
452484
453485 def update (self ):
454486 all_variants = self .valobj .GetChildAtIndex (0 )
455487 index = self ._getCurrentVariantIndex (all_variants )
456488 self .variant = all_variants .GetChildAtIndex (index )
489+ self .value = self .variant .GetChildMemberWithName (
490+ ClangEncodedEnumProvider .VALUE_MEMBER_NAME
491+ ).GetSyntheticValue ()
457492
458493 def _getCurrentVariantIndex (self , all_variants : SBValue ) -> int :
459494 default_index = 0
@@ -471,6 +506,23 @@ def _getCurrentVariantIndex(self, all_variants: SBValue) -> int:
471506 return default_index
472507
473508
509+ def ClangEncodedEnumSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
510+ enum_synth = ClangEncodedEnumProvider (valobj .GetNonSyntheticValue (), _dict )
511+ variant = enum_synth .variant
512+ name = _getVariantName (variant )
513+
514+ if valobj .GetNumChildren () == 0 :
515+ return name
516+
517+ child_name : str = valobj .GetChildAtIndex (0 ).name
518+ if child_name == "0" or child_name == "__0" :
519+ # enum variant is a tuple struct
520+ return name + TupleSummaryProvider (valobj , _dict )
521+ else :
522+ # enum variant is a regular struct
523+ return name + StructSummaryProvider (valobj , _dict )
524+
525+
474526class MSVCEnumSyntheticProvider :
475527 """
476528 Synthetic provider for sum-type enums on MSVC. For a detailed explanation of the internals,
@@ -479,12 +531,14 @@ class MSVCEnumSyntheticProvider:
479531 https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
480532 """
481533
534+ valobj : SBValue
535+ variant : SBValue
536+ value : SBValue
537+
482538 __slots__ = ["valobj" , "variant" , "value" ]
483539
484540 def __init__ (self , valobj : SBValue , _dict : LLDBOpaque ):
485541 self .valobj = valobj
486- self .variant : SBValue
487- self .value : SBValue
488542 self .update ()
489543
490544 def update (self ):
@@ -652,21 +706,6 @@ def get_type_name(self) -> str:
652706 return name
653707
654708
655- def StructSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
656- output = []
657- for i in range (valobj .GetNumChildren ()):
658- child : SBValue = valobj .GetChildAtIndex (i )
659- summary = child .summary
660- if summary is None :
661- summary = child .value
662- if summary is None :
663- summary = StructSummaryProvider (child , _dict )
664- summary = child .GetName () + ":" + summary
665- output .append (summary )
666-
667- return "{" + ", " .join (output ) + "}"
668-
669-
670709def MSVCEnumSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
671710 enum_synth = MSVCEnumSyntheticProvider (valobj .GetNonSyntheticValue (), _dict )
672711 variant_names : SBType = valobj .target .FindFirstType (
@@ -783,21 +822,6 @@ def get_type_name(self) -> str:
783822 return "(" + name + ")"
784823
785824
786- def TupleSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ):
787- output : List [str ] = []
788-
789- for i in range (0 , valobj .GetNumChildren ()):
790- child : SBValue = valobj .GetChildAtIndex (i )
791- summary = child .summary
792- if summary is None :
793- summary = child .value
794- if summary is None :
795- summary = "{...}"
796- output .append (summary )
797-
798- return "(" + ", " .join (output ) + ")"
799-
800-
801825class StdVecSyntheticProvider :
802826 """Pretty-printer for alloc::vec::Vec<T>
803827
0 commit comments