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
18using namespace lldb;
19using namespace lldb_private;
20
21class ValueListImpl {
22public:
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
72private:
73  std::vector<lldb::SBValue> m_values;
74  Status m_error;
75};
76
77SBValueList::SBValueList() { LLDB_INSTRUMENT_VA(this); }
78
79SBValueList::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
86SBValueList::SBValueList(const ValueListImpl *lldb_object_ptr) {
87  if (lldb_object_ptr)
88    m_opaque_up = std::make_unique<ValueListImpl>(*lldb_object_ptr);
89}
90
91SBValueList::~SBValueList() = default;
92
93bool SBValueList::IsValid() const {
94  LLDB_INSTRUMENT_VA(this);
95  return this->operator bool();
96}
97SBValueList::operator bool() const {
98  LLDB_INSTRUMENT_VA(this);
99
100  return (m_opaque_up != nullptr);
101}
102
103void SBValueList::Clear() {
104  LLDB_INSTRUMENT_VA(this);
105
106  m_opaque_up.reset();
107}
108
109const 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
121ValueListImpl *SBValueList::operator->() { return m_opaque_up.get(); }
122
123ValueListImpl &SBValueList::operator*() { return *m_opaque_up; }
124
125const ValueListImpl *SBValueList::operator->() const {
126  return m_opaque_up.get();
127}
128
129const ValueListImpl &SBValueList::operator*() const { return *m_opaque_up; }
130
131void 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
138void 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
145void 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
154SBValue 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
164uint32_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
174void SBValueList::CreateIfNeeded() {
175  if (m_opaque_up == nullptr)
176    m_opaque_up = std::make_unique<ValueListImpl>();
177}
178
179SBValue 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
188SBValue 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
197void *SBValueList::opaque_ptr() { return m_opaque_up.get(); }
198
199ValueListImpl &SBValueList::ref() {
200  CreateIfNeeded();
201  return *m_opaque_up;
202}
203
204lldb::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
212void SBValueList::SetError(const lldb_private::Status &status) {
213  ref().SetError(status);
214}
215