Skip to content

[lldb][TypeSynthetic][NFC] Make SyntheticChildrenFrontend::Update() return an enum #80167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 16 additions & 11 deletions lldb/include/lldb/DataFormatters/TypeSynthetic.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@ class SyntheticChildrenFrontEnd {

virtual size_t GetIndexOfChildWithName(ConstString name) = 0;

// this function is assumed to always succeed and it if fails, the front-end
// should know to deal with it in the correct way (most probably, by refusing
// to return any children) the return value of Update() should actually be
// interpreted as "ValueObjectSyntheticFilter cache is good/bad" if =true,
// ValueObjectSyntheticFilter is allowed to use the children it fetched
// previously and cached if =false, ValueObjectSyntheticFilter must throw
// away its cache, and query again for children
virtual bool Update() = 0;
/// This function is assumed to always succeed and if it fails, the front-end
/// should know to deal with it in the correct way (most probably, by refusing
/// to return any children). The return value of \ref Update should actually
/// be interpreted as "ValueObjectSyntheticFilter cache is good/bad". If this
/// function returns \ref lldb::ChildCacheState::eReuse, \ref
/// ValueObjectSyntheticFilter is allowed to use the children it fetched
/// previously and cached. Otherwise, \ref ValueObjectSyntheticFilter must
/// throw away its cache, and query again for children.
virtual lldb::ChildCacheState Update() = 0;

// if this function returns false, then CalculateNumChildren() MUST return 0
// since UI frontends might validly decide not to inquire for children given
Expand Down Expand Up @@ -116,7 +117,9 @@ class SyntheticValueProviderFrontEnd : public SyntheticChildrenFrontEnd {
return UINT32_MAX;
}

bool Update() override { return false; }
lldb::ChildCacheState Update() override {
return lldb::ChildCacheState::eRefetch;
}

bool MightHaveChildren() override { return false; }

Expand Down Expand Up @@ -328,7 +331,9 @@ class TypeFilterImpl : public SyntheticChildren {
filter->GetExpressionPathAtIndex(idx), true);
}

bool Update() override { return false; }
lldb::ChildCacheState Update() override {
return lldb::ChildCacheState::eRefetch;
}

bool MightHaveChildren() override { return filter->GetCount() > 0; }

