summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Core/CXXFormatterFunctions.h18
-rw-r--r--lldb/include/lldb/Core/FormatClasses.h40
-rw-r--r--lldb/include/lldb/Core/ValueObjectSyntheticFilter.h2
-rw-r--r--lldb/include/lldb/Interpreter/ScriptInterpreter.h20
-rw-r--r--lldb/include/lldb/Interpreter/ScriptInterpreterPython.h3
-rw-r--r--lldb/scripts/Python/python-wrapper.swig162
-rw-r--r--lldb/source/Core/CXXFormatterFunctions.cpp36
-rw-r--r--lldb/source/Core/ValueObjectSyntheticFilter.cpp15
-rw-r--r--lldb/source/Interpreter/ScriptInterpreterPython.cpp37
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;
OpenPOWER on IntegriCloud