|
1 | 1 | import sys
|
2 | 2 |
|
3 | 3 | from lldb import (
|
| 4 | + SBValue, |
4 | 5 | SBData,
|
| 6 | + SBType, |
5 | 7 | SBError,
|
6 | 8 | eBasicTypeLong,
|
7 | 9 | eBasicTypeUnsignedLong,
|
@@ -912,3 +914,77 @@ def StdNonZeroNumberSummaryProvider(valobj, _dict):
|
912 | 914 | return str(inner_inner.GetValueAsSigned())
|
913 | 915 | else:
|
914 | 916 | return inner_inner.GetValue()
|
| 917 | + |
| 918 | + |
| 919 | +class PtrSyntheticProvider(DefaultSyntheticProvider): |
| 920 | + def get_type_name(self) -> str: |
| 921 | + type: SBType = self.valobj.GetType() |
| 922 | + name_parts: list[str] = [] |
| 923 | + |
| 924 | + # "&&" indicates an rval reference. This doesn't technically mean anything in Rust, but the |
| 925 | + # debug info is generated as such so we can differentiate between "ref-to-ref" (illegal in |
| 926 | + # TypeSystemClang) and "ref-to-pointer". |
| 927 | + # |
| 928 | + # Whenever there is a "&&", we can be sure that the pointer it is pointing to is actually |
| 929 | + # supposed to be a reference. (e.g. u8 *&& -> &mut &mut u8) |
| 930 | + was_r_ref: bool = False |
| 931 | + ptr_type: SBType = type |
| 932 | + ptee_type: SBType = type.GetPointeeType() |
| 933 | + |
| 934 | + while ptr_type.is_pointer or ptr_type.is_reference: |
| 935 | + # remove the `const` modifier as it indicates the const-ness of any pointer/ref pointing *to* it |
| 936 | + # not its own constness |
| 937 | + # For example: |
| 938 | + # const u8 *const * -> &&u8 |
| 939 | + # u8 *const * -> &&mut u8 |
| 940 | + # const u8 ** -> &mut &u8 |
| 941 | + # u8 ** -> &mut &mut u8 |
| 942 | + ptr_name: str = ptr_type.GetName().removesuffix("const") |
| 943 | + ptee_name: str = ptee_type.GetName() |
| 944 | + |
| 945 | + is_ref: bool = False |
| 946 | + |
| 947 | + if was_r_ref or ptr_name[-1] == "&": |
| 948 | + is_ref = True |
| 949 | + |
| 950 | + was_r_ref = ptr_name[-2:] == "&&" |
| 951 | + |
| 952 | + if ptee_type.is_pointer or ptee_type.is_reference: |
| 953 | + if ptee_name.endswith("const"): |
| 954 | + if is_ref: |
| 955 | + name_parts.append("&") |
| 956 | + else: |
| 957 | + name_parts.append("*const ") |
| 958 | + else: |
| 959 | + if is_ref: |
| 960 | + name_parts.append("&mut ") |
| 961 | + else: |
| 962 | + name_parts.append("*mut ") |
| 963 | + |
| 964 | + else: |
| 965 | + if ptee_name.startswith("const "): |
| 966 | + if is_ref: |
| 967 | + name_parts.append("&") |
| 968 | + else: |
| 969 | + name_parts.append("*const ") |
| 970 | + else: |
| 971 | + if is_ref: |
| 972 | + name_parts.append("&mut ") |
| 973 | + else: |
| 974 | + name_parts.append("*mut ") |
| 975 | + |
| 976 | + ptr_type = ptee_type |
| 977 | + ptee_type = ptee_type.GetPointeeType() |
| 978 | + |
| 979 | + name_parts.append(ptr_type.GetUnqualifiedType().GetName()) |
| 980 | + return "".join(name_parts) |
| 981 | + |
| 982 | + |
| 983 | +def PtrSummaryProvider(valobj: SBValue, dict) -> str: |
| 984 | + while True: |
| 985 | + t: SBType = valobj.GetType() |
| 986 | + if t.is_pointer or t.is_reference: |
| 987 | + valobj = valobj.Dereference() |
| 988 | + else: |
| 989 | + break |
| 990 | + return valobj.value |
0 commit comments