Expand Down Expand Up @@ -427,7 +432,7 @@ class ScriptedSyntheticChildren : public SyntheticChildren {

lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;

bool Update() override;
lldb::ChildCacheState Update() override;

bool MightHaveChildren() override;

Expand Down
2 changes: 1 addition & 1 deletion lldb/include/lldb/DataFormatters/VectorIterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class VectorIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd {

lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;

bool Update() override;
lldb::ChildCacheState Update() override;

bool MightHaveChildren() override;

Expand Down
9 changes: 9 additions & 0 deletions lldb/include/lldb/lldb-enumerations.h
Original file line number Diff line number Diff line change
Expand Up @@ -1305,6 +1305,15 @@ enum CompletionType {
eTerminatorCompletion = (1ul << 27)
};

/// Specifies if children need to be re-computed
/// after a call to \ref SyntheticChildrenFrontEnd::Update.
enum class ChildCacheState {
eRefetch = 0, ///< Children need to be recomputed dynamically.

eReuse = 1, ///< Children did not change and don't need to be recomputed;
///< re-use what we computed the last time we called Update.
};

} // namespace lldb

#endif // LLDB_LLDB_ENUMERATIONS_H
6 changes: 4 additions & 2 deletions lldb/source/Core/ValueObjectSyntheticFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ class DummySyntheticFrontEnd : public SyntheticChildrenFrontEnd {

bool MightHaveChildren() override { return m_backend.MightHaveChildren(); }

bool Update() override { return false; }
lldb::ChildCacheState Update() override {
return lldb::ChildCacheState::eRefetch;
}
};

ValueObjectSynthetic::ValueObjectSynthetic(ValueObject &parent,
Expand Down Expand Up @@ -177,7 +179,7 @@ bool ValueObjectSynthetic::UpdateValue() {
}

// let our backend do its update
if (!m_synth_filter_up->Update()) {
if (m_synth_filter_up->Update() == lldb::ChildCacheState::eRefetch) {
LLDB_LOGF(log,
"[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
"filter said caches are stale - clearing",
Expand Down
8 changes: 5 additions & 3 deletions lldb/source/DataFormatters/TypeSynthetic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,13 @@ size_t ScriptedSyntheticChildren::FrontEnd::CalculateNumChildren(uint32_t max) {
return m_interpreter->CalculateNumChildren(m_wrapper_sp, max);
}

bool ScriptedSyntheticChildren::FrontEnd::Update() {
lldb::ChildCacheState ScriptedSyntheticChildren::FrontEnd::Update() {
if (!m_wrapper_sp || m_interpreter == nullptr)
return false;
return lldb::ChildCacheState::eRefetch;

return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp);
return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp)
? lldb::ChildCacheState::eReuse
: lldb::ChildCacheState::eRefetch;
}

bool ScriptedSyntheticChildren::FrontEnd::MightHaveChildren() {
Expand Down
4 changes: 2 additions & 2 deletions lldb/source/DataFormatters/VectorType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ class VectorTypeSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
return child_sp;
}

bool Update() override {
lldb::ChildCacheState Update() override {
m_parent_format = m_backend.GetFormat();
CompilerType parent_type(m_backend.GetCompilerType());
CompilerType element_type;
Expand All @@ -258,7 +258,7 @@ class VectorTypeSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
::CalculateNumChildren(element_type, num_elements, m_child_type)
.value_or(0);
m_item_format = GetItemFormatForFormat(m_parent_format, m_child_type);
return false;
return lldb::ChildCacheState::eRefetch;
}

bool MightHaveChildren() override { return true; }
Expand Down
4 changes: 3 additions & 1 deletion lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ class BlockPointerSyntheticFrontEnd : public SyntheticChildrenFrontEnd {

// return true if this object is now safe to use forever without ever
// updating again; the typical (and tested) answer here is 'false'
bool Update() override { return false; }
lldb::ChildCacheState Update() override {
return lldb::ChildCacheState::eRefetch;
}

// maybe return false if the block pointer is, say, null
bool MightHaveChildren() override { return true; }
Expand Down
16 changes: 8 additions & 8 deletions lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,24 +125,24 @@ lldb::ValueObjectSP lldb_private::formatters::
return lldb::ValueObjectSP();
}

bool lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::
Update() {
lldb::ChildCacheState
lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::Update() {
m_resume_ptr_sp.reset();
m_destroy_ptr_sp.reset();
m_promise_ptr_sp.reset();

ValueObjectSP valobj_sp = m_backend.GetNonSyntheticValue();
if (!valobj_sp)
return false;
return lldb::ChildCacheState::eRefetch;

lldb::addr_t frame_ptr_addr = GetCoroFramePtrFromHandle(valobj_sp);
if (frame_ptr_addr == 0 || frame_ptr_addr == LLDB_INVALID_ADDRESS)
return false;
return lldb::ChildCacheState::eRefetch;

auto ts = valobj_sp->GetCompilerType().GetTypeSystem();
auto ast_ctx = ts.dyn_cast_or_null<TypeSystemClang>();
if (!ast_ctx)
return false;
return lldb::ChildCacheState::eRefetch;

// Create the `resume` and `destroy` children.
lldb::TargetSP target_sp = m_backend.GetTargetSP();
Expand All @@ -165,7 +165,7 @@ bool lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::
CompilerType promise_type(
valobj_sp->GetCompilerType().GetTypeTemplateArgument(0));
if (!promise_type)
return false;
return lldb::ChildCacheState::eRefetch;

// Try to infer the promise_type if it was type-erased
if (promise_type.IsVoidType()) {
Expand All @@ -180,7 +180,7 @@ bool lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::
// If we don't know the promise type, we don't display the `promise` member.
// `CreateValueObjectFromAddress` below would fail for `void` types.
if (promise_type.IsVoidType()) {
return false;
return lldb::ChildCacheState::eRefetch;
}

// Add the `promise` member. We intentionally add `promise` as a pointer type
Expand All @@ -194,7 +194,7 @@ bool lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::
if (error.Success())
m_promise_ptr_sp = promisePtr->Clone(ConstString("promise"));

return false;
return lldb::ChildCacheState::eRefetch;
}

bool lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Plugins/Language/CPlusPlus/Coroutines.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class StdlibCoroutineHandleSyntheticFrontEnd

lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;

bool Update() override;
lldb::ChildCacheState Update() override;

bool MightHaveChildren() override;

Expand Down
8 changes: 4 additions & 4 deletions lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class GenericBitsetFrontEnd : public SyntheticChildrenFrontEnd {
}

bool MightHaveChildren() override { return true; }
bool Update() override;
lldb::ChildCacheState Update() override;
size_t CalculateNumChildren() override { return m_elements.size(); }
ValueObjectSP GetChildAtIndex(size_t idx) override;

Expand Down Expand Up @@ -78,13 +78,13 @@ llvm::StringRef GenericBitsetFrontEnd::GetDataContainerMemberName() {
llvm_unreachable("Unknown StdLib enum");
}

bool GenericBitsetFrontEnd::Update() {
lldb::ChildCacheState GenericBitsetFrontEnd::Update() {
m_elements.clear();
m_first = nullptr;

TargetSP target_sp = m_backend.GetTargetSP();
if (!target_sp)
return false;
return lldb::ChildCacheState::eRefetch;

size_t size = 0;

Expand All @@ -94,7 +94,7 @@ bool GenericBitsetFrontEnd::Update() {
m_elements.assign(size, ValueObjectSP());
m_first =
m_backend.GetChildMemberWithName(GetDataContainerMemberName()).get();
return false;
return lldb::ChildCacheState::eRefetch;
}

ValueObjectSP GenericBitsetFrontEnd::GetChildAtIndex(size_t idx) {
Expand Down
8 changes: 4 additions & 4 deletions lldb/source/Plugins/Language/CPlusPlus/GenericOptional.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class GenericOptionalFrontend : public SyntheticChildrenFrontEnd {
size_t CalculateNumChildren() override { return m_has_value ? 1U : 0U; }

ValueObjectSP GetChildAtIndex(size_t idx) override;
bool Update() override;
lldb::ChildCacheState Update() override;

private:
bool m_has_value = false;
Expand All @@ -61,7 +61,7 @@ GenericOptionalFrontend::GenericOptionalFrontend(ValueObject &valobj,
}
}

bool GenericOptionalFrontend::Update() {
lldb::ChildCacheState GenericOptionalFrontend::Update() {
ValueObjectSP engaged_sp;

if (m_stdlib == StdLib::LibCxx)
Expand All @@ -71,14 +71,14 @@ bool GenericOptionalFrontend::Update() {
->GetChildMemberWithName("_M_engaged");

if (!engaged_sp)
return false;
return lldb::ChildCacheState::eRefetch;

// _M_engaged/__engaged is a bool flag and is true if the optional contains a
// value. Converting it to unsigned gives us a size of 1 if it contains a
// value and 0 if not.
m_has_value = engaged_sp->GetValueAsUnsigned(0) != 0;

return false;
return lldb::ChildCacheState::eRefetch;
}

ValueObjectSP GenericOptionalFrontend::GetChildAtIndex(size_t _idx) {
Expand Down
Loading