<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 llvm-svn: 166495
This commit is contained in:
@@ -418,12 +418,76 @@ 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
|
||||
*/
|
||||
// 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 @@ LLDBSwigPython_CalculateNumChildren
|
||||
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 @@ LLDBSwigPython_UpdateSynthProviderInstance
|
||||
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*
|
||||
|
||||
Reference in New Issue
Block a user