xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp (revision dda2819751e49c83612958492e38917049128b41)
1*dda28197Spatrick //===-- LibStdcppTuple.cpp ------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "LibStdcpp.h"
10061da546Spatrick 
11061da546Spatrick #include "lldb/Core/ValueObject.h"
12061da546Spatrick #include "lldb/DataFormatters/FormattersHelpers.h"
13061da546Spatrick #include "lldb/DataFormatters/TypeSynthetic.h"
14061da546Spatrick #include "lldb/Utility/ConstString.h"
15061da546Spatrick 
16061da546Spatrick #include <memory>
17061da546Spatrick #include <vector>
18061da546Spatrick 
19061da546Spatrick using namespace lldb;
20061da546Spatrick using namespace lldb_private;
21061da546Spatrick using namespace lldb_private::formatters;
22061da546Spatrick 
23061da546Spatrick namespace {
24061da546Spatrick 
25061da546Spatrick class LibStdcppTupleSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
26061da546Spatrick public:
27061da546Spatrick   explicit LibStdcppTupleSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
28061da546Spatrick 
29061da546Spatrick   size_t CalculateNumChildren() override;
30061da546Spatrick 
31061da546Spatrick   lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
32061da546Spatrick 
33061da546Spatrick   bool Update() override;
34061da546Spatrick 
35061da546Spatrick   bool MightHaveChildren() override;
36061da546Spatrick 
37061da546Spatrick   size_t GetIndexOfChildWithName(ConstString name) override;
38061da546Spatrick 
39061da546Spatrick private:
40061da546Spatrick   // The lifetime of a ValueObject and all its derivative ValueObjects
41061da546Spatrick   // (children, clones, etc.) is managed by a ClusterManager. These
42061da546Spatrick   // objects are only destroyed when every shared pointer to any of them
43061da546Spatrick   // is destroyed, so we must not store a shared pointer to any ValueObject
44061da546Spatrick   // derived from our backend ValueObject (since we're in the same cluster).
45061da546Spatrick   std::vector<ValueObject*> m_members;
46061da546Spatrick };
47061da546Spatrick 
48061da546Spatrick } // end of anonymous namespace
49061da546Spatrick 
LibStdcppTupleSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)50061da546Spatrick LibStdcppTupleSyntheticFrontEnd::LibStdcppTupleSyntheticFrontEnd(
51061da546Spatrick     lldb::ValueObjectSP valobj_sp)
52061da546Spatrick     : SyntheticChildrenFrontEnd(*valobj_sp) {
53061da546Spatrick   Update();
54061da546Spatrick }
55061da546Spatrick 
Update()56061da546Spatrick bool LibStdcppTupleSyntheticFrontEnd::Update() {
57061da546Spatrick   m_members.clear();
58061da546Spatrick 
59061da546Spatrick   ValueObjectSP valobj_backend_sp = m_backend.GetSP();
60061da546Spatrick   if (!valobj_backend_sp)
61061da546Spatrick     return false;
62061da546Spatrick 
63061da546Spatrick   ValueObjectSP next_child_sp = valobj_backend_sp->GetNonSyntheticValue();
64061da546Spatrick   while (next_child_sp != nullptr) {
65061da546Spatrick     ValueObjectSP current_child = next_child_sp;
66061da546Spatrick     next_child_sp = nullptr;
67061da546Spatrick 
68061da546Spatrick     size_t child_count = current_child->GetNumChildren();
69061da546Spatrick     for (size_t i = 0; i < child_count; ++i) {
70061da546Spatrick       ValueObjectSP child_sp = current_child->GetChildAtIndex(i, true);
71061da546Spatrick       llvm::StringRef name_str = child_sp->GetName().GetStringRef();
72061da546Spatrick       if (name_str.startswith("std::_Tuple_impl<")) {
73061da546Spatrick         next_child_sp = child_sp;
74061da546Spatrick       } else if (name_str.startswith("std::_Head_base<")) {
75061da546Spatrick         ValueObjectSP value_sp =
76061da546Spatrick             child_sp->GetChildMemberWithName(ConstString("_M_head_impl"), true);
77061da546Spatrick         if (value_sp) {
78061da546Spatrick           StreamString name;
79061da546Spatrick           name.Printf("[%zd]", m_members.size());
80061da546Spatrick           m_members.push_back(value_sp->Clone(ConstString(name.GetString())).get());
81061da546Spatrick         }
82061da546Spatrick       }
83061da546Spatrick     }
84061da546Spatrick   }
85061da546Spatrick 
86061da546Spatrick   return false;
87061da546Spatrick }
88061da546Spatrick 
MightHaveChildren()89061da546Spatrick bool LibStdcppTupleSyntheticFrontEnd::MightHaveChildren() { return true; }
90061da546Spatrick 
91061da546Spatrick lldb::ValueObjectSP
GetChildAtIndex(size_t idx)92061da546Spatrick LibStdcppTupleSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
93061da546Spatrick   if (idx < m_members.size() && m_members[idx])
94061da546Spatrick     return m_members[idx]->GetSP();
95061da546Spatrick   return lldb::ValueObjectSP();
96061da546Spatrick }
97061da546Spatrick 
CalculateNumChildren()98061da546Spatrick size_t LibStdcppTupleSyntheticFrontEnd::CalculateNumChildren() {
99061da546Spatrick   return m_members.size();
100061da546Spatrick }
101061da546Spatrick 
GetIndexOfChildWithName(ConstString name)102061da546Spatrick size_t LibStdcppTupleSyntheticFrontEnd::GetIndexOfChildWithName(
103061da546Spatrick     ConstString name) {
104061da546Spatrick   return ExtractIndexFromString(name.GetCString());
105061da546Spatrick }
106061da546Spatrick 
107061da546Spatrick SyntheticChildrenFrontEnd *
LibStdcppTupleSyntheticFrontEndCreator(CXXSyntheticChildren *,lldb::ValueObjectSP valobj_sp)108061da546Spatrick lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator(
109061da546Spatrick     CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
110061da546Spatrick   return (valobj_sp ? new LibStdcppTupleSyntheticFrontEnd(valobj_sp) : nullptr);
111061da546Spatrick }
112