[llvm] 773467c - [LLDB] Add formatters for PointerIntPair, PointerUnion

Sergej Jaskiewicz via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 27 01:54:27 PST 2022


Author: Sergej Jaskiewicz
Date: 2022-01-27T12:54:16+03:00
New Revision: 773467c8126318f8d735e36ed0b6eafc952bb74c

URL: https://github.com/llvm/llvm-project/commit/773467c8126318f8d735e36ed0b6eafc952bb74c
DIFF: https://github.com/llvm/llvm-project/commit/773467c8126318f8d735e36ed0b6eafc952bb74c.diff

LOG: [LLDB] Add formatters for PointerIntPair, PointerUnion

Also, add summaries for `SmallVector` and `ArrayRef`,
and fix the `StringRef` summary provider so it doesn't
ignore the `Length` field.

Differential Revision: https://reviews.llvm.org/D117779

Added: 
    

Modified: 
    llvm/utils/lldbDataFormatters.py

Removed: 
    


################################################################################
diff  --git a/llvm/utils/lldbDataFormatters.py b/llvm/utils/lldbDataFormatters.py
index 4fc420ff997d..6326c4f65ec7 100644
--- a/llvm/utils/lldbDataFormatters.py
+++ b/llvm/utils/lldbDataFormatters.py
@@ -5,18 +5,28 @@
 """
 
 import lldb
+import json
 
 def __lldb_init_module(debugger, internal_dict):
     debugger.HandleCommand('type category define -e llvm -l c++')
     debugger.HandleCommand('type synthetic add -w llvm '
                            '-l lldbDataFormatters.SmallVectorSynthProvider '
                            '-x "^llvm::SmallVectorImpl<.+>$"')
+    debugger.HandleCommand('type summary add -w llvm '
+                           '-s "size=${svar%#}" '
+                           '-x "^llvm::SmallVectorImpl<.+>$"')
     debugger.HandleCommand('type synthetic add -w llvm '
                            '-l lldbDataFormatters.SmallVectorSynthProvider '
                            '-x "^llvm::SmallVector<.+,.+>$"')
+    debugger.HandleCommand('type summary add -w llvm '
+                           '-s "size=${svar%#}" '
+                           '-x "^llvm::SmallVector<.+,.+>$"')
     debugger.HandleCommand('type synthetic add -w llvm '
                            '-l lldbDataFormatters.ArrayRefSynthProvider '
                            '-x "^llvm::ArrayRef<.+>$"')
+    debugger.HandleCommand('type summary add -w llvm '
+                           '-s "size=${svar%#}" '
+                           '-x "^llvm::ArrayRef<.+>$"')
     debugger.HandleCommand('type synthetic add -w llvm '
                            '-l lldbDataFormatters.OptionalSynthProvider '
                            '-x "^llvm::Optional<.+>$"')
@@ -32,6 +42,13 @@ def __lldb_init_module(debugger, internal_dict):
     debugger.HandleCommand('type summary add -w llvm '
                            '-F lldbDataFormatters.ConstStringSummaryProvider '
                            '-x "^lldb_private::ConstString$"')
+    debugger.HandleCommand('type synthetic add -w llvm '
+                           '-l lldbDataFormatters.PointerIntPairSynthProvider '
+                           '-x "^llvm::PointerIntPair<.+>$"')
+    debugger.HandleCommand('type synthetic add -w llvm '
+                           '-l lldbDataFormatters.PointerUnionSynthProvider '
+                           '-x "^llvm::PointerUnion<.+>$"')
+
 
 # Pretty printer for llvm::SmallVector/llvm::SmallVectorImpl
 class SmallVectorSynthProvider:
@@ -151,19 +168,122 @@ def SmallStringSummaryProvider(valobj, internal_dict):
     res += "\""
     return res
 
+
 def StringRefSummaryProvider(valobj, internal_dict):
     if valobj.GetNumChildren() == 2:
         # StringRef's are also used to point at binary blobs in memory,
         # so filter out suspiciously long strings.
-        max_length = 256
-        length = valobj.GetChildAtIndex(1).GetValueAsUnsigned(max_length)
+        max_length = 1024
+        actual_length = valobj.GetChildAtIndex(1).GetValueAsUnsigned()
+        truncate = actual_length > max_length
+        length = min(max_length, actual_length)
         if length == 0:
-            return "NULL"
-        if length < max_length:
-            return valobj.GetChildAtIndex(0).GetSummary()
-    return ""
+            return '""'
+
+        data = valobj.GetChildAtIndex(0).GetPointeeData(item_count=length)
+        error = lldb.SBError()
+        string = data.ReadRawData(error, 0, data.GetByteSize()).decode()
+        if error.Fail():
+            return "<error: %s>" % error.description
+
+        # json.dumps conveniently escapes the string for us.
+        string = json.dumps(string)
+        if truncate:
+            string += "..."
+        return string
+    return None
+
 
 def ConstStringSummaryProvider(valobj, internal_dict):
     if valobj.GetNumChildren() == 1:
         return valobj.GetChildAtIndex(0).GetSummary()
     return ""
+
+
+def get_expression_path(val):
+    stream = lldb.SBStream()
+    if not val.GetExpressionPath(stream):
+        return None
+    return stream.GetData()
+
+
+class PointerIntPairSynthProvider:
+    def __init__(self, valobj, internal_dict):
+        self.valobj = valobj
+        self.update()
+
+    def num_children(self):
+        return 2
+
+    def get_child_index(self, name):
+        if name == 'Pointer':
+            return 0
+        if name == 'Int':
+            return 1
+        return None
+
+    def get_child_at_index(self, index):
+        expr_path = get_expression_path(self.valobj)
+        if index == 0:
+            return self.valobj.CreateValueFromExpression('Pointer', f'({self.pointer_ty.name}){expr_path}.getPointer()')
+        if index == 1:
+            return self.valobj.CreateValueFromExpression('Int', f'({self.int_ty.name}){expr_path}.getInt()')
+        return None
+
+    def update(self):
+        self.pointer_ty = self.valobj.GetType().GetTemplateArgumentType(0)
+        self.int_ty = self.valobj.GetType().GetTemplateArgumentType(2)
+
+
+def parse_template_parameters(typename):
+    """
+    LLDB doesn't support template parameter packs, so let's parse them manually.
+    """
+    result = []
+    start = typename.find('<')
+    end = typename.rfind('>')
+    if start < 1 or end < 2 or end - start < 2:
+        return result
+
+    nesting_level = 0
+    current_parameter_start = start + 1
+
+    for i in range(start + 1, end + 1):
+        c = typename[i]
+        if c == '<':
+            nesting_level += 1
+        elif c == '>':
+            nesting_level -= 1
+        elif c == ',' and nesting_level == 0:
+            result.append(typename[current_parameter_start:i].strip())
+            current_parameter_start = i + 1
+
+    result.append(typename[current_parameter_start:i].strip())
+
+    return result
+
+
+class PointerUnionSynthProvider:
+    def __init__(self, valobj, internal_dict):
+        self.valobj = valobj
+        self.update()
+
+    def num_children(self):
+        return 1
+
+    def get_child_index(self, name):
+        if name == 'Ptr':
+            return 0
+        return None
+
+    def get_child_at_index(self, index):
+        if index != 0:
+            return None
+        ptr_type_name = self.template_args[self.active_type_tag]
+        return self.valobj.CreateValueFromExpression('Ptr', f'({ptr_type_name}){self.val_expr_path}.getPointer()')
+
+    def update(self):
+        self.pointer_int_pair = self.valobj.GetChildMemberWithName('Val')
+        self.val_expr_path = get_expression_path(self.valobj.GetChildMemberWithName('Val'))
+        self.active_type_tag = self.valobj.CreateValueFromExpression('', f'(int){self.val_expr_path}.getInt()').GetValueAsSigned()
+        self.template_args = parse_template_parameters(self.valobj.GetType().name)


        


More information about the llvm-commits mailing list