ValueObjectChild.cpp revision 462d4147f3bb9141bf62d904f58a623db00669df
1f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt//===-- ValueObjectChild.cpp ------------------------------------*- C++ -*-===//
2f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt//
3f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt//                     The LLVM Compiler Infrastructure
4f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt//
5f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt// This file is distributed under the University of Illinois Open Source
6f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt// License. See LICENSE.TXT for details.
7f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt//
8f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt//===----------------------------------------------------------------------===//
9f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
10f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#include "lldb/Core/ValueObjectChild.h"
11f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
12f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#include "lldb/Core/Module.h"
13f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#include "lldb/Core/ValueObjectList.h"
14f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
15f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#include "lldb/Symbol/ClangASTType.h"
16f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#include "lldb/Symbol/ObjectFile.h"
17f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#include "lldb/Symbol/SymbolContext.h"
18f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#include "lldb/Symbol/Type.h"
19f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#include "lldb/Symbol/Variable.h"
20f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
21f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#include "lldb/Target/ExecutionContext.h"
22f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#include "lldb/Target/Process.h"
23f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#include "lldb/Target/Target.h"
24f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
25f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtusing namespace lldb_private;
26f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
27f86232838cf712377867cb42417c1613ab5dc425Dmitry ShmidtValueObjectChild::ValueObjectChild
28f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt(
29f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    ValueObject* parent,
30f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    clang::ASTContext *clang_ast,
31f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    void *clang_type,
32f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    const ConstString &name,
33f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    uint32_t byte_size,
34f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    int32_t byte_offset,
35f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    uint32_t bitfield_bit_size,
36f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    uint32_t bitfield_bit_offset
37f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt) :
38f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    ValueObject (),
39f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    m_parent (parent),
40f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    m_clang_ast (clang_ast),
41f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    m_clang_type (clang_type),
42f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    m_byte_size (byte_size),
43f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    m_byte_offset (byte_offset),
44f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    m_bitfield_bit_size (bitfield_bit_size),
45f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    m_bitfield_bit_offset (bitfield_bit_offset)
46f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt{
47f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    m_name = name;
48f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt}
49f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
50f86232838cf712377867cb42417c1613ab5dc425Dmitry ShmidtValueObjectChild::~ValueObjectChild()
51f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt{
52f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt}
53f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
54f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtvoid *
55f86232838cf712377867cb42417c1613ab5dc425Dmitry ShmidtValueObjectChild::GetClangType()
56f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt{
57f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    return m_clang_type;
58f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt}
59f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
60f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtlldb::ValueType
61f86232838cf712377867cb42417c1613ab5dc425Dmitry ShmidtValueObjectChild::GetValueType() const
62f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt{
63f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    return m_parent->GetValueType();
64f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt}
65f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
664ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtuint32_t
674ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry ShmidtValueObjectChild::CalculateNumChildren()
68f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt{
69f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    return ClangASTContext::GetNumChildren (m_clang_type, true);
70f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt}
71f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
72f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtclang::ASTContext *
73f86232838cf712377867cb42417c1613ab5dc425Dmitry ShmidtValueObjectChild::GetClangAST ()
74f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt{
75f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt    return m_clang_ast;
76f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt}
77f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
78size_t
79ValueObjectChild::GetByteSize()
80{
81    return m_byte_size;
82}
83
84off_t
85ValueObjectChild::GetByteOffset()
86{
87    return m_byte_offset;
88}
89
90uint32_t
91ValueObjectChild::GetBitfieldBitSize()
92{
93    return m_bitfield_bit_size;
94}
95
96uint32_t
97ValueObjectChild::GetBitfieldBitOffset()
98{
99    return m_bitfield_bit_offset;
100}
101
102ConstString
103ValueObjectChild::GetTypeName()
104{
105    if (m_type_name.IsEmpty())
106    {
107        m_type_name = ClangASTType::GetClangTypeName (GetClangType());
108        if (m_type_name)
109        {
110            if (m_bitfield_bit_size > 0)
111            {
112                const char *clang_type_name = m_type_name.AsCString();
113                if (clang_type_name)
114                {
115                    std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0);
116                    ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", clang_type_name, m_bitfield_bit_size);
117                    m_type_name.SetCString(&bitfield_type_name.front());
118                }
119            }
120        }
121    }
122    return m_type_name;
123}
124
125void
126ValueObjectChild::UpdateValue (ExecutionContextScope *exe_scope)
127{
128    m_error.Clear();
129    SetValueIsValid (false);
130    ValueObject* parent = m_parent;
131    if (parent)
132    {
133        if (parent->UpdateValueIfNeeded(exe_scope))
134        {
135            m_value.SetContext(Value::eContextTypeOpaqueClangQualType, m_clang_type);
136
137            // Copy the parent scalar value and the scalar value type
138            m_value.GetScalar() = parent->GetValue().GetScalar();
139            Value::ValueType value_type = parent->GetValue().GetValueType();
140            m_value.SetValueType (value_type);
141
142            if (ClangASTContext::IsPointerOrReferenceType (parent->GetClangType()))
143            {
144                uint32_t offset = 0;
145                m_value.GetScalar() = parent->GetDataExtractor().GetPointer(&offset);
146                // For pointers, m_byte_offset should only ever be set if we
147                // ValueObject::GetSyntheticArrayMemberFromPointer() was called
148                if (ClangASTContext::IsPointerType (parent->GetClangType()) && m_byte_offset)
149                    m_value.GetScalar() += m_byte_offset;
150                if (value_type == Value::eValueTypeScalar ||
151                    value_type == Value::eValueTypeFileAddress)
152                    m_value.SetValueType (Value::eValueTypeLoadAddress);
153            }
154            else
155            {
156                switch (value_type)
157                {
158                case Value::eValueTypeLoadAddress:
159                case Value::eValueTypeFileAddress:
160                case Value::eValueTypeHostAddress:
161                    {
162                        lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
163                        if (addr == LLDB_INVALID_ADDRESS || addr == 0)
164                        {
165                            m_error.SetErrorStringWithFormat("Parent address is invalid: 0x%llx.\n", addr);
166                            break;
167                        }
168                        // Set this object's scalar value to the address of its
169                        // value be adding its byte offset to the parent address
170                        m_value.GetScalar() += GetByteOffset();
171                    }
172                    break;
173
174                case Value::eValueTypeScalar:
175                    // TODO: What if this is a register value? Do we try and
176                    // extract the child value from within the parent data?
177                    // Probably...
178                default:
179                    m_error.SetErrorString ("Parent has invalid value.");
180                    break;
181                }
182            }
183
184            if (m_error.Success())
185            {
186                ExecutionContext exe_ctx (exe_scope);
187                m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST (), m_data, 0);
188            }
189        }
190        else
191        {
192            m_error.SetErrorStringWithFormat("Parent failed to evaluate: %s.\n", parent->GetError().AsCString());
193        }
194    }
195    else
196    {
197        m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject.");
198    }
199}
200
201
202bool
203ValueObjectChild::IsInScope (StackFrame *frame)
204{
205    return m_parent->IsInScope (frame);
206}
207