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,62 @@ 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+
238+ def StructSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
239+ # structs need the field name before the field value
240+ output = (
241+ f"{ valobj .GetChildAtIndex (i ).GetName ()} :{ child } "
242+ for i , child in enumerate (aggregate_field_summary (valobj , _dict ))
243+ )
244+
245+ return "{" + ", " .join (output ) + "}"
246+
247+
248+ def TupleSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ):
249+ return "(" + ", " .join (aggregate_field_summary (valobj , _dict )) + ")"
250+
251+
252+ def aggregate_field_summary (valobj : SBValue , _dict ) -> Generator [str , None , None ]:
253+ for i in range (0 , valobj .GetNumChildren ()):
254+ child : SBValue = valobj .GetChildAtIndex (i )
255+ summary = child .summary
256+ if summary is None :
257+ summary = child .value
258+ if summary is None :
259+ if is_tuple_fields (child ):
260+ summary = TupleSummaryProvider (child , _dict )
261+ else :
262+ summary = StructSummaryProvider (child , _dict )
263+ yield summary
264+
265+
209266def SizeSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
210267 return "size=" + str (valobj .GetNumChildren ())
211268
@@ -454,49 +511,55 @@ def get_type_name(self):
454511 return "&str"
455512
456513
457- def _getVariantName (variant ) -> str :
514+ def _getVariantName (variant : SBValue ) -> str :
458515 """
459516 Since the enum variant's type name is in the form `TheEnumName::TheVariantName$Variant`,
460517 we can extract `TheVariantName` from it for display purpose.
461518 """
462519 s = variant .GetType ().GetName ()
463- match = re .search (r"::([^:]+)\$Variant$" , s )
464- return match .group (1 ) if match else ""
520+ if not s .endswith ("$Variant" ):
521+ return ""
522+
523+ # trim off path and "$Variant"
524+ # len("$Variant") == 8
525+ return s .rsplit ("::" , 1 )[1 ][:- 8 ]
465526
466527
467528class ClangEncodedEnumProvider :
468529 """Pretty-printer for 'clang-encoded' enums support implemented in LLDB"""
469530
531+ valobj : SBValue
532+ variant : SBValue
533+ value : SBValue
534+
470535 DISCRIMINANT_MEMBER_NAME = "$discr$"
471536 VALUE_MEMBER_NAME = "value"
472537
538+ __slots__ = ("valobj" , "variant" , "value" )
539+
473540 def __init__ (self , valobj : SBValue , _dict : LLDBOpaque ):
474541 self .valobj = valobj
475542 self .update ()
476543
477544 def has_children (self ) -> bool :
478- return True
545+ return self . value . MightHaveChildren ()
479546
480547 def num_children (self ) -> int :
481- return 1
548+ return self . value . GetNumChildren ()
482549
483- def get_child_index (self , _name : str ) -> int :
484- return - 1
550+ def get_child_index (self , name : str ) -> int :
551+ return self . value . GetIndexOfChildWithName ( name )
485552
486553 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
554+ return self .value .GetChildAtIndex (index )
495555
496556 def update (self ):
497557 all_variants = self .valobj .GetChildAtIndex (0 )
498558 index = self ._getCurrentVariantIndex (all_variants )
499559 self .variant = all_variants .GetChildAtIndex (index )
560+ self .value = self .variant .GetChildMemberWithName (
561+ ClangEncodedEnumProvider .VALUE_MEMBER_NAME
562+ ).GetSyntheticValue ()
500563
501564 def _getCurrentVariantIndex (self , all_variants : SBValue ) -> int :
502565 default_index = 0
@@ -514,6 +577,23 @@ def _getCurrentVariantIndex(self, all_variants: SBValue) -> int:
514577 return default_index
515578
516579
580+ def ClangEncodedEnumSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
581+ enum_synth = ClangEncodedEnumProvider (valobj .GetNonSyntheticValue (), _dict )
582+ variant = enum_synth .variant
583+ name = _getVariantName (variant )
584+
585+ if valobj .GetNumChildren () == 0 :
586+ return name
587+
588+ child_name : str = valobj .GetChildAtIndex (0 ).name
589+ if child_name == "0" or child_name == "__0" :
590+ # enum variant is a tuple struct
591+ return name + TupleSummaryProvider (valobj , _dict )
592+ else :
593+ # enum variant is a regular struct
594+ return name + StructSummaryProvider (valobj , _dict )
595+
596+
517597class MSVCEnumSyntheticProvider :
518598 """
519599 Synthetic provider for sum-type enums on MSVC. For a detailed explanation of the internals,
@@ -522,12 +602,14 @@ class MSVCEnumSyntheticProvider:
522602 https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
523603 """
524604
605+ valobj : SBValue
606+ variant : SBValue
607+ value : SBValue
608+
525609 __slots__ = ["valobj" , "variant" , "value" ]
526610
527611 def __init__ (self , valobj : SBValue , _dict : LLDBOpaque ):
528612 self .valobj = valobj
529- self .variant : SBValue
530- self .value : SBValue
531613 self .update ()
532614
533615 def update (self ):
@@ -695,21 +777,6 @@ def get_type_name(self) -> str:
695777 return name
696778
697779
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-
713780def MSVCEnumSummaryProvider (valobj : SBValue , _dict : LLDBOpaque ) -> str :
714781 enum_synth = MSVCEnumSyntheticProvider (valobj .GetNonSyntheticValue (), _dict )
715782 variant_names : SBType = valobj .target .FindFirstType (
@@ -826,21 +893,6 @@ def get_type_name(self) -> str:
826893 return "(" + name + ")"
827894
828895
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-
844896class StdVecSyntheticProvider :
845897 """Pretty-printer for alloc::vec::Vec<T>
846898
0 commit comments