diff options
-rw-r--r-- | lldb/include/lldb/Core/CXXFormatterFunctions.h | 18 | ||||
-rw-r--r-- | lldb/include/lldb/Core/FormatClasses.h | 40 | ||||
-rw-r--r-- | lldb/include/lldb/Core/ValueObjectSyntheticFilter.h | 2 | ||||
-rw-r--r-- | lldb/include/lldb/Interpreter/ScriptInterpreter.h | 20 | ||||
-rw-r--r-- | lldb/include/lldb/Interpreter/ScriptInterpreterPython.h | 3 | ||||
-rw-r--r-- | lldb/scripts/Python/python-wrapper.swig | 162 | ||||
-rw-r--r-- | lldb/source/Core/CXXFormatterFunctions.cpp | 36 | ||||
-rw-r--r-- | lldb/source/Core/ValueObjectSyntheticFilter.cpp | 15 | ||||
-rw-r--r-- | lldb/source/Interpreter/ScriptInterpreterPython.cpp | 37 |
9 files changed, 248 insertions, 85 deletions
diff --git a/lldb/include/lldb/Core/CXXFormatterFunctions.h b/lldb/include/lldb/Core/CXXFormatterFunctions.h index 8cb2212a999..9ae021ae781 100644 --- a/lldb/include/lldb/Core/CXXFormatterFunctions.h +++ b/lldb/include/lldb/Core/CXXFormatterFunctions.h @@ -107,6 +107,9 @@ namespace lldb_private { virtual bool Update(); + virtual bool + MightHaveChildren (); + virtual uint32_t GetIndexOfChildWithName (const ConstString &name); @@ -135,6 +138,9 @@ namespace lldb_private { virtual bool Update(); + virtual bool + MightHaveChildren (); + virtual uint32_t GetIndexOfChildWithName (const ConstString &name); @@ -163,6 +169,9 @@ namespace lldb_private { virtual bool Update(); + virtual bool + MightHaveChildren (); + virtual uint32_t GetIndexOfChildWithName (const ConstString &name); @@ -205,6 +214,9 @@ namespace lldb_private { virtual bool Update(); + virtual bool + MightHaveChildren (); + virtual uint32_t GetIndexOfChildWithName (const ConstString &name); @@ -258,6 +270,9 @@ namespace lldb_private { virtual bool Update(); + virtual bool + MightHaveChildren (); + virtual uint32_t GetIndexOfChildWithName (const ConstString &name); @@ -286,6 +301,9 @@ namespace lldb_private { virtual bool Update(); + virtual bool + MightHaveChildren (); + virtual uint32_t GetIndexOfChildWithName (const ConstString &name); diff --git a/lldb/include/lldb/Core/FormatClasses.h b/lldb/include/lldb/Core/FormatClasses.h index 3546c18c055..e479e69bd5e 100644 --- a/lldb/include/lldb/Core/FormatClasses.h +++ b/lldb/include/lldb/Core/FormatClasses.h @@ -228,17 +228,17 @@ protected: ValueObject &m_backend; public: - SyntheticChildrenFrontEnd(ValueObject &backend) : - m_backend(backend) + SyntheticChildrenFrontEnd (ValueObject &backend) : + m_backend(backend) {} virtual - ~SyntheticChildrenFrontEnd() + ~SyntheticChildrenFrontEnd () { } virtual uint32_t - CalculateNumChildren() = 0; + CalculateNumChildren () = 0; virtual lldb::ValueObjectSP GetChildAtIndex (uint32_t idx) = 0; @@ -252,7 +252,14 @@ public: // if =true, ValueObjectSyntheticFilter is allowed to use the children it fetched previously and cached // if =false, ValueObjectSyntheticFilter must throw away its cache, and query again for children virtual bool - Update() = 0; + Update () = 0; + + // if this function returns false, then CalculateNumChildren() MUST return 0 since UI frontends + // might validly decide not to inquire for children given a false return value from this call + // if it returns true, then CalculateNumChildren() can return any number >= 0 (0 being valid) + // it should if at all possible be more efficient than CalculateNumChildren() + virtual bool + MightHaveChildren () = 0; typedef STD_SHARED_PTR(SyntheticChildrenFrontEnd) SharedPointer; typedef std::auto_ptr<SyntheticChildrenFrontEnd> AutoPointer; @@ -566,6 +573,12 @@ public: virtual bool Update() { return false; } + virtual bool + MightHaveChildren () + { + return filter->GetCount() > 0; + } + virtual uint32_t GetIndexOfChildWithName (const ConstString &name) { @@ -726,7 +739,16 @@ public: return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp); } - + + virtual bool + MightHaveChildren() + { + if (!m_wrapper_sp || m_interpreter == NULL) + return false; + + return m_interpreter->MightHaveChildrenSynthProviderInstance(m_wrapper_sp); + } + virtual uint32_t GetIndexOfChildWithName (const ConstString &name) { @@ -923,6 +945,12 @@ public: return filter->GetCount(); } + virtual bool + MightHaveChildren () + { + return filter->GetCount() > 0; + } + virtual lldb::ValueObjectSP GetChildAtIndex (uint32_t idx) { diff --git a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h index eadfc69e777..f0b1761443d 100644 --- a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h +++ b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h @@ -141,6 +141,8 @@ protected: ConstString m_parent_type_name; + LazyBool m_might_have_children; + private: friend class ValueObject; ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter); diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index 2d375da3577..fe2096222b3 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -87,11 +87,13 @@ public: const char *session_dictionary_name, const lldb::ProcessSP& process_sp); - typedef uint32_t (*SWIGPythonCalculateNumChildren) (void *implementor); - typedef void* (*SWIGPythonGetChildAtIndex) (void *implementor, uint32_t idx); - typedef int (*SWIGPythonGetIndexOfChildWithName) (void *implementor, const char* child_name); - typedef void* (*SWIGPythonCastPyObjectToSBValue) (void* data); - typedef bool (*SWIGPythonUpdateSynthProviderInstance) (void* data); + typedef uint32_t (*SWIGPythonCalculateNumChildren) (void *implementor); + typedef void* (*SWIGPythonGetChildAtIndex) (void *implementor, uint32_t idx); + typedef int (*SWIGPythonGetIndexOfChildWithName) (void *implementor, const char* child_name); + typedef void* (*SWIGPythonCastPyObjectToSBValue) (void* data); + typedef bool (*SWIGPythonUpdateSynthProviderInstance) (void* data); + typedef bool (*SWIGPythonMightHaveChildrenSynthProviderInstance) (void* data); + typedef bool (*SWIGPythonCallCommand) (const char *python_function_name, const char *session_dictionary_name, @@ -296,7 +298,13 @@ public: { return false; } - + + virtual bool + MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor) + { + return true; + } + virtual bool RunScriptBasedCommand (const char* impl_function, const char* args, diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h b/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h index 4fa6e2592ae..e94eb368408 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h @@ -109,6 +109,9 @@ public: UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor); virtual bool + MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor); + + virtual bool RunScriptBasedCommand(const char* impl_function, const char* args, ScriptedCommandSynchronicity synchronicity, diff --git a/lldb/scripts/Python/python-wrapper.swig b/lldb/scripts/Python/python-wrapper.swig index a3aeefb1f77..199cc639cb2 100644 --- a/lldb/scripts/Python/python-wrapper.swig +++ b/lldb/scripts/Python/python-wrapper.swig @@ -418,46 +418,104 @@ LLDBSwigPythonCreateSyntheticProvider Py_RETURN_NONE; } -/* -these four calls below are meant to support -Python-based synthetic children providers -they essentially mimic the four pure virtual -method calls provided by the frontend class -*/ - -SWIGEXPORT uint32_t -LLDBSwigPython_CalculateNumChildren +// wrapper that calls an optional instance member of an object taking no arguments +static PyObject* +LLDBSwigPython_CallOptionalMember ( - PyObject *implementor + PyObject* self, + char* callee_name, + PyObject* ret_if_not_found = Py_None, + bool* was_found = NULL ) { + if (self == NULL || self == Py_None) + { + if (was_found) + *was_found = false; + Py_XINCREF(ret_if_not_found); + return ret_if_not_found; + } - static char callee_name[] = "num_children"; + PyObject* pmeth = PyObject_GetAttrString(self, callee_name); - if (implementor == NULL || implementor == Py_None) - return 0; - PyObject* py_return = PyObject_CallMethod(implementor, callee_name, NULL); if (PyErr_Occurred()) { - PyErr_Print(); PyErr_Clear(); } - if (py_return == NULL || py_return == Py_None) + if (pmeth == NULL || pmeth == Py_None) { - Py_XDECREF(py_return); - return UINT32_MAX; + if (was_found) + *was_found = false; + Py_XDECREF(pmeth); + Py_XINCREF(ret_if_not_found); + return ret_if_not_found; } - long retval = PyInt_AsLong(py_return); - Py_DECREF(py_return); - if (retval >= 0) - return (uint32_t)retval; + + if (PyCallable_Check(pmeth) == 0) + { + if (PyErr_Occurred()) + { + PyErr_Clear(); + } + + Py_XDECREF(pmeth); + if (was_found) + *was_found = false; + Py_XINCREF(ret_if_not_found); + return ret_if_not_found; + } + + if (was_found) + *was_found = true; + + if (PyErr_Occurred()) + { + PyErr_Clear(); + } + + Py_XDECREF(pmeth); + + // right now we know this function exists and is callable.. + PyObject* py_return = PyObject_CallMethod(self, callee_name, NULL); + + // if it fails, print the error but otherwise go on if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); } - return 0; + + return py_return; +} + +SWIGEXPORT uint32_t +LLDBSwigPython_CalculateNumChildren +( + PyObject *implementor +) +{ + uint32_t ret_val = UINT32_MAX; + + static char callee_name[] = "num_children"; + + PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, NULL); + + if (!py_return) + return ret_val; + + if (PyInt_Check(py_return)) + ret_val = PyInt_AsLong(py_return); + + Py_XDECREF(py_return); + + if (PyErr_Occurred()) + { + PyErr_Print(); + PyErr_Clear(); + } + + return ret_val; } SWIGEXPORT PyObject* @@ -542,64 +600,38 @@ LLDBSwigPython_UpdateSynthProviderInstance PyObject *implementor ) { - bool ret_val = false; static char callee_name[] = "update"; - if (implementor == NULL || implementor == Py_None) - return ret_val; - - // all this code is here because update is optional, so we don't want to bother trying to call it unless it's been def:ined for us - // other synth provider calls are mandatory, so we want to fail in a very obvious way if they are missing! - PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name); - - if (PyErr_Occurred()) - { - PyErr_Clear(); - } + PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name); - if (pmeth == NULL || pmeth == Py_None) - { - Py_XDECREF(pmeth); - return ret_val; - } + if (py_return == Py_True) + ret_val = true; - if (PyCallable_Check(pmeth) == 0) - { - if (PyErr_Occurred()) - { - PyErr_Clear(); - } + Py_XDECREF(py_return); + + return ret_val; +} - Py_XDECREF(pmeth); - return ret_val; - } +SWIGEXPORT bool +LLDBSwigPython_MightHaveChildrenSynthProviderInstance +( + PyObject *implementor +) +{ + bool ret_val = false; - if (PyErr_Occurred()) - { - PyErr_Clear(); - } + static char callee_name[] = "has_children"; - Py_XDECREF(pmeth); + PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, Py_True); - // right now we know this function exists and is callable.. - PyObject* py_return = PyObject_CallMethod(implementor, callee_name, NULL); - - // if it fails, print the error but otherwise go on - if (PyErr_Occurred()) - { - PyErr_Print(); - PyErr_Clear(); - } - if (py_return == Py_True) ret_val = true; Py_XDECREF(py_return); return ret_val; - } SWIGEXPORT void* diff --git a/lldb/source/Core/CXXFormatterFunctions.cpp b/lldb/source/Core/CXXFormatterFunctions.cpp index 67f769805ea..bc205b194a8 100644 --- a/lldb/source/Core/CXXFormatterFunctions.cpp +++ b/lldb/source/Core/CXXFormatterFunctions.cpp @@ -773,6 +773,12 @@ lldb_private::formatters::NSArrayMSyntheticFrontEnd::Update() return false; } +bool +lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren () +{ + return CalculateNumChildren() > 0; +} + static uint32_t ExtractIndexFromString (const char* item_name) { @@ -882,6 +888,12 @@ lldb_private::formatters::NSArrayISyntheticFrontEnd::Update() return false; } +bool +lldb_private::formatters::NSArrayISyntheticFrontEnd::MightHaveChildren () +{ + return CalculateNumChildren() > 0; +} + lldb::ValueObjectSP lldb_private::formatters::NSArrayISyntheticFrontEnd::GetChildAtIndex (uint32_t idx) { @@ -976,6 +988,12 @@ lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::Update() return false; } +bool +lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::MightHaveChildren () +{ + return CalculateNumChildren() > 0; +} + uint32_t lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) { @@ -1067,6 +1085,12 @@ lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::Update() return false; } +bool +lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::MightHaveChildren () +{ + return CalculateNumChildren() > 0; +} + uint32_t lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) { @@ -1159,6 +1183,12 @@ lldb_private::formatters::NSDictionaryISyntheticFrontEnd::Update() return false; } +bool +lldb_private::formatters::NSDictionaryISyntheticFrontEnd::MightHaveChildren () +{ + return CalculateNumChildren() > 0; +} + lldb::ValueObjectSP lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex (uint32_t idx) { @@ -1300,6 +1330,12 @@ lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update() return false; } +bool +lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::MightHaveChildren () +{ + return CalculateNumChildren() > 0; +} + lldb::ValueObjectSP lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex (uint32_t idx) { diff --git a/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/lldb/source/Core/ValueObjectSyntheticFilter.cpp index fe8e90cf181..e19d90085be 100644 --- a/lldb/source/Core/ValueObjectSyntheticFilter.cpp +++ b/lldb/source/Core/ValueObjectSyntheticFilter.cpp @@ -45,6 +45,12 @@ public: } bool + MightHaveChildren () + { + return true; + } + + bool Update() { return false; @@ -58,7 +64,8 @@ ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::Synthetic m_children_byindex(), m_name_toindex(), m_synthetic_children_count(UINT32_MAX), - m_parent_type_name(parent.GetTypeName()) + m_parent_type_name(parent.GetTypeName()), + m_might_have_children(eLazyBoolCalculate) { #ifdef LLDB_CONFIGURATION_DEBUG std::string new_name(parent.GetName().AsCString()); @@ -99,8 +106,9 @@ ValueObjectSynthetic::CalculateNumChildren() bool ValueObjectSynthetic::MightHaveChildren() { - // TODO: make this more efficient by adding API calls to calculate this efficiently - return GetNumChildren () > 0; + if (m_might_have_children == eLazyBoolCalculate) + m_might_have_children = (m_synth_filter_ap->MightHaveChildren() ? eLazyBoolYes : eLazyBoolNo); + return (m_might_have_children == eLazyBoolNo ? false : true); } @@ -164,6 +172,7 @@ ValueObjectSynthetic::UpdateValue () // that they need to come back to us asking for children m_children_count_valid = false; m_synthetic_children_count = UINT32_MAX; + m_might_have_children = eLazyBoolCalculate; } CopyParentData(); diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp index 7261e5d8733..fdd406a764a 100644 --- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp +++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp @@ -53,6 +53,7 @@ static ScriptInterpreter::SWIGPythonGetChildAtIndex g_swig_get_child_index = NUL static ScriptInterpreter::SWIGPythonGetIndexOfChildWithName g_swig_get_index_child = NULL; static ScriptInterpreter::SWIGPythonCastPyObjectToSBValue g_swig_cast_to_sbvalue = NULL; static ScriptInterpreter::SWIGPythonUpdateSynthProviderInstance g_swig_update_provider = NULL; +static ScriptInterpreter::SWIGPythonMightHaveChildrenSynthProviderInstance g_swig_mighthavechildren_provider = NULL; static ScriptInterpreter::SWIGPythonCallCommand g_swig_call_command = NULL; static ScriptInterpreter::SWIGPythonCallModuleInit g_swig_call_module_init = NULL; static ScriptInterpreter::SWIGPythonCreateOSPlugin g_swig_create_os_plugin = NULL; @@ -99,11 +100,12 @@ LLDBSwigPythonCreateSyntheticProvider ); -extern "C" uint32_t LLDBSwigPython_CalculateNumChildren (void *implementor); -extern "C" void* LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx); -extern "C" int LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name); -extern "C" void* LLDBSWIGPython_CastPyObjectToSBValue (void* data); -extern "C" bool LLDBSwigPython_UpdateSynthProviderInstance (void* implementor); +extern "C" uint32_t LLDBSwigPython_CalculateNumChildren (void *implementor); +extern "C" void* LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx); +extern "C" int LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name); +extern "C" void* LLDBSWIGPython_CastPyObjectToSBValue (void* data); +extern "C" bool LLDBSwigPython_UpdateSynthProviderInstance (void* implementor); +extern "C" bool LLDBSwigPython_MightHaveChildrenSynthProviderInstance (void* implementor); extern "C" bool LLDBSwigPythonCallCommand ( @@ -2348,6 +2350,30 @@ ScriptInterpreterPython::UpdateSynthProviderInstance (const lldb::ScriptInterpre } bool +ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor_sp) +{ + bool ret_val = false; + + if (!implementor_sp) + return ret_val; + + void* implementor = implementor_sp->GetObject(); + + if (!implementor) + return ret_val; + + if (!g_swig_mighthavechildren_provider) + return ret_val; + + { + Locker py_lock(this); + ret_val = g_swig_mighthavechildren_provider (implementor); + } + + return ret_val; +} + +bool ScriptInterpreterPython::LoadScriptingModule (const char* pathname, bool can_reload, bool init_lldb_globals, @@ -2566,6 +2592,7 @@ ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback python_swig_ini g_swig_get_index_child = LLDBSwigPython_GetIndexOfChildWithName; g_swig_cast_to_sbvalue = LLDBSWIGPython_CastPyObjectToSBValue; g_swig_update_provider = LLDBSwigPython_UpdateSynthProviderInstance; + g_swig_mighthavechildren_provider = LLDBSwigPython_MightHaveChildrenSynthProviderInstance; g_swig_call_command = LLDBSwigPythonCallCommand; g_swig_call_module_init = LLDBSwigPythonCallModuleInit; g_swig_create_os_plugin = LLDBSWIGPythonCreateOSPlugin; |