Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxSliceArray.cpp
39642 views
//===-- LibCxxSliceArray.cpp-----------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "LibCxx.h"910#include "lldb/Core/ValueObject.h"11#include "lldb/DataFormatters/FormattersHelpers.h"12#include <optional>1314using namespace lldb;15using namespace lldb_private;16using namespace lldb_private::formatters;1718namespace lldb_private {19namespace formatters {2021bool LibcxxStdSliceArraySummaryProvider(ValueObject &valobj, Stream &stream,22const TypeSummaryOptions &options) {23ValueObjectSP obj = valobj.GetNonSyntheticValue();24if (!obj)25return false;2627ValueObjectSP ptr_sp = obj->GetChildMemberWithName("__size_");28if (!ptr_sp)29return false;30const size_t size = ptr_sp->GetValueAsUnsigned(0);3132ptr_sp = obj->GetChildMemberWithName("__stride_");33if (!ptr_sp)34return false;35const size_t stride = ptr_sp->GetValueAsUnsigned(0);3637stream.Printf("stride=%zu size=%zu", stride, size);3839return true;40}4142/// Data formatter for libc++'s std::slice_array.43///44/// A slice_array is created by using:45/// operator[](std::slice slicearr);46/// and std::slice is created by:47/// slice(std::size_t start, std::size_t size, std::size_t stride);48/// The std::slice_array has the following members:49/// - __vp_ points to std::valarray::__begin_ + @a start50/// - __size_ is @a size51/// - __stride_is @a stride52class LibcxxStdSliceArraySyntheticFrontEnd : public SyntheticChildrenFrontEnd {53public:54LibcxxStdSliceArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);5556~LibcxxStdSliceArraySyntheticFrontEnd() override;5758llvm::Expected<uint32_t> CalculateNumChildren() override;5960lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;6162lldb::ChildCacheState Update() override;6364bool MightHaveChildren() override;6566size_t GetIndexOfChildWithName(ConstString name) override;6768private:69/// A non-owning pointer to slice_array.__vp_.70ValueObject *m_start = nullptr;71/// slice_array.__size_.72size_t m_size = 0;73/// slice_array.__stride_.74size_t m_stride = 0;75/// The type of slice_array's template argument T.76CompilerType m_element_type;77/// The sizeof slice_array's template argument T.78uint32_t m_element_size = 0;79};8081} // namespace formatters82} // namespace lldb_private8384lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::85LibcxxStdSliceArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)86: SyntheticChildrenFrontEnd(*valobj_sp), m_element_type() {87if (valobj_sp)88Update();89}9091lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::92~LibcxxStdSliceArraySyntheticFrontEnd() {93// these need to stay around because they are child objects who will follow94// their parent's life cycle95// delete m_start;96}9798llvm::Expected<uint32_t> lldb_private::formatters::99LibcxxStdSliceArraySyntheticFrontEnd::CalculateNumChildren() {100return m_size;101}102103lldb::ValueObjectSP104lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::GetChildAtIndex(105uint32_t idx) {106if (!m_start)107return lldb::ValueObjectSP();108109uint64_t offset = idx * m_stride * m_element_size;110offset = offset + m_start->GetValueAsUnsigned(0);111StreamString name;112name.Printf("[%" PRIu64 "]", (uint64_t)idx);113return CreateValueObjectFromAddress(name.GetString(), offset,114m_backend.GetExecutionContextRef(),115m_element_type);116}117118lldb::ChildCacheState119lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::Update() {120m_start = nullptr;121122CompilerType type = m_backend.GetCompilerType();123if (type.GetNumTemplateArguments() == 0)124return ChildCacheState::eRefetch;125126m_element_type = type.GetTypeTemplateArgument(0);127if (std::optional<uint64_t> size = m_element_type.GetByteSize(nullptr))128m_element_size = *size;129130if (m_element_size == 0)131return ChildCacheState::eRefetch;132133ValueObjectSP start = m_backend.GetChildMemberWithName("__vp_");134ValueObjectSP size = m_backend.GetChildMemberWithName("__size_");135ValueObjectSP stride = m_backend.GetChildMemberWithName("__stride_");136137if (!start || !size || !stride)138return ChildCacheState::eRefetch;139140m_start = start.get();141m_size = size->GetValueAsUnsigned(0);142m_stride = stride->GetValueAsUnsigned(0);143144return ChildCacheState::eRefetch;145}146147bool lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::148MightHaveChildren() {149return true;150}151152size_t lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::153GetIndexOfChildWithName(ConstString name) {154if (!m_start)155return std::numeric_limits<size_t>::max();156return ExtractIndexFromString(name.GetCString());157}158159lldb_private::SyntheticChildrenFrontEnd *160lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEndCreator(161CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {162if (!valobj_sp)163return nullptr;164return new LibcxxStdSliceArraySyntheticFrontEnd(valobj_sp);165}166167168