xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15ffd83dbSDimitry Andric //===-- LibCxxTuple.cpp ---------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "LibCxx.h"
100b57cec5SDimitry Andric #include "lldb/DataFormatters/FormattersHelpers.h"
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric using namespace lldb;
130b57cec5SDimitry Andric using namespace lldb_private;
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric namespace {
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric class TupleFrontEnd: public SyntheticChildrenFrontEnd {
180b57cec5SDimitry Andric public:
190b57cec5SDimitry Andric   TupleFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) {
200b57cec5SDimitry Andric     Update();
210b57cec5SDimitry Andric   }
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric   size_t GetIndexOfChildWithName(ConstString name) override {
240b57cec5SDimitry Andric     return formatters::ExtractIndexFromString(name.GetCString());
250b57cec5SDimitry Andric   }
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric   bool MightHaveChildren() override { return true; }
28*0fca6ea1SDimitry Andric   lldb::ChildCacheState Update() override;
29*0fca6ea1SDimitry Andric   llvm::Expected<uint32_t> CalculateNumChildren() override {
30*0fca6ea1SDimitry Andric     return m_elements.size();
31*0fca6ea1SDimitry Andric   }
32*0fca6ea1SDimitry Andric   ValueObjectSP GetChildAtIndex(uint32_t idx) override;
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric private:
359dba64beSDimitry Andric   // The lifetime of a ValueObject and all its derivative ValueObjects
369dba64beSDimitry Andric   // (children, clones, etc.) is managed by a ClusterManager. These
379dba64beSDimitry Andric   // objects are only destroyed when every shared pointer to any of them
389dba64beSDimitry Andric   // is destroyed, so we must not store a shared pointer to any ValueObject
399dba64beSDimitry Andric   // derived from our backend ValueObject (since we're in the same cluster).
409dba64beSDimitry Andric   std::vector<ValueObject*> m_elements;
419dba64beSDimitry Andric   ValueObject* m_base = nullptr;
420b57cec5SDimitry Andric };
430b57cec5SDimitry Andric }
440b57cec5SDimitry Andric 
45*0fca6ea1SDimitry Andric lldb::ChildCacheState TupleFrontEnd::Update() {
460b57cec5SDimitry Andric   m_elements.clear();
479dba64beSDimitry Andric   m_base = nullptr;
489dba64beSDimitry Andric 
499dba64beSDimitry Andric   ValueObjectSP base_sp;
5006c3fb27SDimitry Andric   base_sp = m_backend.GetChildMemberWithName("__base_");
519dba64beSDimitry Andric   if (!base_sp) {
520b57cec5SDimitry Andric     // Pre r304382 name of the base element.
5306c3fb27SDimitry Andric     base_sp = m_backend.GetChildMemberWithName("base_");
540b57cec5SDimitry Andric   }
559dba64beSDimitry Andric   if (!base_sp)
56*0fca6ea1SDimitry Andric     return lldb::ChildCacheState::eRefetch;
579dba64beSDimitry Andric   m_base = base_sp.get();
589dba64beSDimitry Andric   m_elements.assign(base_sp->GetCompilerType().GetNumDirectBaseClasses(),
599dba64beSDimitry Andric                     nullptr);
60*0fca6ea1SDimitry Andric   return lldb::ChildCacheState::eRefetch;
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric 
63*0fca6ea1SDimitry Andric ValueObjectSP TupleFrontEnd::GetChildAtIndex(uint32_t idx) {
640b57cec5SDimitry Andric   if (idx >= m_elements.size())
650b57cec5SDimitry Andric     return ValueObjectSP();
669dba64beSDimitry Andric   if (!m_base)
670b57cec5SDimitry Andric     return ValueObjectSP();
680b57cec5SDimitry Andric   if (m_elements[idx])
699dba64beSDimitry Andric     return m_elements[idx]->GetSP();
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   CompilerType holder_type =
729dba64beSDimitry Andric       m_base->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr);
730b57cec5SDimitry Andric   if (!holder_type)
740b57cec5SDimitry Andric     return ValueObjectSP();
7506c3fb27SDimitry Andric   ValueObjectSP holder_sp = m_base->GetChildAtIndex(idx);
760b57cec5SDimitry Andric   if (!holder_sp)
770b57cec5SDimitry Andric     return ValueObjectSP();
780b57cec5SDimitry Andric 
7906c3fb27SDimitry Andric   ValueObjectSP elem_sp = holder_sp->GetChildAtIndex(0);
800b57cec5SDimitry Andric   if (elem_sp)
810b57cec5SDimitry Andric     m_elements[idx] =
829dba64beSDimitry Andric         elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str())).get();
830b57cec5SDimitry Andric 
849dba64beSDimitry Andric   if (m_elements[idx])
859dba64beSDimitry Andric     return m_elements[idx]->GetSP();
869dba64beSDimitry Andric   return ValueObjectSP();
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric SyntheticChildrenFrontEnd *
900b57cec5SDimitry Andric formatters::LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,
910b57cec5SDimitry Andric                                        lldb::ValueObjectSP valobj_sp) {
920b57cec5SDimitry Andric   if (valobj_sp)
930b57cec5SDimitry Andric     return new TupleFrontEnd(*valobj_sp);
940b57cec5SDimitry Andric   return nullptr;
950b57cec5SDimitry Andric }
96