15e9eaf87SMark de Wever //===-- LibCxxValarray.cpp ------------------------------------------------===// 25e9eaf87SMark de Wever // 35e9eaf87SMark de Wever // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45e9eaf87SMark de Wever // See https://llvm.org/LICENSE.txt for license information. 55e9eaf87SMark de Wever // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65e9eaf87SMark de Wever // 75e9eaf87SMark de Wever //===----------------------------------------------------------------------===// 85e9eaf87SMark de Wever 95e9eaf87SMark de Wever #include "LibCxx.h" 105e9eaf87SMark de Wever 115e9eaf87SMark de Wever #include "lldb/DataFormatters/FormattersHelpers.h" 12*b852fb1eSJonas Devlieghere #include "lldb/ValueObject/ValueObject.h" 135e9eaf87SMark de Wever #include <optional> 145e9eaf87SMark de Wever 155e9eaf87SMark de Wever using namespace lldb; 165e9eaf87SMark de Wever using namespace lldb_private; 175e9eaf87SMark de Wever using namespace lldb_private::formatters; 185e9eaf87SMark de Wever 195e9eaf87SMark de Wever namespace lldb_private { 205e9eaf87SMark de Wever namespace formatters { 215e9eaf87SMark de Wever class LibcxxStdValarraySyntheticFrontEnd : public SyntheticChildrenFrontEnd { 225e9eaf87SMark de Wever public: 235e9eaf87SMark de Wever LibcxxStdValarraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); 245e9eaf87SMark de Wever 255e9eaf87SMark de Wever ~LibcxxStdValarraySyntheticFrontEnd() override; 265e9eaf87SMark de Wever 27624ea68cSAdrian Prantl llvm::Expected<uint32_t> CalculateNumChildren() override; 285e9eaf87SMark de Wever 29e710523eSAdrian Prantl lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override; 305e9eaf87SMark de Wever 315e9eaf87SMark de Wever lldb::ChildCacheState Update() override; 325e9eaf87SMark de Wever 335e9eaf87SMark de Wever bool MightHaveChildren() override; 345e9eaf87SMark de Wever 355e9eaf87SMark de Wever size_t GetIndexOfChildWithName(ConstString name) override; 365e9eaf87SMark de Wever 375e9eaf87SMark de Wever private: 385e9eaf87SMark de Wever /// A non-owning pointer to valarray's __begin_ member. 395e9eaf87SMark de Wever ValueObject *m_start = nullptr; 405e9eaf87SMark de Wever /// A non-owning pointer to valarray's __end_ member. 415e9eaf87SMark de Wever ValueObject *m_finish = nullptr; 425e9eaf87SMark de Wever /// The type of valarray's template argument T. 435e9eaf87SMark de Wever CompilerType m_element_type; 445e9eaf87SMark de Wever /// The sizeof valarray's template argument T. 455e9eaf87SMark de Wever uint32_t m_element_size = 0; 465e9eaf87SMark de Wever }; 475e9eaf87SMark de Wever 485e9eaf87SMark de Wever } // namespace formatters 495e9eaf87SMark de Wever } // namespace lldb_private 505e9eaf87SMark de Wever 515e9eaf87SMark de Wever lldb_private::formatters::LibcxxStdValarraySyntheticFrontEnd:: 525e9eaf87SMark de Wever LibcxxStdValarraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) 535e9eaf87SMark de Wever : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type() { 545e9eaf87SMark de Wever if (valobj_sp) 555e9eaf87SMark de Wever Update(); 565e9eaf87SMark de Wever } 575e9eaf87SMark de Wever 585e9eaf87SMark de Wever lldb_private::formatters::LibcxxStdValarraySyntheticFrontEnd:: 595e9eaf87SMark de Wever ~LibcxxStdValarraySyntheticFrontEnd() { 605e9eaf87SMark de Wever // these need to stay around because they are child objects who will follow 615e9eaf87SMark de Wever // their parent's life cycle 625e9eaf87SMark de Wever // delete m_start; 635e9eaf87SMark de Wever // delete m_finish; 645e9eaf87SMark de Wever } 655e9eaf87SMark de Wever 66624ea68cSAdrian Prantl llvm::Expected<uint32_t> lldb_private::formatters:: 67624ea68cSAdrian Prantl LibcxxStdValarraySyntheticFrontEnd::CalculateNumChildren() { 685e9eaf87SMark de Wever if (!m_start || !m_finish) 695e9eaf87SMark de Wever return 0; 705e9eaf87SMark de Wever uint64_t start_val = m_start->GetValueAsUnsigned(0); 715e9eaf87SMark de Wever uint64_t finish_val = m_finish->GetValueAsUnsigned(0); 725e9eaf87SMark de Wever 735e9eaf87SMark de Wever if (start_val == 0 || finish_val == 0) 745e9eaf87SMark de Wever return 0; 755e9eaf87SMark de Wever 765e9eaf87SMark de Wever if (start_val >= finish_val) 775e9eaf87SMark de Wever return 0; 785e9eaf87SMark de Wever 795e9eaf87SMark de Wever size_t num_children = (finish_val - start_val); 805e9eaf87SMark de Wever if (num_children % m_element_size) 815e9eaf87SMark de Wever return 0; 825e9eaf87SMark de Wever return num_children / m_element_size; 835e9eaf87SMark de Wever } 845e9eaf87SMark de Wever 855e9eaf87SMark de Wever lldb::ValueObjectSP 865e9eaf87SMark de Wever lldb_private::formatters::LibcxxStdValarraySyntheticFrontEnd::GetChildAtIndex( 87e710523eSAdrian Prantl uint32_t idx) { 885e9eaf87SMark de Wever if (!m_start || !m_finish) 895e9eaf87SMark de Wever return lldb::ValueObjectSP(); 905e9eaf87SMark de Wever 915e9eaf87SMark de Wever uint64_t offset = idx * m_element_size; 925e9eaf87SMark de Wever offset = offset + m_start->GetValueAsUnsigned(0); 935e9eaf87SMark de Wever StreamString name; 945e9eaf87SMark de Wever name.Printf("[%" PRIu64 "]", (uint64_t)idx); 955e9eaf87SMark de Wever return CreateValueObjectFromAddress(name.GetString(), offset, 965e9eaf87SMark de Wever m_backend.GetExecutionContextRef(), 975e9eaf87SMark de Wever m_element_type); 985e9eaf87SMark de Wever } 995e9eaf87SMark de Wever 1005e9eaf87SMark de Wever lldb::ChildCacheState 1015e9eaf87SMark de Wever lldb_private::formatters::LibcxxStdValarraySyntheticFrontEnd::Update() { 1025e9eaf87SMark de Wever m_start = m_finish = nullptr; 1035e9eaf87SMark de Wever 1045e9eaf87SMark de Wever CompilerType type = m_backend.GetCompilerType(); 1055e9eaf87SMark de Wever if (type.GetNumTemplateArguments() == 0) 1065e9eaf87SMark de Wever return ChildCacheState::eRefetch; 1075e9eaf87SMark de Wever 1085e9eaf87SMark de Wever m_element_type = type.GetTypeTemplateArgument(0); 1095e9eaf87SMark de Wever if (std::optional<uint64_t> size = m_element_type.GetByteSize(nullptr)) 1105e9eaf87SMark de Wever m_element_size = *size; 1115e9eaf87SMark de Wever 1125e9eaf87SMark de Wever if (m_element_size == 0) 1135e9eaf87SMark de Wever return ChildCacheState::eRefetch; 1145e9eaf87SMark de Wever 1155e9eaf87SMark de Wever ValueObjectSP start = m_backend.GetChildMemberWithName("__begin_"); 1165e9eaf87SMark de Wever ValueObjectSP finish = m_backend.GetChildMemberWithName("__end_"); 1175e9eaf87SMark de Wever 1185e9eaf87SMark de Wever if (!start || !finish) 1195e9eaf87SMark de Wever return ChildCacheState::eRefetch; 1205e9eaf87SMark de Wever 1215e9eaf87SMark de Wever m_start = start.get(); 1225e9eaf87SMark de Wever m_finish = finish.get(); 1235e9eaf87SMark de Wever 1245e9eaf87SMark de Wever return ChildCacheState::eRefetch; 1255e9eaf87SMark de Wever } 1265e9eaf87SMark de Wever 1275e9eaf87SMark de Wever bool lldb_private::formatters::LibcxxStdValarraySyntheticFrontEnd:: 1285e9eaf87SMark de Wever MightHaveChildren() { 1295e9eaf87SMark de Wever return true; 1305e9eaf87SMark de Wever } 1315e9eaf87SMark de Wever 1325e9eaf87SMark de Wever size_t lldb_private::formatters::LibcxxStdValarraySyntheticFrontEnd:: 1335e9eaf87SMark de Wever GetIndexOfChildWithName(ConstString name) { 1345e9eaf87SMark de Wever if (!m_start || !m_finish) 1355e9eaf87SMark de Wever return std::numeric_limits<size_t>::max(); 1365e9eaf87SMark de Wever return ExtractIndexFromString(name.GetCString()); 1375e9eaf87SMark de Wever } 1385e9eaf87SMark de Wever 1395e9eaf87SMark de Wever lldb_private::SyntheticChildrenFrontEnd * 1405e9eaf87SMark de Wever lldb_private::formatters::LibcxxStdValarraySyntheticFrontEndCreator( 1415e9eaf87SMark de Wever CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { 1425e9eaf87SMark de Wever if (!valobj_sp) 1435e9eaf87SMark de Wever return nullptr; 1445e9eaf87SMark de Wever return new LibcxxStdValarraySyntheticFrontEnd(valobj_sp); 1455e9eaf87SMark de Wever } 146