Home | History | Annotate | Download | only in Core
      1 //===-- ValueObjectChild.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/Core/ValueObjectChild.h"
     11 
     12 #include "lldb/Core/Module.h"
     13 #include "lldb/Core/ValueObjectList.h"
     14 
     15 #include "lldb/Symbol/ClangASTType.h"
     16 #include "lldb/Symbol/ObjectFile.h"
     17 #include "lldb/Symbol/SymbolContext.h"
     18 #include "lldb/Symbol/Type.h"
     19 #include "lldb/Symbol/Variable.h"
     20 
     21 #include "lldb/Target/ExecutionContext.h"
     22 #include "lldb/Target/Process.h"
     23 #include "lldb/Target/Target.h"
     24 
     25 using namespace lldb_private;
     26 
     27 ValueObjectChild::ValueObjectChild
     28 (
     29     ValueObject &parent,
     30     const ClangASTType &clang_type,
     31     const ConstString &name,
     32     uint64_t byte_size,
     33     int32_t byte_offset,
     34     uint32_t bitfield_bit_size,
     35     uint32_t bitfield_bit_offset,
     36     bool is_base_class,
     37     bool is_deref_of_parent,
     38     AddressType child_ptr_or_ref_addr_type
     39 ) :
     40     ValueObject (parent),
     41     m_clang_type (clang_type),
     42     m_byte_size (byte_size),
     43     m_byte_offset (byte_offset),
     44     m_bitfield_bit_size (bitfield_bit_size),
     45     m_bitfield_bit_offset (bitfield_bit_offset),
     46     m_is_base_class (is_base_class),
     47     m_is_deref_of_parent (is_deref_of_parent)
     48 {
     49     m_name = name;
     50     SetAddressTypeOfChildren(child_ptr_or_ref_addr_type);
     51 }
     52 
     53 ValueObjectChild::~ValueObjectChild()
     54 {
     55 }
     56 
     57 lldb::ValueType
     58 ValueObjectChild::GetValueType() const
     59 {
     60     return m_parent->GetValueType();
     61 }
     62 
     63 size_t
     64 ValueObjectChild::CalculateNumChildren()
     65 {
     66     return GetClangType().GetNumChildren (true);
     67 }
     68 
     69 ConstString
     70 ValueObjectChild::GetTypeName()
     71 {
     72     if (m_type_name.IsEmpty())
     73     {
     74         m_type_name = GetClangType().GetConstTypeName ();
     75         if (m_type_name)
     76         {
     77             if (m_bitfield_bit_size > 0)
     78             {
     79                 const char *clang_type_name = m_type_name.AsCString();
     80                 if (clang_type_name)
     81                 {
     82                     std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0);
     83                     ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", clang_type_name, m_bitfield_bit_size);
     84                     m_type_name.SetCString(&bitfield_type_name.front());
     85                 }
     86             }
     87         }
     88     }
     89     return m_type_name;
     90 }
     91 
     92 ConstString
     93 ValueObjectChild::GetQualifiedTypeName()
     94 {
     95     ConstString qualified_name = GetClangType().GetConstTypeName();
     96     if (qualified_name)
     97     {
     98         if (m_bitfield_bit_size > 0)
     99         {
    100             const char *clang_type_name = qualified_name.AsCString();
    101             if (clang_type_name)
    102             {
    103                 std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0);
    104                 ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", clang_type_name, m_bitfield_bit_size);
    105                 qualified_name.SetCString(&bitfield_type_name.front());
    106             }
    107         }
    108     }
    109     return qualified_name;
    110 }
    111 
    112 bool
    113 ValueObjectChild::UpdateValue ()
    114 {
    115     m_error.Clear();
    116     SetValueIsValid (false);
    117     ValueObject* parent = m_parent;
    118     if (parent)
    119     {
    120         if (parent->UpdateValueIfNeeded(false))
    121         {
    122             m_value.SetClangType(GetClangType());
    123 
    124             // Copy the parent scalar value and the scalar value type
    125             m_value.GetScalar() = parent->GetValue().GetScalar();
    126             Value::ValueType value_type = parent->GetValue().GetValueType();
    127             m_value.SetValueType (value_type);
    128 
    129             if (parent->GetClangType().IsPointerOrReferenceType ())
    130             {
    131                 lldb::addr_t addr = parent->GetPointerValue ();
    132                 m_value.GetScalar() = addr;
    133 
    134                 if (addr == LLDB_INVALID_ADDRESS)
    135                 {
    136                     m_error.SetErrorString ("parent address is invalid.");
    137                 }
    138                 else if (addr == 0)
    139                 {
    140                     m_error.SetErrorString ("parent is NULL");
    141                 }
    142                 else
    143                 {
    144                     m_value.GetScalar() += m_byte_offset;
    145                     AddressType addr_type = parent->GetAddressTypeOfChildren();
    146 
    147                     switch (addr_type)
    148                     {
    149                         case eAddressTypeFile:
    150                             {
    151                                 lldb::ProcessSP process_sp (GetProcessSP());
    152                                 if (process_sp && process_sp->IsAlive() == true)
    153                                     m_value.SetValueType (Value::eValueTypeLoadAddress);
    154                                 else
    155                                     m_value.SetValueType(Value::eValueTypeFileAddress);
    156                             }
    157                             break;
    158                         case eAddressTypeLoad:
    159                             m_value.SetValueType (Value::eValueTypeLoadAddress);
    160                             break;
    161                         case eAddressTypeHost:
    162                             m_value.SetValueType(Value::eValueTypeHostAddress);
    163                             break;
    164                         case eAddressTypeInvalid:
    165                             // TODO: does this make sense?
    166                             m_value.SetValueType(Value::eValueTypeScalar);
    167                             break;
    168                     }
    169                 }
    170             }
    171             else
    172             {
    173                 switch (value_type)
    174                 {
    175                 case Value::eValueTypeLoadAddress:
    176                 case Value::eValueTypeFileAddress:
    177                 case Value::eValueTypeHostAddress:
    178                     {
    179                         lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
    180                         if (addr == LLDB_INVALID_ADDRESS)
    181                         {
    182                             m_error.SetErrorString ("parent address is invalid.");
    183                         }
    184                         else if (addr == 0)
    185                         {
    186                             m_error.SetErrorString ("parent is NULL");
    187                         }
    188                         else
    189                         {
    190                             // Set this object's scalar value to the address of its
    191                             // value by adding its byte offset to the parent address
    192                             m_value.GetScalar() += GetByteOffset();
    193                         }
    194                     }
    195                     break;
    196 
    197                 case Value::eValueTypeScalar:
    198                     // TODO: What if this is a register value? Do we try and
    199                     // extract the child value from within the parent data?
    200                     // Probably...
    201                 default:
    202                     m_error.SetErrorString ("parent has invalid value.");
    203                     break;
    204                 }
    205             }
    206 
    207             if (m_error.Success())
    208             {
    209                 ExecutionContext exe_ctx (GetExecutionContextRef().Lock());
    210                 m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
    211             }
    212         }
    213         else
    214         {
    215             m_error.SetErrorStringWithFormat("parent failed to evaluate: %s", parent->GetError().AsCString());
    216         }
    217     }
    218     else
    219     {
    220         m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject.");
    221     }
    222 
    223     return m_error.Success();
    224 }
    225 
    226 
    227 bool
    228 ValueObjectChild::IsInScope ()
    229 {
    230     ValueObject* root(GetRoot());
    231     if (root)
    232         return root->IsInScope ();
    233     return false;
    234 }
    235