Home | History | Annotate | Download | only in Core
      1 //===-- ValueObjectConstResultImpl.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/ValueObjectConstResultImpl.h"
     11 
     12 #include "lldb/Core/ValueObjectChild.h"
     13 #include "lldb/Core/ValueObjectConstResult.h"
     14 #include "lldb/Core/ValueObjectConstResultChild.h"
     15 #include "lldb/Core/ValueObjectMemory.h"
     16 #include "lldb/Core/DataExtractor.h"
     17 #include "lldb/Core/Module.h"
     18 #include "lldb/Core/ValueObjectList.h"
     19 
     20 #include "lldb/Symbol/ClangASTType.h"
     21 #include "lldb/Symbol/ObjectFile.h"
     22 #include "lldb/Symbol/SymbolContext.h"
     23 #include "lldb/Symbol/Type.h"
     24 #include "lldb/Symbol/Variable.h"
     25 
     26 #include "lldb/Target/ExecutionContext.h"
     27 #include "lldb/Target/Process.h"
     28 #include "lldb/Target/Target.h"
     29 
     30 using namespace lldb;
     31 using namespace lldb_private;
     32 
     33 // this macro enables a simpler implementation for some method calls in this object that relies only upon
     34 // ValueObject knowning how to set the address type of its children correctly. the alternative implementation
     35 // relies on being able to create a target copy of the frozen object, which makes it less bug-prone but less
     36 // efficient as well. once we are confident the faster implementation is bug-free, this macro (and the slower
     37 // implementations) can go
     38 #define TRIVIAL_IMPL 1
     39 
     40 ValueObjectConstResultImpl::ValueObjectConstResultImpl (ValueObject* valobj,
     41                                                         lldb::addr_t live_address) :
     42     m_impl_backend(valobj),
     43     m_live_address(live_address),
     44     m_live_address_type(eAddressTypeLoad),
     45     m_load_addr_backend(),
     46     m_address_of_backend()
     47 {
     48 }
     49 
     50 lldb::ValueObjectSP
     51 ValueObjectConstResultImpl::DerefOnTarget()
     52 {
     53     if (m_load_addr_backend.get() == NULL)
     54     {
     55         lldb::addr_t tgt_address = m_impl_backend->GetPointerValue();
     56         ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
     57         m_load_addr_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
     58                                                               m_impl_backend->GetClangType(),
     59                                                               m_impl_backend->GetName(),
     60                                                               tgt_address,
     61                                                               eAddressTypeLoad,
     62                                                               exe_ctx.GetAddressByteSize());
     63     }
     64     return m_load_addr_backend;
     65 }
     66 
     67 lldb::ValueObjectSP
     68 ValueObjectConstResultImpl::Dereference (Error &error)
     69 {
     70     if (m_impl_backend == NULL)
     71         return lldb::ValueObjectSP();
     72 
     73 #if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
     74     return m_impl_backend->ValueObject::Dereference(error);
     75 #else
     76     m_impl_backend->UpdateValueIfNeeded(false);
     77 
     78     if (NeedsDerefOnTarget())
     79         return DerefOnTarget()->Dereference(error);
     80     else
     81         return m_impl_backend->ValueObject::Dereference(error);
     82 #endif
     83 }
     84 
     85 ValueObject *
     86 ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
     87 {
     88     if (m_impl_backend == NULL)
     89         return NULL;
     90 
     91     m_impl_backend->UpdateValueIfNeeded(false);
     92 
     93     ValueObjectConstResultChild *valobj = NULL;
     94 
     95     bool omit_empty_base_classes = true;
     96     bool ignore_array_bounds = synthetic_array_member;
     97     std::string child_name_str;
     98     uint32_t child_byte_size = 0;
     99     int32_t child_byte_offset = 0;
    100     uint32_t child_bitfield_bit_size = 0;
    101     uint32_t child_bitfield_bit_offset = 0;
    102     bool child_is_base_class = false;
    103     bool child_is_deref_of_parent = false;
    104 
    105     const bool transparent_pointers = synthetic_array_member == false;
    106     ClangASTType clang_type = m_impl_backend->GetClangType();
    107     ClangASTType child_clang_type;
    108 
    109     ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
    110 
    111     child_clang_type = clang_type.GetChildClangTypeAtIndex (&exe_ctx,
    112                                                             m_impl_backend->GetName().GetCString(),
    113                                                             idx,
    114                                                             transparent_pointers,
    115                                                             omit_empty_base_classes,
    116                                                             ignore_array_bounds,
    117                                                             child_name_str,
    118                                                             child_byte_size,
    119                                                             child_byte_offset,
    120                                                             child_bitfield_bit_size,
    121                                                             child_bitfield_bit_offset,
    122                                                             child_is_base_class,
    123                                                             child_is_deref_of_parent);
    124     if (child_clang_type && child_byte_size)
    125     {
    126         if (synthetic_index)
    127             child_byte_offset += child_byte_size * synthetic_index;
    128 
    129         ConstString child_name;
    130         if (!child_name_str.empty())
    131             child_name.SetCString (child_name_str.c_str());
    132 
    133         valobj = new ValueObjectConstResultChild (*m_impl_backend,
    134                                                   child_clang_type,
    135                                                   child_name,
    136                                                   child_byte_size,
    137                                                   child_byte_offset,
    138                                                   child_bitfield_bit_size,
    139                                                   child_bitfield_bit_offset,
    140                                                   child_is_base_class,
    141                                                   child_is_deref_of_parent);
    142         valobj->m_impl.SetLiveAddress(m_live_address+child_byte_offset);
    143     }
    144 
    145     return valobj;
    146 }
    147 
    148 lldb::ValueObjectSP
    149 ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset, const ClangASTType& type, bool can_create)
    150 {
    151     if (m_impl_backend == NULL)
    152         return lldb::ValueObjectSP();
    153 
    154 #if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
    155     return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
    156 #else
    157     m_impl_backend->UpdateValueIfNeeded(false);
    158 
    159     if (NeedsDerefOnTarget())
    160         return DerefOnTarget()->GetSyntheticChildAtOffset(offset, type, can_create);
    161     else
    162         return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create);
    163 #endif
    164 }
    165 
    166 lldb::ValueObjectSP
    167 ValueObjectConstResultImpl::AddressOf (Error &error)
    168 {
    169     if (m_address_of_backend.get() != NULL)
    170         return m_address_of_backend;
    171 
    172     if (m_impl_backend == NULL)
    173         return lldb::ValueObjectSP();
    174     if (m_live_address != LLDB_INVALID_ADDRESS)
    175     {
    176         ClangASTType clang_type(m_impl_backend->GetClangType());
    177 
    178         lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t)));
    179 
    180         std::string new_name("&");
    181         new_name.append(m_impl_backend->GetName().AsCString(""));
    182         ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
    183         m_address_of_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
    184                                                                clang_type.GetPointerType(),
    185                                                                ConstString(new_name.c_str()),
    186                                                                buffer,
    187                                                                lldb::endian::InlHostByteOrder(),
    188                                                                exe_ctx.GetAddressByteSize());
    189 
    190         m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar);
    191         m_address_of_backend->GetValue().GetScalar() = m_live_address;
    192 
    193         return m_address_of_backend;
    194     }
    195     else
    196         return lldb::ValueObjectSP();
    197 }
    198 
    199 lldb::addr_t
    200 ValueObjectConstResultImpl::GetAddressOf (bool scalar_is_load_address,
    201                                           AddressType *address_type)
    202 {
    203 
    204     if (m_impl_backend == NULL)
    205         return 0;
    206 
    207     if (m_live_address == LLDB_INVALID_ADDRESS)
    208     {
    209         return m_impl_backend->ValueObject::GetAddressOf (scalar_is_load_address,
    210                                                           address_type);
    211     }
    212 
    213     if (address_type)
    214         *address_type = m_live_address_type;
    215 
    216     return m_live_address;
    217 }
    218 
    219 size_t
    220 ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data,
    221                                             uint32_t item_idx,
    222                                             uint32_t item_count)
    223 {
    224     if (m_impl_backend == NULL)
    225         return 0;
    226 #if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1
    227     return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
    228 #else
    229     m_impl_backend->UpdateValueIfNeeded(false);
    230 
    231     if (NeedsDerefOnTarget() && m_impl_backend->IsPointerType())
    232         return DerefOnTarget()->GetPointeeData(data, item_idx, item_count);
    233     else
    234         return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
    235 #endif
    236 }
    237