Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxProxyArray.cpp
39642 views
//===-- LibCxxProxyArray.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 {2021/// Data formatter for libc++'s std::"proxy_array".22///23/// A proxy_array's are created by using:24/// std::gslice_array operator[](const std::gslice& gslicearr);25/// std::mask_array operator[](const std::valarray<bool>& boolarr);26/// std::indirect_array operator[](const std::valarray<std::size_t>& indarr);27///28/// These arrays have the following members:29/// - __vp_ points to std::valarray::__begin_30/// - __1d_ an array of offsets of the elements from @a __vp_31class LibcxxStdProxyArraySyntheticFrontEnd : public SyntheticChildrenFrontEnd {32public:33LibcxxStdProxyArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);3435~LibcxxStdProxyArraySyntheticFrontEnd() override;3637llvm::Expected<uint32_t> CalculateNumChildren() override;3839lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;4041lldb::ChildCacheState Update() override;4243bool MightHaveChildren() override;4445size_t GetIndexOfChildWithName(ConstString name) override;4647private:48/// A non-owning pointer to the array's __vp_.49ValueObject *m_base = nullptr;50/// The type of the array's template argument T.51CompilerType m_element_type;52/// The sizeof the array's template argument T.53uint32_t m_element_size = 0;5455/// A non-owning pointer to the array's __1d_.__begin_.56ValueObject *m_start = nullptr;57/// A non-owning pointer to the array's __1d_.__end_.58ValueObject *m_finish = nullptr;59/// The type of the __1d_ array's template argument T (size_t).60CompilerType m_element_type_size_t;61/// The sizeof the __1d_ array's template argument T (size_t)62uint32_t m_element_size_size_t = 0;63};6465} // namespace formatters66} // namespace lldb_private6768lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEnd::69LibcxxStdProxyArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)70: SyntheticChildrenFrontEnd(*valobj_sp), m_element_type() {71if (valobj_sp)72Update();73}7475lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEnd::76~LibcxxStdProxyArraySyntheticFrontEnd() {77// these need to stay around because they are child objects who will follow78// their parent's life cycle79// delete m_base;80}8182llvm::Expected<uint32_t> lldb_private::formatters::83LibcxxStdProxyArraySyntheticFrontEnd::CalculateNumChildren() {8485if (!m_start || !m_finish)86return 0;87uint64_t start_val = m_start->GetValueAsUnsigned(0);88uint64_t finish_val = m_finish->GetValueAsUnsigned(0);8990if (start_val == 0 || finish_val == 0)91return 0;9293if (start_val >= finish_val)94return 0;9596size_t num_children = (finish_val - start_val);97if (num_children % m_element_size_size_t)98return 0;99return num_children / m_element_size_size_t;100}101102lldb::ValueObjectSP103lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEnd::GetChildAtIndex(104uint32_t idx) {105if (!m_base)106return lldb::ValueObjectSP();107108uint64_t offset = idx * m_element_size_size_t;109offset = offset + m_start->GetValueAsUnsigned(0);110111lldb::ValueObjectSP indirect = CreateValueObjectFromAddress(112"", offset, m_backend.GetExecutionContextRef(), m_element_type_size_t);113if (!indirect)114return lldb::ValueObjectSP();115116const size_t value = indirect->GetValueAsUnsigned(0);117if (!value)118return lldb::ValueObjectSP();119120offset = value * m_element_size;121offset = offset + m_base->GetValueAsUnsigned(0);122123StreamString name;124name.Printf("[%" PRIu64 "] -> [%zu]", (uint64_t)idx, value);125return CreateValueObjectFromAddress(name.GetString(), offset,126m_backend.GetExecutionContextRef(),127m_element_type);128}129130lldb::ChildCacheState131lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEnd::Update() {132m_base = nullptr;133m_start = nullptr;134m_finish = nullptr;135136CompilerType type = m_backend.GetCompilerType();137if (type.GetNumTemplateArguments() == 0)138return ChildCacheState::eRefetch;139140m_element_type = type.GetTypeTemplateArgument(0);141if (std::optional<uint64_t> size = m_element_type.GetByteSize(nullptr))142m_element_size = *size;143144if (m_element_size == 0)145return ChildCacheState::eRefetch;146147ValueObjectSP vector = m_backend.GetChildMemberWithName("__1d_");148if (!vector)149return ChildCacheState::eRefetch;150151type = vector->GetCompilerType();152if (type.GetNumTemplateArguments() == 0)153return ChildCacheState::eRefetch;154155m_element_type_size_t = type.GetTypeTemplateArgument(0);156if (std::optional<uint64_t> size = m_element_type_size_t.GetByteSize(nullptr))157m_element_size_size_t = *size;158159if (m_element_size_size_t == 0)160return ChildCacheState::eRefetch;161162ValueObjectSP base = m_backend.GetChildMemberWithName("__vp_");163ValueObjectSP start = vector->GetChildMemberWithName("__begin_");164ValueObjectSP finish = vector->GetChildMemberWithName("__end_");165if (!base || !start || !finish)166return ChildCacheState::eRefetch;167168m_base = base.get();169m_start = start.get();170m_finish = finish.get();171172return ChildCacheState::eRefetch;173}174175bool lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEnd::176MightHaveChildren() {177return true;178}179180size_t lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEnd::181GetIndexOfChildWithName(ConstString name) {182if (!m_base)183return std::numeric_limits<size_t>::max();184return ExtractIndexFromString(name.GetCString());185}186187lldb_private::SyntheticChildrenFrontEnd *188lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEndCreator(189CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {190if (!valobj_sp)191return nullptr;192return new LibcxxStdProxyArraySyntheticFrontEnd(valobj_sp);193}194195196