11from __future__ import annotations
2- import re
32import sys
4- from typing import List , TYPE_CHECKING , Generator
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 , SBTarget
1718
@@ -206,6 +207,34 @@ def resolve_msvc_template_arg(arg_name: str, target: SBTarget) -> SBType:
206207 return result
207208
208209
210+ def StructSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
211+ # structs need the field name before the field value
212+ output = (
213+ f"{ valobj .GetChildAtIndex (i ).GetName ()} :{ child } "
214+ for i , child in enumerate (aggregate_field_summary (valobj , _dict ))
215+ )
216+
217+ return "{" + ", " .join (output ) + "}"
218+
219+
220+ def TupleSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ):
221+ return "(" + ", " .join (aggregate_field_summary (valobj , _dict )) + ")"
222+
223+
224+ def aggregate_field_summary (valobj : SBValue , _dict ) -> Generator [str , None , None ]:
225+ for i in range (0 , valobj .GetNumChildren ()):
226+ child : SBValue = valobj .GetChildAtIndex (i )
227+ summary = child .summary
228+ if summary is None :
229+ summary = child .value
230+ if summary is None :
231+ if is_tuple_fields (child ):
232+ summary = TupleSummaryProvider (child , _dict )
233+ else :
234+ summary = StructSummaryProvider (child , _dict )
235+ yield summary
236+
237+
209238def SizeSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
210239 return "size=" + str (valobj .GetNumChildren ())
211240
@@ -454,49 +483,55 @@ def get_type_name(self):
454483 return "&str"
455484
456485
457- def _getVariantName (variant ) -> str :
486+ def _getVariantName (variant : SBValue ) -> str :
458487 """
459488 Since the enum variant's type name is in the form `TheEnumName::TheVariantName$Variant`,
460489 we can extract `TheVariantName` from it for display purpose.
461490 """
462491 s = variant .GetType ().GetName ()
463- match = re .search (r"::([^:]+)\$Variant$" , s )
464- return match .group (1 ) if match else ""
492+ if not s .endswith ("$Variant" ):
493+ return ""
494+
495+ # trim off path and "$Variant"
496+ # len("$Variant") == 8
497+ return s .rsplit ("::" , 1 )[1 ][:- 8 ]
465498
466499
467500class ClangEncodedEnumProvider :
468501 """Pretty-printer for 'clang-encoded' enums support implemented in LLDB"""
469502
503+ valobj : SBValue
504+ variant : SBValue
505+ value : SBValue
506+
470507 DISCRIMINANT_MEMBER_NAME = "$discr$"
471508 VALUE_MEMBER_NAME = "value"
472509
510+ __slots__ = ("valobj" , "variant" , "value" )
511+
473512 def __init__ (self , valobj : SBValue , _dict : LLDBOpaque ):
474513 self .valobj = valobj
475514 self .update ()
476515
477516 def has_children (self ) -> bool :
478- return True
517+ return self . value . MightHaveChildren ()
479518
480519 def num_children (self ) -> int :
481- return 1
520+ return self . value . GetNumChildren ()
482521
483- def get_child_index (self , _name : str ) -> int :
484- return - 1
522+ def get_child_index (self , name : str ) -> int :
523+ return self . value . GetIndexOfChildWithName ( name )
485524
486525 def get_child_at_index (self , index : int ) -> SBValue :
487- if index == 0 :
488- value = self .variant .GetChildMemberWithName (
489- ClangEncodedEnumProvider .VALUE_MEMBER_NAME
490- )
491- return value .CreateChildAtOffset (
492- _getVariantName (self .variant ), 0 , value .GetType ()
493- )
494- return None
526+ return self .value .GetChildAtIndex (index )
495527
496528 def update (self ):
497529 all_variants = self .valobj .GetChildAtIndex (0 )
498530 index = self ._getCurrentVariantIndex (all_variants )
499531 self .variant = all_variants .GetChildAtIndex (index )
532+ self .value = self .variant .GetChildMemberWithName (
533+ ClangEncodedEnumProvider .VALUE_MEMBER_NAME
534+ ).GetSyntheticValue ()
500535
501536 def _getCurrentVariantIndex (self , all_variants : SBValue ) -> int :
502537 default_index = 0
@@ -514,6 +549,23 @@ def _getCurrentVariantIndex(self, all_variants: SBValue) -> int:
514549 return default_index
515550
516551
552+ def ClangEncodedEnumSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
553+ enum_synth = ClangEncodedEnumProvider (valobj .GetNonSyntheticValue (), _dict )
554+ variant = enum_synth .variant
555+ name = _getVariantName (variant )
556+
557+ if valobj .GetNumChildren () == 0 :
558+ return name
559+
560+ child_name : str = valobj .GetChildAtIndex (0 ).name
561+ if child_name == "0" or child_name == "__0" :
562+ # enum variant is a tuple struct
563+ return name + TupleSummaryProvider (valobj , _dict )
564+ else :
565+ # enum variant is a regular struct
566+ return name + StructSummaryProvider (valobj , _dict )
567+
568+
517569class MSVCEnumSyntheticProvider :
518570 """
519571 Synthetic provider for sum-type enums on MSVC. For a detailed explanation of the internals,
@@ -522,12 +574,14 @@ class MSVCEnumSyntheticProvider:
522574 https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
523575 """
524576
577+ valobj : SBValue
578+ variant : SBValue
579+ value : SBValue
580+
525581 __slots__ = ["valobj" , "variant" , "value" ]
526582
527583 def __init__ (self , valobj : SBValue , _dict : LLDBOpaque ):
528584 self .valobj = valobj
529- self .variant : SBValue
530- self .value : SBValue
531585 self .update ()
532586
533587 def update (self ):
@@ -695,21 +749,6 @@ def get_type_name(self) -> str:
695749 return name
696750
697751
698- def StructSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
699- output = []
700- for i in range (valobj .GetNumChildren ()):
701- child : SBValue = valobj .GetChildAtIndex (i )
702- summary = child .summary
703- if summary is None :
704- summary = child .value
705- if summary is None :
706- summary = StructSummaryProvider (child , _dict )
707- summary = child .GetName () + ":" + summary
708- output .append (summary )
709-
710- return "{" + ", " .join (output ) + "}"
711-
712-
713752def MSVCEnumSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
714753 enum_synth = MSVCEnumSyntheticProvider (valobj .GetNonSyntheticValue (), _dict )
715754 variant_names : SBType = valobj .target .FindFirstType (
@@ -826,21 +865,6 @@ def get_type_name(self) -> str:
826865 return "(" + name + ")"
827866
828867
829- def TupleSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ):
830- output : List [str ] = []
831-
832- for i in range (0 , valobj .GetNumChildren ()):
833- child : SBValue = valobj .GetChildAtIndex (i )
834- summary = child .summary
835- if summary is None :
836- summary = child .value
837- if summary is None :
838- summary = "{...}"
839- output .append (summary )
840-
841- return "(" + ", " .join (output ) + ")"
842-
843-
844868class StdVecSyntheticProvider :
845869 """Pretty-printer for alloc::vec::Vec<T>
846870
0 commit comments