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