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 "SBValue.h"
11 
12 #include "lldb/Core/DataExtractor.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/Stream.h"
15 #include "lldb/Core/StreamFile.h"
16 #include "lldb/Core/Value.h"
17 #include "lldb/Core/ValueObject.h"
18 #include "lldb/Symbol/Block.h"
19 #include "lldb/Symbol/ObjectFile.h"
20 #include "lldb/Symbol/Variable.h"
21 #include "lldb/Target/ExecutionContext.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/StackFrame.h"
24 #include "lldb/Target/Thread.h"
25 
26 #include "SBProcess.h"
27 #include "SBTarget.h"
28 #include "SBThread.h"
29 #include "SBFrame.h"
30 #include "SBDebugger.h"
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
35 SBValue::SBValue () :
36     m_lldb_object_sp ()
37 {
38 }
39 
40 SBValue::SBValue (const lldb::ValueObjectSP &value_sp) :
41     m_lldb_object_sp (value_sp)
42 {
43 }
44 
45 SBValue::~SBValue()
46 {
47 }
48 
49 bool
50 SBValue::IsValid () const
51 {
52     return  (m_lldb_object_sp.get() != NULL);
53 }
54 
55 void
56 SBValue::Print (FILE *out_file, SBFrame *frame, bool print_type, bool print_value)
57 {
58     if (out_file == NULL)
59         return;
60 
61     if (IsValid())
62     {
63 
64         SBThread sb_thread = frame->GetThread();
65         SBProcess sb_process = sb_thread.GetProcess();
66 
67         lldb_private::StackFrame *lldb_frame = frame->GetLLDBObjectPtr();
68         lldb_private::Thread *lldb_thread = sb_thread.GetLLDBObjectPtr();
69         lldb_private::Process *lldb_process = sb_process.get();
70 
71         lldb_private::ExecutionContext context (lldb_process, lldb_thread, lldb_frame);
72 
73         lldb_private::StreamFile out_stream (out_file);
74 
75         out_stream.Printf ("%s ", m_lldb_object_sp->GetName().AsCString (NULL));
76         if (! m_lldb_object_sp->IsInScope (lldb_frame))
77             out_stream.Printf ("[out-of-scope] ");
78         if (print_type)
79         {
80             out_stream.Printf ("(%s) ", m_lldb_object_sp->GetTypeName().AsCString ("<unknown-type>"));
81         }
82 
83         if (print_value)
84         {
85             ExecutionContextScope *exe_scope = frame->get();
86             const char *val_cstr = m_lldb_object_sp->GetValueAsCString(exe_scope);
87             const char *err_cstr = m_lldb_object_sp->GetError().AsCString();
88 
89             if (!err_cstr)
90             {
91                 const char *sum_cstr = m_lldb_object_sp->GetSummaryAsCString(exe_scope);
92                 const bool is_aggregate =
93                 ClangASTContext::IsAggregateType (m_lldb_object_sp->GetOpaqueClangQualType());
94                 if (val_cstr)
95                     out_stream.Printf ("= %s ", val_cstr);
96 
97                 if (sum_cstr)
98                     out_stream.Printf ("%s ", sum_cstr);
99 
100                 if (is_aggregate)
101                 {
102                     out_stream.PutChar ('{');
103                     const uint32_t num_children = m_lldb_object_sp->GetNumChildren();
104                     if (num_children)
105                     {
106                         out_stream.IndentMore();
107                         for (uint32_t idx = 0; idx < num_children; ++idx)
108                         {
109                             lldb::ValueObjectSP child_sp (m_lldb_object_sp->GetChildAtIndex (idx, true));
110                             if (child_sp.get())
111                             {
112                                 out_stream.EOL();
113                                 out_stream.Indent();
114                                 out_stream.Printf ("%s (%s) = %s", child_sp.get()->GetName().AsCString (""),
115                                                    child_sp.get()->GetTypeName().AsCString ("<unknown type>"),
116                                                    child_sp.get()->GetValueAsCString(exe_scope));
117                             }
118                         }
119                         out_stream.IndentLess();
120                     }
121                     out_stream.EOL();
122                     out_stream.Indent ("}");
123                 }
124             }
125         }
126         out_stream.EOL ();
127     }
128 }
129 
130 const char *
131 SBValue::GetName()
132 {
133     if (IsValid())
134         return m_lldb_object_sp->GetName().AsCString();
135     else
136         return NULL;
137 }
138 
139 const char *
140 SBValue::GetTypeName ()
141 {
142     if (IsValid())
143         return m_lldb_object_sp->GetTypeName().AsCString();
144     else
145         return NULL;
146 }
147 
148 size_t
149 SBValue::GetByteSize ()
150 {
151     size_t result = 0;
152 
153     if (IsValid())
154         result = m_lldb_object_sp->GetByteSize();
155 
156     return result;
157 }
158 
159 bool
160 SBValue::IsInScope (const SBFrame &frame)
161 {
162     bool result = false;
163 
164     if (IsValid())
165         result = m_lldb_object_sp->IsInScope (frame.get());
166 
167     return result;
168 }
169 
170 const char *
171 SBValue::GetValue (const SBFrame &frame)
172 {
173     const char *value_string = NULL;
174     if ( m_lldb_object_sp)
175         value_string = m_lldb_object_sp->GetValueAsCString(frame.get());
176     return value_string;
177 }
178 
179 bool
180 SBValue::GetValueDidChange ()
181 {
182     if (IsValid())
183         return m_lldb_object_sp->GetValueDidChange();
184     return false;
185 }
186 
187 const char *
188 SBValue::GetSummary (const SBFrame &frame)
189 {
190     const char *value_string = NULL;
191     if ( m_lldb_object_sp)
192         value_string = m_lldb_object_sp->GetSummaryAsCString(frame.get());
193     return value_string;
194 }
195 
196 const char *
197 SBValue::GetLocation (const SBFrame &frame)
198 {
199     const char *value_string = NULL;
200     if (IsValid())
201         value_string = m_lldb_object_sp->GetLocationAsCString(frame.get());
202     return value_string;
203 }
204 
205 bool
206 SBValue::SetValueFromCString (const SBFrame &frame, const char *value_str)
207 {
208     bool success = false;
209     if (IsValid())
210         success = m_lldb_object_sp->SetValueFromCString (frame.get(), value_str);
211     return success;
212 }
213 
214 SBValue
215 SBValue::GetChildAtIndex (uint32_t idx)
216 {
217     lldb::ValueObjectSP child_sp;
218 
219     if (IsValid())
220     {
221         child_sp = m_lldb_object_sp->GetChildAtIndex (idx, true);
222     }
223 
224     SBValue sb_value (child_sp);
225     return sb_value;
226 }
227 
228 uint32_t
229 SBValue::GetIndexOfChildWithName (const char *name)
230 {
231     if (IsValid())
232         return m_lldb_object_sp->GetIndexOfChildWithName (ConstString(name));
233     return UINT32_MAX;
234 }
235 
236 SBValue
237 SBValue::GetChildMemberWithName (const char *name)
238 {
239     lldb::ValueObjectSP child_sp;
240     const ConstString str_name (name);
241 
242     if (IsValid())
243     {
244         child_sp = m_lldb_object_sp->GetChildMemberWithName (str_name, true);
245     }
246 
247     SBValue sb_value (child_sp);
248     return sb_value;
249 }
250 
251 
252 uint32_t
253 SBValue::GetNumChildren ()
254 {
255     uint32_t num_children = 0;
256 
257     if (IsValid())
258     {
259         num_children = m_lldb_object_sp->GetNumChildren();
260     }
261 
262     return num_children;
263 }
264 
265 bool
266 SBValue::ValueIsStale ()
267 {
268     bool result = true;
269 
270     if (IsValid())
271     {
272         result = m_lldb_object_sp->GetValueIsValid();
273     }
274 
275     return result;
276 }
277 
278 
279 SBValue
280 SBValue::Dereference ()
281 {
282     if (IsValid())
283     {
284         if (m_lldb_object_sp->IsPointerType())
285         {
286             return GetChildAtIndex(0);
287         }
288     }
289     return *this;
290 }
291 
292 bool
293 SBValue::TypeIsPtrType ()
294 {
295     bool is_ptr_type = false;
296 
297     if (IsValid())
298     {
299         is_ptr_type = m_lldb_object_sp->IsPointerType();
300     }
301 
302     return is_ptr_type;
303 }
304 
305 
306 lldb_private::ExecutionContext
307 SBValue::GetCurrentExecutionContext ()
308 {
309     lldb_private::Process *process = NULL;
310     lldb_private::Thread *thread = NULL;
311     lldb_private::StackFrame *frame = NULL;
312 
313     SBTarget sb_target = SBDebugger::GetCurrentTarget();
314     if (sb_target.IsValid())
315     {
316         SBProcess sb_process = sb_target.GetProcess();
317         if (sb_process.IsValid())
318         {
319             process = sb_process.get();
320             SBThread sb_thread = sb_process.GetCurrentThread();
321             if (sb_thread.IsValid())
322             {
323                 thread = sb_thread.GetLLDBObjectPtr();
324                 frame = thread->GetStackFrameAtIndex(0).get();
325                 lldb_private::ExecutionContext exe_context (process, thread, frame);
326                 return exe_context;
327             }
328             else
329             {
330                 lldb_private::ExecutionContext exe_context (process, NULL, NULL);
331                 return exe_context;
332             }
333         }
334     }
335 
336     lldb_private::ExecutionContext exe_context (NULL, NULL, NULL);
337     return exe_context;
338 }
339 
340 
341 void *
342 SBValue::GetOpaqueType()
343 {
344     if (m_lldb_object_sp)
345         return m_lldb_object_sp->GetOpaqueClangQualType();
346     return NULL;
347 }
348 
349 // Mimic shared pointer...
350 lldb_private::ValueObject *
351 SBValue::get() const
352 {
353     return m_lldb_object_sp.get();
354 }
355 
356 lldb_private::ValueObject *
357 SBValue::operator->() const
358 {
359     return m_lldb_object_sp.get();
360 }
361 
362 lldb::ValueObjectSP &
363 SBValue::operator*()
364 {
365     return m_lldb_object_sp;
366 }
367 
368 const lldb::ValueObjectSP &
369 SBValue::operator*() const
370 {
371     return m_lldb_object_sp;
372 }
373