brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.7 KiB · 072e688 Raw
737 lines · plain
1/* Typemap definitions, to allow SWIG to properly handle 'char**' data types.2 3NOTE: If there's logic to free memory in a %typemap(freearg), it will also be4run if you call SWIG_fail on an error path. Don't manually free() an argument5AND call SWIG_fail at the same time, because it will result in a double free.6 7*/8 9%typemap(in) char ** {10  /* Check if is a list  */11  if (PythonList::Check($input)) {12    PythonList list(PyRefType::Borrowed, $input);13    int size = list.GetSize();14    int i = 0;15    $1 = (char **)malloc((size + 1) * sizeof(char *));16    for (i = 0; i < size; i++) {17      PythonString py_str = list.GetItemAtIndex(i).AsType<PythonString>();18      if (!py_str.IsAllocated()) {19        PyErr_SetString(PyExc_TypeError, "list must contain strings");20        SWIG_fail;21      }22 23      $1[i] = const_cast<char *>(py_str.GetString().data());24    }25    $1[i] = 0;26  } else if ($input == Py_None) {27    $1 = NULL;28  } else {29    PyErr_SetString(PyExc_TypeError, "not a list");30    SWIG_fail;31  }32}33 34%typemap(typecheck) char ** {35  /* Check if is a list  */36  $1 = 1;37  if (PythonList::Check($input)) {38    PythonList list(PyRefType::Borrowed, $input);39    int size = list.GetSize();40    int i = 0;41    for (i = 0; i < size; i++) {42      PythonString s = list.GetItemAtIndex(i).AsType<PythonString>();43      if (!s.IsAllocated()) {44        $1 = 0;45      }46    }47  } else {48    $1 = (($input == Py_None) ? 1 : 0);49  }50}51 52%typemap(freearg) char** {53  free((char *) $1);54}55 56%typecheck(SWIG_TYPECHECK_POINTER) lldb::ScriptObjectPtr {57  PythonObject obj(PyRefType::Borrowed, $input);58  if (!obj.IsValid()) {59    PyErr_Clear();60    $1 = 0;61  } else {62    $1 = 1;63  }64}65 66%typemap(in) lldb::ScriptObjectPtr {67  if ($input == Py_None) {68    $1 = nullptr;69  } else {70    PythonObject obj(PyRefType::Borrowed, $input);71    if (!obj.IsValid()) {72      PyErr_SetString(PyExc_TypeError, "Script object is not valid");73      SWIG_fail;74    }75 76    auto lldb_module = PythonModule::Import("lldb");77    if (!lldb_module) {78      std::string err_msg = llvm::toString(lldb_module.takeError());79      PyErr_SetString(PyExc_TypeError, err_msg.c_str());80      SWIG_fail;81    }82 83    auto sb_structured_data_class = lldb_module.get().Get("SBStructuredData");84    if (!sb_structured_data_class) {85      std::string err_msg = llvm::toString(sb_structured_data_class.takeError());86      PyErr_SetString(PyExc_TypeError, err_msg.c_str());87      SWIG_fail;88    }89 90    if (obj.IsInstance(sb_structured_data_class.get())) {91      $1 = obj.get();92    } else {93      auto type = obj.GetType();94      if (!type) {95        std::string err_msg = llvm::toString(type.takeError());96        PyErr_SetString(PyExc_TypeError, err_msg.c_str());97        SWIG_fail;98      }99 100      auto type_name = As<std::string>(type.get().GetAttribute("__name__"));101      if (!type_name) {102        std::string err_msg = llvm::toString(type_name.takeError());103        PyErr_SetString(PyExc_TypeError, err_msg.c_str());104        SWIG_fail;105      }106 107      if (llvm::StringRef(type_name.get()).starts_with("SB")) {108        std::string error_msg = "Input type is invalid: " + type_name.get();109        PyErr_SetString(PyExc_TypeError, error_msg.c_str());110        SWIG_fail;111      } else {112        $1 = obj.get();113      }114    }115  }116}117 118%typemap(out) lldb::ScriptObjectPtr {119  $result = (PyObject*) $1;120  if (!$result)121    $result = Py_None;122  Py_INCREF($result);123}124 125%typemap(out) lldb::SBScriptObject {126  $result = nullptr;127  if (const void* impl = $1.GetPointer())128    $result = (PyObject*) impl;129  if (!$result) {130    $result = Py_None;131    Py_INCREF(Py_None);132  } else {133    Py_INCREF($result);134  }135}136 137%typemap(out) char** {138  int len;139  int i;140  len = 0;141  while ($1[len])142    len++;143  PythonList list(len);144  for (i = 0; i < len; i++)145    list.SetItemAtIndex(i, PythonString($1[i]));146  $result = list.release();147}148 149%typemap(in) lldb::tid_t {150  PythonObject obj = Retain<PythonObject>($input);151  lldb::tid_t value = unwrapOrSetPythonException(As<unsigned long long>(obj));152  if (PyErr_Occurred())153    SWIG_fail;154  $1 = value;155}156 157%typemap(in) lldb::StateType {158  PythonObject obj = Retain<PythonObject>($input);159  unsigned long long state_type_value =160      unwrapOrSetPythonException(As<unsigned long long>(obj));161  if (PyErr_Occurred())162    SWIG_fail;163  if (state_type_value > lldb::StateType::kLastStateType) {164    PyErr_SetString(PyExc_ValueError, "Not a valid StateType value");165    SWIG_fail;166  }167  $1 = static_cast<lldb::StateType>(state_type_value);168}169 170/* Typemap definitions to allow SWIG to properly handle char buffer. */171 172// typemap for a char buffer173%typemap(in) (char *dst, size_t dst_len) {174  if (!PyLong_Check($input)) {175    PyErr_SetString(PyExc_ValueError, "Expecting an integer");176    SWIG_fail;177  }178  $2 = PyLong_AsLong($input);179  if ($2 <= 0) {180    PyErr_SetString(PyExc_ValueError, "Positive integer expected");181    SWIG_fail;182  }183  $1 = (char *)malloc($2);184}185// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated186// as char data instead of byte data.187%typemap(in) (void *char_buf, size_t size) = (char *dst, size_t dst_len);188 189// Return the char buffer.  Discarding any previous return result190%typemap(argout) (char *dst, size_t dst_len) {191  Py_XDECREF($result); /* Blow away any previous result */192  if (result == 0) {193    PythonString string("");194    $result = string.release();195    Py_INCREF($result);196  } else {197    llvm::StringRef ref(static_cast<const char *>($1), result);198    PythonString string(ref);199    $result = string.release();200  }201  free($1);202}203// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated204// as char data instead of byte data.205%typemap(argout) (void *char_buf, size_t size) = (char *dst, size_t dst_len);206 207 208// typemap for handling an snprintf-like API like SBThread::GetStopDescription.209%typemap(in) (char *dst_or_null, size_t dst_len) {210  if (!PyLong_Check($input)) {211    PyErr_SetString(PyExc_ValueError, "Expecting an integer");212    SWIG_fail;213  }214  $2 = PyLong_AsLong($input);215  if ($2 <= 0) {216    PyErr_SetString(PyExc_ValueError, "Positive integer expected");217    SWIG_fail;218  }219  $1 = (char *)malloc($2);220}221 222// Disable default type checking for this method to avoid SWIG dispatch issues.223// 224// Problem: SBThread::GetStopDescription has two overloads:225//   1. GetStopDescription(char* dst_or_null, size_t dst_len) 226//   2. GetStopDescription(lldb::SBStream& stream)227//228// SWIG generates a dispatch function to select the correct overload based on argument types.229// see https://www.swig.org/Doc4.0/SWIGDocumentation.html#Typemaps_overloading.230// However, this dispatcher doesn't consider typemaps that transform function signatures.231//232// In Python, our typemap converts GetStopDescription(char*, size_t) to GetStopDescription(int).233// The dispatcher still checks against the original (char*, size_t) signature instead of 234// the transformed (int) signature, causing type matching to fail.235// This only affects SBThread::GetStopDescription since the type check also matches 236// the argument name, which is unique to this function.237%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) (char *dst_or_null, size_t dst_len) ""238 239%typemap(argout) (char *dst_or_null, size_t dst_len) {240  Py_XDECREF($result); /* Blow away any previous result */241  llvm::StringRef ref($1);242  PythonString string(ref);243  $result = string.release();244  free($1);245}246 247 248// For lldb::SBFileSpec::GetPath249%typemap(in) (char *dst_path, size_t dst_len) = (char *dst_or_null, size_t dst_len);250%typemap(argout) (char *dst_path, size_t dst_len) = (char *dst_or_null, size_t dst_len);251 252 253// typemap for an outgoing buffer254// See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len).255// Ditto for SBProcess::PutSTDIN(const char *src, size_t src_len).256%typemap(in) (const char *cstr, uint32_t cstr_len),257             (const char *src, size_t src_len) {258  if (PythonString::Check($input)) {259    PythonString str(PyRefType::Borrowed, $input);260    $1 = (char *)str.GetString().data();261    $2 = str.GetSize();262  } else if (PythonByteArray::Check($input)) {263    PythonByteArray bytearray(PyRefType::Borrowed, $input);264    $1 = (char *)bytearray.GetBytes().data();265    $2 = bytearray.GetSize();266  } else if (PythonBytes::Check($input)) {267    PythonBytes bytes(PyRefType::Borrowed, $input);268    $1 = (char *)bytes.GetBytes().data();269    $2 = bytes.GetSize();270  } else {271    PyErr_SetString(PyExc_ValueError, "Expecting a string");272    SWIG_fail;273  }274}275// For SBProcess::WriteMemory, SBTarget::GetInstructions and SBDebugger::DispatchInput.276%typemap(in) (const void *buf, size_t size),277             (const void *data, size_t data_len),278             (const void *buf, uint64_t size) {279  if (PythonString::Check($input)) {280    PythonString str(PyRefType::Borrowed, $input);281    $1 = (void *)str.GetString().data();282    $2 = str.GetSize();283  } else if (PythonByteArray::Check($input)) {284    PythonByteArray bytearray(PyRefType::Borrowed, $input);285    $1 = (void *)bytearray.GetBytes().data();286    $2 = bytearray.GetSize();287  } else if (PythonBytes::Check($input)) {288    PythonBytes bytes(PyRefType::Borrowed, $input);289    $1 = (void *)bytes.GetBytes().data();290    $2 = bytes.GetSize();291  } else {292    PyErr_SetString(PyExc_ValueError, "Expecting a buffer");293    SWIG_fail;294  }295}296 297// typemap for an incoming buffer298// See also SBProcess::ReadMemory.299%typemap(in) (void *buf, size_t size) {300  if (PyLong_Check($input)) {301    $2 = PyLong_AsLong($input);302  } else {303    PyErr_SetString(PyExc_ValueError, "Expecting an integer or long object");304    SWIG_fail;305  }306  if ($2 <= 0) {307    PyErr_SetString(PyExc_ValueError, "Positive integer expected");308    SWIG_fail;309  }310  $1 = (void *)malloc($2);311}312 313// Return the buffer.  Discarding any previous return result314// See also SBProcess::ReadMemory.315%typemap(argout) (void *buf, size_t size) {316  Py_XDECREF($result); /* Blow away any previous result */317  if (result == 0) {318    $result = Py_None;319    Py_INCREF($result);320  } else {321    PythonBytes bytes(static_cast<const uint8_t *>($1), result);322    $result = bytes.release();323  }324  free($1);325}326 327%{328namespace {329template <class T>330T PyLongAsT(PyObject *obj) {331  static_assert(true, "unsupported type");332}333 334template <> uint64_t PyLongAsT<uint64_t>(PyObject *obj) {335  return static_cast<uint64_t>(PyLong_AsUnsignedLongLong(obj));336}337 338template <> uint32_t PyLongAsT<uint32_t>(PyObject *obj) {339  return static_cast<uint32_t>(PyLong_AsUnsignedLong(obj));340}341 342template <> int64_t PyLongAsT<int64_t>(PyObject *obj) {343  return static_cast<int64_t>(PyLong_AsLongLong(obj));344}345 346template <> int32_t PyLongAsT<int32_t>(PyObject *obj) {347  return static_cast<int32_t>(PyLong_AsLong(obj));348}349 350template <class T> bool SetNumberFromPyObject(T &number, PyObject *obj) {351  if (PyLong_Check(obj))352    number = PyLongAsT<T>(obj);353  else354    return false;355 356  return true;357}358 359template <> bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {360  if (PyFloat_Check(obj)) {361    number = PyFloat_AsDouble(obj);362    return true;363  }364 365  return false;366}367 368} // namespace369%}370 371// these typemaps allow Python users to pass list objects372// and have them turn into C++ arrays (this is useful, for instance373// when creating SBData objects from lists of numbers)374%typemap(in) (uint64_t* array, size_t array_len),375             (uint32_t* array, size_t array_len),376             (int64_t* array, size_t array_len),377             (int32_t* array, size_t array_len),378             (double* array, size_t array_len) {379  /* Check if is a list  */380  if (PyList_Check($input)) {381    int size = PyList_Size($input);382    int i = 0;383    $2 = size;384    $1 = ($1_type)malloc(size * sizeof($*1_type));385    for (i = 0; i < size; i++) {386      PyObject *o = PyList_GetItem($input, i);387      if (!SetNumberFromPyObject($1[i], o)) {388        PyErr_SetString(PyExc_TypeError, "list must contain numbers");389        SWIG_fail;390      }391 392      if (PyErr_Occurred()) {393        SWIG_fail;394      }395    }396  } else if ($input == Py_None) {397    $1 = NULL;398    $2 = 0;399  } else {400    PyErr_SetString(PyExc_TypeError, "not a list");401    SWIG_fail;402  }403}404 405%typemap(freearg) (uint64_t* array, size_t array_len),406                  (uint32_t* array, size_t array_len),407                  (int64_t* array, size_t array_len),408                  (int32_t* array, size_t array_len),409                  (double* array, size_t array_len) {410  free($1);411}412 413// these typemaps wrap SBModule::GetVersion() from requiring a memory buffer414// to the more Pythonic style where a list is returned and no previous allocation415// is necessary - this will break if more than 50 versions are ever returned416%typemap(typecheck) (uint32_t *versions, uint32_t num_versions) {417  $1 = ($input == Py_None ? 1 : 0);418}419 420%typemap(in, numinputs=0) (uint32_t *versions) {421  $1 = (uint32_t *)malloc(sizeof(uint32_t) * 50);422}423 424%typemap(in, numinputs=0) (uint32_t num_versions) {425  $1 = 50;426}427 428%typemap(argout) (uint32_t *versions, uint32_t num_versions) {429  uint32_t count = result;430  if (count >= $2)431    count = $2;432  PyObject *list = PyList_New(count);433  for (uint32_t j = 0; j < count; j++) {434    PyObject *item = PyLong_FromLong($1[j]);435    int ok = PyList_SetItem(list, j, item);436    if (ok != 0) {437      $result = Py_None;438      break;439    }440  }441  $result = list;442}443 444%typemap(freearg) (uint32_t *versions) {445  free($1);446}447 448// For Log::LogOutputCallback449%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {450  if (!($input == Py_None ||451        PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {452    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");453    SWIG_fail;454  }455 456  // FIXME (filcab): We can't currently check if our callback is already457  // LLDBSwigPythonCallPythonLogOutputCallback (to DECREF the previous458  // baton) nor can we just remove all traces of a callback, if we want to459  // revert to a file logging mechanism.460 461  // Don't lose the callback reference462  Py_INCREF($input);463  $1 = LLDBSwigPythonCallPythonLogOutputCallback;464  $2 = $input;465}466 467%typemap(typecheck) (lldb::LogOutputCallback log_callback, void *baton) {468  $1 = $input == Py_None;469  $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));470}471 472// For lldb::SBDebuggerDestroyCallback473%typemap(in) (lldb::SBDebuggerDestroyCallback destroy_callback, void *baton) {474  if (!($input == Py_None ||475        PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {476    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");477    SWIG_fail;478  }479 480  // FIXME (filcab): We can't currently check if our callback is already481  // LLDBSwigPythonCallPythonSBDebuggerTerminateCallback (to DECREF the previous482  // baton) nor can we just remove all traces of a callback, if we want to483  // revert to a file logging mechanism.484 485  // Don't lose the callback reference486  Py_INCREF($input);487  $1 = LLDBSwigPythonCallPythonSBDebuggerTerminateCallback;488  $2 = $input;489}490 491%typemap(typecheck) (lldb::SBDebuggerDestroyCallback destroy_callback, void *baton) {492  $1 = $input == Py_None;493  $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));494}495 496// For lldb::SBCommandPrintCallback497%typemap(in) (lldb::SBCommandPrintCallback callback, void *baton) {498  if (!($input == Py_None ||499        PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {500    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");501    SWIG_fail;502  }503 504  // Don't lose the callback reference.505  Py_INCREF($input);506  $1 = LLDBSwigPythonCallPythonCommandPrintCallback;507  $2 = $input;508}509 510%typemap(typecheck) (lldb::SBCommandPrintCallback callback, void *baton) {511  $1 = $input == Py_None;512  $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));513}514 515%typemap(in) (lldb::CommandOverrideCallback callback, void *baton) {516  if (!($input == Py_None ||517        PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {518    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");519    SWIG_fail;520  }521 522  // Don't lose the callback reference.523  Py_INCREF($input);524  $1 = LLDBSwigPythonCallPythonSBCommandInterpreterSetCommandOverrideCallback;525  $2 = $input;526}527%typemap(typecheck) (lldb::CommandOverrideCallback callback, void *baton) {528  $1 = $input == Py_None;529  $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));530}531 532%typemap(in) lldb::FileSP {533  PythonFile py_file(PyRefType::Borrowed, $input);534  if (!py_file) {535    PyErr_SetString(PyExc_TypeError, "not a file");536    SWIG_fail;537  }538  auto sp = unwrapOrSetPythonException(py_file.ConvertToFile());539  if (!sp)540    SWIG_fail;541  $1 = sp;542}543 544%typemap(in) lldb::FileSP FORCE_IO_METHODS {545  PythonFile py_file(PyRefType::Borrowed, $input);546  if (!py_file) {547    PyErr_SetString(PyExc_TypeError, "not a file");548    SWIG_fail;549  }550  auto sp = unwrapOrSetPythonException(551      py_file.ConvertToFileForcingUseOfScriptingIOMethods());552  if (!sp)553    SWIG_fail;554  $1 = sp;555}556 557%typemap(in) lldb::FileSP BORROWED {558  PythonFile py_file(PyRefType::Borrowed, $input);559  if (!py_file) {560    PyErr_SetString(PyExc_TypeError, "not a file");561    SWIG_fail;562  }563  auto sp =564      unwrapOrSetPythonException(py_file.ConvertToFile(/*borrowed=*/true));565  if (!sp)566    SWIG_fail;567  $1 = sp;568}569 570%typemap(in) lldb::FileSP BORROWED_FORCE_IO_METHODS {571  PythonFile py_file(PyRefType::Borrowed, $input);572  if (!py_file) {573    PyErr_SetString(PyExc_TypeError, "not a file");574    SWIG_fail;575  }576  auto sp = unwrapOrSetPythonException(577      py_file.ConvertToFileForcingUseOfScriptingIOMethods(/*borrowed=*/true));578  if (!sp)579    SWIG_fail;580  $1 = sp;581}582 583%typecheck(SWIG_TYPECHECK_POINTER) lldb::FileSP {584  if (PythonFile::Check($input)) {585    $1 = 1;586  } else {587    PyErr_Clear();588    $1 = 0;589  }590}591 592%typemap(out) lldb::FileSP {593  $result = nullptr;594  const lldb::FileSP &sp = $1;595  if (sp) {596    PythonFile pyfile = unwrapOrSetPythonException(PythonFile::FromFile(*sp));597    if (!pyfile.IsValid())598      SWIG_fail;599    $result = pyfile.release();600  }601  if (!$result) {602    $result = Py_None;603    Py_INCREF(Py_None);604  }605}606 607%typemap(in) (const char* string, int len) {608  if ($input == Py_None) {609    $1 = NULL;610    $2 = 0;611  } else if (PythonString::Check($input)) {612    PythonString py_str(PyRefType::Borrowed, $input);613    llvm::StringRef str = py_str.GetString();614    $1 = const_cast<char *>(str.data());615    $2 = str.size();616    // In Python 2, if $input is a PyUnicode object then this617    // will trigger a Unicode -> String conversion, in which618    // case the `PythonString` will now own the PyString.  Thus619    // if it goes out of scope, the data will be deleted.  The620    // only way to avoid this is to leak the Python object in621    // that case.  Note that if there was no conversion, then622    // releasing the string will not leak anything, since we623    // created this as a borrowed reference.624    py_str.release();625  } else {626    PyErr_SetString(PyExc_TypeError, "not a string-like object");627    SWIG_fail;628  }629}630 631 632// Typemap for SBFile::Write.633%typemap(in) (const uint8_t *buf, size_t num_bytes) {634  if (PythonByteArray::Check($input)) {635    PythonByteArray bytearray(PyRefType::Borrowed, $input);636    $1 = (uint8_t *)bytearray.GetBytes().data();637    $2 = bytearray.GetSize();638  } else if (PythonBytes::Check($input)) {639    PythonBytes bytes(PyRefType::Borrowed, $input);640    $1 = (uint8_t *)bytes.GetBytes().data();641    $2 = bytes.GetSize();642  } else {643    PyErr_SetString(PyExc_ValueError, "Expecting a bytes or bytearray object");644    SWIG_fail;645  }646}647 648// Typemap for SBFile::Read.649%typemap(in) (uint8_t *buf, size_t num_bytes) {650  if (PythonByteArray::Check($input)) {651    PythonByteArray bytearray(PyRefType::Borrowed, $input);652    $1 = (uint8_t *)bytearray.GetBytes().data();653    $2 = bytearray.GetSize();654  } else {655    PyErr_SetString(PyExc_ValueError, "Expecting a bytearray");656    SWIG_fail;657  }658}659 660%typemap(in) (const char **symbol_name, uint32_t num_names) {661  using namespace lldb_private;662  /* Check if is a list  */663  if (PythonList::Check($input)) {664    PythonList list(PyRefType::Borrowed, $input);665    $2 = list.GetSize();666    int i = 0;667    $1 = (char**)malloc(($2+1)*sizeof(char*));668    for (i = 0; i < $2; i++) {669      PythonString py_str = list.GetItemAtIndex(i).AsType<PythonString>();670      if (!py_str.IsAllocated()) {671        PyErr_SetString(PyExc_TypeError,"list must contain strings and blubby");672        free($1);673        return nullptr;674      }675 676      $1[i] = const_cast<char*>(py_str.GetString().data());677    }678    $1[i] = 0;679  } else if ($input == Py_None) {680    $1 =  NULL;681  } else {682    PyErr_SetString(PyExc_TypeError,"not a list");683    return NULL;684  }685}686 687// For lldb::SBPlatformLocateModuleCallback688%typemap(in) (lldb::SBPlatformLocateModuleCallback callback,689              void *callback_baton) {690  if (!($input == Py_None ||691        PyCallable_Check(reinterpret_cast<PyObject *>($input)))) {692    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");693    SWIG_fail;694  }695 696  if ($input == Py_None) {697    $1 = nullptr;698    $2 = nullptr;699  } else {700    PythonCallable callable = Retain<PythonCallable>($input);701    if (!callable.IsValid()) {702      PyErr_SetString(PyExc_TypeError, "Need a valid callable object");703      SWIG_fail;704    }705 706    llvm::Expected<PythonCallable::ArgInfo> arg_info = callable.GetArgInfo();707    if (!arg_info) {708      PyErr_SetString(PyExc_TypeError,709                      ("Could not get arguments: " +710                          llvm::toString(arg_info.takeError())).c_str());711      SWIG_fail;712    }713 714    if (arg_info.get().max_positional_args != 3) {715      PyErr_SetString(PyExc_TypeError, "Expected 3 argument callable object");716      SWIG_fail;717    }718 719    // NOTE: When this is called multiple times, this will leak the Python720    // callable object as other callbacks, because this does not call Py_DECREF721    // the object. But it should be almost zero impact since this method is722    // expected to be called only once.723 724    // Don't lose the callback reference725    Py_INCREF($input);726 727    $1 = LLDBSwigPythonCallLocateModuleCallback;728    $2 = $input;729  }730}731 732%typemap(typecheck) (lldb::SBPlatformLocateModuleCallback callback,733                     void *callback_baton) {734  $1 = $input == Py_None;735  $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject *>($input));736}737