<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
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@166495 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/scripts/Python/python-wrapper.swig b/scripts/Python/python-wrapper.swig
index a3aeefb..199cc63 100644
--- a/scripts/Python/python-wrapper.swig
+++ b/scripts/Python/python-wrapper.swig
@@ -418,12 +418,76 @@
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
-*/
+// wrapper that calls an optional instance member of an object taking no arguments
+static PyObject*
+LLDBSwigPython_CallOptionalMember
+(
+ 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;
+ }
+
+ PyObject* pmeth = PyObject_GetAttrString(self, callee_name);
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ if (pmeth == NULL || pmeth == Py_None)
+ {
+ if (was_found)
+ *was_found = false;
+ Py_XDECREF(pmeth);
+ Py_XINCREF(ret_if_not_found);
+ return ret_if_not_found;
+ }
+
+ 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 py_return;
+}
SWIGEXPORT uint32_t
LLDBSwigPython_CalculateNumChildren
@@ -431,33 +495,27 @@
PyObject *implementor
)
{
+ uint32_t ret_val = UINT32_MAX;
static char callee_name[] = "num_children";
- if (implementor == NULL || implementor == Py_None)
- return 0;
- PyObject* py_return = PyObject_CallMethod(implementor, callee_name, NULL);
- if (PyErr_Occurred())
- {
- PyErr_Print();
- PyErr_Clear();
- }
+ PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, NULL);
- if (py_return == NULL || py_return == Py_None)
- {
- Py_XDECREF(py_return);
- return UINT32_MAX;
- }
- long retval = PyInt_AsLong(py_return);
- Py_DECREF(py_return);
- if (retval >= 0)
- return (uint32_t)retval;
+ 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 0;
+
+ 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;
+ PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name);
- // 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();
- }
-
- if (pmeth == NULL || pmeth == Py_None)
- {
- Py_XDECREF(pmeth);
- return ret_val;
- }
-
- if (PyCallable_Check(pmeth) == 0)
- {
- if (PyErr_Occurred())
- {
- PyErr_Clear();
- }
-
- Py_XDECREF(pmeth);
- return ret_val;
- }
-
- if (PyErr_Occurred())
- {
- PyErr_Clear();
- }
-
- Py_XDECREF(pmeth);
-
- // 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 bool
+LLDBSwigPython_MightHaveChildrenSynthProviderInstance
+(
+ PyObject *implementor
+)
+{
+ bool ret_val = false;
+
+ static char callee_name[] = "has_children";
+
+ PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, Py_True);
+
+ if (py_return == Py_True)
+ ret_val = true;
+
+ Py_XDECREF(py_return);
+
+ return ret_val;
}
SWIGEXPORT void*