| import lldb | |
| from lldb_providers import * | |
| from rust_types import RustType, classify_struct, classify_union | |
| # BACKCOMPAT: rust 1.35 | |
| def is_hashbrown_hashmap(hash_map: lldb.SBValue) -> bool: | |
| return len(hash_map.type.fields) == 1 | |
| def classify_rust_type(type: lldb.SBType) -> str: | |
| type_class = type.GetTypeClass() | |
| if type_class == lldb.eTypeClassStruct: | |
| return classify_struct(type.name, type.fields) | |
| if type_class == lldb.eTypeClassUnion: | |
| return classify_union(type.fields) | |
| return RustType.OTHER | |
| def summary_lookup(valobj: lldb.SBValue, _dict: LLDBOpaque) -> str: | |
| """Returns the summary provider for the given value""" | |
| rust_type = classify_rust_type(valobj.GetType()) | |
| if rust_type == RustType.STD_STRING: | |
| return StdStringSummaryProvider(valobj, _dict) | |
| if rust_type == RustType.STD_OS_STRING: | |
| return StdOsStringSummaryProvider(valobj, _dict) | |
| if rust_type == RustType.STD_STR: | |
| return StdStrSummaryProvider(valobj, _dict) | |
| if rust_type == RustType.STD_VEC: | |
| return SizeSummaryProvider(valobj, _dict) | |
| if rust_type == RustType.STD_VEC_DEQUE: | |
| return SizeSummaryProvider(valobj, _dict) | |
| if rust_type == RustType.STD_SLICE: | |
| return SizeSummaryProvider(valobj, _dict) | |
| if rust_type == RustType.STD_HASH_MAP: | |
| return SizeSummaryProvider(valobj, _dict) | |
| if rust_type == RustType.STD_HASH_SET: | |
| return SizeSummaryProvider(valobj, _dict) | |
| if rust_type == RustType.STD_RC: | |
| return StdRcSummaryProvider(valobj, _dict) | |
| if rust_type == RustType.STD_ARC: | |
| return StdRcSummaryProvider(valobj, _dict) | |
| if rust_type == RustType.STD_REF: | |
| return StdRefSummaryProvider(valobj, _dict) | |
| if rust_type == RustType.STD_REF_MUT: | |
| return StdRefSummaryProvider(valobj, _dict) | |
| if rust_type == RustType.STD_REF_CELL: | |
| return StdRefSummaryProvider(valobj, _dict) | |
| if rust_type == RustType.STD_NONZERO_NUMBER: | |
| return StdNonZeroNumberSummaryProvider(valobj, _dict) | |
| if rust_type == RustType.STD_PATHBUF: | |
| return StdPathBufSummaryProvider(valobj, _dict) | |
| if rust_type == RustType.STD_PATH: | |
| return StdPathSummaryProvider(valobj, _dict) | |
| return "" | |
| def synthetic_lookup(valobj: lldb.SBValue, _dict: LLDBOpaque) -> object: | |
| """Returns the synthetic provider for the given value""" | |
| rust_type = classify_rust_type(valobj.GetType()) | |
| if rust_type == RustType.STRUCT: | |
| return StructSyntheticProvider(valobj, _dict) | |
| if rust_type == RustType.STRUCT_VARIANT: | |
| return StructSyntheticProvider(valobj, _dict, is_variant=True) | |
| if rust_type == RustType.TUPLE: | |
| return TupleSyntheticProvider(valobj, _dict) | |
| if rust_type == RustType.TUPLE_VARIANT: | |
| return TupleSyntheticProvider(valobj, _dict, is_variant=True) | |
| if rust_type == RustType.EMPTY: | |
| return EmptySyntheticProvider(valobj, _dict) | |
| if rust_type == RustType.REGULAR_ENUM: | |
| discriminant = valobj.GetChildAtIndex(0).GetChildAtIndex(0).GetValueAsUnsigned() | |
| return synthetic_lookup(valobj.GetChildAtIndex(discriminant), _dict) | |
| if rust_type == RustType.SINGLETON_ENUM: | |
| return synthetic_lookup(valobj.GetChildAtIndex(0), _dict) | |
| if rust_type == RustType.ENUM: | |
| # this little trick lets us treat `synthetic_lookup` as a "recognizer function" for the enum | |
| # summary providers, reducing the number of lookups we have to do. This is a huge time save | |
| # because there's no way (via type name) to recognize sum-type enums on `*-gnu` targets. The | |
| # alternative would be to shove every single type through `summary_lookup`, which is | |
| # incredibly wasteful. Once these scripts are updated for LLDB 19.0 and we can use | |
| # `--recognizer-function`, this hack will only be needed for backwards compatibility. | |
| summary: lldb.SBTypeSummary = valobj.GetTypeSummary() | |
| if ( | |
| summary.summary_data is None | |
| or summary.summary_data.strip() | |
| != "lldb_lookup.ClangEncodedEnumSummaryProvider(valobj,internal_dict)" | |
| ): | |
| rust_category: lldb.SBTypeCategory = lldb.debugger.GetCategory("Rust") | |
| rust_category.AddTypeSummary( | |
| lldb.SBTypeNameSpecifier(valobj.GetTypeName()), | |
| lldb.SBTypeSummary().CreateWithFunctionName( | |
| "lldb_lookup.ClangEncodedEnumSummaryProvider" | |
| ), | |
| ) | |
| return ClangEncodedEnumProvider(valobj, _dict) | |
| if rust_type == RustType.STD_VEC: | |
| return StdVecSyntheticProvider(valobj, _dict) | |
| if rust_type == RustType.STD_VEC_DEQUE: | |
| return StdVecDequeSyntheticProvider(valobj, _dict) | |
| if rust_type == RustType.STD_SLICE or rust_type == RustType.STD_STR: | |
| return StdSliceSyntheticProvider(valobj, _dict) | |
| if rust_type == RustType.STD_HASH_MAP: | |
| if is_hashbrown_hashmap(valobj): | |
| return StdHashMapSyntheticProvider(valobj, _dict) | |
| else: | |
| return StdOldHashMapSyntheticProvider(valobj, _dict) | |
| if rust_type == RustType.STD_HASH_SET: | |
| hash_map = valobj.GetChildAtIndex(0) | |
| if is_hashbrown_hashmap(hash_map): | |
| return StdHashMapSyntheticProvider(valobj, _dict, show_values=False) | |
| else: | |
| return StdOldHashMapSyntheticProvider(hash_map, _dict, show_values=False) | |
| if rust_type == RustType.STD_RC: | |
| return StdRcSyntheticProvider(valobj, _dict) | |
| if rust_type == RustType.STD_ARC: | |
| return StdRcSyntheticProvider(valobj, _dict, is_atomic=True) | |
| if rust_type == RustType.STD_CELL: | |
| return StdCellSyntheticProvider(valobj, _dict) | |
| if rust_type == RustType.STD_REF: | |
| return StdRefSyntheticProvider(valobj, _dict) | |
| if rust_type == RustType.STD_REF_MUT: | |
| return StdRefSyntheticProvider(valobj, _dict) | |
| if rust_type == RustType.STD_REF_CELL: | |
| return StdRefSyntheticProvider(valobj, _dict, is_cell=True) | |
| return DefaultSyntheticProvider(valobj, _dict) |