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