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
21
23#include "../SWIGPythonBridge.h"
25
26namespace lldb_private {
29public:
31 ~ScriptedPythonInterface() override = default;
32
41
43
51
53 std::variant<std::monostate, InvalidArgumentCountPayload> payload;
54 };
55
56 llvm::Expected<FileSpec> GetScriptedModulePath() override {
57 using namespace python;
59
62
64 return llvm::createStringError("scripted Interface has invalid object");
65
66 PythonObject py_obj =
67 PythonObject(PyRefType::Borrowed,
68 static_cast<PyObject *>(m_object_instance_sp->GetValue()));
69
70 if (!py_obj.IsAllocated())
71 return llvm::createStringError(
72 "scripted Interface has invalid python object");
73
74 PythonObject py_obj_class = py_obj.GetAttributeValue("__class__");
75 if (!py_obj_class.IsValid())
76 return llvm::createStringError(
77 "scripted Interface python object is missing '__class__' attribute");
78
79 PythonObject py_obj_module = py_obj_class.GetAttributeValue("__module__");
80 if (!py_obj_module.IsValid())
81 return llvm::createStringError(
82 "scripted Interface python object '__class__' is missing "
83 "'__module__' attribute");
84
85 PythonString py_obj_module_str = py_obj_module.Str();
86 if (!py_obj_module_str.IsValid())
87 return llvm::createStringError(
88 "scripted Interface python object '__class__.__module__' attribute "
89 "is not a string");
90
91 llvm::StringRef py_obj_module_str_ref = py_obj_module_str.GetString();
92 PythonModule py_module = PythonModule::AddModule(py_obj_module_str_ref);
93 if (!py_module.IsValid())
94 return llvm::createStringError("failed to import '%s' module",
95 py_obj_module_str_ref.data());
96
97 PythonObject py_module_file = py_module.GetAttributeValue("__file__");
98 if (!py_module_file.IsValid())
99 return llvm::createStringError(
100 "module '%s' is missing '__file__' attribute",
101 py_obj_module_str_ref.data());
102
103 PythonString py_module_file_str = py_module_file.Str();
104 if (!py_module_file_str.IsValid())
105 return llvm::createStringError(
106 "module '%s.__file__' attribute is not a string",
107 py_obj_module_str_ref.data());
108
109 return FileSpec(py_module_file_str.GetString());
110 }
111
112 llvm::Expected<std::map<llvm::StringLiteral, AbstractMethodCheckerPayload>>
114 const python::PythonDictionary &class_dict) const {
115
116 using namespace python;
117
118 std::map<llvm::StringLiteral, AbstractMethodCheckerPayload> checker;
119#define SET_CASE_AND_CONTINUE(method_name, case) \
120 { \
121 checker[method_name] = {case, {}}; \
122 continue; \
123 }
124
125 for (const AbstractMethodRequirement &requirement :
127 llvm::StringLiteral method_name = requirement.name;
128 if (!class_dict.HasKey(method_name))
129 SET_CASE_AND_CONTINUE(method_name,
131 llvm::Expected<PythonObject> callable_or_err =
132 class_dict.GetItem(method_name);
133 if (!callable_or_err) {
134 llvm::consumeError(callable_or_err.takeError());
135 SET_CASE_AND_CONTINUE(method_name,
137 }
138
139 PythonCallable callable = callable_or_err->AsType<PythonCallable>();
140 if (!callable)
141 SET_CASE_AND_CONTINUE(method_name,
143
144 if (!requirement.min_arg_count)
146
147 auto arg_info_or_err = callable.GetArgInfo();
148 if (!arg_info_or_err) {
149 llvm::consumeError(arg_info_or_err.takeError());
150 SET_CASE_AND_CONTINUE(method_name,
152 }
153
154 PythonCallable::ArgInfo arg_info = *arg_info_or_err;
155 if (requirement.min_arg_count <= arg_info.max_positional_args) {
157 } else {
158 checker[method_name] = {
161 requirement.min_arg_count, arg_info.max_positional_args)};
162 }
163 }
164
165#undef SET_CASE_AND_CONTINUE
166
167 return checker;
168 }
169
170 template <typename... Args>
171 llvm::Expected<StructuredData::GenericSP>
172 CreatePluginObject(const ScriptedMetadata &scripted_metadata,
173 StructuredData::Generic *script_obj, Args... args) {
174 using namespace python;
176
177 Log *log = GetLog(LLDBLog::Script);
178 auto create_error = [](llvm::StringLiteral format, auto &&...ts) {
179 return llvm::createStringError(
180 llvm::formatv(format.data(), std::forward<decltype(ts)>(ts)...)
181 .str());
182 };
183
184 m_scripted_metadata = scripted_metadata;
185 llvm::StringRef class_name = scripted_metadata.GetClassName();
186 bool has_class_name = !class_name.empty();
187 bool has_interpreter_dict =
188 !(llvm::StringRef(m_interpreter.GetDictionaryName()).empty());
189 if (!has_class_name && !has_interpreter_dict && !script_obj) {
190 if (!has_class_name)
191 return create_error("Missing script class name.");
192 else if (!has_interpreter_dict)
193 return create_error("Invalid script interpreter dictionary.");
194 else
195 return create_error("Missing scripting object.");
196 }
197
200
201 PythonObject result = {};
202
203 if (script_obj) {
204 result = PythonObject(PyRefType::Borrowed,
205 static_cast<PyObject *>(script_obj->GetValue()));
206 } else {
207 auto dict =
208 PythonModule::MainModule().ResolveName<python::PythonDictionary>(
209 m_interpreter.GetDictionaryName());
210 if (!dict.IsAllocated())
211 return create_error("Could not find interpreter dictionary: {0}",
212 m_interpreter.GetDictionaryName());
213
214 auto init =
215 PythonObject::ResolveNameWithDictionary<python::PythonCallable>(
216 class_name, dict);
217 if (!init.IsAllocated())
218 return create_error("Could not find script class: {0}",
219 class_name.data());
220
221 std::tuple<Args...> original_args = std::forward_as_tuple(args...);
222 auto transformed_args = TransformArgs(original_args);
223
224 std::string error_string;
225 llvm::Expected<PythonCallable::ArgInfo> arg_info = init.GetArgInfo();
226 if (!arg_info) {
227 llvm::handleAllErrors(
228 arg_info.takeError(),
229 [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
230 [&](const llvm::ErrorInfoBase &E) {
231 error_string.append(E.message());
232 });
233 return llvm::createStringError(llvm::inconvertibleErrorCode(),
234 error_string);
235 }
236
237 llvm::Expected<PythonObject> expected_return_object =
238 create_error("Resulting object is not initialized.");
239
240 // This relax the requirement on the number of argument for
241 // initializing scripting extension if the size of the interface
242 // parameter pack contains 1 less element than the extension maximum
243 // number of positional arguments for this initializer.
244 //
245 // This addresses the cases where the embedded interpreter session
246 // dictionary is passed to the extension initializer which is not used
247 // most of the time.
248 // Note, though none of our API's suggest defining the interfaces with
249 // varargs, we have some extant clients that were doing that. To keep
250 // from breaking them, we just say putting a varargs in these signatures
251 // turns off argument checking.
252 size_t num_args = sizeof...(Args);
253 if (arg_info->max_positional_args != PythonCallable::ArgInfo::UNBOUNDED &&
254 num_args != arg_info->max_positional_args) {
255 if (num_args != arg_info->max_positional_args - 1) {
256 // `expected_return_object` starts in an error state; consume it
257 // before we return with a different error, or its destructor
258 // will abort.
259 llvm::consumeError(expected_return_object.takeError());
260 return create_error("Passed arguments ({0}) doesn't match the number "
261 "of expected arguments ({1}).",
262 num_args, arg_info->max_positional_args);
263 }
264
265 std::apply(
266 [&init, &expected_return_object](auto &&...args) {
267 llvm::consumeError(expected_return_object.takeError());
268 expected_return_object = init(args...);
269 },
270 std::tuple_cat(transformed_args, std::make_tuple(dict)));
271 } else {
272 std::apply(
273 [&init, &expected_return_object](auto &&...args) {
274 llvm::consumeError(expected_return_object.takeError());
275 expected_return_object = init(args...);
276 },
277 transformed_args);
278 }
279
280 if (!expected_return_object)
281 return expected_return_object.takeError();
282 result = expected_return_object.get();
283 }
284
285 if (!result.IsValid())
286 return create_error("Resulting object is not a valid Python Object.");
287 if (!result.HasAttribute("__class__"))
288 return create_error("Resulting object doesn't have '__class__' member.");
289
290 PythonObject obj_class = result.GetAttributeValue("__class__");
291 if (!obj_class.IsValid())
292 return create_error("Resulting class object is not a valid.");
293 if (!obj_class.HasAttribute("__name__"))
294 return create_error(
295 "Resulting object class doesn't have '__name__' member.");
296 PythonString obj_class_name =
297 obj_class.GetAttributeValue("__name__").AsType<PythonString>();
298
299 PythonObject object_class_mapping_proxy =
300 obj_class.GetAttributeValue("__dict__");
301 if (!obj_class.HasAttribute("__dict__"))
302 return create_error(
303 "Resulting object class doesn't have '__dict__' member.");
304
305 PythonCallable dict_converter = PythonModule::BuiltinsModule()
306 .ResolveName("dict")
307 .AsType<PythonCallable>();
308 if (!dict_converter.IsAllocated())
309 return create_error(
310 "Python 'builtins' module doesn't have 'dict' class.");
311
312 PythonDictionary object_class_dict =
313 dict_converter(object_class_mapping_proxy).AsType<PythonDictionary>();
314 if (!object_class_dict.IsAllocated())
315 return create_error("Coudn't create dictionary from resulting object "
316 "class mapping proxy object.");
317
318 auto checker_or_err = CheckAbstractMethodImplementation(object_class_dict);
319 if (!checker_or_err)
320 return checker_or_err.takeError();
321
322 llvm::Error abstract_method_errors = llvm::Error::success();
323 for (const auto &method_checker : *checker_or_err)
324 switch (method_checker.second.checker_case) {
326 abstract_method_errors = llvm::joinErrors(
327 std::move(abstract_method_errors),
328 std::move(create_error("Abstract method {0}.{1} not implemented.",
329 obj_class_name.GetString(),
330 method_checker.first)));
331 break;
333 abstract_method_errors = llvm::joinErrors(
334 std::move(abstract_method_errors),
335 std::move(create_error("Abstract method {0}.{1} not allocated.",
336 obj_class_name.GetString(),
337 method_checker.first)));
338 break;
340 abstract_method_errors = llvm::joinErrors(
341 std::move(abstract_method_errors),
342 std::move(create_error("Abstract method {0}.{1} not callable.",
343 obj_class_name.GetString(),
344 method_checker.first)));
345 break;
347 abstract_method_errors = llvm::joinErrors(
348 std::move(abstract_method_errors),
349 std::move(create_error(
350 "Abstract method {0}.{1} has unknown argument count.",
351 obj_class_name.GetString(), method_checker.first)));
352 break;
354 auto &payload_variant = method_checker.second.payload;
355 if (!std::holds_alternative<
357 payload_variant)) {
358 abstract_method_errors = llvm::joinErrors(
359 std::move(abstract_method_errors),
360 std::move(create_error(
361 "Abstract method {0}.{1} has unexpected argument count.",
362 obj_class_name.GetString(), method_checker.first)));
363 } else {
364 auto payload = std::get<
366 payload_variant);
367 abstract_method_errors = llvm::joinErrors(
368 std::move(abstract_method_errors),
369 std::move(
370 create_error("Abstract method {0}.{1} has unexpected "
371 "argument count (expected {2} but has {3}).",
372 obj_class_name.GetString(), method_checker.first,
373 payload.required_argument_count,
374 payload.actual_argument_count)));
375 }
376 } break;
378 LLDB_LOG(log, "Abstract method {0}.{1} implemented & valid.",
379 obj_class_name.GetString(), method_checker.first);
380 break;
381 }
382
383 if (abstract_method_errors) {
384 Status error = Status::FromError(std::move(abstract_method_errors));
385 LLDB_LOG(log, "Abstract method error in {0}:\n{1}", class_name,
386 error.AsCString());
387 return error.ToError();
388 }
389
391 new StructuredPythonObject(std::move(result)));
393 }
394
395 /// Call a static method on a Python class without creating an instance.
396 ///
397 /// This method resolves a Python class by name and calls a static method
398 /// on it, returning the result. This is useful for calling class-level
399 /// methods that don't require an instance.
400 ///
401 /// \param class_name The fully-qualified name of the Python class.
402 /// \param method_name The name of the static method to call.
403 /// \param error Output parameter to receive error information if the call
404 /// fails.
405 /// \param args Arguments to pass to the static method.
406 ///
407 /// \return The return value of the static method call, or an error value.
408 template <typename T = StructuredData::ObjectSP, typename... Args>
409 T CallStaticMethod(llvm::StringRef class_name, llvm::StringRef method_name,
410 Status &error, Args &&...args) {
411 using namespace python;
413
414 std::string caller_signature =
415 llvm::Twine(LLVM_PRETTY_FUNCTION + llvm::Twine(" (") +
416 llvm::Twine(class_name) + llvm::Twine(".") +
417 llvm::Twine(method_name) + llvm::Twine(")"))
418 .str();
419
420 if (class_name.empty())
421 return ErrorWithMessage<T>(caller_signature, "missing script class name",
422 error);
423
426
427 // Get the interpreter dictionary.
428 auto dict =
429 PythonModule::MainModule().ResolveName<python::PythonDictionary>(
430 m_interpreter.GetDictionaryName());
431 if (!dict.IsAllocated())
432 return ErrorWithMessage<T>(
433 caller_signature,
434 llvm::formatv("could not find interpreter dictionary: {0}",
435 m_interpreter.GetDictionaryName())
436 .str(),
437 error);
438
439 // Resolve the class.
440 auto class_obj =
441 PythonObject::ResolveNameWithDictionary<python::PythonCallable>(
442 class_name, dict);
443 if (!class_obj.IsAllocated())
444 return ErrorWithMessage<T>(
445 caller_signature,
446 llvm::formatv("could not find script class: {0}", class_name).str(),
447 error);
448
449 // Get the static method from the class.
450 if (!class_obj.HasAttribute(method_name))
451 return ErrorWithMessage<T>(
452 caller_signature,
453 llvm::formatv("class {0} does not have method {1}", class_name,
454 method_name)
455 .str(),
456 error);
457
458 PythonCallable method =
459 class_obj.GetAttributeValue(method_name).AsType<PythonCallable>();
460 if (!method.IsAllocated())
461 return ErrorWithMessage<T>(caller_signature,
462 llvm::formatv("method {0}.{1} is not callable",
463 class_name, method_name)
464 .str(),
465 error);
466
467 // Transform the arguments.
468 std::tuple<Args...> original_args = std::forward_as_tuple(args...);
469 auto transformed_args = TransformArgs(original_args);
470
471 // Call the static method.
472 llvm::Expected<PythonObject> expected_return_object =
473 llvm::createStringError("not initialized");
474 std::apply(
475 [&method, &expected_return_object](auto &&...args) {
476 llvm::consumeError(expected_return_object.takeError());
477 expected_return_object = method(args...);
478 },
479 transformed_args);
480
481 if (llvm::Error e = expected_return_object.takeError()) {
482 error = Status::FromError(std::move(e));
483 return ErrorWithMessage<T>(
484 caller_signature, "python static method could not be called", error);
485 }
486
487 PythonObject py_return = std::move(expected_return_object.get());
488
489 // Re-assign reference and pointer arguments if needed.
490 if (sizeof...(Args) > 0)
491 if (!ReassignPtrsOrRefsArgs(original_args, transformed_args))
492 return ErrorWithMessage<T>(
493 caller_signature,
494 "couldn't re-assign reference and pointer arguments", error);
495
496 // Extract value from Python object (handles unallocated case).
497 return ExtractValueFromPythonObject<T>(py_return, error);
498 }
499
500protected:
501 template <typename T = StructuredData::ObjectSP>
505
506 template <typename T = StructuredData::ObjectSP, typename... Args>
507 T Dispatch(llvm::StringRef method_name, Status &error, Args &&...args) {
508 using namespace python;
510
511 std::string caller_signature =
512 llvm::Twine(LLVM_PRETTY_FUNCTION + llvm::Twine(" (") +
513 llvm::Twine(method_name) + llvm::Twine(")"))
514 .str();
516 return ErrorWithMessage<T>(caller_signature, "python object ill-formed",
517 error);
518
521
522 PythonObject implementor(PyRefType::Borrowed,
523 (PyObject *)m_object_instance_sp->GetValue());
524
525 if (!implementor.IsAllocated())
526 return llvm::is_contained(GetAbstractMethods(), method_name)
527 ? ErrorWithMessage<T>(caller_signature,
528 "python implementor not allocated",
529 error)
530 : T{};
531
532 std::tuple<Args...> original_args = std::forward_as_tuple(args...);
533 auto transformed_args = TransformArgs(original_args);
534
535 llvm::Expected<PythonObject> expected_return_object =
536 llvm::createStringError("not initialized");
537 std::apply(
538 [&implementor, &method_name, &expected_return_object](auto &&...args) {
539 llvm::consumeError(expected_return_object.takeError());
540 expected_return_object =
541 implementor.CallMethod(method_name.data(), args...);
542 },
543 transformed_args);
544
545 if (llvm::Error e = expected_return_object.takeError()) {
546 error = Status::FromError(std::move(e));
547 return ErrorWithMessage<T>(caller_signature,
548 "python method could not be called", error);
549 }
550
551 PythonObject py_return = std::move(expected_return_object.get());
552
553 // Now that we called the python method with the transformed arguments,
554 // we need to iterate again over both the original and transformed
555 // parameter pack, and transform back the parameter that were passed in
556 // the original parameter pack as references or pointers.
557 if (sizeof...(Args) > 0)
558 if (!ReassignPtrsOrRefsArgs(original_args, transformed_args))
559 return ErrorWithMessage<T>(
560 caller_signature,
561 "couldn't re-assign reference and pointer arguments", error);
562
563 if (!py_return.IsAllocated())
564 return {};
565 return ExtractValueFromPythonObject<T>(py_return, error);
566 }
567
568 template <typename... Args>
569 Status GetStatusFromMethod(llvm::StringRef method_name, Args &&...args) {
571 Dispatch<Status>(method_name, error, std::forward<Args>(args)...);
572
573 return error;
574 }
575
576 template <typename T> T Transform(T object) {
577 // No Transformation for generic usage
578 return {object};
579 }
580
582 // Boolean arguments need to be turned into python objects.
583 return python::PythonBoolean(arg);
584 }
585
589
591 return python::SWIGBridge::ToSWIGWrapper(std::move(arg));
592 }
593
597
598 template <typename T, typename = std::enable_if_t<
599 std::is_base_of_v<StructuredData::Object, T>>>
600 python::PythonObject Transform(std::shared_ptr<T> arg) {
601 return Transform(StructuredDataImpl(arg));
602 }
603
607
611
615
619
623
627
631
635
639
643
647
651
655
659
663
667
671
675
676 python::PythonObject Transform(const std::vector<std::string> &arg) {
678 for (const std::string &s : arg)
680 return list;
681 }
682
687
691
692 template <typename T, typename U>
693 void ReverseTransform(T &original_arg, U transformed_arg, Status &error) {
694 // If U is not a PythonObject, don't touch it!
695 }
696
697 template <typename T>
698 void ReverseTransform(T &original_arg, python::PythonObject transformed_arg,
699 Status &error) {
700 original_arg = ExtractValueFromPythonObject<T>(transformed_arg, error);
701 }
702
703 // Read-only arguments (passed as `const T&`) have nothing to write back:
704 // there's no `T` value to reassign into a const reference, and no
705 // `ExtractValueFromPythonObject<T>` specialization should be required just
706 // to satisfy this round-trip for a value the callee never mutates.
707 template <typename T>
708 void ReverseTransform(const T &original_arg,
709 python::PythonObject transformed_arg, Status &error) {}
710
711 void ReverseTransform(bool &original_arg,
712 python::PythonObject transformed_arg, Status &error) {
714 python::PyRefType::Borrowed, transformed_arg.get());
715 if (boolean_arg.IsValid())
716 original_arg = boolean_arg.GetValue();
717 else
719 "{}: Invalid boolean argument.", LLVM_PRETTY_FUNCTION);
720 }
721
722 template <std::size_t... I, typename... Args>
723 auto TransformTuple(const std::tuple<Args...> &args,
724 std::index_sequence<I...>) {
725 return std::make_tuple(Transform(std::get<I>(args))...);
726 }
727
728 // This will iterate over the Dispatch parameter pack and replace in-place
729 // every `lldb_private` argument that has a SB counterpart.
730 template <typename... Args>
731 auto TransformArgs(const std::tuple<Args...> &args) {
732 return TransformTuple(args, std::make_index_sequence<sizeof...(Args)>());
733 }
734
735 template <typename T, typename U>
736 void TransformBack(T &original_arg, U transformed_arg, Status &error) {
737 ReverseTransform(original_arg, transformed_arg, error);
738 }
739
740 // ScopedPythonObject is non-copyable — passing it through the generic
741 // TransformBack would trigger the deleted copy ctor. It manages its own
742 // cleanup via the destructor when the transformed-args tuple destructs, so
743 // there is nothing to reverse-transform back into the original arg.
744 template <typename T, typename SB>
745 void TransformBack(T &original_arg,
746 python::ScopedPythonObject<SB> &transformed_arg,
747 Status &error) {}
748
749 template <std::size_t... I, typename... Ts, typename... Us>
750 bool ReassignPtrsOrRefsArgs(std::tuple<Ts...> &original_args,
751 std::tuple<Us...> &transformed_args,
752 std::index_sequence<I...>) {
754 (TransformBack(std::get<I>(original_args), std::get<I>(transformed_args),
755 error),
756 ...);
757 return error.Success();
758 }
759
760 template <typename... Ts, typename... Us>
761 bool ReassignPtrsOrRefsArgs(std::tuple<Ts...> &original_args,
762 std::tuple<Us...> &transformed_args) {
763 if (sizeof...(Ts) != sizeof...(Us))
764 return false;
765
766 return ReassignPtrsOrRefsArgs(original_args, transformed_args,
767 std::make_index_sequence<sizeof...(Ts)>());
768 }
769
770 template <typename T, typename... Args>
771 void FormatArgs(std::string &fmt, T arg, Args... args) const {
772 FormatArgs(fmt, arg);
773 FormatArgs(fmt, args...);
774 }
775
776 template <typename T> void FormatArgs(std::string &fmt, T arg) const {
778 }
779
780 void FormatArgs(std::string &fmt) const {}
781
782 // The lifetime is managed by the ScriptInterpreter
784};
785
786template <>
790
791template <>
795
796template <>
799
800template <>
803
804template <>
808
809template <>
813
814template <>
818
819template <>
823
824template <>
828
829template <>
833
834template <>
837
838template <>
841
842template <>
846
847template <>
848std::optional<MemoryRegionInfo>
850 std::optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error);
851
852template <>
856
857template <>
861
862template <>
866
867template <>
871
872template <>
876
877template <>
881
882template <>
883std::optional<lldb::ValueType>
885 std::optional<lldb::ValueType>>(python::PythonObject &p, Status &error);
886
887template <>
891
892template <>
893std::vector<std::string>
896
897} // namespace lldb_private
898
899#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:375
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)
std::optional< ScriptedMetadata > m_scripted_metadata
llvm::SmallVector< llvm::StringLiteral > const GetAbstractMethods() const
virtual llvm::SmallVector< AbstractMethodRequirement > GetAbstractMethodRequirements() const =0
StructuredData::GenericSP m_object_instance_sp
llvm::StringRef GetClassName() const
python::ScopedPythonObject< lldb::SBCommandReturnObject > Transform(CommandReturnObject *arg)
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)
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
python::PythonObject Transform(const TypeSummaryOptions &arg)
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
python::PythonObject Transform(lldb::DebuggerSP arg)
ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter)
python::PythonObject Transform(const std::vector< std::string > &arg)
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)
python::PythonObject Transform(std::shared_ptr< T > 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)
llvm::Expected< StructuredData::GenericSP > CreatePluginObject(const ScriptedMetadata &scripted_metadata, StructuredData::Generic *script_obj, Args... args)
python::PythonObject Transform(lldb::TargetSP arg)
void TransformBack(T &original_arg, python::ScopedPythonObject< SB > &transformed_arg, Status &error)
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)
void ReverseTransform(const T &original_arg, python::PythonObject transformed_arg, Status &error)
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
void AppendItem(const PythonObject &object)
StructuredData::ObjectSP CreateStructuredObject() const
static PythonObject ToSWIGWrapper(std::unique_ptr< lldb::SBValue > value_sb)
A class that automatically clears an SB object when it goes out of scope.
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:338
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::Debugger > DebuggerSP
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