LLDB mainline
ScriptedPythonInterface.h
Go to the documentation of this file.
1//===-- ScriptedPythonInterface.h -------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPYTHONINTERFACE_H
10#define LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPYTHONINTERFACE_H
11
12#include <optional>
13#include <sstream>
14#include <tuple>
15#include <type_traits>
16#include <utility>
17
20
22#include "../SWIGPythonBridge.h"
24
25namespace lldb_private {
28public:
30 ~ScriptedPythonInterface() override = default;
31
40
42
50
52 std::variant<std::monostate, InvalidArgumentCountPayload> payload;
53 };
54
55 llvm::Expected<FileSpec> GetScriptedModulePath() override {
56 using namespace python;
58
61
63 return llvm::createStringError("scripted Interface has invalid object");
64
65 PythonObject py_obj =
66 PythonObject(PyRefType::Borrowed,
67 static_cast<PyObject *>(m_object_instance_sp->GetValue()));
68
69 if (!py_obj.IsAllocated())
70 return llvm::createStringError(
71 "scripted Interface has invalid python object");
72
73 PythonObject py_obj_class = py_obj.GetAttributeValue("__class__");
74 if (!py_obj_class.IsValid())
75 return llvm::createStringError(
76 "scripted Interface python object is missing '__class__' attribute");
77
78 PythonObject py_obj_module = py_obj_class.GetAttributeValue("__module__");
79 if (!py_obj_module.IsValid())
80 return llvm::createStringError(
81 "scripted Interface python object '__class__' is missing "
82 "'__module__' attribute");
83
84 PythonString py_obj_module_str = py_obj_module.Str();
85 if (!py_obj_module_str.IsValid())
86 return llvm::createStringError(
87 "scripted Interface python object '__class__.__module__' attribute "
88 "is not a string");
89
90 llvm::StringRef py_obj_module_str_ref = py_obj_module_str.GetString();
91 PythonModule py_module = PythonModule::AddModule(py_obj_module_str_ref);
92 if (!py_module.IsValid())
93 return llvm::createStringError("failed to import '%s' module",
94 py_obj_module_str_ref.data());
95
96 PythonObject py_module_file = py_module.GetAttributeValue("__file__");
97 if (!py_module_file.IsValid())
98 return llvm::createStringError(
99 "module '%s' is missing '__file__' attribute",
100 py_obj_module_str_ref.data());
101
102 PythonString py_module_file_str = py_module_file.Str();
103 if (!py_module_file_str.IsValid())
104 return llvm::createStringError(
105 "module '%s.__file__' attribute is not a string",
106 py_obj_module_str_ref.data());
107
108 return FileSpec(py_module_file_str.GetString());
109 }
110
111 llvm::Expected<std::map<llvm::StringLiteral, AbstractMethodCheckerPayload>>
113 const python::PythonDictionary &class_dict) const {
114
115 using namespace python;
116
117 std::map<llvm::StringLiteral, AbstractMethodCheckerPayload> checker;
118#define SET_CASE_AND_CONTINUE(method_name, case) \
119 { \
120 checker[method_name] = {case, {}}; \
121 continue; \
122 }
123
124 for (const AbstractMethodRequirement &requirement :
126 llvm::StringLiteral method_name = requirement.name;
127 if (!class_dict.HasKey(method_name))
128 SET_CASE_AND_CONTINUE(method_name,
130 llvm::Expected<PythonObject> callable_or_err =
131 class_dict.GetItem(method_name);
132 if (!callable_or_err) {
133 llvm::consumeError(callable_or_err.takeError());
134 SET_CASE_AND_CONTINUE(method_name,
136 }
137
138 PythonCallable callable = callable_or_err->AsType<PythonCallable>();
139 if (!callable)
140 SET_CASE_AND_CONTINUE(method_name,
142
143 if (!requirement.min_arg_count)
145
146 auto arg_info_or_err = callable.GetArgInfo();
147 if (!arg_info_or_err) {
148 llvm::consumeError(arg_info_or_err.takeError());
149 SET_CASE_AND_CONTINUE(method_name,
151 }
152
153 PythonCallable::ArgInfo arg_info = *arg_info_or_err;
154 if (requirement.min_arg_count <= arg_info.max_positional_args) {
156 } else {
157 checker[method_name] = {
160 requirement.min_arg_count, arg_info.max_positional_args)};
161 }
162 }
163
164#undef SET_CASE_AND_CONTINUE
165
166 return checker;
167 }
168
169 template <typename... Args>
170 llvm::Expected<StructuredData::GenericSP>
171 CreatePluginObject(llvm::StringRef class_name,
172 StructuredData::Generic *script_obj, Args... args) {
173 using namespace python;
175
176 Log *log = GetLog(LLDBLog::Script);
177 auto create_error = [](llvm::StringLiteral format, auto &&...ts) {
178 return llvm::createStringError(
179 llvm::formatv(format.data(), std::forward<decltype(ts)>(ts)...)
180 .str());
181 };
182
183 bool has_class_name = !class_name.empty();
184 bool has_interpreter_dict =
185 !(llvm::StringRef(m_interpreter.GetDictionaryName()).empty());
186 if (!has_class_name && !has_interpreter_dict && !script_obj) {
187 if (!has_class_name)
188 return create_error("Missing script class name.");
189 else if (!has_interpreter_dict)
190 return create_error("Invalid script interpreter dictionary.");
191 else
192 return create_error("Missing scripting object.");
193 }
194
197
198 PythonObject result = {};
199
200 if (script_obj) {
201 result = PythonObject(PyRefType::Borrowed,
202 static_cast<PyObject *>(script_obj->GetValue()));
203 } else {
204 auto dict =
205 PythonModule::MainModule().ResolveName<python::PythonDictionary>(
206 m_interpreter.GetDictionaryName());
207 if (!dict.IsAllocated())
208 return create_error("Could not find interpreter dictionary: {0}",
209 m_interpreter.GetDictionaryName());
210
211 auto init =
212 PythonObject::ResolveNameWithDictionary<python::PythonCallable>(
213 class_name, dict);
214 if (!init.IsAllocated())
215 return create_error("Could not find script class: {0}",
216 class_name.data());
217
218 std::tuple<Args...> original_args = std::forward_as_tuple(args...);
219 auto transformed_args = TransformArgs(original_args);
220
221 std::string error_string;
222 llvm::Expected<PythonCallable::ArgInfo> arg_info = init.GetArgInfo();
223 if (!arg_info) {
224 llvm::handleAllErrors(
225 arg_info.takeError(),
226 [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
227 [&](const llvm::ErrorInfoBase &E) {
228 error_string.append(E.message());
229 });
230 return llvm::createStringError(llvm::inconvertibleErrorCode(),
231 error_string);
232 }
233
234 llvm::Expected<PythonObject> expected_return_object =
235 create_error("Resulting object is not initialized.");
236
237 // This relax the requirement on the number of argument for
238 // initializing scripting extension if the size of the interface
239 // parameter pack contains 1 less element than the extension maximum
240 // number of positional arguments for this initializer.
241 //
242 // This addresses the cases where the embedded interpreter session
243 // dictionary is passed to the extension initializer which is not used
244 // most of the time.
245 // Note, though none of our API's suggest defining the interfaces with
246 // varargs, we have some extant clients that were doing that. To keep
247 // from breaking them, we just say putting a varargs in these signatures
248 // turns off argument checking.
249 size_t num_args = sizeof...(Args);
250 if (arg_info->max_positional_args != PythonCallable::ArgInfo::UNBOUNDED &&
251 num_args != arg_info->max_positional_args) {
252 if (num_args != arg_info->max_positional_args - 1)
253 return create_error("Passed arguments ({0}) doesn't match the number "
254 "of expected arguments ({1}).",
255 num_args, arg_info->max_positional_args);
256
257 std::apply(
258 [&init, &expected_return_object](auto &&...args) {
259 llvm::consumeError(expected_return_object.takeError());
260 expected_return_object = init(args...);
261 },
262 std::tuple_cat(transformed_args, std::make_tuple(dict)));
263 } else {
264 std::apply(
265 [&init, &expected_return_object](auto &&...args) {
266 llvm::consumeError(expected_return_object.takeError());
267 expected_return_object = init(args...);
268 },
269 transformed_args);
270 }
271
272 if (!expected_return_object)
273 return expected_return_object.takeError();
274 result = expected_return_object.get();
275 }
276
277 if (!result.IsValid())
278 return create_error("Resulting object is not a valid Python Object.");
279 if (!result.HasAttribute("__class__"))
280 return create_error("Resulting object doesn't have '__class__' member.");
281
282 PythonObject obj_class = result.GetAttributeValue("__class__");
283 if (!obj_class.IsValid())
284 return create_error("Resulting class object is not a valid.");
285 if (!obj_class.HasAttribute("__name__"))
286 return create_error(
287 "Resulting object class doesn't have '__name__' member.");
288 PythonString obj_class_name =
289 obj_class.GetAttributeValue("__name__").AsType<PythonString>();
290
291 PythonObject object_class_mapping_proxy =
292 obj_class.GetAttributeValue("__dict__");
293 if (!obj_class.HasAttribute("__dict__"))
294 return create_error(
295 "Resulting object class doesn't have '__dict__' member.");
296
297 PythonCallable dict_converter = PythonModule::BuiltinsModule()
298 .ResolveName("dict")
299 .AsType<PythonCallable>();
300 if (!dict_converter.IsAllocated())
301 return create_error(
302 "Python 'builtins' module doesn't have 'dict' class.");
303
304 PythonDictionary object_class_dict =
305 dict_converter(object_class_mapping_proxy).AsType<PythonDictionary>();
306 if (!object_class_dict.IsAllocated())
307 return create_error("Coudn't create dictionary from resulting object "
308 "class mapping proxy object.");
309
310 auto checker_or_err = CheckAbstractMethodImplementation(object_class_dict);
311 if (!checker_or_err)
312 return checker_or_err.takeError();
313
314 llvm::Error abstract_method_errors = llvm::Error::success();
315 for (const auto &method_checker : *checker_or_err)
316 switch (method_checker.second.checker_case) {
318 abstract_method_errors = llvm::joinErrors(
319 std::move(abstract_method_errors),
320 std::move(create_error("Abstract method {0}.{1} not implemented.",
321 obj_class_name.GetString(),
322 method_checker.first)));
323 break;
325 abstract_method_errors = llvm::joinErrors(
326 std::move(abstract_method_errors),
327 std::move(create_error("Abstract method {0}.{1} not allocated.",
328 obj_class_name.GetString(),
329 method_checker.first)));
330 break;
332 abstract_method_errors = llvm::joinErrors(
333 std::move(abstract_method_errors),
334 std::move(create_error("Abstract method {0}.{1} not callable.",
335 obj_class_name.GetString(),
336 method_checker.first)));
337 break;
339 abstract_method_errors = llvm::joinErrors(
340 std::move(abstract_method_errors),
341 std::move(create_error(
342 "Abstract method {0}.{1} has unknown argument count.",
343 obj_class_name.GetString(), method_checker.first)));
344 break;
346 auto &payload_variant = method_checker.second.payload;
347 if (!std::holds_alternative<
349 payload_variant)) {
350 abstract_method_errors = llvm::joinErrors(
351 std::move(abstract_method_errors),
352 std::move(create_error(
353 "Abstract method {0}.{1} has unexpected argument count.",
354 obj_class_name.GetString(), method_checker.first)));
355 } else {
356 auto payload = std::get<
358 payload_variant);
359 abstract_method_errors = llvm::joinErrors(
360 std::move(abstract_method_errors),
361 std::move(
362 create_error("Abstract method {0}.{1} has unexpected "
363 "argument count (expected {2} but has {3}).",
364 obj_class_name.GetString(), method_checker.first,
365 payload.required_argument_count,
366 payload.actual_argument_count)));
367 }
368 } break;
370 LLDB_LOG(log, "Abstract method {0}.{1} implemented & valid.",
371 obj_class_name.GetString(), method_checker.first);
372 break;
373 }
374
375 if (abstract_method_errors) {
376 Status error = Status::FromError(std::move(abstract_method_errors));
377 LLDB_LOG(log, "Abstract method error in {0}:\n{1}", class_name,
378 error.AsCString());
379 return error.ToError();
380 }
381
383 new StructuredPythonObject(std::move(result)));
385 }
386
387 /// Call a static method on a Python class without creating an instance.
388 ///
389 /// This method resolves a Python class by name and calls a static method
390 /// on it, returning the result. This is useful for calling class-level
391 /// methods that don't require an instance.
392 ///
393 /// \param class_name The fully-qualified name of the Python class.
394 /// \param method_name The name of the static method to call.
395 /// \param error Output parameter to receive error information if the call
396 /// fails.
397 /// \param args Arguments to pass to the static method.
398 ///
399 /// \return The return value of the static method call, or an error value.
400 template <typename T = StructuredData::ObjectSP, typename... Args>
401 T CallStaticMethod(llvm::StringRef class_name, llvm::StringRef method_name,
402 Status &error, Args &&...args) {
403 using namespace python;
405
406 std::string caller_signature =
407 llvm::Twine(LLVM_PRETTY_FUNCTION + llvm::Twine(" (") +
408 llvm::Twine(class_name) + llvm::Twine(".") +
409 llvm::Twine(method_name) + llvm::Twine(")"))
410 .str();
411
412 if (class_name.empty())
413 return ErrorWithMessage<T>(caller_signature, "missing script class name",
414 error);
415
418
419 // Get the interpreter dictionary.
420 auto dict =
421 PythonModule::MainModule().ResolveName<python::PythonDictionary>(
422 m_interpreter.GetDictionaryName());
423 if (!dict.IsAllocated())
424 return ErrorWithMessage<T>(
425 caller_signature,
426 llvm::formatv("could not find interpreter dictionary: {0}",
427 m_interpreter.GetDictionaryName())
428 .str(),
429 error);
430
431 // Resolve the class.
432 auto class_obj =
433 PythonObject::ResolveNameWithDictionary<python::PythonCallable>(
434 class_name, dict);
435 if (!class_obj.IsAllocated())
436 return ErrorWithMessage<T>(
437 caller_signature,
438 llvm::formatv("could not find script class: {0}", class_name).str(),
439 error);
440
441 // Get the static method from the class.
442 if (!class_obj.HasAttribute(method_name))
443 return ErrorWithMessage<T>(
444 caller_signature,
445 llvm::formatv("class {0} does not have method {1}", class_name,
446 method_name)
447 .str(),
448 error);
449
450 PythonCallable method =
451 class_obj.GetAttributeValue(method_name).AsType<PythonCallable>();
452 if (!method.IsAllocated())
453 return ErrorWithMessage<T>(caller_signature,
454 llvm::formatv("method {0}.{1} is not callable",
455 class_name, method_name)
456 .str(),
457 error);
458
459 // Transform the arguments.
460 std::tuple<Args...> original_args = std::forward_as_tuple(args...);
461 auto transformed_args = TransformArgs(original_args);
462
463 // Call the static method.
464 llvm::Expected<PythonObject> expected_return_object =
465 llvm::createStringError("Not initialized.");
466 std::apply(
467 [&method, &expected_return_object](auto &&...args) {
468 llvm::consumeError(expected_return_object.takeError());
469 expected_return_object = method(args...);
470 },
471 transformed_args);
472
473 if (llvm::Error e = expected_return_object.takeError()) {
474 error = Status::FromError(std::move(e));
475 return ErrorWithMessage<T>(
476 caller_signature, "python static method could not be called", error);
477 }
478
479 PythonObject py_return = std::move(expected_return_object.get());
480
481 // Re-assign reference and pointer arguments if needed.
482 if (sizeof...(Args) > 0)
483 if (!ReassignPtrsOrRefsArgs(original_args, transformed_args))
484 return ErrorWithMessage<T>(
485 caller_signature,
486 "couldn't re-assign reference and pointer arguments", error);
487
488 // Extract value from Python object (handles unallocated case).
489 return ExtractValueFromPythonObject<T>(py_return, error);
490 }
491
492protected:
493 template <typename T = StructuredData::ObjectSP>
497
498 template <typename T = StructuredData::ObjectSP, typename... Args>
499 T Dispatch(llvm::StringRef method_name, Status &error, Args &&...args) {
500 using namespace python;
502
503 std::string caller_signature =
504 llvm::Twine(LLVM_PRETTY_FUNCTION + llvm::Twine(" (") +
505 llvm::Twine(method_name) + llvm::Twine(")"))
506 .str();
508 return ErrorWithMessage<T>(caller_signature, "python object ill-formed",
509 error);
510
513
514 PythonObject implementor(PyRefType::Borrowed,
515 (PyObject *)m_object_instance_sp->GetValue());
516
517 if (!implementor.IsAllocated())
518 return llvm::is_contained(GetAbstractMethods(), method_name)
519 ? ErrorWithMessage<T>(caller_signature,
520 "python implementor not allocated",
521 error)
522 : T{};
523
524 std::tuple<Args...> original_args = std::forward_as_tuple(args...);
525 auto transformed_args = TransformArgs(original_args);
526
527 llvm::Expected<PythonObject> expected_return_object =
528 llvm::createStringError("Not initialized.");
529 std::apply(
530 [&implementor, &method_name, &expected_return_object](auto &&...args) {
531 llvm::consumeError(expected_return_object.takeError());
532 expected_return_object =
533 implementor.CallMethod(method_name.data(), args...);
534 },
535 transformed_args);
536
537 if (llvm::Error e = expected_return_object.takeError()) {
538 error = Status::FromError(std::move(e));
539 return ErrorWithMessage<T>(caller_signature,
540 "python method could not be called", error);
541 }
542
543 PythonObject py_return = std::move(expected_return_object.get());
544
545 // Now that we called the python method with the transformed arguments,
546 // we need to iterate again over both the original and transformed
547 // parameter pack, and transform back the parameter that were passed in
548 // the original parameter pack as references or pointers.
549 if (sizeof...(Args) > 0)
550 if (!ReassignPtrsOrRefsArgs(original_args, transformed_args))
551 return ErrorWithMessage<T>(
552 caller_signature,
553 "couldn't re-assign reference and pointer arguments", error);
554
555 if (!py_return.IsAllocated())
556 return {};
557 return ExtractValueFromPythonObject<T>(py_return, error);
558 }
559
560 template <typename... Args>
561 Status GetStatusFromMethod(llvm::StringRef method_name, Args &&...args) {
563 Dispatch<Status>(method_name, error, std::forward<Args>(args)...);
564
565 return error;
566 }
567
568 template <typename T> T Transform(T object) {
569 // No Transformation for generic usage
570 return {object};
571 }
572
574 // Boolean arguments need to be turned into python objects.
575 return python::PythonBoolean(arg);
576 }
577
581
583 return python::SWIGBridge::ToSWIGWrapper(std::move(arg));
584 }
585
589
593
597
601
605
609
613
617
621
625
629
633
637
641
645
649
653
657
658 template <typename T, typename U>
659 void ReverseTransform(T &original_arg, U transformed_arg, Status &error) {
660 // If U is not a PythonObject, don't touch it!
661 }
662
663 template <typename T>
664 void ReverseTransform(T &original_arg, python::PythonObject transformed_arg,
665 Status &error) {
666 original_arg = ExtractValueFromPythonObject<T>(transformed_arg, error);
667 }
668
669 void ReverseTransform(bool &original_arg,
670 python::PythonObject transformed_arg, Status &error) {
672 python::PyRefType::Borrowed, transformed_arg.get());
673 if (boolean_arg.IsValid())
674 original_arg = boolean_arg.GetValue();
675 else
677 "{}: Invalid boolean argument.", LLVM_PRETTY_FUNCTION);
678 }
679
680 template <std::size_t... I, typename... Args>
681 auto TransformTuple(const std::tuple<Args...> &args,
682 std::index_sequence<I...>) {
683 return std::make_tuple(Transform(std::get<I>(args))...);
684 }
685
686 // This will iterate over the Dispatch parameter pack and replace in-place
687 // every `lldb_private` argument that has a SB counterpart.
688 template <typename... Args>
689 auto TransformArgs(const std::tuple<Args...> &args) {
690 return TransformTuple(args, std::make_index_sequence<sizeof...(Args)>());
691 }
692
693 template <typename T, typename U>
694 void TransformBack(T &original_arg, U transformed_arg, Status &error) {
695 ReverseTransform(original_arg, transformed_arg, error);
696 }
697
698 template <std::size_t... I, typename... Ts, typename... Us>
699 bool ReassignPtrsOrRefsArgs(std::tuple<Ts...> &original_args,
700 std::tuple<Us...> &transformed_args,
701 std::index_sequence<I...>) {
703 (TransformBack(std::get<I>(original_args), std::get<I>(transformed_args),
704 error),
705 ...);
706 return error.Success();
707 }
708
709 template <typename... Ts, typename... Us>
710 bool ReassignPtrsOrRefsArgs(std::tuple<Ts...> &original_args,
711 std::tuple<Us...> &transformed_args) {
712 if (sizeof...(Ts) != sizeof...(Us))
713 return false;
714
715 return ReassignPtrsOrRefsArgs(original_args, transformed_args,
716 std::make_index_sequence<sizeof...(Ts)>());
717 }
718
719 template <typename T, typename... Args>
720 void FormatArgs(std::string &fmt, T arg, Args... args) const {
721 FormatArgs(fmt, arg);
722 FormatArgs(fmt, args...);
723 }
724
725 template <typename T> void FormatArgs(std::string &fmt, T arg) const {
727 }
728
729 void FormatArgs(std::string &fmt) const {}
730
731 // The lifetime is managed by the ScriptInterpreter
733};
734
735template <>
739
740template <>
744
745template <>
748
749template <>
752
753template <>
757
758template <>
762
763template <>
767
768template <>
772
773template <>
777
778template <>
782
783template <>
786
787template <>
790
791template <>
795
796template <>
797std::optional<MemoryRegionInfo>
799 std::optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error);
800
801template <>
805
806template <>
810
811template <>
815
816template <>
820
821template <>
825
826} // namespace lldb_private
827
828#endif // LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_INTERFACES_SCRIPTEDPYTHONINTERFACE_H
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:369
ScriptInterpreterPythonImpl::Locker Locker
#define SET_CASE_AND_CONTINUE(method_name, case)
A command line argument class.
Definition Args.h:33
A file utility class.
Definition FileSpec.h:57
static Ret ErrorWithMessage(llvm::StringRef caller_name, llvm::StringRef error_msg, Status &error, LLDBLog log_category=LLDBLog::Process)
llvm::SmallVector< llvm::StringLiteral > const GetAbstractMethods() const
virtual llvm::SmallVector< AbstractMethodRequirement > GetAbstractMethodRequirements() const =0
StructuredData::GenericSP m_object_instance_sp
python::PythonObject Transform(lldb::StackFrameListSP arg)
python::PythonObject Transform(lldb::ThreadPlanSP arg)
Status GetStatusFromMethod(llvm::StringRef method_name, Args &&...args)
python::PythonObject Transform(lldb::ProcessSP arg)
llvm::Expected< StructuredData::GenericSP > CreatePluginObject(llvm::StringRef class_name, StructuredData::Generic *script_obj, Args... args)
void TransformBack(T &original_arg, U transformed_arg, Status &error)
ScriptInterpreterPythonImpl & m_interpreter
python::PythonObject Transform(Event *arg)
auto TransformArgs(const std::tuple< Args... > &args)
python::PythonObject Transform(lldb::ExecutionContextRefSP arg)
python::PythonObject Transform(lldb::ThreadSP arg)
llvm::Expected< std::map< llvm::StringLiteral, AbstractMethodCheckerPayload > > CheckAbstractMethodImplementation(const python::PythonDictionary &class_dict) const
python::PythonObject Transform(const StructuredDataImpl &arg)
T ExtractValueFromPythonObject(python::PythonObject &p, Status &error)
~ScriptedPythonInterface() override=default
llvm::Expected< FileSpec > GetScriptedModulePath() override
python::PythonObject Transform(lldb::DescriptionLevel arg)
python::PythonObject Transform(const Status &arg)
python::PythonObject Transform(const SymbolContext &arg)
void ReverseTransform(T &original_arg, python::PythonObject transformed_arg, Status &error)
void FormatArgs(std::string &fmt, T arg, Args... args) const
python::PythonObject Transform(lldb::BreakpointSP arg)
void FormatArgs(std::string &fmt, T arg) const
ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter)
void ReverseTransform(T &original_arg, U transformed_arg, Status &error)
T CallStaticMethod(llvm::StringRef class_name, llvm::StringRef method_name, Status &error, Args &&...args)
Call a static method on a Python class without creating an instance.
T Dispatch(llvm::StringRef method_name, Status &error, Args &&...args)
python::PythonObject Transform(lldb::BreakpointLocationSP arg)
bool ReassignPtrsOrRefsArgs(std::tuple< Ts... > &original_args, std::tuple< Us... > &transformed_args)
python::PythonObject Transform(lldb::StreamSP arg)
python::PythonObject Transform(Status &&arg)
python::PythonObject Transform(lldb::DataExtractorSP arg)
python::PythonObject Transform(lldb::StackFrameSP arg)
bool ReassignPtrsOrRefsArgs(std::tuple< Ts... > &original_args, std::tuple< Us... > &transformed_args, std::index_sequence< I... >)
python::PythonObject Transform(lldb::ProcessLaunchInfoSP arg)
python::PythonObject Transform(lldb::TargetSP arg)
auto TransformTuple(const std::tuple< Args... > &args, std::index_sequence< I... >)
void ReverseTransform(bool &original_arg, python::PythonObject transformed_arg, Status &error)
python::PythonObject Transform(lldb::ValueObjectSP arg)
python::PythonObject Transform(lldb::ProcessAttachInfoSP arg)
An error handling class.
Definition Status.h:118
Status Clone() const
Don't call this function in new code.
Definition Status.h:174
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:136
std::shared_ptr< Generic > GenericSP
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
std::shared_ptr< Array > ArraySP
Defines a symbol context baton that can be handed other debug core functions.
llvm::Expected< PythonObject > GetItem(const PythonObject &key) const
bool HasKey(const llvm::Twine &key) const
StructuredData::ObjectSP CreateStructuredObject() const
static PythonObject ToSWIGWrapper(std::unique_ptr< lldb::SBValue > value_sb)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:332
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::BreakpointLocation > BreakpointLocationSP
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::ProcessAttachInfo > ProcessAttachInfoSP
std::shared_ptr< lldb_private::Stream > StreamSP
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::ValueObjectList > ValueObjectListSP
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
std::shared_ptr< lldb_private::ProcessLaunchInfo > ProcessLaunchInfoSP
std::shared_ptr< lldb_private::StackFrameList > StackFrameListSP
std::shared_ptr< lldb_private::ExecutionContextRef > ExecutionContextRefSP
std::variant< std::monostate, InvalidArgumentCountPayload > payload