1 //===-- SBValue.cpp ---------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/API/SBValue.h"
11 #include "lldb/API/SBStream.h"
12 
13 #include "lldb/Core/DataExtractor.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/Stream.h"
16 #include "lldb/Core/StreamFile.h"
17 #include "lldb/Core/Value.h"
18 #include "lldb/Core/ValueObject.h"
19 #include "lldb/Symbol/Block.h"
20 #include "lldb/Symbol/ObjectFile.h"
21 #include "lldb/Symbol/Variable.h"
22 #include "lldb/Target/ExecutionContext.h"
23 #include "lldb/Target/Process.h"
24 #include "lldb/Target/StackFrame.h"
25 #include "lldb/Target/Thread.h"
26 
27 #include "lldb/API/SBProcess.h"
28 #include "lldb/API/SBTarget.h"
29 #include "lldb/API/SBThread.h"
30 #include "lldb/API/SBFrame.h"
31 #include "lldb/API/SBDebugger.h"
32 
33 using namespace lldb;
34 using namespace lldb_private;
35 
36 SBValue::SBValue () :
37     m_opaque_sp ()
38 {
39 }
40 
41 SBValue::SBValue (const lldb::ValueObjectSP &value_sp) :
42     m_opaque_sp (value_sp)
43 {
44 }
45 
46 SBValue::~SBValue()
47 {
48 }
49 
50 bool
51 SBValue::IsValid () const
52 {
53     return  (m_opaque_sp.get() != NULL);
54 }
55 
56 SBError
57 SBValue::GetError()
58 {
59     SBError sb_error;
60 
61     if (m_opaque_sp.get())
62         sb_error.SetError(m_opaque_sp->GetError());
63 
64     return sb_error;
65 }
66 
67 const char *
68 SBValue::GetName()
69 {
70     if (IsValid())
71         return m_opaque_sp->GetName().AsCString();
72     else
73         return NULL;
74 }
75 
76 const char *
77 SBValue::GetTypeName ()
78 {
79     if (IsValid())
80         return m_opaque_sp->GetTypeName().AsCString();
81     else
82         return NULL;
83 }
84 
85 size_t
86 SBValue::GetByteSize ()
87 {
88     size_t result = 0;
89 
90     if (IsValid())
91         result = m_opaque_sp->GetByteSize();
92 
93     return result;
94 }
95 
96 bool
97 SBValue::IsInScope (const SBFrame &frame)
98 {
99     bool result = false;
100 
101     if (IsValid())
102         result = m_opaque_sp->IsInScope (frame.get());
103 
104     return result;
105 }
106 
107 const char *
108 SBValue::GetValue (const SBFrame &frame)
109 {
110     const char *value_string = NULL;
111     if ( m_opaque_sp)
112         value_string = m_opaque_sp->GetValueAsCString (frame.get());
113     return value_string;
114 }
115 
116 const char *
117 SBValue::GetObjectDescription (const SBFrame &frame)
118 {
119     const char *value_string = NULL;
120     if ( m_opaque_sp)
121         value_string = m_opaque_sp->GetObjectDescription (frame.get());
122     return value_string;
123 }
124 
125 bool
126 SBValue::GetValueDidChange (const SBFrame &frame)
127 {
128     if (IsValid())
129         return m_opaque_sp->GetValueDidChange (frame.get());
130     return false;
131 }
132 
133 const char *
134 SBValue::GetSummary (const SBFrame &frame)
135 {
136     const char *value_string = NULL;
137     if ( m_opaque_sp)
138         value_string = m_opaque_sp->GetSummaryAsCString(frame.get());
139     return value_string;
140 }
141 
142 const char *
143 SBValue::GetLocation (const SBFrame &frame)
144 {
145     const char *value_string = NULL;
146     if (IsValid())
147         value_string = m_opaque_sp->GetLocationAsCString(frame.get());
148     return value_string;
149 }
150 
151 bool
152 SBValue::SetValueFromCString (const SBFrame &frame, const char *value_str)
153 {
154     bool success = false;
155     if (IsValid())
156         success = m_opaque_sp->SetValueFromCString (frame.get(), value_str);
157     return success;
158 }
159 
160 SBValue
161 SBValue::GetChildAtIndex (uint32_t idx)
162 {
163     lldb::ValueObjectSP child_sp;
164 
165     if (IsValid())
166     {
167         child_sp = m_opaque_sp->GetChildAtIndex (idx, true);
168     }
169 
170     SBValue sb_value (child_sp);
171     return sb_value;
172 }
173 
174 uint32_t
175 SBValue::GetIndexOfChildWithName (const char *name)
176 {
177     if (IsValid())
178         return m_opaque_sp->GetIndexOfChildWithName (ConstString(name));
179     return UINT32_MAX;
180 }
181 
182 SBValue
183 SBValue::GetChildMemberWithName (const char *name)
184 {
185     lldb::ValueObjectSP child_sp;
186     const ConstString str_name (name);
187 
188     if (IsValid())
189     {
190         child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true);
191     }
192 
193     SBValue sb_value (child_sp);
194     return sb_value;
195 }
196 
197 
198 uint32_t
199 SBValue::GetNumChildren ()
200 {
201     uint32_t num_children = 0;
202 
203     if (IsValid())
204     {
205         num_children = m_opaque_sp->GetNumChildren();
206     }
207 
208     return num_children;
209 }
210 
211 bool
212 SBValue::ValueIsStale ()
213 {
214     bool result = true;
215 
216     if (IsValid())
217     {
218         result = m_opaque_sp->GetValueIsValid();
219     }
220 
221     return result;
222 }
223 
224 
225 SBValue
226 SBValue::Dereference ()
227 {
228     if (IsValid())
229     {
230         if (m_opaque_sp->IsPointerType())
231         {
232             return GetChildAtIndex(0);
233         }
234     }
235     return *this;
236 }
237 
238 bool
239 SBValue::TypeIsPtrType ()
240 {
241     bool is_ptr_type = false;
242 
243     if (IsValid())
244     {
245         is_ptr_type = m_opaque_sp->IsPointerType();
246     }
247 
248     return is_ptr_type;
249 }
250 
251 void *
252 SBValue::GetOpaqueType()
253 {
254     if (m_opaque_sp)
255         return m_opaque_sp->GetClangType();
256     return NULL;
257 }
258 
259 // Mimic shared pointer...
260 lldb_private::ValueObject *
261 SBValue::get() const
262 {
263     return m_opaque_sp.get();
264 }
265 
266 lldb_private::ValueObject *
267 SBValue::operator->() const
268 {
269     return m_opaque_sp.get();
270 }
271 
272 lldb::ValueObjectSP &
273 SBValue::operator*()
274 {
275     return m_opaque_sp;
276 }
277 
278 const lldb::ValueObjectSP &
279 SBValue::operator*() const
280 {
281     return m_opaque_sp;
282 }
283 
284 bool
285 SBValue::GetDescription (SBStream &description)
286 {
287     if (m_opaque_sp)
288     {
289         const char *name = GetName();
290         const char *type_name = GetTypeName ();
291         size_t byte_size = GetByteSize ();
292         uint32_t num_children = GetNumChildren ();
293         bool is_stale = ValueIsStale ();
294         description.Printf ("name: '%s', type: %s, size: %d", (name != NULL ? name : "<unknown name>"),
295                             (type_name != NULL ? type_name : "<unknown type name>"), (int) byte_size);
296         if (num_children > 0)
297             description.Printf (", num_children: %d", num_children);
298 
299         if (is_stale)
300             description.Printf (" [value is stale]");
301     }
302     else
303         description.Printf ("No value");
304 
305     return true;
306 }
307