LLDB mainline
ScriptedSyntheticChildrenPythonInterface.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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#include "../lldb-python.h"
10
15
16#include "../SWIGPythonBridge.h"
19
20using namespace lldb;
21using namespace lldb_private;
22using namespace lldb_private::python;
24
30
31llvm::Expected<StructuredData::GenericSP>
33 llvm::StringRef class_name, ValueObject &backend) {
34 if (class_name.empty())
35 return llvm::createStringError("empty class name");
36
37 ValueObjectSP valobj_sp = backend.GetSP();
38 if (!valobj_sp)
39 return llvm::createStringError("invalid backing value");
40
41 Locker py_lock(&m_interpreter,
44
45 // Hand the provider's __init__ a fresh SBValue view of the backing value
46 // with synthetic children disabled, so introspecting it doesn't recursively
47 // re-enter this provider. `SetPreferSyntheticValue` lives on the SBValue's
48 // ValueImpl, so this override doesn't affect the caller's original view.
49 PythonObject val_arg =
50 SWIGBridge::ToSWIGWrapper(valobj_sp, /*use_synthetic=*/false);
51
52 ScriptedMetadata scripted_metadata(class_name,
55 scripted_metadata, /*script_obj=*/nullptr, std::move(val_arg));
56}
57
58llvm::Expected<uint32_t>
61 StructuredData::ObjectSP obj = Dispatch("num_children", error, max);
62 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
63 error))
64 return 0;
65 // Cap at max in case the provider ignores the argument (e.g. defines
66 // `num_children(self)`) and returns an unbounded count.
67 return std::min<uint32_t>(obj->GetUnsignedIntegerValue(), max);
68}
69
75
76llvm::Expected<uint32_t>
78 ConstString name) {
81 Dispatch("get_child_index", error, name.GetCString());
82 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
83 error))
84 return llvm::createStringErrorV("type has no child named '{0}'", name);
85
86 // `CreateStructuredObject` only produces a `SignedInteger` for values that
87 // don't fit as unsigned, i.e. negative ones; a non-negative index comes
88 // back as `UnsignedInteger` instead, so check the sign this way rather
89 // than via `GetSignedIntegerValue`, which would misread every valid index.
90 if (obj->GetAsSignedInteger())
91 return llvm::createStringErrorV("type has no child named '{0}'", name);
92 return static_cast<uint32_t>(obj->GetUnsignedIntegerValue());
93}
94
97 // update() is optional; a missing method means "always refetch".
99 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
100 error))
101 return lldb::eRefetch;
102 return obj->GetBooleanValue() ? lldb::eReuse : lldb::eRefetch;
103}
104
107 // has_children() is optional and defaults to True when missing.
108 StructuredData::ObjectSP obj = Dispatch("has_children", error);
109 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
110 error))
111 return true;
112 return obj->GetBooleanValue();
113}
114
120
123 StructuredData::ObjectSP obj = Dispatch("get_type_name", error);
124 if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
125 error))
126 return {};
127 return ConstString(obj->GetStringValue());
128}
129
131 const std::vector<llvm::StringRef> ci_usages = {
132 "type synthetic add -l <ClassName> <TypeName>"};
133 const std::vector<llvm::StringRef> api_usages = {
134 "SBTypeSynthetic.CreateWithClassName"};
137 "Provide synthetic children for a type, used by 'type synthetic add -l'",
139 eScriptLanguagePython, {ci_usages, api_usages});
140}
141
static llvm::raw_ostream & error(Stream &strm)
ScriptInterpreterPythonImpl::Locker Locker
A uniqued constant string class.
Definition ConstString.h:40
const char * GetCString() const
Get the string value as a C string.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
static bool CheckStructuredDataObject(llvm::StringRef caller, T obj, Status &error)
static bool CreateInstance(lldb::ScriptLanguage language, ScriptedInterfaceUsages usages)
ScriptInterpreterPythonImpl & m_interpreter
ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter)
T Dispatch(llvm::StringRef method_name, Status &error, Args &&...args)
llvm::Expected< StructuredData::GenericSP > CreatePluginObject(const ScriptedMetadata &scripted_metadata, StructuredData::Generic *script_obj, Args... args)
llvm::Expected< StructuredData::GenericSP > CreatePluginObject(llvm::StringRef class_name, ValueObject &backend) override
llvm::Expected< uint32_t > GetIndexOfChildWithName(ConstString name) override
An error handling class.
Definition Status.h:118
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
lldb::ValueObjectSP GetSP()
static PythonObject ToSWIGWrapper(std::unique_ptr< lldb::SBValue > value_sb)
A class that represents a running process on the host machine.
@ eScriptLanguagePython
@ eScriptedExtensionScriptedSyntheticChildren
ChildCacheState
Specifies if children need to be re-computed after a call to SyntheticChildrenFrontEnd::Update.
@ eRefetch
Children need to be recomputed dynamically.
@ eReuse
Children did not change and don't need to be recomputed; re-use what we computed the last time we cal...
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP