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