[llvm][utils] Support dereferencing llvm::Optional lldb formatter

Add deref support to `llvm::Optional` in `lldbDataFormatters.py`.

This creates a synthetic provider that adds dereference support, but otherwise proxies all access to the underlying value.

With this change, an optional value can be displayed by running `v *someOptional`, and its contents can be accessed with the arrow `operator->`, for example `v someOpt->HasThing`. This matches expressions usable from expression evaluation.

See also D97165 and D97524.

Differential Revision: https://reviews.llvm.org/D97525
This commit is contained in:
Dave Lee 2021-02-21 21:45:04 -08:00
parent 3a677b29a3
commit 408456f53e
1 changed files with 29 additions and 3 deletions

View File

@ -4,6 +4,8 @@ LLDB Formatters for LLVM data types.
Load into LLDB with 'command script import /path/to/lldbDataFormatters.py'
"""
import lldb
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand('type category define -e llvm -l c++')
debugger.HandleCommand('type synthetic add -w llvm '
@ -15,6 +17,9 @@ def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand('type synthetic add -w llvm '
'-l lldbDataFormatters.ArrayRefSynthProvider '
'-x "^llvm::ArrayRef<.+>$"')
debugger.HandleCommand('type synthetic add -w llvm '
'-l lldbDataFormatters.OptionalSynthProvider '
'-x "^llvm::Optional<.+>$"')
debugger.HandleCommand('type summary add -w llvm '
'-F lldbDataFormatters.OptionalSummaryProvider '
'-x "^llvm::Optional<.+>$"')
@ -97,7 +102,7 @@ class ArrayRefSynthProvider:
self.type_size = self.data_type.GetByteSize()
assert self.type_size != 0
def OptionalSummaryProvider(valobj, internal_dict):
def GetOptionalValue(valobj):
storage = valobj.GetChildMemberWithName('Storage')
if not storage:
storage = valobj
@ -108,11 +113,32 @@ def OptionalSummaryProvider(valobj, internal_dict):
return '<could not read llvm::Optional>'
if hasVal == 0:
return 'None'
return None
underlying_type = storage.GetType().GetTemplateArgumentType(0)
storage = storage.GetChildMemberWithName('value')
return str(storage.Cast(underlying_type))
return storage.Cast(underlying_type)
def OptionalSummaryProvider(valobj, internal_dict):
return GetOptionalValue(valobj).summary
class OptionalSynthProvider:
"""Provides deref support to llvm::Optional<T>"""
def __init__(self, valobj, internal_dict):
self.valobj = valobj
def num_children(self):
return self.valobj.num_children
def get_child_index(self, name):
if name == '$$dereference$$':
return self.valobj.num_children + 1
return self.valobj.GetIndexOfChildWithName(name)
def get_child_at_index(self, index):
if index < self.valobj.num_children:
return self.valobj.GetChildAtIndex(index)
return GetOptionalValue(self.valobj) or lldb.SBValue()
def SmallStringSummaryProvider(valobj, internal_dict):
num_elements = valobj.GetNumChildren()