SBValue.cpp revision ef80aabe53b7fdf61309ba6d3d6865c94c681345
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    return IsInScope();
142}
143
144bool
145SBValue::IsInScope ()
146{
147    bool result = false;
148
149    if (m_opaque_sp)
150    {
151        if (m_opaque_sp->GetUpdatePoint().GetTarget())
152            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
153        result = m_opaque_sp->IsInScope ();
154    }
155
156    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
157    if (log)
158        log->Printf ("SBValue(%p)::IsInScope () => %i", m_opaque_sp.get(), result);
159
160    return result;
161}
162
163const char *
164SBValue::GetValue (const SBFrame &sb_frame)
165{
166    return GetValue();
167}
168
169const char *
170SBValue::GetValue ()
171{
172    const char *cstr = NULL;
173    if (m_opaque_sp)
174    {
175        if (m_opaque_sp->GetUpdatePoint().GetTarget())
176            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
177        cstr = m_opaque_sp->GetValueAsCString ();
178    }
179    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
180    if (log)
181    {
182        if (cstr)
183            log->Printf ("SBValue(%p)::GetValue => \"%s\"", m_opaque_sp.get(), cstr);
184        else
185            log->Printf ("SBValue(%p)::GetValue => NULL", m_opaque_sp.get());
186    }
187
188    return cstr;
189}
190
191ValueType
192SBValue::GetValueType ()
193{
194    ValueType result = eValueTypeInvalid;
195    if (m_opaque_sp)
196        result = m_opaque_sp->GetValueType();
197    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
198    if (log)
199    {
200        switch (result)
201        {
202        case eValueTypeInvalid:         log->Printf ("SBValue(%p)::GetValueType () => eValueTypeInvalid", m_opaque_sp.get()); break;
203        case eValueTypeVariableGlobal:  log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", m_opaque_sp.get()); break;
204        case eValueTypeVariableStatic:  log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", m_opaque_sp.get()); break;
205        case eValueTypeVariableArgument:log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", m_opaque_sp.get()); break;
206        case eValueTypeVariableLocal:   log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", m_opaque_sp.get()); break;
207        case eValueTypeRegister:        log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", m_opaque_sp.get()); break;
208        case eValueTypeRegisterSet:     log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", m_opaque_sp.get()); break;
209        case eValueTypeConstResult:     log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", m_opaque_sp.get()); break;
210        default:     log->Printf ("SBValue(%p)::GetValueType () => %i ???", m_opaque_sp.get(), result); break;
211        }
212    }
213    return result;
214}
215
216const char *
217SBValue::GetObjectDescription (const SBFrame &sb_frame)
218{
219    return GetObjectDescription ();
220}
221
222const char *
223SBValue::GetObjectDescription ()
224{
225    const char *cstr = NULL;
226    if (m_opaque_sp)
227    {
228        if (m_opaque_sp->GetUpdatePoint().GetTarget())
229            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
230        cstr = m_opaque_sp->GetObjectDescription ();
231    }
232    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
233    if (log)
234    {
235        if (cstr)
236            log->Printf ("SBValue(%p)::GetObjectDescription => \"%s\"", m_opaque_sp.get(), cstr);
237        else
238            log->Printf ("SBValue(%p)::GetObjectDescription => NULL", m_opaque_sp.get());
239    }
240    return cstr;
241}
242
243bool
244SBValue::GetValueDidChange (const SBFrame &sb_frame)
245{
246    return GetValueDidChange ();
247}
248
249bool
250SBValue::GetValueDidChange ()
251{
252    bool result = false;
253    if (m_opaque_sp)
254    {
255        if (m_opaque_sp->GetUpdatePoint().GetTarget())
256            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
257        result = m_opaque_sp->GetValueDidChange ();
258    }
259    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
260    if (log)
261        log->Printf ("SBValue(%p)::GetValueDidChange => %i", m_opaque_sp.get(), result);
262
263    return result;
264}
265
266const char *
267SBValue::GetSummary (const SBFrame &sb_frame)
268{
269    return GetSummary ();
270}
271
272const char *
273SBValue::GetSummary ()
274{
275    const char *cstr = NULL;
276    if (m_opaque_sp)
277    {
278        if (m_opaque_sp->GetUpdatePoint().GetTarget())
279            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
280        cstr = m_opaque_sp->GetSummaryAsCString();
281    }
282    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
283    if (log)
284    {
285        if (cstr)
286            log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr);
287        else
288            log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get());
289    }
290    return cstr;
291}
292
293const char *
294SBValue::GetLocation (const SBFrame &sb_frame)
295{
296    return GetLocation ();
297}
298
299const char *
300SBValue::GetLocation ()
301{
302    const char *cstr = NULL;
303    if (m_opaque_sp)
304    {
305        if (m_opaque_sp->GetUpdatePoint().GetTarget())
306            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
307        cstr = m_opaque_sp->GetLocationAsCString();
308    }
309    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
310    if (log)
311    {
312        if (cstr)
313            log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr);
314        else
315            log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get());
316    }
317    return cstr;
318}
319
320bool
321SBValue::SetValueFromCString (const SBFrame &sb_frame, const char *value_str)
322{
323    return SetValueFromCString (value_str);
324}
325
326bool
327SBValue::SetValueFromCString (const char *value_str)
328{
329    bool success = false;
330    if (m_opaque_sp)
331    {
332        if (m_opaque_sp->GetUpdatePoint().GetTarget())
333            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
334        success = m_opaque_sp->SetValueFromCString (value_str);
335    }
336    return success;
337}
338
339SBValue
340SBValue::GetChildAtIndex (uint32_t idx)
341{
342    bool use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue();
343    return GetChildAtIndex (idx, use_dynamic_value);
344}
345
346SBValue
347SBValue::GetChildAtIndex (uint32_t idx, bool use_dynamic_value)
348{
349    lldb::ValueObjectSP child_sp;
350
351    if (m_opaque_sp)
352    {
353        child_sp = m_opaque_sp->GetChildAtIndex (idx, true);
354    }
355
356    if (use_dynamic_value)
357    {
358        if (child_sp)
359        {
360            lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (true);
361            if (dynamic_sp)
362                child_sp = dynamic_sp;
363        }
364    }
365
366    SBValue sb_value (child_sp);
367    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
368    if (log)
369        log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", m_opaque_sp.get(), idx, sb_value.get());
370
371    return sb_value;
372}
373
374uint32_t
375SBValue::GetIndexOfChildWithName (const char *name)
376{
377    uint32_t idx = UINT32_MAX;
378    if (m_opaque_sp)
379        idx = m_opaque_sp->GetIndexOfChildWithName (ConstString(name));
380    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
381    if (log)
382    {
383        if (idx == UINT32_MAX)
384            log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", m_opaque_sp.get(), name, idx);
385        else
386            log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", m_opaque_sp.get(), name, idx);
387    }
388    return idx;
389}
390
391SBValue
392SBValue::GetChildMemberWithName (const char *name)
393{
394    bool use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue();
395    return GetChildMemberWithName (name, use_dynamic_value);
396}
397
398SBValue
399SBValue::GetChildMemberWithName (const char *name, bool use_dynamic_value)
400{
401    lldb::ValueObjectSP child_sp;
402    const ConstString str_name (name);
403
404    if (m_opaque_sp)
405    {
406        child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true);
407    }
408
409    if (use_dynamic_value)
410    {
411        if (child_sp)
412        {
413            lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (true);
414            if (dynamic_sp)
415                child_sp = dynamic_sp;
416        }
417    }
418
419    SBValue sb_value (child_sp);
420
421    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
422    if (log)
423        log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", m_opaque_sp.get(), name, sb_value.get());
424
425    return sb_value;
426}
427
428
429uint32_t
430SBValue::GetNumChildren ()
431{
432    uint32_t num_children = 0;
433
434    if (m_opaque_sp)
435        num_children = m_opaque_sp->GetNumChildren();
436
437    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
438    if (log)
439        log->Printf ("SBValue(%p)::GetNumChildren () => %u", m_opaque_sp.get(), num_children);
440
441    return num_children;
442}
443
444
445SBValue
446SBValue::Dereference ()
447{
448    SBValue sb_value;
449    if (m_opaque_sp)
450    {
451        Error error;
452        sb_value = m_opaque_sp->Dereference (error);
453    }
454    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
455    if (log)
456        log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", m_opaque_sp.get(), sb_value.get());
457
458    return sb_value;
459}
460
461bool
462SBValue::TypeIsPointerType ()
463{
464    bool is_ptr_type = false;
465
466    if (m_opaque_sp)
467        is_ptr_type = m_opaque_sp->IsPointerType();
468
469    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
470    if (log)
471        log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", m_opaque_sp.get(), is_ptr_type);
472
473
474    return is_ptr_type;
475}
476
477void *
478SBValue::GetOpaqueType()
479{
480    if (m_opaque_sp)
481        return m_opaque_sp->GetClangType();
482    return NULL;
483}
484
485// Mimic shared pointer...
486lldb_private::ValueObject *
487SBValue::get() const
488{
489    return m_opaque_sp.get();
490}
491
492lldb_private::ValueObject *
493SBValue::operator->() const
494{
495    return m_opaque_sp.get();
496}
497
498lldb::ValueObjectSP &
499SBValue::operator*()
500{
501    return m_opaque_sp;
502}
503
504const lldb::ValueObjectSP &
505SBValue::operator*() const
506{
507    return m_opaque_sp;
508}
509
510bool
511SBValue::GetExpressionPath (SBStream &description)
512{
513    if (m_opaque_sp)
514    {
515        m_opaque_sp->GetExpressionPath (description.ref(), false);
516        return true;
517    }
518    return false;
519}
520
521bool
522SBValue::GetExpressionPath (SBStream &description, bool qualify_cxx_base_classes)
523{
524    if (m_opaque_sp)
525    {
526        m_opaque_sp->GetExpressionPath (description.ref(), qualify_cxx_base_classes);
527        return true;
528    }
529    return false;
530}
531
532bool
533SBValue::GetDescription (SBStream &description)
534{
535    if (m_opaque_sp)
536    {
537        // Don't call all these APIs and cause more logging!
538//        const char *name = GetName();
539//        const char *type_name = GetTypeName ();
540//        size_t byte_size = GetByteSize ();
541//        uint32_t num_children = GetNumChildren ();
542//        bool is_stale = ValueIsStale ();
543//        description.Printf ("name: '%s', type: %s, size: %d", (name != NULL ? name : "<unknown name>"),
544//                            (type_name != NULL ? type_name : "<unknown type name>"), (int) byte_size);
545//        if (num_children > 0)
546//            description.Printf (", num_children: %d", num_children);
547//
548//        if (is_stale)
549//            description.Printf (" [value is stale]");
550
551        description.Printf ("name: '%s'", m_opaque_sp->GetName().GetCString());
552    }
553    else
554        description.Printf ("No value");
555
556    return true;
557}
558
559lldb::Format
560SBValue::GetFormat () const
561{
562    if (m_opaque_sp)
563        return m_opaque_sp->GetFormat();
564    return eFormatDefault;
565}
566
567void
568SBValue::SetFormat (lldb::Format format)
569{
570    if (m_opaque_sp)
571        m_opaque_sp->SetFormat(format);
572}
573
574