1 //===-- SBValueList.cpp ---------------------------------------------------===//
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 "lldb/API/SBValueList.h"
10 #include "lldb/API/SBError.h"
11 #include "lldb/API/SBStream.h"
12 #include "lldb/API/SBValue.h"
13 #include "lldb/Core/ValueObjectList.h"
14 #include "lldb/Utility/Instrumentation.h"
15 #include "lldb/Utility/Status.h"
16 #include <vector>
17 
18 using namespace lldb;
19 using namespace lldb_private;
20 
21 class ValueListImpl {
22 public:
23   ValueListImpl() = default;
24 
25   ValueListImpl(const ValueListImpl &rhs) = default;
26 
27   ValueListImpl &operator=(const ValueListImpl &rhs) {
28     if (this == &rhs)
29       return *this;
30     m_values = rhs.m_values;
31     m_error = rhs.m_error;
32     return *this;
33   }
34 
35   uint32_t GetSize() { return m_values.size(); }
36 
37   void Append(const lldb::SBValue &sb_value) { m_values.push_back(sb_value); }
38 
39   void Append(const ValueListImpl &list) {
40     for (auto val : list.m_values)
41       Append(val);
42   }
43 
44   lldb::SBValue GetValueAtIndex(uint32_t index) {
45     if (index >= GetSize())
46       return lldb::SBValue();
47     return m_values[index];
48   }
49 
50   lldb::SBValue FindValueByUID(lldb::user_id_t uid) {
51     for (auto val : m_values) {
52       if (val.IsValid() && val.GetID() == uid)
53         return val;
54     }
55     return lldb::SBValue();
56   }
57 
58   lldb::SBValue GetFirstValueByName(const char *name) const {
59     if (name) {
60       for (auto val : m_values) {
61         if (val.IsValid() && val.GetName() && strcmp(name, val.GetName()) == 0)
62           return val;
63       }
64     }
65     return lldb::SBValue();
66   }
67 
68   const Status &GetError() const { return m_error; }
69 
70   void SetError(const Status &error) { m_error = error; }
71 
72 private:
73   std::vector<lldb::SBValue> m_values;
74   Status m_error;
75 };
76 
77 SBValueList::SBValueList() { LLDB_INSTRUMENT_VA(this); }
78 
79 SBValueList::SBValueList(const SBValueList &rhs) {
80   LLDB_INSTRUMENT_VA(this, rhs);
81 
82   if (rhs.IsValid())
83     m_opaque_up = std::make_unique<ValueListImpl>(*rhs);
84 }
85 
86 SBValueList::SBValueList(const ValueListImpl *lldb_object_ptr) {
87   if (lldb_object_ptr)
88     m_opaque_up = std::make_unique<ValueListImpl>(*lldb_object_ptr);
89 }
90 
91 SBValueList::~SBValueList() = default;
92 
93 bool SBValueList::IsValid() const {
94   LLDB_INSTRUMENT_VA(this);
95   return this->operator bool();
96 }
97 SBValueList::operator bool() const {
98   LLDB_INSTRUMENT_VA(this);
99 
100   return (m_opaque_up != nullptr);
101 }
102 
103 void SBValueList::Clear() {
104   LLDB_INSTRUMENT_VA(this);
105 
106   m_opaque_up.reset();
107 }
108 
109 const SBValueList &SBValueList::operator=(const SBValueList &rhs) {
110   LLDB_INSTRUMENT_VA(this, rhs);
111 
112   if (this != &rhs) {
113     if (rhs.IsValid())
114       m_opaque_up = std::make_unique<ValueListImpl>(*rhs);
115     else
116       m_opaque_up.reset();
117   }
118   return *this;
119 }
120 
121 ValueListImpl *SBValueList::operator->() { return m_opaque_up.get(); }
122 
123 ValueListImpl &SBValueList::operator*() { return *m_opaque_up; }
124 
125 const ValueListImpl *SBValueList::operator->() const {
126   return m_opaque_up.get();
127 }
128 
129 const ValueListImpl &SBValueList::operator*() const { return *m_opaque_up; }
130 
131 void SBValueList::Append(const SBValue &val_obj) {
132   LLDB_INSTRUMENT_VA(this, val_obj);
133 
134   CreateIfNeeded();
135   m_opaque_up->Append(val_obj);
136 }
137 
138 void SBValueList::Append(lldb::ValueObjectSP &val_obj_sp) {
139   if (val_obj_sp) {
140     CreateIfNeeded();
141     m_opaque_up->Append(SBValue(val_obj_sp));
142   }
143 }
144 
145 void SBValueList::Append(const lldb::SBValueList &value_list) {
146   LLDB_INSTRUMENT_VA(this, value_list);
147 
148   if (value_list.IsValid()) {
149     CreateIfNeeded();
150     m_opaque_up->Append(*value_list);
151   }
152 }
153 
154 SBValue SBValueList::GetValueAtIndex(uint32_t idx) const {
155   LLDB_INSTRUMENT_VA(this, idx);
156 
157   SBValue sb_value;
158   if (m_opaque_up)
159     sb_value = m_opaque_up->GetValueAtIndex(idx);
160 
161   return sb_value;
162 }
163 
164 uint32_t SBValueList::GetSize() const {
165   LLDB_INSTRUMENT_VA(this);
166 
167   uint32_t size = 0;
168   if (m_opaque_up)
169     size = m_opaque_up->GetSize();
170 
171   return size;
172 }
173 
174 void SBValueList::CreateIfNeeded() {
175   if (m_opaque_up == nullptr)
176     m_opaque_up = std::make_unique<ValueListImpl>();
177 }
178 
179 SBValue SBValueList::FindValueObjectByUID(lldb::user_id_t uid) {
180   LLDB_INSTRUMENT_VA(this, uid);
181 
182   SBValue sb_value;
183   if (m_opaque_up)
184     sb_value = m_opaque_up->FindValueByUID(uid);
185   return sb_value;
186 }
187 
188 SBValue SBValueList::GetFirstValueByName(const char *name) const {
189   LLDB_INSTRUMENT_VA(this, name);
190 
191   SBValue sb_value;
192   if (m_opaque_up)
193     sb_value = m_opaque_up->GetFirstValueByName(name);
194   return sb_value;
195 }
196 
197 void *SBValueList::opaque_ptr() { return m_opaque_up.get(); }
198 
199 ValueListImpl &SBValueList::ref() {
200   CreateIfNeeded();
201   return *m_opaque_up;
202 }
203 
204 lldb::SBError SBValueList::GetError() {
205   LLDB_INSTRUMENT_VA(this);
206   SBError sb_error;
207   if (m_opaque_up)
208     sb_error.SetError(m_opaque_up->GetError());
209   return sb_error;
210 }
211 
212 void SBValueList::SetError(const lldb_private::Status &status) {
213   ref().SetError(status);
214 }
215