1 //===-- ValueObjectConstResultImpl.cpp ---------------------------*- C++
2 //-*-===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 
11 #include "lldb/Core/ValueObjectConstResultImpl.h"
12 
13 #include "lldb/Core/DataExtractor.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/ValueObjectChild.h"
16 #include "lldb/Core/ValueObjectConstResult.h"
17 #include "lldb/Core/ValueObjectConstResultCast.h"
18 #include "lldb/Core/ValueObjectConstResultChild.h"
19 #include "lldb/Core/ValueObjectList.h"
20 #include "lldb/Core/ValueObjectMemory.h"
21 
22 #include "lldb/Symbol/CompilerType.h"
23 #include "lldb/Symbol/ObjectFile.h"
24 #include "lldb/Symbol/SymbolContext.h"
25 #include "lldb/Symbol/Type.h"
26 #include "lldb/Symbol/Variable.h"
27 
28 #include "lldb/Target/ExecutionContext.h"
29 #include "lldb/Target/Process.h"
30 #include "lldb/Target/Target.h"
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
35 ValueObjectConstResultImpl::ValueObjectConstResultImpl(
36     ValueObject *valobj, lldb::addr_t live_address)
37     : m_impl_backend(valobj), m_live_address(live_address),
38       m_live_address_type(eAddressTypeLoad), m_load_addr_backend(),
39       m_address_of_backend() {}
40 
41 lldb::ValueObjectSP ValueObjectConstResultImpl::Dereference(Error &error) {
42   if (m_impl_backend == NULL)
43     return lldb::ValueObjectSP();
44 
45   return m_impl_backend->ValueObject::Dereference(error);
46 }
47 
48 ValueObject *ValueObjectConstResultImpl::CreateChildAtIndex(
49     size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
50   if (m_impl_backend == NULL)
51     return NULL;
52 
53   m_impl_backend->UpdateValueIfNeeded(false);
54 
55   ValueObjectConstResultChild *valobj = NULL;
56 
57   bool omit_empty_base_classes = true;
58   bool ignore_array_bounds = synthetic_array_member;
59   std::string child_name_str;
60   uint32_t child_byte_size = 0;
61   int32_t child_byte_offset = 0;
62   uint32_t child_bitfield_bit_size = 0;
63   uint32_t child_bitfield_bit_offset = 0;
64   bool child_is_base_class = false;
65   bool child_is_deref_of_parent = false;
66   uint64_t language_flags;
67 
68   const bool transparent_pointers = synthetic_array_member == false;
69   CompilerType compiler_type = m_impl_backend->GetCompilerType();
70   CompilerType child_compiler_type;
71 
72   ExecutionContext exe_ctx(m_impl_backend->GetExecutionContextRef());
73 
74   child_compiler_type = compiler_type.GetChildCompilerTypeAtIndex(
75       &exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
76       ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset,
77       child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
78       child_is_deref_of_parent, m_impl_backend, language_flags);
79   if (child_compiler_type && child_byte_size) {
80     if (synthetic_index)
81       child_byte_offset += child_byte_size * synthetic_index;
82 
83     ConstString child_name;
84     if (!child_name_str.empty())
85       child_name.SetCString(child_name_str.c_str());
86 
87     valobj = new ValueObjectConstResultChild(
88         *m_impl_backend, child_compiler_type, child_name, child_byte_size,
89         child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
90         child_is_base_class, child_is_deref_of_parent,
91         m_live_address == LLDB_INVALID_ADDRESS
92             ? m_live_address
93             : m_live_address + child_byte_offset,
94         language_flags);
95   }
96 
97   return valobj;
98 }
99 
100 lldb::ValueObjectSP ValueObjectConstResultImpl::GetSyntheticChildAtOffset(
101     uint32_t offset, const CompilerType &type, bool can_create,
102     ConstString name_const_str) {
103   if (m_impl_backend == NULL)
104     return lldb::ValueObjectSP();
105 
106   return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(
107       offset, type, can_create, name_const_str);
108 }
109 
110 lldb::ValueObjectSP ValueObjectConstResultImpl::AddressOf(Error &error) {
111   if (m_address_of_backend.get() != NULL)
112     return m_address_of_backend;
113 
114   if (m_impl_backend == NULL)
115     return lldb::ValueObjectSP();
116   if (m_live_address != LLDB_INVALID_ADDRESS) {
117     CompilerType compiler_type(m_impl_backend->GetCompilerType());
118 
119     lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(
120         &m_live_address, sizeof(lldb::addr_t)));
121 
122     std::string new_name("&");
123     new_name.append(m_impl_backend->GetName().AsCString(""));
124     ExecutionContext exe_ctx(m_impl_backend->GetExecutionContextRef());
125     m_address_of_backend = ValueObjectConstResult::Create(
126         exe_ctx.GetBestExecutionContextScope(), compiler_type.GetPointerType(),
127         ConstString(new_name.c_str()), buffer, endian::InlHostByteOrder(),
128         exe_ctx.GetAddressByteSize());
129 
130     m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar);
131     m_address_of_backend->GetValue().GetScalar() = m_live_address;
132 
133     return m_address_of_backend;
134   } else
135     return m_impl_backend->ValueObject::AddressOf(error);
136 }
137 
138 lldb::ValueObjectSP
139 ValueObjectConstResultImpl::Cast(const CompilerType &compiler_type) {
140   if (m_impl_backend == NULL)
141     return lldb::ValueObjectSP();
142 
143   ValueObjectConstResultCast *result_cast =
144       new ValueObjectConstResultCast(*m_impl_backend, m_impl_backend->GetName(),
145                                      compiler_type, m_live_address);
146   return result_cast->GetSP();
147 }
148 
149 lldb::addr_t
150 ValueObjectConstResultImpl::GetAddressOf(bool scalar_is_load_address,
151                                          AddressType *address_type) {
152 
153   if (m_impl_backend == NULL)
154     return 0;
155 
156   if (m_live_address == LLDB_INVALID_ADDRESS) {
157     return m_impl_backend->ValueObject::GetAddressOf(scalar_is_load_address,
158                                                      address_type);
159   }
160 
161   if (address_type)
162     *address_type = m_live_address_type;
163 
164   return m_live_address;
165 }
166 
167 size_t ValueObjectConstResultImpl::GetPointeeData(DataExtractor &data,
168                                                   uint32_t item_idx,
169                                                   uint32_t item_count) {
170   if (m_impl_backend == NULL)
171     return 0;
172   return m_impl_backend->ValueObject::GetPointeeData(data, item_idx,
173                                                      item_count);
174 }
175