SBValue.cpp revision e179a5840a49167964ca768a13c252c58c9cffcc
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/Log.h"
15#include "lldb/Core/Module.h"
16#include "lldb/Core/Stream.h"
17#include "lldb/Core/StreamFile.h"
18#include "lldb/Core/Value.h"
19#include "lldb/Core/ValueObject.h"
20#include "lldb/Symbol/Block.h"
21#include "lldb/Symbol/ObjectFile.h"
22#include "lldb/Symbol/Variable.h"
23#include "lldb/Target/ExecutionContext.h"
24#include "lldb/Target/Process.h"
25#include "lldb/Target/StackFrame.h"
26#include "lldb/Target/Target.h"
27#include "lldb/Target/Thread.h"
28
29#include "lldb/API/SBProcess.h"
30#include "lldb/API/SBTarget.h"
31#include "lldb/API/SBThread.h"
32#include "lldb/API/SBFrame.h"
33#include "lldb/API/SBDebugger.h"
34
35using namespace lldb;
36using namespace lldb_private;
37
38SBValue::SBValue () :
39    m_opaque_sp ()
40{
41}
42
43SBValue::SBValue (const lldb::ValueObjectSP &value_sp) :
44    m_opaque_sp (value_sp)
45{
46}
47
48SBValue::SBValue(const SBValue &rhs) :
49    m_opaque_sp (rhs.m_opaque_sp)
50{
51}
52
53const SBValue &
54SBValue::operator = (const SBValue &rhs)
55{
56    if (this != &rhs)
57        m_opaque_sp = rhs.m_opaque_sp;
58    return *this;
59}
60
61SBValue::~SBValue()
62{
63}
64
65bool
66SBValue::IsValid () const
67{
68    // If this function ever changes to anything that does more than just
69    // check if the opaque shared pointer is non NULL, then we need to update
70    // all "if (m_opaque_sp)" code in this file.
71    return m_opaque_sp.get() != NULL;
72}
73
74SBError
75SBValue::GetError()
76{
77    SBError sb_error;
78
79    if (m_opaque_sp.get())
80        sb_error.SetError(m_opaque_sp->GetError());
81
82    return sb_error;
83}
84
85const char *
86SBValue::GetName()
87{
88
89    const char *name = NULL;
90    if (m_opaque_sp)
91        name = m_opaque_sp->GetName().GetCString();
92
93    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
94    if (log)
95    {
96        if (name)
97            log->Printf ("SBValue(%p)::GetName () => \"%s\"", m_opaque_sp.get(), name);
98        else
99            log->Printf ("SBValue(%p)::GetName () => NULL", m_opaque_sp.get(), name);
100    }
101
102    return name;
103}
104
105const char *
106SBValue::GetTypeName ()
107{
108    const char *name = NULL;
109    if (m_opaque_sp)
110        name = m_opaque_sp->GetTypeName().GetCString();
111    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
112    if (log)
113    {
114        if (name)
115            log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"", m_opaque_sp.get(), name);
116        else
117            log->Printf ("SBValue(%p)::GetTypeName () => NULL", m_opaque_sp.get());
118    }
119
120    return name;
121}
122
123size_t
124SBValue::GetByteSize ()
125{
126    size_t result = 0;
127
128    if (m_opaque_sp)
129        result = m_opaque_sp->GetByteSize();
130
131    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
132    if (log)
133        log->Printf ("SBValue(%p)::GetByteSize () => %zu", m_opaque_sp.get(), result);
134
135    return result;
136}
137
138bool
139SBValue::IsInScope (const SBFrame &sb_frame)
140{
141    bool result = false;
142
143    if (m_opaque_sp)
144    {
145        StackFrame *frame = sb_frame.get();
146        if (frame)
147        {
148            Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex());
149            result = m_opaque_sp->IsInScope (frame);
150        }
151    }
152
153    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
154    if (log)
155        log->Printf ("SBValue(%p)::IsInScope () => %i", m_opaque_sp.get(), result);
156
157    return result;
158}
159
160const char *
161SBValue::GetValue (const SBFrame &sb_frame)
162{
163    const char *cstr = NULL;
164    if (m_opaque_sp)
165    {
166        StackFrame *frame = sb_frame.get();
167        if (frame)
168        {
169            Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex());
170            cstr = m_opaque_sp->GetValueAsCString (frame);
171        }
172    }
173    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
174    if (log)
175    {
176        if (cstr)
177            log->Printf ("SBValue(%p)::GetValue (SBFrame(%p)) => \"%s\"", m_opaque_sp.get(), sb_frame.get(), cstr);
178        else
179            log->Printf ("SBValue(%p)::GetValue (SBFrame(%p)) => NULL", m_opaque_sp.get(), sb_frame.get());
180    }
181
182    return cstr;
183}
184
185ValueType
186SBValue::GetValueType ()
187{
188    ValueType result = eValueTypeInvalid;
189    if (m_opaque_sp)
190        result = m_opaque_sp->GetValueType();
191    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
192    if (log)
193    {
194        switch (result)
195        {
196        case eValueTypeInvalid:         log->Printf ("SBValue(%p)::GetValueType () => eValueTypeInvalid", m_opaque_sp.get()); break;
197        case eValueTypeVariableGlobal:  log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", m_opaque_sp.get()); break;
198        case eValueTypeVariableStatic:  log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", m_opaque_sp.get()); break;
199        case eValueTypeVariableArgument:log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", m_opaque_sp.get()); break;
200        case eValueTypeVariableLocal:   log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", m_opaque_sp.get()); break;
201        case eValueTypeRegister:        log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", m_opaque_sp.get()); break;
202        case eValueTypeRegisterSet:     log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", m_opaque_sp.get()); break;
203        case eValueTypeConstResult:     log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", m_opaque_sp.get()); break;
204        default:     log->Printf ("SBValue(%p)::GetValueType () => %i ???", m_opaque_sp.get(), result); break;
205        }
206    }
207    return result;
208}
209
210const char *
211SBValue::GetObjectDescription (const SBFrame &sb_frame)
212{
213    const char *cstr = NULL;
214    if ( m_opaque_sp)
215    {
216        StackFrame *frame = sb_frame.get();
217        if (frame)
218        {
219            Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex());
220            cstr = m_opaque_sp->GetObjectDescription (frame);
221        }
222    }
223    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
224    if (log)
225    {
226        if (cstr)
227            log->Printf ("SBValue(%p)::GetObjectDescription (SBFrame(%p)) => \"%s\"", m_opaque_sp.get(), sb_frame.get(), cstr);
228        else
229            log->Printf ("SBValue(%p)::GetObjectDescription (SBFrame(%p)) => NULL", m_opaque_sp.get(), sb_frame.get());
230    }
231    return cstr;
232}
233
234bool
235SBValue::GetValueDidChange (const SBFrame &sb_frame)
236{
237    bool result = false;
238    if (m_opaque_sp)
239    {
240        StackFrame *frame = sb_frame.get();
241        if (frame)
242        {
243            Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex());
244            result = m_opaque_sp->GetValueDidChange (frame);
245        }
246    }
247    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
248    if (log)
249        log->Printf ("SBValue(%p)::GetValueDidChange (SBFrame(%p)) => %i", m_opaque_sp.get(), sb_frame.get(), result);
250
251    return result;
252}
253
254const char *
255SBValue::GetSummary (const SBFrame &sb_frame)
256{
257    const char *cstr = NULL;
258    if (m_opaque_sp)
259    {
260        StackFrame *frame = sb_frame.get();
261        if (frame)
262        {
263            Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex());
264            cstr = m_opaque_sp->GetSummaryAsCString(frame);
265        }
266    }
267    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
268    if (log)
269    {
270        if (cstr)
271            log->Printf ("SBValue(%p)::GetSummary (SBFrame(%p)) => \"%s\"", m_opaque_sp.get(), sb_frame.get(), cstr);
272        else
273            log->Printf ("SBValue(%p)::GetSummary (SBFrame(%p)) => NULL", m_opaque_sp.get(), sb_frame.get());
274    }
275    return cstr;
276}
277
278const char *
279SBValue::GetLocation (const SBFrame &sb_frame)
280{
281    const char *cstr = NULL;
282    if (m_opaque_sp)
283    {
284        StackFrame *frame = sb_frame.get();
285        if (frame)
286        {
287            Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex());
288            cstr = m_opaque_sp->GetLocationAsCString(frame);
289        }
290    }
291    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
292    if (log)
293    {
294        if (cstr)
295            log->Printf ("SBValue(%p)::GetSummary (SBFrame(%p)) => \"%s\"", m_opaque_sp.get(), sb_frame.get(), cstr);
296        else
297            log->Printf ("SBValue(%p)::GetSummary (SBFrame(%p)) => NULL", m_opaque_sp.get(), sb_frame.get());
298    }
299    return cstr;
300}
301
302bool
303SBValue::SetValueFromCString (const SBFrame &sb_frame, const char *value_str)
304{
305    bool success = false;
306    if (m_opaque_sp)
307    {
308        StackFrame *frame = sb_frame.get();
309        if (frame)
310        {
311            Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex());
312            success = m_opaque_sp->SetValueFromCString (frame, value_str);
313        }
314    }
315    return success;
316}
317
318SBValue
319SBValue::GetChildAtIndex (uint32_t idx)
320{
321    lldb::ValueObjectSP child_sp;
322
323    if (m_opaque_sp)
324    {
325        child_sp = m_opaque_sp->GetChildAtIndex (idx, true);
326    }
327
328    SBValue sb_value (child_sp);
329    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
330    if (log)
331        log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", m_opaque_sp.get(), idx, sb_value.get());
332
333    return sb_value;
334}
335
336uint32_t
337SBValue::GetIndexOfChildWithName (const char *name)
338{
339    uint32_t idx = UINT32_MAX;
340    if (m_opaque_sp)
341        idx = m_opaque_sp->GetIndexOfChildWithName (ConstString(name));
342    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
343    if (log)
344    {
345        if (idx == UINT32_MAX)
346            log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", m_opaque_sp.get(), name, idx);
347        else
348            log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", m_opaque_sp.get(), name, idx);
349    }
350    return idx;
351}
352
353SBValue
354SBValue::GetChildMemberWithName (const char *name)
355{
356    lldb::ValueObjectSP child_sp;
357    const ConstString str_name (name);
358
359    if (m_opaque_sp)
360    {
361        child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true);
362    }
363
364    SBValue sb_value (child_sp);
365
366    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
367    if (log)
368        log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", m_opaque_sp.get(), name, sb_value.get());
369
370    return sb_value;
371}
372
373
374uint32_t
375SBValue::GetNumChildren ()
376{
377    uint32_t num_children = 0;
378
379    if (m_opaque_sp)
380        num_children = m_opaque_sp->GetNumChildren();
381
382    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
383    if (log)
384        log->Printf ("SBValue(%p)::GetNumChildren () => %u", m_opaque_sp.get(), num_children);
385
386    return num_children;
387}
388
389
390SBValue
391SBValue::Dereference ()
392{
393    SBValue sb_value;
394    if (m_opaque_sp)
395    {
396        Error error;
397        sb_value = m_opaque_sp->Dereference (error);
398    }
399    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
400    if (log)
401        log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", m_opaque_sp.get(), sb_value.get());
402
403    return sb_value;
404}
405
406bool
407SBValue::TypeIsPointerType ()
408{
409    bool is_ptr_type = false;
410
411    if (m_opaque_sp)
412        is_ptr_type = m_opaque_sp->IsPointerType();
413
414    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
415    if (log)
416        log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", m_opaque_sp.get(), is_ptr_type);
417
418
419    return is_ptr_type;
420}
421
422void *
423SBValue::GetOpaqueType()
424{
425    if (m_opaque_sp)
426        return m_opaque_sp->GetClangType();
427    return NULL;
428}
429
430// Mimic shared pointer...
431lldb_private::ValueObject *
432SBValue::get() const
433{
434    return m_opaque_sp.get();
435}
436
437lldb_private::ValueObject *
438SBValue::operator->() const
439{
440    return m_opaque_sp.get();
441}
442
443lldb::ValueObjectSP &
444SBValue::operator*()
445{
446    return m_opaque_sp;
447}
448
449const lldb::ValueObjectSP &
450SBValue::operator*() const
451{
452    return m_opaque_sp;
453}
454
455bool
456SBValue::GetExpressionPath (SBStream &description)
457{
458    if (m_opaque_sp)
459    {
460        m_opaque_sp->GetExpressionPath (description.ref());
461        return true;
462    }
463    return false;
464}
465
466bool
467SBValue::GetDescription (SBStream &description)
468{
469    if (m_opaque_sp)
470    {
471        // Don't call all these APIs and cause more logging!
472//        const char *name = GetName();
473//        const char *type_name = GetTypeName ();
474//        size_t byte_size = GetByteSize ();
475//        uint32_t num_children = GetNumChildren ();
476//        bool is_stale = ValueIsStale ();
477//        description.Printf ("name: '%s', type: %s, size: %d", (name != NULL ? name : "<unknown name>"),
478//                            (type_name != NULL ? type_name : "<unknown type name>"), (int) byte_size);
479//        if (num_children > 0)
480//            description.Printf (", num_children: %d", num_children);
481//
482//        if (is_stale)
483//            description.Printf (" [value is stale]");
484
485        description.Printf ("name: '%s'", m_opaque_sp->GetName().GetCString());
486    }
487    else
488        description.Printf ("No value");
489
490    return true;
491}
492
493lldb::Format
494SBValue::GetFormat () const
495{
496    if (m_opaque_sp)
497        return m_opaque_sp->GetFormat();
498    return eFormatDefault;
499}
500
501void
502SBValue::SetFormat (lldb::Format format)
503{
504    if (m_opaque_sp)
505        m_opaque_sp->SetFormat(format);
506}
507
508