]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Core/ValueObjectChild.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / source / Core / ValueObjectChild.cpp
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                 const bool thread_and_frame_only_if_stopped = true;
210                 ExecutionContext exe_ctx (GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped));
211                 if (GetClangType().GetTypeInfo() & ClangASTType::eTypeHasValue)
212                     m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
213                 else
214                     m_error.Clear(); // No value so nothing to read...
215             }
216         }
217         else
218         {
219             m_error.SetErrorStringWithFormat("parent failed to evaluate: %s", parent->GetError().AsCString());
220         }
221     }
222     else
223     {
224         m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject.");
225     }
226     
227     return m_error.Success();
228 }
229
230
231 bool
232 ValueObjectChild::IsInScope ()
233 {
234     ValueObject* root(GetRoot());
235     if (root)
236         return root->IsInScope ();
237     return false;
238 }