[Lldb-commits] [lldb] r166495 - in /lldb/trunk: include/lldb/Core/CXXFormatterFunctions.h include/lldb/Core/FormatClasses.h include/lldb/Core/ValueObjectSyntheticFilter.h include/lldb/Interpreter/ScriptInterpreter.h include/lldb/Interpreter/ScriptInterpreterPython.h scripts/Python/python-wrapper.swig source/Core/CXXFormatterFunctions.cpp source/Core/ValueObjectSyntheticFilter.cpp source/Interpreter/ScriptInterpreterPython.cpp
Enrico Granata
egranata at apple.com
Tue Oct 23 12:54:09 PDT 2012
Author: enrico
Date: Tue Oct 23 14:54:09 2012
New Revision: 166495
URL: http://llvm.org/viewvc/llvm-project?rev=166495&view=rev
Log:
<rdar://problem/12523238> Commit 1 of 3
This commit enables the new HasChildren() feature for synthetic children providers
Namely, it hooks up the required bits and pieces so that individual synthetic children providers can implement a new (optional) has_children call
Default implementations have been provided where necessary so that any existing providers continue to work and behave correctly
Next steps are:
2) writing smart implementations of has_children for our providers whenever possible
3) make a test case
Modified:
lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h
lldb/trunk/include/lldb/Core/FormatClasses.h
lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h
lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
lldb/trunk/scripts/Python/python-wrapper.swig
lldb/trunk/source/Core/CXXFormatterFunctions.cpp
lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
Modified: lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h?rev=166495&r1=166494&r2=166495&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h (original)
+++ lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h Tue Oct 23 14:54:09 2012
@@ -107,6 +107,9 @@
virtual bool
Update();
+ virtual bool
+ MightHaveChildren ();
+
virtual uint32_t
GetIndexOfChildWithName (const ConstString &name);
@@ -135,6 +138,9 @@
virtual bool
Update();
+ virtual bool
+ MightHaveChildren ();
+
virtual uint32_t
GetIndexOfChildWithName (const ConstString &name);
@@ -163,6 +169,9 @@
virtual bool
Update();
+ virtual bool
+ MightHaveChildren ();
+
virtual uint32_t
GetIndexOfChildWithName (const ConstString &name);
@@ -205,6 +214,9 @@
virtual bool
Update();
+ virtual bool
+ MightHaveChildren ();
+
virtual uint32_t
GetIndexOfChildWithName (const ConstString &name);
@@ -258,6 +270,9 @@
virtual bool
Update();
+ virtual bool
+ MightHaveChildren ();
+
virtual uint32_t
GetIndexOfChildWithName (const ConstString &name);
@@ -286,6 +301,9 @@
virtual bool
Update();
+ virtual bool
+ MightHaveChildren ();
+
virtual uint32_t
GetIndexOfChildWithName (const ConstString &name);
Modified: lldb/trunk/include/lldb/Core/FormatClasses.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatClasses.h?rev=166495&r1=166494&r2=166495&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatClasses.h (original)
+++ lldb/trunk/include/lldb/Core/FormatClasses.h Tue Oct 23 14:54:09 2012
@@ -228,17 +228,17 @@
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 @@
// 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 @@
virtual bool
Update() { return false; }
+ virtual bool
+ MightHaveChildren ()
+ {
+ return filter->GetCount() > 0;
+ }
+
virtual uint32_t
GetIndexOfChildWithName (const ConstString &name)
{
@@ -726,7 +739,16 @@
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 @@
return filter->GetCount();
}
+ virtual bool
+ MightHaveChildren ()
+ {
+ return filter->GetCount() > 0;
+ }
+
virtual lldb::ValueObjectSP
GetChildAtIndex (uint32_t idx)
{
Modified: lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h?rev=166495&r1=166494&r2=166495&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h Tue Oct 23 14:54:09 2012
@@ -141,6 +141,8 @@
ConstString m_parent_type_name;
+ LazyBool m_might_have_children;
+
private:
friend class ValueObject;
ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter);
Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=166495&r1=166494&r2=166495&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Tue Oct 23 14:54:09 2012
@@ -87,11 +87,13 @@
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 @@
{
return false;
}
-
+
+ virtual bool
+ MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor)
+ {
+ return true;
+ }
+
virtual bool
RunScriptBasedCommand (const char* impl_function,
const char* args,
Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=166495&r1=166494&r2=166495&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Tue Oct 23 14:54:09 2012
@@ -109,6 +109,9 @@
UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor);
virtual bool
+ MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor);
+
+ virtual bool
RunScriptBasedCommand(const char* impl_function,
const char* args,
ScriptedCommandSynchronicity synchronicity,
Modified: lldb/trunk/scripts/Python/python-wrapper.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-wrapper.swig?rev=166495&r1=166494&r2=166495&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-wrapper.swig (original)
+++ lldb/trunk/scripts/Python/python-wrapper.swig Tue Oct 23 14:54:09 2012
@@ -418,46 +418,104 @@
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 @@
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*
Modified: lldb/trunk/source/Core/CXXFormatterFunctions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/CXXFormatterFunctions.cpp?rev=166495&r1=166494&r2=166495&view=diff
==============================================================================
--- lldb/trunk/source/Core/CXXFormatterFunctions.cpp (original)
+++ lldb/trunk/source/Core/CXXFormatterFunctions.cpp Tue Oct 23 14:54:09 2012
@@ -773,6 +773,12 @@
return false;
}
+bool
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren ()
+{
+ return CalculateNumChildren() > 0;
+}
+
static uint32_t
ExtractIndexFromString (const char* item_name)
{
@@ -882,6 +888,12 @@
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 @@
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 @@
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 @@
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 @@
return false;
}
+bool
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::MightHaveChildren ()
+{
+ return CalculateNumChildren() > 0;
+}
+
lldb::ValueObjectSP
lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
{
Modified: lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp?rev=166495&r1=166494&r2=166495&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp Tue Oct 23 14:54:09 2012
@@ -45,6 +45,12 @@
}
bool
+ MightHaveChildren ()
+ {
+ return true;
+ }
+
+ bool
Update()
{
return false;
@@ -58,7 +64,8 @@
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 @@
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 @@
// 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();
Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=166495&r1=166494&r2=166495&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Tue Oct 23 14:54:09 2012
@@ -53,6 +53,7 @@
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 @@
);
-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 @@
}
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 @@
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;
More information about the lldb-commits
mailing list