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::make_error<llvm::StringError>("Not initialized.",
466 llvm::inconvertibleErrorCode());
467 std::apply(
468 [&method, &expected_return_object](auto &&...args) {
469 llvm::consumeError(expected_return_object.takeError());
470 expected_return_object = method(args...);
471 },
472 transformed_args);
473
474 if (llvm::Error e = expected_return_object.takeError()) {
475 error = Status::FromError(std::move(e));
476 return ErrorWithMessage<T>(
477 caller_signature, "python static method could not be called", error);
478 }
479
480 PythonObject py_return = std::move(expected_return_object.get());
481
482 // Re-assign reference and pointer arguments if needed.
483 if (sizeof...(Args) > 0)
484 if (!ReassignPtrsOrRefsArgs(original_args, transformed_args))
485 return ErrorWithMessage<T>(
486 caller_signature,
487 "couldn't re-assign reference and pointer arguments", error);
488
489 // Extract value from Python object (handles unallocated case).
490 return ExtractValueFromPythonObject<T>(py_return, error);
491 }
492
493protected:
494 template <typename T = StructuredData::ObjectSP>
498
499 template <typename T = StructuredData::ObjectSP, typename... Args>
500 T Dispatch(llvm::StringRef method_name, Status &error, Args &&...args) {
501 using namespace python;
503
504 std::string caller_signature =
505 llvm::Twine(LLVM_PRETTY_FUNCTION + llvm::Twine(" (") +
506 llvm::Twine(method_name) + llvm::Twine(")"))
507 .str();
509 return ErrorWithMessage<T>(caller_signature, "python object ill-formed",
510 error);
511
514
515 PythonObject implementor(PyRefType::Borrowed,
516 (PyObject *)m_object_instance_sp->GetValue());
517
518 if (!implementor.IsAllocated())
519 return llvm::is_contained(GetAbstractMethods(), method_name)
520 ? ErrorWithMessage<T>(caller_signature,
521 "python implementor not allocated",
522 error)
523 : T{};
524
525 std::tuple<Args...> original_args = std::forward_as_tuple(args...);
526 auto transformed_args = TransformArgs(original_args);
527
528 llvm::Expected<PythonObject> expected_return_object =
529 llvm::make_error<llvm::StringError>("Not initialized.",
530 llvm::inconvertibleErrorCode());
531 std::apply(
532 [&implementor, &method_name, &expected_return_object](auto &&...args) {
533 llvm::consumeError(expected_return_object.takeError());
534 expected_return_object =
535 implementor.CallMethod(method_name.data(), args...);
536 },
537 transformed_args);
538
539 if (llvm::Error e = expected_return_object.takeError()) {
540 error = Status::FromError(std::move(e));
541 return ErrorWithMessage<T>(caller_signature,
542 "python method could not be called", error);
543 }
544
545 PythonObject py_return = std::move(expected_return_object.get());
546
547 // Now that we called the python method with the transformed arguments,
548 // we need to iterate again over both the original and transformed
549 // parameter pack, and transform back the parameter that were passed in
550 // the original parameter pack as references or pointers.
551 if (sizeof...(Args) > 0)
552 if (!ReassignPtrsOrRefsArgs(original_args, transformed_args))
553 return ErrorWithMessage<T>(
554 caller_signature,
555 "couldn't re-assign reference and pointer arguments", error);
556
557 if (!py_return.IsAllocated())
558 return {};
559 return ExtractValueFromPythonObject<T>(py_return, error);
560 }
561
562 template <typename... Args>
563 Status GetStatusFromMethod(llvm::StringRef method_name, Args &&...args) {
565 Dispatch<Status>(method_name, error, std::forward<Args>(args)...);
566
567 return error;
568 }
569
570 template <typename T> T Transform(T object) {
571 // No Transformation for generic usage
572 return {object};
573 }
574
576 // Boolean arguments need to be turned into python objects.
577 return python::PythonBoolean(arg);
578 }
579
583
585 return python::SWIGBridge::ToSWIGWrapper(std::move(arg));
586 }
587
591
595
599
603
607
611
615
619
623
627
631
635
639
643
647
651
655
659
660 template <typename T, typename U>
661 void ReverseTransform(T &original_arg, U transformed_arg, Status &error) {
662 // If U is not a PythonObject, don't touch it!
663 }
664
665 template <typename T>
666 void ReverseTransform(T &original_arg, python::PythonObject transformed_arg,
667 Status &error) {
668 original_arg = ExtractValueFromPythonObject<T>(transformed_arg, error);
669 }
670
671 void ReverseTransform(bool &original_arg,
672 python::PythonObject transformed_arg, Status &error) {
674 python::PyRefType::Borrowed, transformed_arg.get());
675 if (boolean_arg.IsValid())
676 original_arg = boolean_arg.GetValue();
677 else
679 "{}: Invalid boolean argument.", LLVM_PRETTY_FUNCTION);
680 }
681
682 template <std::size_t... I, typename... Args>
683 auto TransformTuple(const std::tuple<Args...> &args,
684 std::index_sequence<I...>) {
685 return std::make_tuple(Transform(std::get<I>(args))...);
686 }
687
688 // This will iterate over the Dispatch parameter pack and replace in-place
689 // every `lldb_private` argument that has a SB counterpart.
690 template <typename... Args>
691 auto TransformArgs(const std::tuple<Args...> &args) {
692 return TransformTuple(args, std::make_index_sequence<sizeof...(Args)>());
693 }
694
695 template <typename T, typename U>
696 void TransformBack(T &original_arg, U transformed_arg, Status &error) {
697 ReverseTransform(original_arg, transformed_arg, error);
698 }
699
700 template <std::size_t... I, typename... Ts, typename... Us>
701 bool ReassignPtrsOrRefsArgs(std::tuple<Ts...> &original_args,
702 std::tuple<Us...> &transformed_args,
703 std::index_sequence<I...>) {
705 (TransformBack(std::get<I>(original_args), std::get<I>(transformed_args),
706 error),
707 ...);
708 return error.Success();
709 }
710
711 template <typename... Ts, typename... Us>
712 bool ReassignPtrsOrRefsArgs(std::tuple<Ts...> &original_args,
713 std::tuple<Us...> &transformed_args) {
714 if (sizeof...(Ts) != sizeof...(Us))
715 return false;
716
717 return ReassignPtrsOrRefsArgs(original_args, transformed_args,
718 std::make_index_sequence<sizeof...(Ts)>());
719 }
720
721 template <typename T, typename... Args>
722 void FormatArgs(std::string &fmt, T arg, Args... args) const {
723 FormatArgs(fmt, arg);
724 FormatArgs(fmt, args...);
725 }
726
727 template <typename T> void FormatArgs(std::string &fmt, T arg) const {
729 }
730
731 void FormatArgs(std::string &fmt) const {}
732
733 // The lifetime is managed by the ScriptInterpreter
735};
736
737template <>
741
742template <>
746
747template <>
750
751template <>
754
755template <>
759
760template <>
764
765template <>
769
770template <>
774
775template <>
779
780template <>
784
785template <>
788
789template <>
792
793template <>
797
798template <>
799std::optional<MemoryRegionInfo>
801 std::optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error);
802
803template <>
807
808template <>
812
813template <>
817
818template <>
822
823template <>
827
828} // namespace lldb_private
829
830#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:137
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