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,54 @@ 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"""
459+ valobj : SBValue
460+ variant : SBValue
461+ value : SBValue
426462
427463 DISCRIMINANT_MEMBER_NAME = "$discr$"
428464 VALUE_MEMBER_NAME = "value"
429465
466+ __slots__ = ("valobj" , "variant" , "value" )
467+
430468 def __init__ (self , valobj : SBValue , _dict : LLDBOpaque ):
431469 self .valobj = valobj
432470 self .update ()
433471
434472 def has_children (self ) -> bool :
435- return True
473+ return self . value . MightHaveChildren ()
436474
437475 def num_children (self ) -> int :
438- return 1
476+ return self . value . GetNumChildren ()
439477
440- def get_child_index (self , _name : str ) -> int :
441- return - 1
478+ def get_child_index (self , name : str ) -> int :
479+ return self . value . GetIndexOfChildWithName ( name )
442480
443481 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
482+ return self .value .GetChildAtIndex (index )
452483
453484 def update (self ):
454485 all_variants = self .valobj .GetChildAtIndex (0 )
455486 index = self ._getCurrentVariantIndex (all_variants )
456487 self .variant = all_variants .GetChildAtIndex (index )
488+ self .value = self .variant .GetChildMemberWithName (
489+ ClangEncodedEnumProvider .VALUE_MEMBER_NAME
490+ ).GetSyntheticValue ()
457491
458492 def _getCurrentVariantIndex (self , all_variants : SBValue ) -> int :
459493 default_index = 0
@@ -471,6 +505,23 @@ def _getCurrentVariantIndex(self, all_variants: SBValue) -> int:
471505 return default_index
472506
473507
508+ def ClangEncodedEnumSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
509+ enum_synth = ClangEncodedEnumProvider (valobj .GetNonSyntheticValue (), _dict )
510+ variant = enum_synth .variant
511+ name = _getVariantName (variant )
512+
513+ if valobj .GetNumChildren () == 0 :
514+ return name
515+
516+ child_name : str = valobj .GetChildAtIndex (0 ).name
517+ if child_name == "0" or child_name == "__0" :
518+ # enum variant is a tuple struct
519+ return name + TupleSummaryProvider (valobj , _dict )
520+ else :
521+ # enum variant is a regular struct
522+ return name + StructSummaryProvider (valobj , _dict )
523+
524+
474525class MSVCEnumSyntheticProvider :
475526 """
476527 Synthetic provider for sum-type enums on MSVC. For a detailed explanation of the internals,
@@ -479,12 +530,14 @@ class MSVCEnumSyntheticProvider:
479530 https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
480531 """
481532
533+ valobj : SBValue
534+ variant : SBValue
535+ value : SBValue
536+
482537 __slots__ = ["valobj" , "variant" , "value" ]
483538
484539 def __init__ (self , valobj : SBValue , _dict : LLDBOpaque ):
485540 self .valobj = valobj
486- self .variant : SBValue
487- self .value : SBValue
488541 self .update ()
489542
490543 def update (self ):
@@ -652,21 +705,6 @@ def get_type_name(self) -> str:
652705 return name
653706
654707
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-
670708def MSVCEnumSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
671709 enum_synth = MSVCEnumSyntheticProvider (valobj .GetNonSyntheticValue (), _dict )
672710 variant_names : SBType = valobj .target .FindFirstType (
@@ -783,21 +821,6 @@ def get_type_name(self) -> str:
783821 return "(" + name + ")"
784822
785823
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-
801824class StdVecSyntheticProvider :
802825 """Pretty-printer for alloc::vec::Vec<T>
803826
0 commit comments