LLDB mainline
ValueObjectSyntheticFilter.cpp
Go to the documentation of this file.
1//===-- ValueObjectSyntheticFilter.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
10
11#include "lldb/Core/Value.h"
17#include "lldb/Utility/Log.h"
18#include "lldb/Utility/Status.h"
19
20#include "llvm/ADT/STLExtras.h"
21#include <optional>
22
23namespace lldb_private {
24class Declaration;
25}
26
27using namespace lldb_private;
28
30public:
32 : SyntheticChildrenFrontEnd(backend) {}
33
34 size_t CalculateNumChildren() override { return m_backend.GetNumChildren(); }
35
36 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
37 return m_backend.GetChildAtIndex(idx);
38 }
39
40 size_t GetIndexOfChildWithName(ConstString name) override {
42 }
43
44 bool MightHaveChildren() override { return m_backend.MightHaveChildren(); }
45
46 bool Update() override { return false; }
47};
48
51 : ValueObject(parent), m_synth_sp(std::move(filter)), m_children_byindex(),
52 m_name_toindex(), m_synthetic_children_cache(),
53 m_synthetic_children_count(UINT32_MAX),
54 m_parent_type_name(parent.GetTypeName()),
55 m_might_have_children(eLazyBoolCalculate),
56 m_provides_value(eLazyBoolCalculate) {
57 SetName(parent.GetName());
58 // Copying the data of an incomplete type won't work as it has no byte size.
62}
63
65
67 return m_parent->GetCompilerType();
68}
69
71 return m_parent->GetTypeName();
72}
73
76}
77
79 if (ConstString synth_name = m_synth_filter_up->GetSyntheticTypeName())
80 return synth_name;
81
83}
84
87
91
92 if (max < UINT32_MAX) {
93 size_t num_children = m_synth_filter_up->CalculateNumChildren(max);
94 LLDB_LOGF(log,
95 "[ValueObjectSynthetic::CalculateNumChildren] for VO of name "
96 "%s and type %s, the filter returned %zu child values",
97 GetName().AsCString(), GetTypeName().AsCString(), num_children);
98 return num_children;
99 } else {
100 size_t num_children = (m_synthetic_children_count =
101 m_synth_filter_up->CalculateNumChildren(max));
102 LLDB_LOGF(log,
103 "[ValueObjectSynthetic::CalculateNumChildren] for VO of name "
104 "%s and type %s, the filter returned %zu child values",
105 GetName().AsCString(), GetTypeName().AsCString(), num_children);
106 return num_children;
107 }
108}
109
112 if (!m_parent)
113 return lldb::ValueObjectSP();
114 if (IsDynamic() && GetDynamicValueType() == valueType)
115 return GetSP();
116 return m_parent->GetDynamicValue(valueType);
117}
118
122 (m_synth_filter_up->MightHaveChildren() ? eLazyBoolYes : eLazyBoolNo);
124}
125
126std::optional<uint64_t> ValueObjectSynthetic::GetByteSize() {
127 return m_parent->GetByteSize();
128}
129
131 return m_parent->GetValueType();
132}
133
135 ValueObject *valobj_for_frontend = m_parent;
136 if (m_synth_sp->WantsDereference())
137 {
139 if (type.IsValid() && type.IsPointerOrReferenceType())
140 {
143 if (error.Success())
144 valobj_for_frontend = deref_sp.get();
145 }
146 }
147 m_synth_filter_up = (m_synth_sp->GetFrontEnd(*valobj_for_frontend));
149 m_synth_filter_up = std::make_unique<DummySyntheticFrontEnd>(*m_parent);
150}
151
154
155 SetValueIsValid(false);
156 m_error.Clear();
157
158 if (!m_parent->UpdateValueIfNeeded(false)) {
159 // our parent could not update.. as we are meaningless without a parent,
160 // just stop
161 if (m_parent->GetError().Fail())
163 return false;
164 }
165
166 // Regenerate the synthetic filter if our typename changes. When the (dynamic)
167 // type of an object changes, so does their synthetic filter of choice.
168 ConstString new_parent_type_name = m_parent->GetTypeName();
169 if (new_parent_type_name != m_parent_type_name) {
170 LLDB_LOGF(log,
171 "[ValueObjectSynthetic::UpdateValue] name=%s, type changed "
172 "from %s to %s, recomputing synthetic filter",
173 GetName().AsCString(), m_parent_type_name.AsCString(),
174 new_parent_type_name.AsCString());
175 m_parent_type_name = new_parent_type_name;
177 }
178
179 // let our backend do its update
180 if (!m_synth_filter_up->Update()) {
181 LLDB_LOGF(log,
182 "[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
183 "filter said caches are stale - clearing",
184 GetName().AsCString());
185 // filter said that cached values are stale
186 {
187 std::lock_guard<std::mutex> guard(m_child_mutex);
188 m_children_byindex.clear();
189 m_name_toindex.clear();
190 }
191 // usually, an object's value can change but this does not alter its
192 // children count for a synthetic VO that might indeed happen, so we need
193 // to tell the upper echelons that they need to come back to us asking for
194 // children
196 {
197 std::lock_guard<std::mutex> guard(m_child_mutex);
199 }
202 } else {
203 LLDB_LOGF(log,
204 "[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
205 "filter said caches are still valid",
206 GetName().AsCString());
207 }
208
210
211 lldb::ValueObjectSP synth_val(m_synth_filter_up->GetSyntheticValue());
212
213 if (synth_val && synth_val->CanProvideValue()) {
214 LLDB_LOGF(log,
215 "[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
216 "filter said it can provide a value",
217 GetName().AsCString());
218
220 CopyValueData(synth_val.get());
221 } else {
222 LLDB_LOGF(log,
223 "[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
224 "filter said it will not provide a value",
225 GetName().AsCString());
226
228 // Copying the data of an incomplete type won't work as it has no byte size.
231 }
232
233 SetValueIsValid(true);
234 return true;
235}
236
238 bool can_create) {
240
241 LLDB_LOGF(log,
242 "[ValueObjectSynthetic::GetChildAtIndex] name=%s, retrieving "
243 "child at index %zu",
244 GetName().AsCString(), idx);
245
247
248 ValueObject *valobj;
249 bool child_is_cached;
250 {
251 std::lock_guard<std::mutex> guard(m_child_mutex);
252 auto cached_child_it = m_children_byindex.find(idx);
253 child_is_cached = cached_child_it != m_children_byindex.end();
254 if (child_is_cached)
255 valobj = cached_child_it->second;
256 }
257
258 if (!child_is_cached) {
259 if (can_create && m_synth_filter_up != nullptr) {
260 LLDB_LOGF(log,
261 "[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
262 "index %zu not cached and will be created",
263 GetName().AsCString(), idx);
264
265 lldb::ValueObjectSP synth_guy = m_synth_filter_up->GetChildAtIndex(idx);
266
267 LLDB_LOGF(
268 log,
269 "[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at index "
270 "%zu created as %p (is "
271 "synthetic: %s)",
272 GetName().AsCString(), idx, static_cast<void *>(synth_guy.get()),
273 synth_guy.get()
274 ? (synth_guy->IsSyntheticChildrenGenerated() ? "yes" : "no")
275 : "no");
276
277 if (!synth_guy)
278 return synth_guy;
279
280 {
281 std::lock_guard<std::mutex> guard(m_child_mutex);
282 if (synth_guy->IsSyntheticChildrenGenerated())
283 m_synthetic_children_cache.push_back(synth_guy);
284 m_children_byindex[idx] = synth_guy.get();
285 }
286 synth_guy->SetPreferredDisplayLanguageIfNeeded(
288 return synth_guy;
289 } else {
290 LLDB_LOGF(log,
291 "[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
292 "index %zu not cached and cannot "
293 "be created (can_create = %s, synth_filter = %p)",
294 GetName().AsCString(), idx, can_create ? "yes" : "no",
295 static_cast<void *>(m_synth_filter_up.get()));
296
297 return lldb::ValueObjectSP();
298 }
299 } else {
300 LLDB_LOGF(log,
301 "[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
302 "index %zu cached as %p",
303 GetName().AsCString(), idx, static_cast<void *>(valobj));
304
305 return valobj->GetSP();
306 }
307}
308
311 bool can_create) {
313
314 uint32_t index = GetIndexOfChildWithName(name);
315
316 if (index == UINT32_MAX)
317 return lldb::ValueObjectSP();
318
319 return GetChildAtIndex(index, can_create);
320}
321
322size_t ValueObjectSynthetic::GetIndexOfChildWithName(llvm::StringRef name_ref) {
324
325 ConstString name(name_ref);
326
327 uint32_t found_index = UINT32_MAX;
328 bool did_find;
329 {
330 std::lock_guard<std::mutex> guard(m_child_mutex);
331 auto name_to_index = m_name_toindex.find(name.GetCString());
332 did_find = name_to_index != m_name_toindex.end();
333 if (did_find)
334 found_index = name_to_index->second;
335 }
336
337 if (!did_find && m_synth_filter_up != nullptr) {
338 uint32_t index = m_synth_filter_up->GetIndexOfChildWithName(name);
339 if (index == UINT32_MAX)
340 return index;
341 std::lock_guard<std::mutex> guard(m_child_mutex);
342 m_name_toindex[name.GetCString()] = index;
343 return index;
344 } else if (!did_find && m_synth_filter_up == nullptr)
345 return UINT32_MAX;
346 else /*if (iter != m_name_toindex.end())*/
347 return found_index;
348}
349
351
353 return m_parent->GetSP();
354}
355
357 m_value = (source->UpdateValueIfNeeded(), source->GetValue());
359 m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
360}
361
363 if (!UpdateValueIfNeeded())
364 return false;
366 return true;
367 return m_parent->CanProvideValue();
368}
369
371 Status &error) {
372 return m_parent->SetValueFromCString(value_str, error);
373}
374
376 if (m_parent) {
378 m_parent->SetFormat(format);
379 }
380 this->ValueObject::SetFormat(format);
382}
383
385 lldb::LanguageType lang) {
387 if (m_parent)
389}
390
393 if (m_parent)
396 } else
398}
399
401 if (m_parent)
403 return false;
404}
405
407 if (m_parent)
410}
411
413 if (m_parent)
414 return m_parent->GetDeclaration(decl);
415
416 return ValueObject::GetDeclaration(decl);
417}
418
420 if (m_parent)
421 return m_parent->GetLanguageFlags();
422 return this->ValueObject::GetLanguageFlags();
423}
424
426 if (m_parent)
428 else
430}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
Definition: Log.h:349
size_t GetIndexOfChildWithName(ConstString name) override
DummySyntheticFrontEnd(ValueObject &backend)
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
bool IsPointerOrReferenceType(CompilerType *pointee_type=nullptr) const
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.
Definition: ConstString.h:182
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:205
A class that describes the declaration location of a lldb object.
Definition: Declaration.h:24
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
An error handling class.
Definition: Status.h:44
void Clear()
Clear the object state.
Definition: Status.cpp:167
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
virtual lldb::DynamicValueType GetDynamicValueType()
size_t GetIndexOfChildWithName(llvm::StringRef name) override
bool SetValueFromCString(const char *value_str, Status &error) override
size_t CalculateNumChildren(uint32_t max) override
Should only be called by ValueObject::GetNumChildren().
lldb::ValueType GetValueType() const override
lldb::LanguageType GetPreferredDisplayLanguage() override
void SetFormat(lldb::Format format) override
lldb::ValueObjectSP GetChildAtIndex(size_t idx, bool can_create=true) override
NameToIndexMap m_name_toindex
Guarded by m_child_mutex;.
ByIndexMap m_children_byindex
Guarded by m_child_mutex;.
std::unique_ptr< SyntheticChildrenFrontEnd > m_synth_filter_up
lldb::ValueObjectSP GetDynamicValue(lldb::DynamicValueType valueType) override
lldb::ValueObjectSP GetNonSyntheticValue() override
SyntheticChildrenCache m_synthetic_children_cache
Guarded by m_child_mutex;.
std::optional< uint64_t > GetByteSize() override
bool GetDeclaration(Declaration &decl) override
bool MightHaveChildren() override
Find out if a ValueObject might have children.
lldb::ValueObjectSP GetChildMemberWithName(llvm::StringRef name, bool can_create=true) override
ValueObjectSynthetic(ValueObject &parent, lldb::SyntheticChildrenSP filter)
void SetLanguageFlags(uint64_t flags) override
void SetValueIsValid(bool valid)
Definition: ValueObject.h:978
void ClearUserVisibleData(uint32_t items=ValueObject::eClearUserVisibleDataItemsAllStrings)
virtual bool IsInScope()
Definition: ValueObject.h:420
size_t GetNumChildren(uint32_t max=UINT32_MAX)
virtual bool MightHaveChildren()
Find out if a ValueObject might have children.
CompilerType GetCompilerType()
Definition: ValueObject.h:352
void SetPreferredDisplayLanguage(lldb::LanguageType lt)
Definition: ValueObject.h:711
struct lldb_private::ValueObject::Bitflags m_flags
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:547
virtual void SetLanguageFlags(uint64_t flags)
Definition: ValueObject.h:789
Status m_error
An error object that can describe any errors that occur when updating values.
Definition: ValueObject.h:853
virtual uint64_t GetLanguageFlags()
Definition: ValueObject.h:787
virtual void SetSyntheticChildrenGenerated(bool b)
Definition: ValueObject.h:643
virtual std::optional< uint64_t > GetByteSize()=0
virtual size_t GetIndexOfChildWithName(llvm::StringRef name)
DataExtractor m_data
A data extractor that can be used to extract the value.
Definition: ValueObject.h:849
virtual lldb::ValueType GetValueType() const =0
virtual ConstString GetTypeName()
Definition: ValueObject.h:365
virtual lldb::ModuleSP GetModule()
Return the module associated with this value object in case the value is from an executable file and ...
virtual lldb::ValueObjectSP GetDynamicValue(lldb::DynamicValueType valueType)
virtual ConstString GetDisplayTypeName()
Definition: ValueObject.h:367
lldb::LanguageType m_preferred_display_language
Definition: ValueObject.h:898
virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx, bool can_create=true)
ValueObject * m_parent
The parent value object, or nullptr if this has no parent.
Definition: ValueObject.h:838
virtual bool GetDeclaration(Declaration &decl)
virtual bool IsSyntheticChildrenGenerated()
Definition: ValueObject.h:639
bool UpdateValueIfNeeded(bool update_format=true)
void SetName(ConstString name)
Change the name of the current ValueObject.
Definition: ValueObject.h:552
const Status & GetError()
virtual lldb::ValueObjectSP Dereference(Status &error)
ConstString GetName() const
Definition: ValueObject.h:463
virtual bool SetValueFromCString(const char *value_str, Status &error)
virtual ConstString GetQualifiedTypeName()
Definition: ValueObject.h:369
virtual void SetFormat(lldb::Format format)
Definition: ValueObject.h:703
const ExecutionContextRef & GetExecutionContextRef() const
Definition: ValueObject.h:330
virtual bool CanProvideValue()
const Value & GetValue() const
Definition: ValueObject.h:489
virtual lldb::LanguageType GetPreferredDisplayLanguage()
Status GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data, Module *module)
Definition: Value.cpp:315
#define UINT32_MAX
Definition: lldb-defines.h:19
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:314
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Definition: lldb-forward.h:467
Format
Display format definitions.
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
std::shared_ptr< lldb_private::SyntheticChildren > SyntheticChildrenSP
Definition: lldb-forward.h:429