]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Core/ValueObjectDynamicValue.cpp
Merge from vendor branch importing dtc 1.4.3
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Core / ValueObjectDynamicValue.cpp
1 //===-- ValueObjectDynamicValue.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/ValueObjectDynamicValue.h"
12
13 // C Includes
14 // C++ Includes
15 // Other libraries and framework includes
16 // Project includes
17 #include "lldb/Core/Log.h"
18 #include "lldb/Core/Module.h"
19 #include "lldb/Core/Value.h"
20 #include "lldb/Core/ValueObject.h"
21 #include "lldb/Core/ValueObjectList.h"
22
23 #include "lldb/Symbol/CompilerType.h"
24 #include "lldb/Symbol/ObjectFile.h"
25 #include "lldb/Symbol/SymbolContext.h"
26 #include "lldb/Symbol/Type.h"
27 #include "lldb/Symbol/Variable.h"
28
29 #include "lldb/Target/ExecutionContext.h"
30 #include "lldb/Target/LanguageRuntime.h"
31 #include "lldb/Target/Process.h"
32 #include "lldb/Target/RegisterContext.h"
33 #include "lldb/Target/Target.h"
34 #include "lldb/Target/Thread.h"
35
36 using namespace lldb_private;
37
38 ValueObjectDynamicValue::ValueObjectDynamicValue(
39     ValueObject &parent, lldb::DynamicValueType use_dynamic)
40     : ValueObject(parent), m_address(), m_dynamic_type_info(),
41       m_use_dynamic(use_dynamic) {
42   SetName(parent.GetName());
43 }
44
45 ValueObjectDynamicValue::~ValueObjectDynamicValue() {
46   m_owning_valobj_sp.reset();
47 }
48
49 CompilerType ValueObjectDynamicValue::GetCompilerTypeImpl() {
50   const bool success = UpdateValueIfNeeded(false);
51   if (success) {
52     if (m_dynamic_type_info.HasType())
53       return m_value.GetCompilerType();
54     else
55       return m_parent->GetCompilerType();
56   }
57   return m_parent->GetCompilerType();
58 }
59
60 ConstString ValueObjectDynamicValue::GetTypeName() {
61   const bool success = UpdateValueIfNeeded(false);
62   if (success) {
63     if (m_dynamic_type_info.HasName())
64       return m_dynamic_type_info.GetName();
65   }
66   return m_parent->GetTypeName();
67 }
68
69 TypeImpl ValueObjectDynamicValue::GetTypeImpl() {
70   const bool success = UpdateValueIfNeeded(false);
71   if (success && m_type_impl.IsValid()) {
72     return m_type_impl;
73   }
74   return m_parent->GetTypeImpl();
75 }
76
77 ConstString ValueObjectDynamicValue::GetQualifiedTypeName() {
78   const bool success = UpdateValueIfNeeded(false);
79   if (success) {
80     if (m_dynamic_type_info.HasName())
81       return m_dynamic_type_info.GetName();
82   }
83   return m_parent->GetQualifiedTypeName();
84 }
85
86 ConstString ValueObjectDynamicValue::GetDisplayTypeName() {
87   const bool success = UpdateValueIfNeeded(false);
88   if (success) {
89     if (m_dynamic_type_info.HasType())
90       return GetCompilerType().GetDisplayTypeName();
91     if (m_dynamic_type_info.HasName())
92       return m_dynamic_type_info.GetName();
93   }
94   return m_parent->GetDisplayTypeName();
95 }
96
97 size_t ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) {
98   const bool success = UpdateValueIfNeeded(false);
99   if (success && m_dynamic_type_info.HasType()) {
100     auto children_count = GetCompilerType().GetNumChildren(true);
101     return children_count <= max ? children_count : max;
102   } else
103     return m_parent->GetNumChildren(max);
104 }
105
106 uint64_t ValueObjectDynamicValue::GetByteSize() {
107   const bool success = UpdateValueIfNeeded(false);
108   if (success && m_dynamic_type_info.HasType()) {
109     ExecutionContext exe_ctx(GetExecutionContextRef());
110     return m_value.GetValueByteSize(nullptr, &exe_ctx);
111   } else
112     return m_parent->GetByteSize();
113 }
114
115 lldb::ValueType ValueObjectDynamicValue::GetValueType() const {
116   return m_parent->GetValueType();
117 }
118
119 bool ValueObjectDynamicValue::UpdateValue() {
120   SetValueIsValid(false);
121   m_error.Clear();
122
123   if (!m_parent->UpdateValueIfNeeded(false)) {
124     // The dynamic value failed to get an error, pass the error along
125     if (m_error.Success() && m_parent->GetError().Fail())
126       m_error = m_parent->GetError();
127     return false;
128   }
129
130   // Setting our type_sp to NULL will route everything back through our
131   // parent which is equivalent to not using dynamic values.
132   if (m_use_dynamic == lldb::eNoDynamicValues) {
133     m_dynamic_type_info.Clear();
134     return true;
135   }
136
137   ExecutionContext exe_ctx(GetExecutionContextRef());
138   Target *target = exe_ctx.GetTargetPtr();
139   if (target) {
140     m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
141     m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
142   }
143
144   // First make sure our Type and/or Address haven't changed:
145   Process *process = exe_ctx.GetProcessPtr();
146   if (!process)
147     return false;
148
149   TypeAndOrName class_type_or_name;
150   Address dynamic_address;
151   bool found_dynamic_type = false;
152   Value::ValueType value_type;
153
154   LanguageRuntime *runtime = nullptr;
155
156   lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
157   if (known_type != lldb::eLanguageTypeUnknown &&
158       known_type != lldb::eLanguageTypeC) {
159     runtime = process->GetLanguageRuntime(known_type);
160     if (runtime)
161       found_dynamic_type = runtime->GetDynamicTypeAndAddress(
162           *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
163           value_type);
164   } else {
165     runtime = process->GetLanguageRuntime(lldb::eLanguageTypeC_plus_plus);
166     if (runtime)
167       found_dynamic_type = runtime->GetDynamicTypeAndAddress(
168           *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
169           value_type);
170
171     if (!found_dynamic_type) {
172       runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
173       if (runtime)
174         found_dynamic_type = runtime->GetDynamicTypeAndAddress(
175             *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
176             value_type);
177     }
178   }
179
180   // Getting the dynamic value may have run the program a bit, and so marked us
181   // as needing updating, but we really
182   // don't...
183
184   m_update_point.SetUpdated();
185
186   if (runtime && found_dynamic_type) {
187     if (class_type_or_name.HasType()) {
188       m_type_impl =
189           TypeImpl(m_parent->GetCompilerType(),
190                    runtime->FixUpDynamicType(class_type_or_name, *m_parent)
191                        .GetCompilerType());
192     } else {
193       m_type_impl.Clear();
194     }
195   } else {
196     m_type_impl.Clear();
197   }
198
199   // If we don't have a dynamic type, then make ourselves just a echo of our
200   // parent.
201   // Or we could return false, and make ourselves an echo of our parent?
202   if (!found_dynamic_type) {
203     if (m_dynamic_type_info)
204       SetValueDidChange(true);
205     ClearDynamicTypeInformation();
206     m_dynamic_type_info.Clear();
207     m_value = m_parent->GetValue();
208     m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
209     return m_error.Success();
210   }
211
212   Value old_value(m_value);
213
214   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES));
215
216   bool has_changed_type = false;
217
218   if (!m_dynamic_type_info) {
219     m_dynamic_type_info = class_type_or_name;
220     has_changed_type = true;
221   } else if (class_type_or_name != m_dynamic_type_info) {
222     // We are another type, we need to tear down our children...
223     m_dynamic_type_info = class_type_or_name;
224     SetValueDidChange(true);
225     has_changed_type = true;
226   }
227
228   if (has_changed_type)
229     ClearDynamicTypeInformation();
230
231   if (!m_address.IsValid() || m_address != dynamic_address) {
232     if (m_address.IsValid())
233       SetValueDidChange(true);
234
235     // We've moved, so we should be fine...
236     m_address = dynamic_address;
237     lldb::TargetSP target_sp(GetTargetSP());
238     lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
239     m_value.GetScalar() = load_address;
240   }
241
242   if (runtime)
243     m_dynamic_type_info =
244         runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent);
245
246   // m_value.SetContext (Value::eContextTypeClangType, corrected_type);
247   m_value.SetCompilerType(m_dynamic_type_info.GetCompilerType());
248
249   m_value.SetValueType(value_type);
250
251   if (has_changed_type && log)
252     log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(),
253                 static_cast<void *>(this), GetTypeName().GetCString());
254
255   if (m_address.IsValid() && m_dynamic_type_info) {
256     // The variable value is in the Scalar value inside the m_value.
257     // We can point our m_data right to it.
258     m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
259     if (m_error.Success()) {
260       if (!CanProvideValue()) {
261         // this value object represents an aggregate type whose
262         // children have values, but this object does not. So we
263         // say we are changed if our location has changed.
264         SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
265                           m_value.GetScalar() != old_value.GetScalar());
266       }
267
268       SetValueIsValid(true);
269       return true;
270     }
271   }
272
273   // We get here if we've failed above...
274   SetValueIsValid(false);
275   return false;
276 }
277
278 bool ValueObjectDynamicValue::IsInScope() { return m_parent->IsInScope(); }
279
280 bool ValueObjectDynamicValue::SetValueFromCString(const char *value_str,
281                                                   Error &error) {
282   if (!UpdateValueIfNeeded(false)) {
283     error.SetErrorString("unable to read value");
284     return false;
285   }
286
287   uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
288   uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
289
290   if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
291     error.SetErrorString("unable to read value");
292     return false;
293   }
294
295   // if we are at an offset from our parent, in order to set ourselves correctly
296   // we would need
297   // to change the new value so that it refers to the correct dynamic type. we
298   // choose not to deal
299   // with that - if anything more than a value overwrite is required, you should
300   // be using the
301   // expression parser instead of the value editing facility
302   if (my_value != parent_value) {
303     // but NULL'ing out a value should always be allowed
304     if (strcmp(value_str, "0")) {
305       error.SetErrorString(
306           "unable to modify dynamic value, use 'expression' command");
307       return false;
308     }
309   }
310
311   bool ret_val = m_parent->SetValueFromCString(value_str, error);
312   SetNeedsUpdate();
313   return ret_val;
314 }
315
316 bool ValueObjectDynamicValue::SetData(DataExtractor &data, Error &error) {
317   if (!UpdateValueIfNeeded(false)) {
318     error.SetErrorString("unable to read value");
319     return false;
320   }
321
322   uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
323   uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
324
325   if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
326     error.SetErrorString("unable to read value");
327     return false;
328   }
329
330   // if we are at an offset from our parent, in order to set ourselves correctly
331   // we would need
332   // to change the new value so that it refers to the correct dynamic type. we
333   // choose not to deal
334   // with that - if anything more than a value overwrite is required, you should
335   // be using the
336   // expression parser instead of the value editing facility
337   if (my_value != parent_value) {
338     // but NULL'ing out a value should always be allowed
339     lldb::offset_t offset = 0;
340
341     if (data.GetPointer(&offset) != 0) {
342       error.SetErrorString(
343           "unable to modify dynamic value, use 'expression' command");
344       return false;
345     }
346   }
347
348   bool ret_val = m_parent->SetData(data, error);
349   SetNeedsUpdate();
350   return ret_val;
351 }
352
353 void ValueObjectDynamicValue::SetPreferredDisplayLanguage(
354     lldb::LanguageType lang) {
355   this->ValueObject::SetPreferredDisplayLanguage(lang);
356   if (m_parent)
357     m_parent->SetPreferredDisplayLanguage(lang);
358 }
359
360 lldb::LanguageType ValueObjectDynamicValue::GetPreferredDisplayLanguage() {
361   if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
362     if (m_parent)
363       return m_parent->GetPreferredDisplayLanguage();
364     return lldb::eLanguageTypeUnknown;
365   } else
366     return m_preferred_display_language;
367 }
368
369 bool ValueObjectDynamicValue::IsSyntheticChildrenGenerated() {
370   if (m_parent)
371     return m_parent->IsSyntheticChildrenGenerated();
372   return false;
373 }
374
375 void ValueObjectDynamicValue::SetSyntheticChildrenGenerated(bool b) {
376   if (m_parent)
377     m_parent->SetSyntheticChildrenGenerated(b);
378   this->ValueObject::SetSyntheticChildrenGenerated(b);
379 }
380
381 bool ValueObjectDynamicValue::GetDeclaration(Declaration &decl) {
382   if (m_parent)
383     return m_parent->GetDeclaration(decl);
384
385   return ValueObject::GetDeclaration(decl);
386 }
387
388 uint64_t ValueObjectDynamicValue::GetLanguageFlags() {
389   if (m_parent)
390     return m_parent->GetLanguageFlags();
391   return this->ValueObject::GetLanguageFlags();
392 }
393
394 void ValueObjectDynamicValue::SetLanguageFlags(uint64_t flags) {
395   if (m_parent)
396     m_parent->SetLanguageFlags(flags);
397   else
398     this->ValueObject::SetLanguageFlags(flags);
399 }