xref: /llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h (revision b6960e2a631df38c076cee2845978b0606cea066)
11f6a57c1SMed Ismail Bennani //===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===//
21f6a57c1SMed Ismail Bennani //
31f6a57c1SMed Ismail Bennani // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41f6a57c1SMed Ismail Bennani // See https://llvm.org/LICENSE.txt for license information.
51f6a57c1SMed Ismail Bennani // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61f6a57c1SMed Ismail Bennani //
71f6a57c1SMed Ismail Bennani //===----------------------------------------------------------------------===//
81f6a57c1SMed Ismail Bennani 
91f6a57c1SMed Ismail Bennani #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
101f6a57c1SMed Ismail Bennani #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
111f6a57c1SMed Ismail Bennani 
12c1d1a752SMed Ismail Bennani #include <optional>
13c1d1a752SMed Ismail Bennani #include <string>
141f6a57c1SMed Ismail Bennani 
15e8504cb0SMed Ismail Bennani #include "lldb/Host/Config.h"
16e8504cb0SMed Ismail Bennani 
17c1d1a752SMed Ismail Bennani #if LLDB_ENABLE_PYTHON
189a14adeaSPavel Labath 
19e8504cb0SMed Ismail Bennani // LLDB Python header must be included first
20e8504cb0SMed Ismail Bennani #include "lldb-python.h"
21e8504cb0SMed Ismail Bennani 
22c154f397SPavel Labath #include "Plugins/ScriptInterpreter/Python/PythonDataObjects.h"
231f6a57c1SMed Ismail Bennani #include "lldb/lldb-forward.h"
241f6a57c1SMed Ismail Bennani #include "lldb/lldb-types.h"
259a14adeaSPavel Labath #include "llvm/Support/Error.h"
261f6a57c1SMed Ismail Bennani 
277e01924eSMed Ismail Bennani namespace lldb {
287e01924eSMed Ismail Bennani class SBEvent;
297e01924eSMed Ismail Bennani class SBCommandReturnObject;
307e01924eSMed Ismail Bennani class SBValue;
317e01924eSMed Ismail Bennani class SBStream;
327e01924eSMed Ismail Bennani class SBStructuredData;
33c4fa6fafSKazuki Sakamoto class SBFileSpec;
34c4fa6fafSKazuki Sakamoto class SBModuleSpec;
35a69ecb24Sjimingham class SBStringList;
367e01924eSMed Ismail Bennani } // namespace lldb
377e01924eSMed Ismail Bennani 
381f6a57c1SMed Ismail Bennani namespace lldb_private {
397e01924eSMed Ismail Bennani namespace python {
407e01924eSMed Ismail Bennani 
417e01924eSMed Ismail Bennani typedef struct swig_type_info swig_type_info;
427e01924eSMed Ismail Bennani 
437e01924eSMed Ismail Bennani python::PythonObject ToSWIGHelper(void *obj, swig_type_info *info);
447e01924eSMed Ismail Bennani 
457e01924eSMed Ismail Bennani /// A class that automatically clears an SB object when it goes out of scope.
467e01924eSMed Ismail Bennani /// Use for cases where the SB object points to a temporary/unowned entity.
477e01924eSMed Ismail Bennani template <typename T> class ScopedPythonObject : PythonObject {
487e01924eSMed Ismail Bennani public:
497e01924eSMed Ismail Bennani   ScopedPythonObject(T *sb, swig_type_info *info)
507e01924eSMed Ismail Bennani       : PythonObject(ToSWIGHelper(sb, info)), m_sb(sb) {}
517e01924eSMed Ismail Bennani   ~ScopedPythonObject() {
527e01924eSMed Ismail Bennani     if (m_sb)
537e01924eSMed Ismail Bennani       *m_sb = T();
547e01924eSMed Ismail Bennani   }
557e01924eSMed Ismail Bennani   ScopedPythonObject(ScopedPythonObject &&rhs)
567e01924eSMed Ismail Bennani       : PythonObject(std::move(rhs)), m_sb(std::exchange(rhs.m_sb, nullptr)) {}
577e01924eSMed Ismail Bennani   ScopedPythonObject(const ScopedPythonObject &) = delete;
587e01924eSMed Ismail Bennani   ScopedPythonObject &operator=(const ScopedPythonObject &) = delete;
597e01924eSMed Ismail Bennani   ScopedPythonObject &operator=(ScopedPythonObject &&) = delete;
607e01924eSMed Ismail Bennani 
617e01924eSMed Ismail Bennani   const PythonObject &obj() const { return *this; }
627e01924eSMed Ismail Bennani 
637e01924eSMed Ismail Bennani private:
647e01924eSMed Ismail Bennani   T *m_sb;
657e01924eSMed Ismail Bennani };
667e01924eSMed Ismail Bennani 
6727b6a4e6SAlex Langford // TODO: We may want to support other languages in the future w/ SWIG (we
6827b6a4e6SAlex Langford // already support Lua right now, for example). We could create a generic
6927b6a4e6SAlex Langford // SWIGBridge class and have this one specialize it, something like this:
7027b6a4e6SAlex Langford //
7127b6a4e6SAlex Langford // <typename T>
7227b6a4e6SAlex Langford // class SWIGBridge {
7327b6a4e6SAlex Langford //   static T ToSWIGWrapper(...);
7427b6a4e6SAlex Langford // };
7527b6a4e6SAlex Langford //
7627b6a4e6SAlex Langford // class SWIGPythonBridge : public SWIGBridge<PythonObject> {
7727b6a4e6SAlex Langford //   template<> static PythonObject ToSWIGWrapper(...);
7827b6a4e6SAlex Langford // };
7927b6a4e6SAlex Langford //
8027b6a4e6SAlex Langford // And we should be able to more easily support things like Lua
8127b6a4e6SAlex Langford class SWIGBridge {
8227b6a4e6SAlex Langford public:
8327b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb);
8427b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp);
8527b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(lldb::TargetSP target_sp);
8627b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp);
87*b6960e2aSrchamala   static PythonObject ToSWIGWrapper(lldb::ModuleSP module_sp);
8827b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp);
8927b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp);
90f732157aSMed Ismail Bennani   static PythonObject ToSWIGWrapper(Status &&status);
9127b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(const StructuredDataImpl &data_impl);
9227b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp);
9327b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp);
9427b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp);
9527b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp);
9627b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp);
9727b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(lldb::TypeImplSP type_impl_sp);
9827b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp);
9927b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options);
10027b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx);
1019a9ec228SMed Ismail Bennani   static PythonObject ToSWIGWrapper(const Stream *stream);
1029a9ec228SMed Ismail Bennani   static PythonObject ToSWIGWrapper(std::shared_ptr<lldb::SBStream> stream_sb);
1039a9ec228SMed Ismail Bennani   static PythonObject ToSWIGWrapper(Event *event);
1047e01924eSMed Ismail Bennani 
10527b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp);
10627b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp);
10727b6a4e6SAlex Langford   static PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp);
108b9d4c94aSMed Ismail Bennani 
10927b6a4e6SAlex Langford   static PythonObject
11027b6a4e6SAlex Langford   ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb);
111c4fa6fafSKazuki Sakamoto   static PythonObject
112c4fa6fafSKazuki Sakamoto   ToSWIGWrapper(std::unique_ptr<lldb::SBFileSpec> file_spec_sb);
113c4fa6fafSKazuki Sakamoto   static PythonObject
114c4fa6fafSKazuki Sakamoto   ToSWIGWrapper(std::unique_ptr<lldb::SBModuleSpec> module_spec_sb);
1157e01924eSMed Ismail Bennani 
11627b6a4e6SAlex Langford   static python::ScopedPythonObject<lldb::SBCommandReturnObject>
1177e01924eSMed Ismail Bennani   ToSWIGWrapper(CommandReturnObject &cmd_retobj);
11827b6a4e6SAlex Langford   // These prototypes are the Pythonic implementations of the required
11927b6a4e6SAlex Langford   // callbacks. Although these are scripting-language specific, their definition
12027b6a4e6SAlex Langford   // depends on the public API.
1217e01924eSMed Ismail Bennani 
12227b6a4e6SAlex Langford   static llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction(
12327b6a4e6SAlex Langford       const char *python_function_name, const char *session_dictionary_name,
12427b6a4e6SAlex Langford       const lldb::StackFrameSP &sb_frame,
12527b6a4e6SAlex Langford       const lldb::BreakpointLocationSP &sb_bp_loc,
12627b6a4e6SAlex Langford       const lldb_private::StructuredDataImpl &args_impl);
12727b6a4e6SAlex Langford 
12827b6a4e6SAlex Langford   static bool LLDBSwigPythonWatchpointCallbackFunction(
12927b6a4e6SAlex Langford       const char *python_function_name, const char *session_dictionary_name,
13027b6a4e6SAlex Langford       const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp);
13127b6a4e6SAlex Langford 
13227b6a4e6SAlex Langford   static bool
13327b6a4e6SAlex Langford   LLDBSwigPythonFormatterCallbackFunction(const char *python_function_name,
13427b6a4e6SAlex Langford                                           const char *session_dictionary_name,
13527b6a4e6SAlex Langford                                           lldb::TypeImplSP type_impl_sp);
13627b6a4e6SAlex Langford 
13727b6a4e6SAlex Langford   static bool LLDBSwigPythonCallTypeScript(
13827b6a4e6SAlex Langford       const char *python_function_name, const void *session_dictionary,
13927b6a4e6SAlex Langford       const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper,
14027b6a4e6SAlex Langford       const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval);
14127b6a4e6SAlex Langford 
14227b6a4e6SAlex Langford   static python::PythonObject
14327b6a4e6SAlex Langford   LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name,
14427b6a4e6SAlex Langford                                         const char *session_dictionary_name,
14527b6a4e6SAlex Langford                                         const lldb::ValueObjectSP &valobj_sp);
14627b6a4e6SAlex Langford 
14727b6a4e6SAlex Langford   static python::PythonObject
14827b6a4e6SAlex Langford   LLDBSwigPythonCreateCommandObject(const char *python_class_name,
14927b6a4e6SAlex Langford                                     const char *session_dictionary_name,
15027b6a4e6SAlex Langford                                     lldb::DebuggerSP debugger_sp);
15127b6a4e6SAlex Langford 
15227b6a4e6SAlex Langford   static python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver(
15327b6a4e6SAlex Langford       const char *python_class_name, const char *session_dictionary_name,
15427b6a4e6SAlex Langford       const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp);
15527b6a4e6SAlex Langford 
15627b6a4e6SAlex Langford   static unsigned int
15727b6a4e6SAlex Langford   LLDBSwigPythonCallBreakpointResolver(void *implementor,
15827b6a4e6SAlex Langford                                        const char *method_name,
15927b6a4e6SAlex Langford                                        lldb_private::SymbolContext *sym_ctx);
16027b6a4e6SAlex Langford 
16127b6a4e6SAlex Langford   static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor,
16227b6a4e6SAlex Langford                                                     uint32_t max);
16327b6a4e6SAlex Langford 
16427b6a4e6SAlex Langford   static PyObject *LLDBSwigPython_GetChildAtIndex(PyObject *implementor,
16527b6a4e6SAlex Langford                                                   uint32_t idx);
16627b6a4e6SAlex Langford 
16727b6a4e6SAlex Langford   static int LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor,
16827b6a4e6SAlex Langford                                                     const char *child_name);
16927b6a4e6SAlex Langford 
17027b6a4e6SAlex Langford   static lldb::ValueObjectSP
17127b6a4e6SAlex Langford   LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data);
17227b6a4e6SAlex Langford 
17327b6a4e6SAlex Langford   static bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor);
17427b6a4e6SAlex Langford 
17527b6a4e6SAlex Langford   static bool
17627b6a4e6SAlex Langford   LLDBSwigPython_MightHaveChildrenSynthProviderInstance(PyObject *implementor);
17727b6a4e6SAlex Langford 
17827b6a4e6SAlex Langford   static PyObject *
17927b6a4e6SAlex Langford   LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor);
18027b6a4e6SAlex Langford 
18127b6a4e6SAlex Langford   static bool
18227b6a4e6SAlex Langford   LLDBSwigPythonCallCommand(const char *python_function_name,
18327b6a4e6SAlex Langford                             const char *session_dictionary_name,
18427b6a4e6SAlex Langford                             lldb::DebuggerSP debugger, const char *args,
18527b6a4e6SAlex Langford                             lldb_private::CommandReturnObject &cmd_retobj,
18627b6a4e6SAlex Langford                             lldb::ExecutionContextRefSP exe_ctx_ref_sp);
18727b6a4e6SAlex Langford 
18827b6a4e6SAlex Langford   static bool
18927b6a4e6SAlex Langford   LLDBSwigPythonCallCommandObject(PyObject *implementor,
19027b6a4e6SAlex Langford                                   lldb::DebuggerSP debugger, const char *args,
19127b6a4e6SAlex Langford                                   lldb_private::CommandReturnObject &cmd_retobj,
19227b6a4e6SAlex Langford                                   lldb::ExecutionContextRefSP exe_ctx_ref_sp);
193a69ecb24Sjimingham   static bool
194a69ecb24Sjimingham   LLDBSwigPythonCallParsedCommandObject(PyObject *implementor,
195a69ecb24Sjimingham                                   lldb::DebuggerSP debugger,
196a69ecb24Sjimingham                                   StructuredDataImpl &args_impl,
197a69ecb24Sjimingham                                   lldb_private::CommandReturnObject &cmd_retobj,
198a69ecb24Sjimingham                                   lldb::ExecutionContextRefSP exe_ctx_ref_sp);
19927b6a4e6SAlex Langford 
20077d131edSjimingham   static std::optional<std::string>
20177d131edSjimingham   LLDBSwigPythonGetRepeatCommandForScriptedCommand(PyObject *implementor,
20277d131edSjimingham                                                    std::string &command);
20377d131edSjimingham 
20404b443e7Sjimingham   static StructuredData::DictionarySP
20504b443e7Sjimingham   LLDBSwigPythonHandleArgumentCompletionForScriptedCommand(
20604b443e7Sjimingham       PyObject *implementor, std::vector<llvm::StringRef> &args_impl,
20704b443e7Sjimingham       size_t args_pos, size_t pos_in_arg);
20804b443e7Sjimingham 
20904b443e7Sjimingham   static StructuredData::DictionarySP
21004b443e7Sjimingham   LLDBSwigPythonHandleOptionArgumentCompletionForScriptedCommand(
21104b443e7Sjimingham       PyObject *implementor, llvm::StringRef &long_option, size_t pos_in_arg);
21204b443e7Sjimingham 
21327b6a4e6SAlex Langford   static bool LLDBSwigPythonCallModuleInit(const char *python_module_name,
21427b6a4e6SAlex Langford                                            const char *session_dictionary_name,
21527b6a4e6SAlex Langford                                            lldb::DebuggerSP debugger);
21627b6a4e6SAlex Langford 
21727b6a4e6SAlex Langford   static python::PythonObject
21827b6a4e6SAlex Langford   LLDBSWIGPythonCreateOSPlugin(const char *python_class_name,
21927b6a4e6SAlex Langford                                const char *session_dictionary_name,
22027b6a4e6SAlex Langford                                const lldb::ProcessSP &process_sp);
22127b6a4e6SAlex Langford 
22227b6a4e6SAlex Langford   static python::PythonObject
22327b6a4e6SAlex Langford   LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name,
22427b6a4e6SAlex Langford                                        const char *session_dictionary_name);
22527b6a4e6SAlex Langford 
22627b6a4e6SAlex Langford   static PyObject *
22727b6a4e6SAlex Langford   LLDBSwigPython_GetRecognizedArguments(PyObject *implementor,
22827b6a4e6SAlex Langford                                         const lldb::StackFrameSP &frame_sp);
22927b6a4e6SAlex Langford 
2303c0fba4fSAdrian Prantl   static bool LLDBSwigPython_ShouldHide(PyObject *implementor,
2313c0fba4fSAdrian Prantl                                         const lldb::StackFrameSP &frame_sp);
2323c0fba4fSAdrian Prantl 
23327b6a4e6SAlex Langford   static bool LLDBSWIGPythonRunScriptKeywordProcess(
23427b6a4e6SAlex Langford       const char *python_function_name, const char *session_dictionary_name,
23527b6a4e6SAlex Langford       const lldb::ProcessSP &process, std::string &output);
23627b6a4e6SAlex Langford 
23727b6a4e6SAlex Langford   static std::optional<std::string>
23827b6a4e6SAlex Langford   LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name,
23927b6a4e6SAlex Langford                                        const char *session_dictionary_name,
24027b6a4e6SAlex Langford                                        lldb::ThreadSP thread);
24127b6a4e6SAlex Langford 
24227b6a4e6SAlex Langford   static bool LLDBSWIGPythonRunScriptKeywordTarget(
24327b6a4e6SAlex Langford       const char *python_function_name, const char *session_dictionary_name,
24427b6a4e6SAlex Langford       const lldb::TargetSP &target, std::string &output);
24527b6a4e6SAlex Langford 
24627b6a4e6SAlex Langford   static std::optional<std::string>
24727b6a4e6SAlex Langford   LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name,
24827b6a4e6SAlex Langford                                       const char *session_dictionary_name,
24927b6a4e6SAlex Langford                                       lldb::StackFrameSP frame);
25027b6a4e6SAlex Langford 
25127b6a4e6SAlex Langford   static bool LLDBSWIGPythonRunScriptKeywordValue(
25227b6a4e6SAlex Langford       const char *python_function_name, const char *session_dictionary_name,
25327b6a4e6SAlex Langford       const lldb::ValueObjectSP &value, std::string &output);
25427b6a4e6SAlex Langford 
25527b6a4e6SAlex Langford   static void *
25627b6a4e6SAlex Langford   LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting,
25727b6a4e6SAlex Langford                                    const lldb::TargetSP &target_sp);
25827b6a4e6SAlex Langford };
2591f6a57c1SMed Ismail Bennani 
2609a14adeaSPavel Labath void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data);
261e31d0c20SMed Ismail Bennani void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data);
262b9d4c94aSMed Ismail Bennani void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data);
263b9d4c94aSMed Ismail Bennani void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data);
2649a14adeaSPavel Labath void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data);
2659a9ec228SMed Ismail Bennani void *LLDBSWIGPython_CastPyObjectToSBEvent(PyObject *data);
2669a9ec228SMed Ismail Bennani void *LLDBSWIGPython_CastPyObjectToSBStream(PyObject *data);
2679a14adeaSPavel Labath void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data);
2689a14adeaSPavel Labath void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
269f732157aSMed Ismail Bennani void *LLDBSWIGPython_CastPyObjectToSBExecutionContext(PyObject *data);
27027b6a4e6SAlex Langford } // namespace python
2711f6a57c1SMed Ismail Bennani 
272ec00502bSShafik Yaghmour } // namespace lldb_private
2731f6a57c1SMed Ismail Bennani 
2741f6a57c1SMed Ismail Bennani #endif // LLDB_ENABLE_PYTHON
2751f6a57c1SMed Ismail Bennani #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
276