llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: Med Ismail Bennani (medismailben) <details> <summary>Changes</summary> Give `type synthetic add -l` a formal `ScriptedSyntheticChildrenInterface`, matching the architecture used elsewhere in this series: a C++ interface header, a Python-backed implementation, `PluginManager` registration with CLI/API usages, and a generatable ABC template (`scripted_synthetic_children.py`) wired into `scripting extension generate`. Teach `Dispatch<T>()` to introspect the target method's arity via `PythonCallable::GetArgInfo()` and drop trailing args before calling, so providers that legitimately define an argument as optional (`num_children(self)` vs. `num_children(self, max_count)`) work through the generic dispatch path. `CalculateNumChildren` now uses `Dispatch<T>()` and the standalone `LLDBSwigPython_CalculateNumChildren` bridge is removed. Only `CreatePluginObject` takes a full `InitSession`/`TearDownSession` session; per-call methods just acquire the GIL. --- Patch is 57.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/210845.diff 22 Files Affected: - (modified) lldb/bindings/python/CMakeLists.txt (+1) - (modified) lldb/bindings/python/python-swigsafecast.swig (+7) - (modified) lldb/bindings/python/python-wrapper.swig (-64) - (modified) lldb/docs/CMakeLists.txt (+1) - (added) lldb/examples/python/templates/scripted_synthetic_children.py (+111) - (modified) lldb/include/lldb/DataFormatters/TypeSynthetic.h (+1-2) - (added) lldb/include/lldb/Interpreter/Interfaces/ScriptedSyntheticChildrenInterface.h (+44) - (modified) lldb/include/lldb/Interpreter/ScriptInterpreter.h (+5-43) - (modified) lldb/include/lldb/lldb-enumerations.h (+2-1) - (modified) lldb/include/lldb/lldb-forward.h (+3) - (modified) lldb/source/DataFormatters/TypeSynthetic.cpp (+37-29) - (modified) lldb/source/Interpreter/ScriptInterpreter.cpp (+4) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt (+1) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.cpp (+2) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptInterpreterPythonInterfaces.h (+1) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedPythonInterface.h (+61-35) - (added) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedSyntheticChildrenPythonInterface.cpp (+233) - (added) lldb/source/Plugins/ScriptInterpreter/Python/Interfaces/ScriptedSyntheticChildrenPythonInterface.h (+63) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h (+2-8) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp (+7-233) - (modified) lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h (+3-27) - (modified) lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp (-12) ``````````diff diff --git a/lldb/bindings/python/CMakeLists.txt b/lldb/bindings/python/CMakeLists.txt index d29b143c1408c..ce6201396bb4f 100644 --- a/lldb/bindings/python/CMakeLists.txt +++ b/lldb/bindings/python/CMakeLists.txt @@ -120,6 +120,7 @@ function(finish_swig_python swig_target lldb_python_bindings_dir lldb_python_tar "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_breakpoint.py" "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_hook.py" "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_stackframe_recognizer.py" + "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_synthetic_children.py" ) if(APPLE) diff --git a/lldb/bindings/python/python-swigsafecast.swig b/lldb/bindings/python/python-swigsafecast.swig index a86dc44ce4106..c5003c019aae2 100644 --- a/lldb/bindings/python/python-swigsafecast.swig +++ b/lldb/bindings/python/python-swigsafecast.swig @@ -17,6 +17,13 @@ PythonObject SWIGBridge::ToSWIGWrapper(lldb::ValueObjectSP value_sp) { return ToSWIGWrapper(std::unique_ptr<lldb::SBValue>(new lldb::SBValue(value_sp))); } +PythonObject SWIGBridge::ToSWIGWrapper(lldb::ValueObjectSP value_sp, + bool use_synthetic) { + auto sb_value = std::unique_ptr<lldb::SBValue>(new lldb::SBValue(value_sp)); + sb_value->SetPreferSyntheticValue(use_synthetic); + return ToSWIGWrapper(std::move(sb_value)); +} + PythonObject SWIGBridge::ToSWIGWrapper(lldb::TargetSP target_sp) { return ToSWIGHelper(new lldb::SBTarget(std::move(target_sp)), SWIGTYPE_p_lldb__SBTarget); diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index 2392737402e20..0beac24568c84 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -181,38 +181,6 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallTypeScript( return true; } -PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateSyntheticProvider( - const char *python_class_name, const char *session_dictionary_name, - const lldb::ValueObjectSP &valobj_sp) { - if (python_class_name == NULL || python_class_name[0] == '\0' || - !session_dictionary_name) - return PythonObject(); - - PyErr_Cleaner py_err_cleaner(true); - - auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>( - session_dictionary_name); - auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>( - python_class_name, dict); - - if (!pfunc.IsAllocated()) - return PythonObject(); - - auto sb_value = std::unique_ptr<lldb::SBValue>(new lldb::SBValue(valobj_sp)); - sb_value->SetPreferSyntheticValue(false); - - PythonObject val_arg = SWIGBridge::ToSWIGWrapper(std::move(sb_value)); - if (!val_arg.IsAllocated()) - return PythonObject(); - - PythonObject result = pfunc(val_arg, dict); - - if (result.IsAllocated()) - return result; - - return PythonObject(); -} - PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateCommandObject( const char *python_class_name, const char *session_dictionary_name, lldb::DebuggerSP debugger_sp) { @@ -256,38 +224,6 @@ static PyObject *LLDBSwigPython_CallOptionalMember( return result.release(); } -size_t lldb_private::python::SWIGBridge::LLDBSwigPython_CalculateNumChildren(PyObject * implementor, - uint32_t max) { - PythonObject self(PyRefType::Borrowed, implementor); - auto pfunc = self.ResolveName<PythonCallable>("num_children"); - - if (!pfunc.IsAllocated()) - return 0; - - auto arg_info = pfunc.GetArgInfo(); - if (!arg_info) { - llvm::consumeError(arg_info.takeError()); - return 0; - } - - size_t ret_val; - if (arg_info.get().max_positional_args < 1) - ret_val = unwrapOrSetPythonException(As<long long>(pfunc.Call())); - else - ret_val = unwrapOrSetPythonException( - As<long long>(pfunc.Call(PythonInteger(max)))); - - if (PyErr_Occurred()) { - PyErr_Print(); - PyErr_Clear(); - return 0; - } - - if (arg_info.get().max_positional_args < 1) - ret_val = std::min(ret_val, static_cast<size_t>(max)); - - return ret_val; -} PyObject *lldb_private::python::SWIGBridge::LLDBSwigPython_GetChildAtIndex(PyObject * implementor, uint32_t idx) { diff --git a/lldb/docs/CMakeLists.txt b/lldb/docs/CMakeLists.txt index dd091836dc1aa..d57415ef1e975 100644 --- a/lldb/docs/CMakeLists.txt +++ b/lldb/docs/CMakeLists.txt @@ -33,6 +33,7 @@ if (LLDB_ENABLE_PYTHON AND SPHINX_FOUND) COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_breakpoint.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/" COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_hook.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/" COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_stackframe_recognizer.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/" + COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_synthetic_children.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/" COMMENT "Copying lldb.py to pretend its a Python package.") add_dependencies(lldb-python-doc-package swig_wrapper_python) diff --git a/lldb/examples/python/templates/scripted_synthetic_children.py b/lldb/examples/python/templates/scripted_synthetic_children.py new file mode 100644 index 0000000000000..61ce038b7f58b --- /dev/null +++ b/lldb/examples/python/templates/scripted_synthetic_children.py @@ -0,0 +1,111 @@ +from abc import ABCMeta, abstractmethod +from typing import Optional + +import lldb + + +class ScriptedSyntheticChildren(metaclass=ABCMeta): + """ + The base class for a scripted synthetic children provider. + + A synthetic children provider allows you to customize how a value is + expanded into children when displayed (e.g. `frame variable`, `bt`). + Register it with `type synthetic add -l <ClassName> ...`. + + Most of the base class methods are `@abstractmethod` that need to be + overwritten by the inheriting class. + """ + + valobj: lldb.SBValue + + def __init__(self, valobj: lldb.SBValue, internal_dict: dict): + """Construct a scripted synthetic children provider. + + Args: + valobj (lldb.SBValue): The value this provider generates children + for. + internal_dict (dict): The session dictionary for the embedded + interpreter, unused in most implementations. + """ + self.valobj = valobj + + @abstractmethod + def num_children(self) -> int: + """The number of children this value has. + + This can optionally take a second `max_count` parameter (i.e. + `def num_children(self, max_count)`) if computing the exact count is + expensive; in that case return `max_count` once at least that many + children are known to exist. + + Returns: + int: The number of children. + """ + pass + + @abstractmethod + def get_child_at_index(self, index: int) -> Optional[lldb.SBValue]: + """Get the child at the given index. + + Args: + index (int): The index of the child to return. + + Returns: + lldb.SBValue: The value for the child at this index, or `None` if + there is no child at this index. + """ + pass + + def get_child_index(self, name: str) -> Optional[int]: + """Get the index of the child with the given name. + + Args: + name (str): The name of the child to look up. + + Returns: + int: The index of the child with this name, or `None`/a negative + value if no such child exists. Defaults to a linear search over + `get_child_at_index`/`num_children`. + """ + pass + + def update(self) -> bool: + """Called when the value backing this provider may have changed + (e.g. after a `continue`), giving the provider a chance to refresh + any cached state. + + Returns: + bool: `True` if the previously computed children can be reused, + `False` if they should be recomputed. Defaults to `False`. + """ + return False + + def has_children(self) -> bool: + """Whether this value might have children, without necessarily + computing them. Used as a cheap check to decide whether to show an + expansion arrow in graphical frontends, for example. + + Returns: + bool: `True` if this value might have children, `False` + otherwise. Defaults to `True`. + """ + return True + + def get_value(self) -> Optional[lldb.SBValue]: + """Override the value shown for this synthetic value itself, + alongside its children. + + Returns: + lldb.SBValue: The value to display, or `None` to keep the + default. Defaults to `None`. + """ + return None + + def get_type_name(self) -> Optional[str]: + """Override the type name shown for this synthetic value. + + Returns: + str: The type name to display, or `None`/empty to keep the + default. Defaults to `None`. + """ + pass diff --git a/lldb/include/lldb/DataFormatters/TypeSynthetic.h b/lldb/include/lldb/DataFormatters/TypeSynthetic.h index 9c17adbde7465..6eb06ba8dda7f 100644 --- a/lldb/include/lldb/DataFormatters/TypeSynthetic.h +++ b/lldb/include/lldb/DataFormatters/TypeSynthetic.h @@ -477,8 +477,7 @@ class ScriptedSyntheticChildren : public SyntheticChildren { private: std::string m_python_class; - StructuredData::ObjectSP m_wrapper_sp; - ScriptInterpreter *m_interpreter; + lldb::ScriptedSyntheticChildrenInterfaceSP m_interface_sp; FrontEnd(const FrontEnd &) = delete; const FrontEnd &operator=(const FrontEnd &) = delete; diff --git a/lldb/include/lldb/Interpreter/Interfaces/ScriptedSyntheticChildrenInterface.h b/lldb/include/lldb/Interpreter/Interfaces/ScriptedSyntheticChildrenInterface.h new file mode 100644 index 0000000000000..c73018c779e1e --- /dev/null +++ b/lldb/include/lldb/Interpreter/Interfaces/ScriptedSyntheticChildrenInterface.h @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_INTERPRETER_INTERFACES_SCRIPTEDSYNTHETICCHILDRENINTERFACE_H +#define LLDB_INTERPRETER_INTERFACES_SCRIPTEDSYNTHETICCHILDRENINTERFACE_H + +#include "ScriptedInterface.h" +#include "lldb/lldb-private.h" +#include "llvm/Support/ErrorExtras.h" + +namespace lldb_private { +class ScriptedSyntheticChildrenInterface : virtual public ScriptedInterface { +public: + virtual llvm::Expected<StructuredData::GenericSP> + CreatePluginObject(llvm::StringRef class_name, ValueObject &backend) = 0; + + virtual llvm::Expected<uint32_t> CalculateNumChildren(uint32_t max) { + return 0; + } + + virtual lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) { + return lldb::ValueObjectSP(); + } + + virtual llvm::Expected<uint32_t> GetIndexOfChildWithName(ConstString name) { + return llvm::createStringErrorV("type has no child named '{0}'", name); + } + + virtual lldb::ChildCacheState Update() { return lldb::eRefetch; } + + virtual bool MightHaveChildren() { return true; } + + virtual lldb::ValueObjectSP GetSyntheticValue() { return nullptr; } + + virtual ConstString GetSyntheticTypeName() { return ConstString(); } +}; +} // namespace lldb_private + +#endif // LLDB_INTERPRETER_INTERFACES_SCRIPTEDSYNTHETICCHILDRENINTERFACE_H diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index 0e65cb4b8ac4a..015c042004e63 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -257,12 +257,6 @@ class ScriptInterpreter : public PluginInterface { return false; } - virtual StructuredData::ObjectSP - CreateSyntheticScriptedProvider(const char *class_name, - lldb::ValueObjectSP valobj) { - return StructuredData::ObjectSP(); - } - virtual StructuredData::GenericSP CreateScriptCommandObject(const char *class_name) { return StructuredData::GenericSP(); @@ -348,43 +342,6 @@ class ScriptInterpreter : public PluginInterface { // Clean up any ref counts to SBObjects that might be in global variables } - virtual size_t - CalculateNumChildren(const StructuredData::ObjectSP &implementor, - uint32_t max) { - return 0; - } - - virtual lldb::ValueObjectSP - GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) { - return lldb::ValueObjectSP(); - } - - virtual llvm::Expected<uint32_t> - GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, - const char *child_name) { - return llvm::createStringError("Type has no child named '%s'", child_name); - } - - virtual bool - UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor) { - return false; - } - - virtual bool MightHaveChildrenSynthProviderInstance( - const StructuredData::ObjectSP &implementor) { - return true; - } - - virtual lldb::ValueObjectSP - GetSyntheticValue(const StructuredData::ObjectSP &implementor) { - return nullptr; - } - - virtual ConstString - GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) { - return ConstString(); - } - virtual bool RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, ScriptedCommandSynchronicity synchronicity, @@ -586,6 +543,11 @@ class ScriptInterpreter : public PluginInterface { return {}; } + virtual lldb::ScriptedSyntheticChildrenInterfaceSP + CreateScriptedSyntheticChildrenInterface() { + return {}; + } + virtual StructuredData::ObjectSP CreateStructuredDataFromScriptObject(ScriptObject obj) { return {}; diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 93c252b55de99..9351ed14c0524 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -268,7 +268,8 @@ enum ScriptedExtension { eScriptedExtensionScriptedThread, eScriptedExtensionScriptedFrame, eScriptedExtensionScriptedStackFrameRecognizer, - kLastScriptedExtension = eScriptedExtensionScriptedStackFrameRecognizer + eScriptedExtensionScriptedSyntheticChildren, + kLastScriptedExtension = eScriptedExtensionScriptedSyntheticChildren }; /// Register numbering types. diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index 157aa5743f016..a1292ed538145 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -200,6 +200,7 @@ class ScriptedThreadInterface; class ScriptedThreadPlanInterface; class ScriptedStackFrameRecognizerInterface; class ScriptedSyntheticChildren; +class ScriptedSyntheticChildrenInterface; class SearchFilter; class Section; class SectionList; @@ -438,6 +439,8 @@ typedef std::shared_ptr<lldb_private::ScriptedBreakpointInterface> ScriptedBreakpointInterfaceSP; typedef std::shared_ptr<lldb_private::ScriptedStackFrameRecognizerInterface> ScriptedStackFrameRecognizerInterfaceSP; +typedef std::shared_ptr<lldb_private::ScriptedSyntheticChildrenInterface> + ScriptedSyntheticChildrenInterfaceSP; typedef std::shared_ptr<lldb_private::Section> SectionSP; typedef std::unique_ptr<lldb_private::SectionList> SectionListUP; typedef std::weak_ptr<lldb_private::Section> SectionWP; diff --git a/lldb/source/DataFormatters/TypeSynthetic.cpp b/lldb/source/DataFormatters/TypeSynthetic.cpp index 2200ccf3b092d..66bcd310ef770 100644 --- a/lldb/source/DataFormatters/TypeSynthetic.cpp +++ b/lldb/source/DataFormatters/TypeSynthetic.cpp @@ -16,6 +16,7 @@ #include "lldb/DataFormatters/FormatterBytecode.h" #include "lldb/DataFormatters/TypeSynthetic.h" #include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/Interfaces/ScriptedSyntheticChildrenInterface.h" #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/Target.h" @@ -164,8 +165,7 @@ lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateChildValueObjectFromData( ScriptedSyntheticChildren::FrontEnd::FrontEnd(std::string pclass, ValueObject &backend) - : SyntheticChildrenFrontEnd(backend), m_python_class(pclass), - m_wrapper_sp(), m_interpreter(nullptr) { + : SyntheticChildrenFrontEnd(backend), m_python_class(pclass) { if (backend.GetID() == LLDB_INVALID_UID) return; @@ -174,87 +174,95 @@ ScriptedSyntheticChildren::FrontEnd::FrontEnd(std::string pclass, if (!target_sp) return; - m_interpreter = target_sp->GetDebugger().GetScriptInterpreter(); + ScriptInterpreter *interpreter = + target_sp->GetDebugger().GetScriptInterpreter(); - if (m_interpreter != nullptr) - m_wrapper_sp = m_interpreter->CreateSyntheticScriptedProvider( - m_python_class.c_str(), backend.GetSP()); + if (!interpreter) + return; + + m_interface_sp = interpreter->CreateScriptedSyntheticChildrenInterface(); + if (!m_interface_sp) + return; + + auto obj_or_err = m_interface_sp->CreatePluginObject(m_python_class, backend); + if (!obj_or_err) { + llvm::consumeError(obj_or_err.takeError()); + m_interface_sp.reset(); + } } ScriptedSyntheticChildren::FrontEnd::~FrontEnd() = default; lldb::ValueObjectSP ScriptedSyntheticChildren::FrontEnd::GetChildAtIndex(uint32_t idx) { - if (!m_wrapper_sp || !m_interpreter) + if (!m_interface_sp) return lldb::ValueObjectSP(); - return m_interpreter->GetChildAtIndex(m_wrapper_sp, idx); + return m_interface_sp->GetChildAtIndex(idx); } bool ScriptedSyntheticChildren::FrontEnd::IsValid() { - return (m_wrapper_sp && m_wrapper_sp->IsValid() && m_interpreter); + return m_interface_sp != nullptr; } llvm::Expected<uint32_t> ScriptedSyntheticChildren::FrontEnd::CalculateNumChildren() { - if (!m_wrapper_sp || m_interpreter == nullptr) + if (!m_interface_sp) return 0; - return m_interpreter->CalculateNumChildren(m_wrapper_sp, UINT32_MAX); + return m_interface_sp->CalculateNumChildren(UINT32_MAX); } llvm::Expected<uint32_t> ScriptedSyntheticChildren::FrontEnd::CalculateNumChildren(uint32_t max) { - if (!m_wrapper_sp || m_interpreter == nullptr) + if (!m_interface_sp) return 0; - return m_interpreter->CalculateNumChildren(m_wrapper_sp, max); + return m_interface_sp->CalculateNumChildren(max); } lldb::ChildCacheState ScriptedSyntheticChildren::FrontEnd::Update() { - if (!m_wrapper_sp || m_interpreter == nullptr) + if (!m_interface_sp) return lldb::ChildCacheState::eRefetch; - return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp) - ? lldb::ChildCacheState::eReuse - : lldb::ChildCacheState::eRefetch; + return m_interface_sp->Update(); } bool ScriptedSyntheticChildren::FrontEnd::MightHaveChildren() { - if (!m_wrapper_sp || m_interpreter == nullptr) + if (!m_interface_sp) return false; - return m_interpreter->MightHaveChildrenSynthProviderInstance(m_wrapper_sp); + return m_interface_sp->MightHaveChildren(); } llvm::Expected<size_t> ScriptedSyntheticChildren::FrontEnd::GetIndexOfChildWithName(ConstString name) { - if (!m_wrapper_sp || m_interpreter == nullptr) + if (!m_interface_sp) return llvm::createStringErrorV("type has no child named '{0}'", name); - return m_interpreter->GetIndexOfChildWithName(m_wrapper_sp, - name.GetCString()); + return m_interface_sp->GetIndexOfChildWithName(name); } lldb::ValueObjectSP ScriptedSyntheticChildren::FrontEnd::GetSyntheticValue() { - if (!m_wrapper_sp || m_interpreter == nullptr) + if (!m_interface_sp) return nullptr; - return m_interpreter->GetSyn... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/210845 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
