]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
Merge ^/vendor/lldb/dist up to its last change, and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / Plugins / Language / CPlusPlus / LibCxxTuple.cpp
1 //===-- LibCxxTuple.cpp -----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "LibCxx.h"
10 #include "lldb/DataFormatters/FormattersHelpers.h"
11
12 using namespace lldb;
13 using namespace lldb_private;
14
15 namespace {
16
17 class TupleFrontEnd: public SyntheticChildrenFrontEnd {
18 public:
19   TupleFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) {
20     Update();
21   }
22
23   size_t GetIndexOfChildWithName(ConstString name) override {
24     return formatters::ExtractIndexFromString(name.GetCString());
25   }
26
27   bool MightHaveChildren() override { return true; }
28   bool Update() override;
29   size_t CalculateNumChildren() override { return m_elements.size(); }
30   ValueObjectSP GetChildAtIndex(size_t idx) override;
31
32 private:
33   // The lifetime of a ValueObject and all its derivative ValueObjects
34   // (children, clones, etc.) is managed by a ClusterManager. These
35   // objects are only destroyed when every shared pointer to any of them
36   // is destroyed, so we must not store a shared pointer to any ValueObject
37   // derived from our backend ValueObject (since we're in the same cluster).
38   std::vector<ValueObject*> m_elements;
39   ValueObject* m_base = nullptr;
40 };
41 }
42
43 bool TupleFrontEnd::Update() {
44   m_elements.clear();
45   m_base = nullptr;
46
47   ValueObjectSP base_sp;
48   base_sp = m_backend.GetChildMemberWithName(ConstString("__base_"), true);
49   if (!base_sp) {
50     // Pre r304382 name of the base element.
51     base_sp = m_backend.GetChildMemberWithName(ConstString("base_"), true);
52   }
53   if (!base_sp)
54     return false;
55   m_base = base_sp.get();
56   m_elements.assign(base_sp->GetCompilerType().GetNumDirectBaseClasses(),
57                     nullptr);
58   return false;
59 }
60
61 ValueObjectSP TupleFrontEnd::GetChildAtIndex(size_t idx) {
62   if (idx >= m_elements.size())
63     return ValueObjectSP();
64   if (!m_base)
65     return ValueObjectSP();
66   if (m_elements[idx])
67     return m_elements[idx]->GetSP();
68
69   CompilerType holder_type =
70       m_base->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr);
71   if (!holder_type)
72     return ValueObjectSP();
73   ValueObjectSP holder_sp = m_base->GetChildAtIndex(idx, true);
74   if (!holder_sp)
75     return ValueObjectSP();
76
77   ValueObjectSP elem_sp = holder_sp->GetChildAtIndex(0, true);
78   if (elem_sp)
79     m_elements[idx] =
80         elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str())).get();
81
82   if (m_elements[idx])
83     return m_elements[idx]->GetSP();
84   return ValueObjectSP();
85 }
86
87 SyntheticChildrenFrontEnd *
88 formatters::LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,
89                                        lldb::ValueObjectSP valobj_sp) {
90   if (valobj_sp)
91     return new TupleFrontEnd(*valobj_sp);
92   return nullptr;
93 }