Modified: trunk/Tools/ChangeLog (239650 => 239651)
--- trunk/Tools/ChangeLog 2019-01-05 02:30:03 UTC (rev 239650)
+++ trunk/Tools/ChangeLog 2019-01-05 05:03:29 UTC (rev 239651)
@@ -1,3 +1,79 @@
+2019-01-04 Daniel Bates <[email protected]>
+
+ [lldb-webkit]: Add support for pretty-printing raw bitmask types
+ https://bugs.webkit.org/show_bug.cgi?id=193024
+
+ Reviewed by Jer Noble.
+
+ Add support infrastructure to pretty-print a raw bitmask type. Included is a pretty-printer
+ for the bitmask type WebEventFlags as an example.
+
+ Exposed a new function lldb_webkit.addSummaryAndSyntheticFormattersForRawBitmaskType()
+ that can be used to register summary and synthetic child formatters for a bitmask type.
+ For example, consider the following enum and bitmask typedefs:
+
+ typedef enum {
+ A = 1 << 0,
+ B = 1 << 1,
+ C = 1 << 2,
+ } SpecialFlagValues;
+ typedef unsigned SpecialFlags;
+
+ To teach lldb-webkit how to pretty print SpecialFlags types, add the following code inside
+ __lldb_init_module():
+
+ addSummaryAndSyntheticFormattersForRawBitmaskType(debugger, "SpecialFlags", {
+ 1 << 0: "A",
+ 1 << 1: "B",
+ 1 << 2: "C",
+ })
+
+ * lldb/lldb_webkit.py:
+ (addSummaryAndSyntheticFormattersForRawBitmaskType):
+ (addSummaryAndSyntheticFormattersForRawBitmaskType.GeneratedRawBitmaskProvider):
+ (addSummaryAndSyntheticFormattersForRawBitmaskType.raw_bitmask_summary_provider):
+ (addSummaryAndSyntheticFormattersForRawBitmaskType.lldb_webkit):
+ A convenience function to dynamically creaste a synthetic formatter class and summary
+ string function for the specified bitmask type and enumerator value to name map. This
+ function register the dynamically created class and function with LLDB.
+
+ (__lldb_init_module):
+ (FlagEnumerationProvider):
+ (FlagEnumerationProvider._enumerator_value_to_name_map):
+ (FlagEnumerationProvider._bitmask):
+ (FlagEnumerationProvider._update):
+ (FlagEnumerationProvider.has_children):
+ (FlagEnumerationProvider.num_children):
+ (FlagEnumerationProvider.get_child_index):
+ (FlagEnumerationProvider.get_child_at_index):
+ (FlagEnumerationProvider.update):
+ Extract out provider logic from WTFOptionSetProvider into a base class that can be shared.
+
+ (WTFOptionSetProvider):
+ (WTFOptionSetProvider._enumerator_value_to_name_map):
+ (WTFOptionSetProvider._bitmask):
+ (WTFOptionSetProvider._update):
+ Write in terms of the base class.
+
+ (RawBitmaskProviderBase):
+ (RawBitmaskProviderBase._enumerator_value_to_name_map):
+ (RawBitmaskProviderBase._bitmask):
+ Added. Base synthetic formatter class for a raw bitmask type. Derived classes are expected to
+ override the class variable ENUMERATOR_VALUE_TO_NAME_MAP with a dictionary of the form:
+ {
+ 1 << 0: "A",
+ 1 << 1: "B",
+ 1 << 2: "C",
+ }
+ It is not necessary to instantiate such a derived class directory. Instead use the convenience
+ function addSummaryAndSyntheticFormattersForRawBitmaskType.
+
+ (WTFOptionSetProvider.has_children): Deleted.
+ (WTFOptionSetProvider.num_children): Deleted.
+ (WTFOptionSetProvider.get_child_index): Deleted.
+ (WTFOptionSetProvider.get_child_at_index): Deleted.
+ (WTFOptionSetProvider.update): Deleted.
+
2019-01-04 Aakash Jain <[email protected]>
[ews-build] Add build step to validate the patch before processing it
Modified: trunk/Tools/lldb/lldb_webkit.py (239650 => 239651)
--- trunk/Tools/lldb/lldb_webkit.py 2019-01-05 02:30:03 UTC (rev 239650)
+++ trunk/Tools/lldb/lldb_webkit.py 2019-01-05 05:03:29 UTC (rev 239651)
@@ -33,6 +33,26 @@
import string
import struct
+
+def addSummaryAndSyntheticFormattersForRawBitmaskType(debugger, type_name, enumerator_value_to_name_map):
+ class GeneratedRawBitmaskProvider(RawBitmaskProviderBase):
+ ENUMERATOR_VALUE_TO_NAME_MAP = enumerator_value_to_name_map.copy()
+
+ def raw_bitmask_summary_provider(valobj, dict):
+ provider = GeneratedRawBitmaskProvider(valobj, dict)
+ return "{ size = %d }" % provider.size
+
+ # Add the provider class and summary function to the global scope so that LLDB
+ # can find them.
+ synthetic_provider_class_name = type_name + 'Provider'
+ summary_provider_function_name = type_name + '_SummaryProvider'
+ globals()[synthetic_provider_class_name] = GeneratedRawBitmaskProvider
+ globals()[summary_provider_function_name] = raw_bitmask_summary_provider
+
+ debugger.HandleCommand('type summary add --expand -F lldb_webkit.%s "%s"' % (summary_provider_function_name, type_name))
+ debugger.HandleCommand('type synthetic add %s --python-class lldb_webkit.%s' % (type_name, synthetic_provider_class_name))
+
+
def __lldb_init_module(debugger, dict):
debugger.HandleCommand('command script add -f lldb_webkit.btjs btjs')
debugger.HandleCommand('type summary add --expand -F lldb_webkit.WTFString_SummaryProvider WTF::String')
@@ -71,7 +91,19 @@
debugger.HandleCommand('type synthetic add -x "^WTF::HashTable<.+>$" --python-class lldb_webkit.WTFHashTableProvider')
debugger.HandleCommand('type synthetic add -x "^WTF::OptionSet<.+>$" --python-class lldb_webkit.WTFOptionSetProvider')
+ addSummaryAndSyntheticFormattersForRawBitmaskType(debugger, "WebEventFlags", {
+ 0x00010000: "WebEventFlagMaskLeftCommandKey",
+ 0x00020000: "WebEventFlagMaskLeftShiftKey",
+ 0x00040000: "WebEventFlagMaskLeftCapsLockKey",
+ 0x00080000: "WebEventFlagMaskLeftOptionKey",
+ 0x00100000: "WebEventFlagMaskLeftControlKey",
+ 0x00800000: "WebEventFlagMaskRightControlKey",
+ 0x00200000: "WebEventFlagMaskRightShiftKey",
+ 0x00400000: "WebEventFlagMaskRightOptionKey",
+ 0x01000000: "WebEventFlagMaskRightCommandKey",
+ })
+
def WTFString_SummaryProvider(valobj, dict):
provider = WTFStringProvider(valobj, dict)
return "{ length = %d, contents = '%s' }" % (provider.get_length(), provider.to_string())
@@ -697,11 +729,24 @@
return WebCoreFrameProvider(frame_ptr, dict())
-class WTFOptionSetProvider:
+class FlagEnumerationProvider(object):
def __init__(self, valobj, internal_dict):
self.valobj = valobj
self.update()
+ # Subclasses must override this to return a dictionary that maps emumerator values to names.
+ def _enumerator_value_to_name_map(self):
+ pass
+
+ # Subclasses must override this to return the bitmask.
+ def _bitmask(self):
+ pass
+
+ # Subclasses can override this to perform any computations when LLDB needs to refresh
+ # this provider.
+ def _update(self):
+ pass
+
def has_children(self):
return bool(self._elements)
@@ -723,21 +768,17 @@
return None
def update(self):
- self.storage = self.valobj.GetChildMemberWithName('m_storage') # May be an invalid value.
+ self._update()
+
self._elements = []
self.size = 0
- template_argument_sbType = self.valobj.GetType().GetTemplateArgumentType(0)
- enumerator_value_to_name_map = {}
- for sbTypeEnumMember in template_argument_sbType.get_enum_members_array():
- enumerator_value = sbTypeEnumMember.GetValueAsUnsigned()
- if enumerator_value not in enumerator_value_to_name_map:
- enumerator_value_to_name_map[enumerator_value] = sbTypeEnumMember.GetName()
+ enumerator_value_to_name_map = self._enumerator_value_to_name_map()
if not enumerator_value_to_name_map:
return
bitmask_with_all_options_set = sum(enumerator_value_to_name_map)
- bitmask = self.storage.GetValueAsUnsigned(0)
+ bitmask = self._bitmask()
if bitmask > bitmask_with_all_options_set:
return # Since this is an invalid value, return so the raw hex form is written out.
@@ -752,6 +793,33 @@
self.size = len(elements)
+class WTFOptionSetProvider(FlagEnumerationProvider):
+ def _enumerator_value_to_name_map(self):
+ template_argument_sbType = self.valobj.GetType().GetTemplateArgumentType(0)
+ enumerator_value_to_name_map = {}
+ for sbTypeEnumMember in template_argument_sbType.get_enum_members_array():
+ enumerator_value = sbTypeEnumMember.GetValueAsUnsigned()
+ if enumerator_value not in enumerator_value_to_name_map:
+ enumerator_value_to_name_map[enumerator_value] = sbTypeEnumMember.GetName()
+ return enumerator_value_to_name_map
+
+ def _bitmask(self):
+ return self.storage.GetValueAsUnsigned(0)
+
+ def _update(self):
+ self.storage = self.valobj.GetChildMemberWithName('m_storage') # May be an invalid value.
+
+
+class RawBitmaskProviderBase(FlagEnumerationProvider):
+ ENUMERATOR_VALUE_TO_NAME_MAP = {}
+
+ def _enumerator_value_to_name_map(self):
+ return self.ENUMERATOR_VALUE_TO_NAME_MAP
+
+ def _bitmask(self):
+ return self.valobj.GetValueAsUnsigned(0)
+
+
class WTFVectorProvider:
def __init__(self, valobj, internal_dict):
self.valobj = valobj