LLDB mainline
TypeSynthetic.cpp
Go to the documentation of this file.
1//===-- TypeSynthetic.cpp -------------------------------------------------===//
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
10
11
13#include "lldb/lldb-public.h"
14
15#include "lldb/Core/Debugger.h"
20#include "lldb/Target/Target.h"
22
23using namespace lldb;
24using namespace lldb_private;
25
26void TypeFilterImpl::AddExpressionPath(const std::string &path) {
27 bool need_add_dot = true;
28 if (path[0] == '.' || (path[0] == '-' && path[1] == '>') || path[0] == '[')
29 need_add_dot = false;
30 // add a '.' symbol to help forgetful users
31 if (!need_add_dot)
32 m_expression_paths.push_back(path);
33 else
34 m_expression_paths.push_back(std::string(".") + path);
35}
36
38 const std::string &path) {
39 if (i >= GetCount())
40 return false;
41 bool need_add_dot = true;
42 if (path[0] == '.' || (path[0] == '-' && path[1] == '>') || path[0] == '[')
43 need_add_dot = false;
44 // add a '.' symbol to help forgetful users
45 if (!need_add_dot)
46 m_expression_paths[i] = path;
47 else
48 m_expression_paths[i] = std::string(".") + path;
49 return true;
50}
51
52llvm::Expected<size_t>
54 const char *name_cstr = name.GetCString();
55 if (name_cstr) {
56 for (size_t i = 0; i < filter->GetCount(); i++) {
57 const char *expr_cstr = filter->GetExpressionPathAtIndex(i);
58 if (expr_cstr) {
59 if (*expr_cstr == '.')
60 expr_cstr++;
61 else if (*expr_cstr == '-' && *(expr_cstr + 1) == '>')
62 expr_cstr += 2;
63 }
64 if (expr_cstr) {
65 if (!::strcmp(name_cstr, expr_cstr))
66 return i;
67 }
68 }
69 }
70 return llvm::createStringError("Type has no child named '%s'",
71 name.AsCString());
72}
73
75 StreamString sstr;
76 sstr.Printf("%s%s%s {\n", Cascades() ? "" : " (not cascading)",
77 SkipsPointers() ? " (skip pointers)" : "",
78 SkipsReferences() ? " (skip references)" : "");
79
80 for (size_t i = 0; i < GetCount(); i++) {
81 sstr.Printf(" %s\n", GetExpressionPathAtIndex(i));
82 }
83
84 sstr.Printf("}");
85 return std::string(sstr.GetString());
86}
87
89
91
93 const SyntheticChildren::Flags &flags, const char *description,
95 : SyntheticChildren(flags), m_create_callback(std::move(callback)),
96 m_description(description ? description : "") {}
97
99
100bool SyntheticChildren::IsScripted() { return false; }
101
102std::string SyntheticChildren::GetDescription() { return ""; }
103
106 return nullptr;
107}
108
110 StreamString sstr;
111 sstr.Printf("%s%s%s %s", Cascades() ? "" : " (not cascading)",
112 SkipsPointers() ? " (skip pointers)" : "",
113 SkipsReferences() ? " (skip references)" : "",
114 m_description.c_str());
115
116 return std::string(sstr.GetString());
117}
118
119uint32_t
121 auto value_or_err = CalculateNumChildren(max);
122 if (value_or_err)
123 return *value_or_err;
124 LLDB_LOG_ERRORV(GetLog(LLDBLog::DataFormatters), value_or_err.takeError(),
125 "{0}");
126 return 0;
127}
128
130 llvm::StringRef name, llvm::StringRef expression,
131 const ExecutionContext &exe_ctx) {
132 ValueObjectSP valobj_sp(
133 ValueObject::CreateValueObjectFromExpression(name, expression, exe_ctx));
134 if (valobj_sp)
135 valobj_sp->SetSyntheticChildrenGenerated(true);
136 return valobj_sp;
137}
138
140 llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx,
141 CompilerType type, bool do_deref) {
143 name, address, exe_ctx, type, do_deref));
144 if (valobj_sp)
145 valobj_sp->SetSyntheticChildrenGenerated(true);
146 return valobj_sp;
147}
148
150 llvm::StringRef name, const DataExtractor &data,
151 const ExecutionContext &exe_ctx, CompilerType type) {
152 ValueObjectSP valobj_sp(
153 ValueObject::CreateValueObjectFromData(name, data, exe_ctx, type));
154 if (valobj_sp)
155 valobj_sp->SetSyntheticChildrenGenerated(true);
156 return valobj_sp;
157}
158
160 ValueObject &backend)
161 : SyntheticChildrenFrontEnd(backend), m_python_class(pclass),
162 m_wrapper_sp(), m_interpreter(nullptr) {
163 if (backend.GetID() == LLDB_INVALID_UID)
164 return;
165
166 TargetSP target_sp = backend.GetTargetSP();
167
168 if (!target_sp)
169 return;
170
171 m_interpreter = target_sp->GetDebugger().GetScriptInterpreter();
172
173 if (m_interpreter != nullptr)
174 m_wrapper_sp = m_interpreter->CreateSyntheticScriptedProvider(
175 m_python_class.c_str(), backend.GetSP());
176}
177
179
183 return lldb::ValueObjectSP();
184
185 return m_interpreter->GetChildAtIndex(m_wrapper_sp, idx);
186}
187
191
192llvm::Expected<uint32_t>
194 if (!m_wrapper_sp || m_interpreter == nullptr)
195 return 0;
196 return m_interpreter->CalculateNumChildren(m_wrapper_sp, UINT32_MAX);
197}
198
199llvm::Expected<uint32_t>
201 if (!m_wrapper_sp || m_interpreter == nullptr)
202 return 0;
203 return m_interpreter->CalculateNumChildren(m_wrapper_sp, max);
204}
205
214
216 if (!m_wrapper_sp || m_interpreter == nullptr)
217 return false;
218
219 return m_interpreter->MightHaveChildrenSynthProviderInstance(m_wrapper_sp);
220}
221
222llvm::Expected<size_t>
224 if (!m_wrapper_sp || m_interpreter == nullptr)
225 return llvm::createStringError("Type has no child named '%s'",
226 name.AsCString());
227 return m_interpreter->GetIndexOfChildWithName(m_wrapper_sp,
228 name.GetCString());
229}
230
232 if (!m_wrapper_sp || m_interpreter == nullptr)
233 return nullptr;
234
235 return m_interpreter->GetSyntheticValue(m_wrapper_sp);
236}
237
239 if (!m_wrapper_sp || m_interpreter == nullptr)
240 return ConstString();
241
242 return m_interpreter->GetSyntheticTypeName(m_wrapper_sp);
243}
244
246 StreamString sstr;
247 sstr.Printf("%s%s%s Python class %s", Cascades() ? "" : " (not cascading)",
248 SkipsPointers() ? " (skip pointers)" : "",
249 SkipsReferences() ? " (skip references)" : "",
250 m_python_class.c_str());
251
252 return std::string(sstr.GetString());
253}
#define LLDB_LOG_ERRORV(log, error,...)
Definition Log.h:408
CreateFrontEndCallback m_create_callback
std::string GetDescription() override
CXXSyntheticChildren(const SyntheticChildren::Flags &flags, const char *description, CreateFrontEndCallback callback)
std::function< SyntheticChildrenFrontEnd *(CXXSyntheticChildren *, lldb::ValueObjectSP)> CreateFrontEndCallback
Generic representation of a type in a programming language.
A uniqued constant string class.
Definition ConstString.h:40
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
const char * GetCString() const
Get the string value as a C string.
An data extractor class.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
lldb::ChildCacheState Update() override
This function is assumed to always succeed and if it fails, the front-end should know to deal with it...
llvm::Expected< size_t > GetIndexOfChildWithName(ConstString name) override
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override
FrontEnd(std::string pclass, ValueObject &backend)
llvm::Expected< uint32_t > CalculateNumChildren() override
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
uint32_t CalculateNumChildrenIgnoringErrors(uint32_t max=UINT32_MAX)
lldb::ValueObjectSP CreateValueObjectFromExpression(llvm::StringRef name, llvm::StringRef expression, const ExecutionContext &exe_ctx)
std::unique_ptr< SyntheticChildrenFrontEnd > AutoPointer
lldb::ValueObjectSP CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data, const ExecutionContext &exe_ctx, CompilerType type)
virtual llvm::Expected< uint32_t > CalculateNumChildren()=0
SyntheticChildrenFrontEnd(ValueObject &backend)
lldb::ValueObjectSP CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx, CompilerType type, bool do_deref=true)
virtual std::string GetDescription()=0
virtual SyntheticChildrenFrontEnd::AutoPointer GetFrontEnd(ValueObject &backend)=0
SyntheticChildren(const Flags &flags)
llvm::Expected< size_t > GetIndexOfChildWithName(ConstString name) override
bool SetExpressionPathAtIndex(size_t i, const char *path)
const char * GetExpressionPathAtIndex(size_t i) const
void AddExpressionPath(const char *path)
std::string GetDescription() override
std::vector< std::string > m_expression_paths
static lldb::ValueObjectSP CreateValueObjectFromExpression(llvm::StringRef name, llvm::StringRef expression, const ExecutionContext &exe_ctx)
lldb::ValueObjectSP GetSP()
lldb::user_id_t GetID() const
Returns a unique id for this ValueObject.
static lldb::ValueObjectSP CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx, CompilerType type, bool do_deref=true)
Given an address either create a value object containing the value at that address,...
static lldb::ValueObjectSP CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data, const ExecutionContext &exe_ctx, CompilerType type)
lldb::TargetSP GetTargetSP() const
#define LLDB_INVALID_UID
#define UINT32_MAX
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
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
std::shared_ptr< lldb_private::Target > TargetSP