1254721Semaste//===-- ValueObjectChild.cpp ------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Core/ValueObjectChild.h"
11254721Semaste
12254721Semaste#include "lldb/Core/Module.h"
13254721Semaste#include "lldb/Core/ValueObjectList.h"
14254721Semaste
15254721Semaste#include "lldb/Symbol/ClangASTType.h"
16254721Semaste#include "lldb/Symbol/ObjectFile.h"
17254721Semaste#include "lldb/Symbol/SymbolContext.h"
18254721Semaste#include "lldb/Symbol/Type.h"
19254721Semaste#include "lldb/Symbol/Variable.h"
20254721Semaste
21254721Semaste#include "lldb/Target/ExecutionContext.h"
22254721Semaste#include "lldb/Target/Process.h"
23254721Semaste#include "lldb/Target/Target.h"
24254721Semaste
25254721Semasteusing namespace lldb_private;
26254721Semaste
27254721SemasteValueObjectChild::ValueObjectChild
28254721Semaste(
29254721Semaste    ValueObject &parent,
30254721Semaste    const ClangASTType &clang_type,
31254721Semaste    const ConstString &name,
32254721Semaste    uint64_t byte_size,
33254721Semaste    int32_t byte_offset,
34254721Semaste    uint32_t bitfield_bit_size,
35254721Semaste    uint32_t bitfield_bit_offset,
36254721Semaste    bool is_base_class,
37254721Semaste    bool is_deref_of_parent,
38254721Semaste    AddressType child_ptr_or_ref_addr_type
39254721Semaste) :
40254721Semaste    ValueObject (parent),
41254721Semaste    m_clang_type (clang_type),
42254721Semaste    m_byte_size (byte_size),
43254721Semaste    m_byte_offset (byte_offset),
44254721Semaste    m_bitfield_bit_size (bitfield_bit_size),
45254721Semaste    m_bitfield_bit_offset (bitfield_bit_offset),
46254721Semaste    m_is_base_class (is_base_class),
47254721Semaste    m_is_deref_of_parent (is_deref_of_parent)
48254721Semaste{
49254721Semaste    m_name = name;
50254721Semaste    SetAddressTypeOfChildren(child_ptr_or_ref_addr_type);
51254721Semaste}
52254721Semaste
53254721SemasteValueObjectChild::~ValueObjectChild()
54254721Semaste{
55254721Semaste}
56254721Semaste
57254721Semastelldb::ValueType
58254721SemasteValueObjectChild::GetValueType() const
59254721Semaste{
60254721Semaste    return m_parent->GetValueType();
61254721Semaste}
62254721Semaste
63254721Semastesize_t
64254721SemasteValueObjectChild::CalculateNumChildren()
65254721Semaste{
66254721Semaste    return GetClangType().GetNumChildren (true);
67254721Semaste}
68254721Semaste
69254721SemasteConstString
70254721SemasteValueObjectChild::GetTypeName()
71254721Semaste{
72254721Semaste    if (m_type_name.IsEmpty())
73254721Semaste    {
74254721Semaste        m_type_name = GetClangType().GetConstTypeName ();
75254721Semaste        if (m_type_name)
76254721Semaste        {
77254721Semaste            if (m_bitfield_bit_size > 0)
78254721Semaste            {
79254721Semaste                const char *clang_type_name = m_type_name.AsCString();
80254721Semaste                if (clang_type_name)
81254721Semaste                {
82254721Semaste                    std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0);
83254721Semaste                    ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", clang_type_name, m_bitfield_bit_size);
84254721Semaste                    m_type_name.SetCString(&bitfield_type_name.front());
85254721Semaste                }
86254721Semaste            }
87254721Semaste        }
88254721Semaste    }
89254721Semaste    return m_type_name;
90254721Semaste}
91254721Semaste
92254721SemasteConstString
93254721SemasteValueObjectChild::GetQualifiedTypeName()
94254721Semaste{
95254721Semaste    ConstString qualified_name = GetClangType().GetConstTypeName();
96254721Semaste    if (qualified_name)
97254721Semaste    {
98254721Semaste        if (m_bitfield_bit_size > 0)
99254721Semaste        {
100254721Semaste            const char *clang_type_name = qualified_name.AsCString();
101254721Semaste            if (clang_type_name)
102254721Semaste            {
103254721Semaste                std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0);
104254721Semaste                ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", clang_type_name, m_bitfield_bit_size);
105254721Semaste                qualified_name.SetCString(&bitfield_type_name.front());
106254721Semaste            }
107254721Semaste        }
108254721Semaste    }
109254721Semaste    return qualified_name;
110254721Semaste}
111254721Semaste
112254721Semastebool
113254721SemasteValueObjectChild::UpdateValue ()
114254721Semaste{
115254721Semaste    m_error.Clear();
116254721Semaste    SetValueIsValid (false);
117254721Semaste    ValueObject* parent = m_parent;
118254721Semaste    if (parent)
119254721Semaste    {
120254721Semaste        if (parent->UpdateValueIfNeeded(false))
121254721Semaste        {
122254721Semaste            m_value.SetClangType(GetClangType());
123254721Semaste
124254721Semaste            // Copy the parent scalar value and the scalar value type
125254721Semaste            m_value.GetScalar() = parent->GetValue().GetScalar();
126254721Semaste            Value::ValueType value_type = parent->GetValue().GetValueType();
127254721Semaste            m_value.SetValueType (value_type);
128254721Semaste
129254721Semaste            if (parent->GetClangType().IsPointerOrReferenceType ())
130254721Semaste            {
131254721Semaste                lldb::addr_t addr = parent->GetPointerValue ();
132254721Semaste                m_value.GetScalar() = addr;
133254721Semaste
134254721Semaste                if (addr == LLDB_INVALID_ADDRESS)
135254721Semaste                {
136254721Semaste                    m_error.SetErrorString ("parent address is invalid.");
137254721Semaste                }
138254721Semaste                else if (addr == 0)
139254721Semaste                {
140254721Semaste                    m_error.SetErrorString ("parent is NULL");
141254721Semaste                }
142254721Semaste                else
143254721Semaste                {
144254721Semaste                    m_value.GetScalar() += m_byte_offset;
145254721Semaste                    AddressType addr_type = parent->GetAddressTypeOfChildren();
146254721Semaste
147254721Semaste                    switch (addr_type)
148254721Semaste                    {
149254721Semaste                        case eAddressTypeFile:
150254721Semaste                            {
151254721Semaste                                lldb::ProcessSP process_sp (GetProcessSP());
152254721Semaste                                if (process_sp && process_sp->IsAlive() == true)
153254721Semaste                                    m_value.SetValueType (Value::eValueTypeLoadAddress);
154254721Semaste                                else
155254721Semaste                                    m_value.SetValueType(Value::eValueTypeFileAddress);
156254721Semaste                            }
157254721Semaste                            break;
158254721Semaste                        case eAddressTypeLoad:
159254721Semaste                            m_value.SetValueType (Value::eValueTypeLoadAddress);
160254721Semaste                            break;
161254721Semaste                        case eAddressTypeHost:
162254721Semaste                            m_value.SetValueType(Value::eValueTypeHostAddress);
163254721Semaste                            break;
164254721Semaste                        case eAddressTypeInvalid:
165254721Semaste                            // TODO: does this make sense?
166254721Semaste                            m_value.SetValueType(Value::eValueTypeScalar);
167254721Semaste                            break;
168254721Semaste                    }
169254721Semaste                }
170254721Semaste            }
171254721Semaste            else
172254721Semaste            {
173254721Semaste                switch (value_type)
174254721Semaste                {
175254721Semaste                case Value::eValueTypeLoadAddress:
176254721Semaste                case Value::eValueTypeFileAddress:
177254721Semaste                case Value::eValueTypeHostAddress:
178254721Semaste                    {
179254721Semaste                        lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
180254721Semaste                        if (addr == LLDB_INVALID_ADDRESS)
181254721Semaste                        {
182254721Semaste                            m_error.SetErrorString ("parent address is invalid.");
183254721Semaste                        }
184254721Semaste                        else if (addr == 0)
185254721Semaste                        {
186254721Semaste                            m_error.SetErrorString ("parent is NULL");
187254721Semaste                        }
188254721Semaste                        else
189254721Semaste                        {
190254721Semaste                            // Set this object's scalar value to the address of its
191254721Semaste                            // value by adding its byte offset to the parent address
192254721Semaste                            m_value.GetScalar() += GetByteOffset();
193254721Semaste                        }
194254721Semaste                    }
195254721Semaste                    break;
196254721Semaste
197254721Semaste                case Value::eValueTypeScalar:
198254721Semaste                    // TODO: What if this is a register value? Do we try and
199254721Semaste                    // extract the child value from within the parent data?
200254721Semaste                    // Probably...
201254721Semaste                default:
202254721Semaste                    m_error.SetErrorString ("parent has invalid value.");
203254721Semaste                    break;
204254721Semaste                }
205254721Semaste            }
206254721Semaste
207254721Semaste            if (m_error.Success())
208254721Semaste            {
209269024Semaste                const bool thread_and_frame_only_if_stopped = true;
210269024Semaste                ExecutionContext exe_ctx (GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped));
211269024Semaste                if (GetClangType().GetTypeInfo() & ClangASTType::eTypeHasValue)
212269024Semaste                    m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
213269024Semaste                else
214269024Semaste                    m_error.Clear(); // No value so nothing to read...
215254721Semaste            }
216254721Semaste        }
217254721Semaste        else
218254721Semaste        {
219254721Semaste            m_error.SetErrorStringWithFormat("parent failed to evaluate: %s", parent->GetError().AsCString());
220254721Semaste        }
221254721Semaste    }
222254721Semaste    else
223254721Semaste    {
224254721Semaste        m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject.");
225254721Semaste    }
226254721Semaste
227254721Semaste    return m_error.Success();
228254721Semaste}
229254721Semaste
230254721Semaste
231254721Semastebool
232254721SemasteValueObjectChild::IsInScope ()
233254721Semaste{
234254721Semaste    ValueObject* root(GetRoot());
235254721Semaste    if (root)
236254721Semaste        return root->IsInScope ();
237254721Semaste    return false;
238254721Semaste}
239