summaryrefslogtreecommitdiff
path: root/lldb/bindings
diff options
context:
space:
mode:
authorJorge Gorbe Moya <jgorbe@google.com>2022-10-11 00:44:06 -0700
committerJorge Gorbe Moya <jgorbe@google.com>2022-10-19 12:53:38 -0700
commitd76566417e592cfac9c710f82575473b1b4a9285 (patch)
tree0dba28904c3700ccfad579cb02f3b2c23dc8dded /lldb/bindings
parentb8b740c834ae39691b3247b30d30f00cae2b9e10 (diff)
downloadllvm-d76566417e592cfac9c710f82575473b1b4a9285.tar.gz
[lldb] Add matching based on Python callbacks for data formatters.
This patch adds a new matching method for data formatters, in addition to the existing exact typename and regex-based matching. The new method allows users to specify the name of a Python callback function that takes a `SBType` object and decides whether the type is a match or not. Here is an overview of the changes performed: - Add a new `eFormatterMatchCallback` matching type, and logic to handle it in `TypeMatcher` and `SBTypeNameSpecifier`. - Extend `FormattersMatchCandidate` instances with a pointer to the current `ScriptInterpreter` and the `TypeImpl` corresponding to the candidate type, so we can run registered callbacks and pass the type to them. All matcher search functions now receive a `FormattersMatchCandidate` instead of a type name. - Add some glue code to ScriptInterpreterPython and the SWIG bindings to allow calling a formatter matching callback. Most of this code is modeled after the equivalent code for watchpoint callback functions. - Add an API test for the new callback-based matching feature. For more context, please check the RFC thread where this feature was originally discussed: https://discourse.llvm.org/t/rfc-python-callback-for-data-formatters-type-matching/64204/11 Differential Revision: https://reviews.llvm.org/D135648
Diffstat (limited to 'lldb/bindings')
-rw-r--r--lldb/bindings/python/python-swigsafecast.swig4
-rw-r--r--lldb/bindings/python/python-wrapper.swig26
2 files changed, 30 insertions, 0 deletions
diff --git a/lldb/bindings/python/python-swigsafecast.swig b/lldb/bindings/python/python-swigsafecast.swig
index eb684133abef..aa5e8e50a2d9 100644
--- a/lldb/bindings/python/python-swigsafecast.swig
+++ b/lldb/bindings/python/python-swigsafecast.swig
@@ -97,6 +97,10 @@ PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp) {
SWIGTYPE_p_lldb__SBExecutionContext);
}
+PythonObject ToSWIGWrapper(lldb::TypeImplSP type_impl_sp) {
+ return ToSWIGHelper(new lldb::SBType(type_impl_sp), SWIGTYPE_p_lldb__SBType);
+}
+
PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options) {
return ToSWIGHelper(new lldb::SBTypeSummaryOptions(summary_options),
SWIGTYPE_p_lldb__SBTypeSummaryOptions);
diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig
index 626fc47bebb9..adac8a405ab9 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -90,6 +90,32 @@ bool lldb_private::LLDBSwigPythonWatchpointCallbackFunction(
return stop_at_watchpoint;
}
+// This function is called by
+// ScriptInterpreterPython::FormatterMatchingCallbackFunction and it's used when
+// a data formatter provides the name of a callback to inspect a candidate type
+// before considering a match.
+bool lldb_private::LLDBSwigPythonFormatterCallbackFunction(
+ const char *python_function_name, const char *session_dictionary_name,
+ lldb::TypeImplSP type_impl_sp) {
+
+ PyErr_Cleaner py_err_cleaner(true);
+
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(
+ session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(
+ python_function_name, dict);
+
+ if (!pfunc.IsAllocated())
+ return false;
+
+ PythonObject result =
+ pfunc(ToSWIGWrapper(type_impl_sp), dict);
+
+ // Only if everything goes okay and the function returns True we'll consider
+ // it a match.
+ return result.get() == Py_True;
+}
+
bool lldb_private::LLDBSwigPythonCallTypeScript(
const char *python_function_name, const void *session_dictionary,
const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper,