1*2f3df613SZachary Turner //===-- ValueObjectDynamicValue.cpp ------------------------------*- C++-*-===//
278a685aaSJim Ingham //
378a685aaSJim Ingham //                     The LLVM Compiler Infrastructure
478a685aaSJim Ingham //
578a685aaSJim Ingham // This file is distributed under the University of Illinois Open Source
678a685aaSJim Ingham // License. See LICENSE.TXT for details.
778a685aaSJim Ingham //
878a685aaSJim Ingham //===----------------------------------------------------------------------===//
978a685aaSJim Ingham 
1078a685aaSJim Ingham #include "lldb/Core/ValueObjectDynamicValue.h"
1178a685aaSJim Ingham 
12*2f3df613SZachary Turner #include "lldb/Core/ArchSpec.h" // for ArchSpec
13*2f3df613SZachary Turner #include "lldb/Core/Scalar.h"   // for Scalar, operator!=
1478a685aaSJim Ingham #include "lldb/Core/Value.h"
1578a685aaSJim Ingham #include "lldb/Core/ValueObject.h"
16a1e5dc86SGreg Clayton #include "lldb/Symbol/CompilerType.h"
1778a685aaSJim Ingham #include "lldb/Symbol/Type.h"
1878a685aaSJim Ingham #include "lldb/Target/ExecutionContext.h"
1978a685aaSJim Ingham #include "lldb/Target/LanguageRuntime.h"
2078a685aaSJim Ingham #include "lldb/Target/Process.h"
2178a685aaSJim Ingham #include "lldb/Target/Target.h"
22*2f3df613SZachary Turner #include "lldb/Utility/DataExtractor.h" // for DataExtractor
23*2f3df613SZachary Turner #include "lldb/Utility/Error.h"         // for Error
24*2f3df613SZachary Turner #include "lldb/Utility/Log.h"
25*2f3df613SZachary Turner #include "lldb/Utility/Logging.h" // for GetLogIfAllCategoriesSet
26*2f3df613SZachary Turner #include "lldb/lldb-types.h"      // for addr_t, offset_t
27*2f3df613SZachary Turner 
28*2f3df613SZachary Turner #include <string.h> // for strcmp, size_t
29*2f3df613SZachary Turner namespace lldb_private {
30*2f3df613SZachary Turner class Declaration;
31*2f3df613SZachary Turner }
3278a685aaSJim Ingham 
3378a685aaSJim Ingham using namespace lldb_private;
3478a685aaSJim Ingham 
35b9c1b51eSKate Stone ValueObjectDynamicValue::ValueObjectDynamicValue(
36b9c1b51eSKate Stone     ValueObject &parent, lldb::DynamicValueType use_dynamic)
37b9c1b51eSKate Stone     : ValueObject(parent), m_address(), m_dynamic_type_info(),
38b9c1b51eSKate Stone       m_use_dynamic(use_dynamic) {
396f3533fbSEnrico Granata   SetName(parent.GetName());
4078a685aaSJim Ingham }
4178a685aaSJim Ingham 
42b9c1b51eSKate Stone ValueObjectDynamicValue::~ValueObjectDynamicValue() {
4378a685aaSJim Ingham   m_owning_valobj_sp.reset();
4478a685aaSJim Ingham }
4578a685aaSJim Ingham 
46b9c1b51eSKate Stone CompilerType ValueObjectDynamicValue::GetCompilerTypeImpl() {
47dc4db5a6SEnrico Granata   const bool success = UpdateValueIfNeeded(false);
48b9c1b51eSKate Stone   if (success) {
49dc4db5a6SEnrico Granata     if (m_dynamic_type_info.HasType())
5099558cc4SGreg Clayton       return m_value.GetCompilerType();
5178a685aaSJim Ingham     else
5299558cc4SGreg Clayton       return m_parent->GetCompilerType();
5378a685aaSJim Ingham   }
5499558cc4SGreg Clayton   return m_parent->GetCompilerType();
55dc4db5a6SEnrico Granata }
5678a685aaSJim Ingham 
57b9c1b51eSKate Stone ConstString ValueObjectDynamicValue::GetTypeName() {
58c3e320a7SEnrico Granata   const bool success = UpdateValueIfNeeded(false);
59b9c1b51eSKate Stone   if (success) {
60f7b1a34eSEnrico Granata     if (m_dynamic_type_info.HasName())
61f7b1a34eSEnrico Granata       return m_dynamic_type_info.GetName();
62f7b1a34eSEnrico Granata   }
63f7b1a34eSEnrico Granata   return m_parent->GetTypeName();
64f7b1a34eSEnrico Granata }
65f7b1a34eSEnrico Granata 
66b9c1b51eSKate Stone TypeImpl ValueObjectDynamicValue::GetTypeImpl() {
67dc4db5a6SEnrico Granata   const bool success = UpdateValueIfNeeded(false);
68b9c1b51eSKate Stone   if (success && m_type_impl.IsValid()) {
69dc4db5a6SEnrico Granata     return m_type_impl;
70dc4db5a6SEnrico Granata   }
71dc4db5a6SEnrico Granata   return m_parent->GetTypeImpl();
72dc4db5a6SEnrico Granata }
73dc4db5a6SEnrico Granata 
74b9c1b51eSKate Stone ConstString ValueObjectDynamicValue::GetQualifiedTypeName() {
75f7b1a34eSEnrico Granata   const bool success = UpdateValueIfNeeded(false);
76b9c1b51eSKate Stone   if (success) {
77f7b1a34eSEnrico Granata     if (m_dynamic_type_info.HasName())
78f7b1a34eSEnrico Granata       return m_dynamic_type_info.GetName();
79f7b1a34eSEnrico Granata   }
80e8daa2f8SEnrico Granata   return m_parent->GetQualifiedTypeName();
81e8daa2f8SEnrico Granata }
82e8daa2f8SEnrico Granata 
83b9c1b51eSKate Stone ConstString ValueObjectDynamicValue::GetDisplayTypeName() {
84e8daa2f8SEnrico Granata   const bool success = UpdateValueIfNeeded(false);
85b9c1b51eSKate Stone   if (success) {
86e8daa2f8SEnrico Granata     if (m_dynamic_type_info.HasType())
8799558cc4SGreg Clayton       return GetCompilerType().GetDisplayTypeName();
88e8daa2f8SEnrico Granata     if (m_dynamic_type_info.HasName())
89e8daa2f8SEnrico Granata       return m_dynamic_type_info.GetName();
90e8daa2f8SEnrico Granata   }
91e8daa2f8SEnrico Granata   return m_parent->GetDisplayTypeName();
9278a685aaSJim Ingham }
9378a685aaSJim Ingham 
94b9c1b51eSKate Stone size_t ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) {
95c3e320a7SEnrico Granata   const bool success = UpdateValueIfNeeded(false);
96b9c1b51eSKate Stone   if (success && m_dynamic_type_info.HasType()) {
979ac7a6c5SSiva Chandra     auto children_count = GetCompilerType().GetNumChildren(true);
989ac7a6c5SSiva Chandra     return children_count <= max ? children_count : max;
99b9c1b51eSKate Stone   } else
1009ac7a6c5SSiva Chandra     return m_parent->GetNumChildren(max);
10178a685aaSJim Ingham }
10278a685aaSJim Ingham 
103b9c1b51eSKate Stone uint64_t ValueObjectDynamicValue::GetByteSize() {
104c3e320a7SEnrico Granata   const bool success = UpdateValueIfNeeded(false);
105b9c1b51eSKate Stone   if (success && m_dynamic_type_info.HasType()) {
10695438038SEnrico Granata     ExecutionContext exe_ctx(GetExecutionContextRef());
10795438038SEnrico Granata     return m_value.GetValueByteSize(nullptr, &exe_ctx);
108b9c1b51eSKate Stone   } else
10978a685aaSJim Ingham     return m_parent->GetByteSize();
11078a685aaSJim Ingham }
11178a685aaSJim Ingham 
112b9c1b51eSKate Stone lldb::ValueType ValueObjectDynamicValue::GetValueType() const {
11378a685aaSJim Ingham   return m_parent->GetValueType();
11478a685aaSJim Ingham }
11578a685aaSJim Ingham 
116b9c1b51eSKate Stone bool ValueObjectDynamicValue::UpdateValue() {
11778a685aaSJim Ingham   SetValueIsValid(false);
11878a685aaSJim Ingham   m_error.Clear();
11978a685aaSJim Ingham 
120b9c1b51eSKate Stone   if (!m_parent->UpdateValueIfNeeded(false)) {
121007d5be6SGreg Clayton     // The dynamic value failed to get an error, pass the error along
122007d5be6SGreg Clayton     if (m_error.Success() && m_parent->GetError().Fail())
123007d5be6SGreg Clayton       m_error = m_parent->GetError();
12478a685aaSJim Ingham     return false;
12578a685aaSJim Ingham   }
12678a685aaSJim Ingham 
1272837b766SJim Ingham   // Setting our type_sp to NULL will route everything back through our
1282837b766SJim Ingham   // parent which is equivalent to not using dynamic values.
129b9c1b51eSKate Stone   if (m_use_dynamic == lldb::eNoDynamicValues) {
130f7b1a34eSEnrico Granata     m_dynamic_type_info.Clear();
1312837b766SJim Ingham     return true;
1322837b766SJim Ingham   }
1332837b766SJim Ingham 
134cc4d0146SGreg Clayton   ExecutionContext exe_ctx(GetExecutionContextRef());
135c14ee32dSGreg Clayton   Target *target = exe_ctx.GetTargetPtr();
136b9c1b51eSKate Stone   if (target) {
137c14ee32dSGreg Clayton     m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
138c14ee32dSGreg Clayton     m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
13978a685aaSJim Ingham   }
14078a685aaSJim Ingham 
14178a685aaSJim Ingham   // First make sure our Type and/or Address haven't changed:
142cc4d0146SGreg Clayton   Process *process = exe_ctx.GetProcessPtr();
14378a685aaSJim Ingham   if (!process)
14478a685aaSJim Ingham     return false;
14578a685aaSJim Ingham 
14661be0903SJim Ingham   TypeAndOrName class_type_or_name;
14778a685aaSJim Ingham   Address dynamic_address;
14878a685aaSJim Ingham   bool found_dynamic_type = false;
1490b6003f3SEnrico Granata   Value::ValueType value_type;
15078a685aaSJim Ingham 
151c74275bcSEnrico Granata   LanguageRuntime *runtime = nullptr;
152c74275bcSEnrico Granata 
15378a685aaSJim Ingham   lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
154b9c1b51eSKate Stone   if (known_type != lldb::eLanguageTypeUnknown &&
155b9c1b51eSKate Stone       known_type != lldb::eLanguageTypeC) {
156c74275bcSEnrico Granata     runtime = process->GetLanguageRuntime(known_type);
15778a685aaSJim Ingham     if (runtime)
158b9c1b51eSKate Stone       found_dynamic_type = runtime->GetDynamicTypeAndAddress(
159b9c1b51eSKate Stone           *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
160b9c1b51eSKate Stone           value_type);
161b9c1b51eSKate Stone   } else {
162c74275bcSEnrico Granata     runtime = process->GetLanguageRuntime(lldb::eLanguageTypeC_plus_plus);
163c74275bcSEnrico Granata     if (runtime)
164b9c1b51eSKate Stone       found_dynamic_type = runtime->GetDynamicTypeAndAddress(
165b9c1b51eSKate Stone           *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
166b9c1b51eSKate Stone           value_type);
16778a685aaSJim Ingham 
168b9c1b51eSKate Stone     if (!found_dynamic_type) {
169c74275bcSEnrico Granata       runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
170c74275bcSEnrico Granata       if (runtime)
171b9c1b51eSKate Stone         found_dynamic_type = runtime->GetDynamicTypeAndAddress(
172b9c1b51eSKate Stone             *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
173b9c1b51eSKate Stone             value_type);
17478a685aaSJim Ingham     }
17578a685aaSJim Ingham   }
17678a685aaSJim Ingham 
177b9c1b51eSKate Stone   // Getting the dynamic value may have run the program a bit, and so marked us
178b9c1b51eSKate Stone   // as needing updating, but we really
17961be0903SJim Ingham   // don't...
18061be0903SJim Ingham 
18161be0903SJim Ingham   m_update_point.SetUpdated();
18261be0903SJim Ingham 
183b9c1b51eSKate Stone   if (runtime && found_dynamic_type) {
184b9c1b51eSKate Stone     if (class_type_or_name.HasType()) {
185b9c1b51eSKate Stone       m_type_impl =
186b9c1b51eSKate Stone           TypeImpl(m_parent->GetCompilerType(),
187b9c1b51eSKate Stone                    runtime->FixUpDynamicType(class_type_or_name, *m_parent)
188b9c1b51eSKate Stone                        .GetCompilerType());
189b9c1b51eSKate Stone     } else {
190df7c7f99SEnrico Granata       m_type_impl.Clear();
191df7c7f99SEnrico Granata     }
192b9c1b51eSKate Stone   } else {
193df7c7f99SEnrico Granata     m_type_impl.Clear();
194df7c7f99SEnrico Granata   }
195dc4db5a6SEnrico Granata 
196b9c1b51eSKate Stone   // If we don't have a dynamic type, then make ourselves just a echo of our
197b9c1b51eSKate Stone   // parent.
1985f57b6eeSEnrico Granata   // Or we could return false, and make ourselves an echo of our parent?
199b9c1b51eSKate Stone   if (!found_dynamic_type) {
200f7b1a34eSEnrico Granata     if (m_dynamic_type_info)
20175badc46SEnrico Granata       SetValueDidChange(true);
202bd83b87dSEnrico Granata     ClearDynamicTypeInformation();
203f7b1a34eSEnrico Granata     m_dynamic_type_info.Clear();
20478a685aaSJim Ingham     m_value = m_parent->GetValue();
20557ee3067SGreg Clayton     m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
20678a685aaSJim Ingham     return m_error.Success();
20778a685aaSJim Ingham   }
20878a685aaSJim Ingham 
20978a685aaSJim Ingham   Value old_value(m_value);
21078a685aaSJim Ingham 
2115160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES));
212d228483dSEnrico Granata 
213e3e91517SEnrico Granata   bool has_changed_type = false;
214e3e91517SEnrico Granata 
215b9c1b51eSKate Stone   if (!m_dynamic_type_info) {
216f7b1a34eSEnrico Granata     m_dynamic_type_info = class_type_or_name;
217e3e91517SEnrico Granata     has_changed_type = true;
218b9c1b51eSKate Stone   } else if (class_type_or_name != m_dynamic_type_info) {
21978a685aaSJim Ingham     // We are another type, we need to tear down our children...
220f7b1a34eSEnrico Granata     m_dynamic_type_info = class_type_or_name;
22178a685aaSJim Ingham     SetValueDidChange(true);
222e3e91517SEnrico Granata     has_changed_type = true;
22378a685aaSJim Ingham   }
22478a685aaSJim Ingham 
225e3e91517SEnrico Granata   if (has_changed_type)
226e3e91517SEnrico Granata     ClearDynamicTypeInformation();
227e3e91517SEnrico Granata 
228b9c1b51eSKate Stone   if (!m_address.IsValid() || m_address != dynamic_address) {
22978a685aaSJim Ingham     if (m_address.IsValid())
23078a685aaSJim Ingham       SetValueDidChange(true);
23178a685aaSJim Ingham 
23278a685aaSJim Ingham     // We've moved, so we should be fine...
23378a685aaSJim Ingham     m_address = dynamic_address;
234cc4d0146SGreg Clayton     lldb::TargetSP target_sp(GetTargetSP());
235cc4d0146SGreg Clayton     lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
23678a685aaSJim Ingham     m_value.GetScalar() = load_address;
23778a685aaSJim Ingham   }
23878a685aaSJim Ingham 
239c74275bcSEnrico Granata   if (runtime)
240b9c1b51eSKate Stone     m_dynamic_type_info =
241b9c1b51eSKate Stone         runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent);
24278a685aaSJim Ingham 
24357ee3067SGreg Clayton   // m_value.SetContext (Value::eContextTypeClangType, corrected_type);
24499558cc4SGreg Clayton   m_value.SetCompilerType(m_dynamic_type_info.GetCompilerType());
24578a685aaSJim Ingham 
2460b6003f3SEnrico Granata   m_value.SetValueType(value_type);
24778a685aaSJim Ingham 
248e3e91517SEnrico Granata   if (has_changed_type && log)
249324a1036SSaleem Abdulrasool     log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(),
250324a1036SSaleem Abdulrasool                 static_cast<void *>(this), GetTypeName().GetCString());
251e3e91517SEnrico Granata 
252b9c1b51eSKate Stone   if (m_address.IsValid() && m_dynamic_type_info) {
25378a685aaSJim Ingham     // The variable value is in the Scalar value inside the m_value.
25478a685aaSJim Ingham     // We can point our m_data right to it.
25557ee3067SGreg Clayton     m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
256b9c1b51eSKate Stone     if (m_error.Success()) {
257b9c1b51eSKate Stone       if (!CanProvideValue()) {
25878a685aaSJim Ingham         // this value object represents an aggregate type whose
25978a685aaSJim Ingham         // children have values, but this object does not. So we
26078a685aaSJim Ingham         // say we are changed if our location has changed.
261b9c1b51eSKate Stone         SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
262b9c1b51eSKate Stone                           m_value.GetScalar() != old_value.GetScalar());
26378a685aaSJim Ingham       }
26478a685aaSJim Ingham 
26578a685aaSJim Ingham       SetValueIsValid(true);
26678a685aaSJim Ingham       return true;
26778a685aaSJim Ingham     }
26878a685aaSJim Ingham   }
26978a685aaSJim Ingham 
27078a685aaSJim Ingham   // We get here if we've failed above...
27178a685aaSJim Ingham   SetValueIsValid(false);
27278a685aaSJim Ingham   return false;
27378a685aaSJim Ingham }
27478a685aaSJim Ingham 
275b9c1b51eSKate Stone bool ValueObjectDynamicValue::IsInScope() { return m_parent->IsInScope(); }
27678a685aaSJim Ingham 
277b9c1b51eSKate Stone bool ValueObjectDynamicValue::SetValueFromCString(const char *value_str,
278b9c1b51eSKate Stone                                                   Error &error) {
279b9c1b51eSKate Stone   if (!UpdateValueIfNeeded(false)) {
28007a4ac22SEnrico Granata     error.SetErrorString("unable to read value");
28107a4ac22SEnrico Granata     return false;
28207a4ac22SEnrico Granata   }
28307a4ac22SEnrico Granata 
28407a4ac22SEnrico Granata   uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
28507a4ac22SEnrico Granata   uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
28607a4ac22SEnrico Granata 
287b9c1b51eSKate Stone   if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
28807a4ac22SEnrico Granata     error.SetErrorString("unable to read value");
28907a4ac22SEnrico Granata     return false;
29007a4ac22SEnrico Granata   }
29107a4ac22SEnrico Granata 
292b9c1b51eSKate Stone   // if we are at an offset from our parent, in order to set ourselves correctly
293b9c1b51eSKate Stone   // we would need
294b9c1b51eSKate Stone   // to change the new value so that it refers to the correct dynamic type. we
295b9c1b51eSKate Stone   // choose not to deal
296b9c1b51eSKate Stone   // with that - if anything more than a value overwrite is required, you should
297b9c1b51eSKate Stone   // be using the
29807a4ac22SEnrico Granata   // expression parser instead of the value editing facility
299b9c1b51eSKate Stone   if (my_value != parent_value) {
30007a4ac22SEnrico Granata     // but NULL'ing out a value should always be allowed
301b9c1b51eSKate Stone     if (strcmp(value_str, "0")) {
302b9c1b51eSKate Stone       error.SetErrorString(
303b9c1b51eSKate Stone           "unable to modify dynamic value, use 'expression' command");
30407a4ac22SEnrico Granata       return false;
30507a4ac22SEnrico Granata     }
30607a4ac22SEnrico Granata   }
30707a4ac22SEnrico Granata 
30807a4ac22SEnrico Granata   bool ret_val = m_parent->SetValueFromCString(value_str, error);
30907a4ac22SEnrico Granata   SetNeedsUpdate();
31007a4ac22SEnrico Granata   return ret_val;
31107a4ac22SEnrico Granata }
312389823e9SSean Callanan 
313b9c1b51eSKate Stone bool ValueObjectDynamicValue::SetData(DataExtractor &data, Error &error) {
314b9c1b51eSKate Stone   if (!UpdateValueIfNeeded(false)) {
315389823e9SSean Callanan     error.SetErrorString("unable to read value");
316389823e9SSean Callanan     return false;
317389823e9SSean Callanan   }
318389823e9SSean Callanan 
319389823e9SSean Callanan   uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
320389823e9SSean Callanan   uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
321389823e9SSean Callanan 
322b9c1b51eSKate Stone   if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
323389823e9SSean Callanan     error.SetErrorString("unable to read value");
324389823e9SSean Callanan     return false;
325389823e9SSean Callanan   }
326389823e9SSean Callanan 
327b9c1b51eSKate Stone   // if we are at an offset from our parent, in order to set ourselves correctly
328b9c1b51eSKate Stone   // we would need
329b9c1b51eSKate Stone   // to change the new value so that it refers to the correct dynamic type. we
330b9c1b51eSKate Stone   // choose not to deal
331b9c1b51eSKate Stone   // with that - if anything more than a value overwrite is required, you should
332b9c1b51eSKate Stone   // be using the
333389823e9SSean Callanan   // expression parser instead of the value editing facility
334b9c1b51eSKate Stone   if (my_value != parent_value) {
335389823e9SSean Callanan     // but NULL'ing out a value should always be allowed
336389823e9SSean Callanan     lldb::offset_t offset = 0;
337389823e9SSean Callanan 
338b9c1b51eSKate Stone     if (data.GetPointer(&offset) != 0) {
339b9c1b51eSKate Stone       error.SetErrorString(
340b9c1b51eSKate Stone           "unable to modify dynamic value, use 'expression' command");
341389823e9SSean Callanan       return false;
342389823e9SSean Callanan     }
343389823e9SSean Callanan   }
344389823e9SSean Callanan 
345389823e9SSean Callanan   bool ret_val = m_parent->SetData(data, error);
346389823e9SSean Callanan   SetNeedsUpdate();
347389823e9SSean Callanan   return ret_val;
348389823e9SSean Callanan }
3499851b1f6SSiva Chandra 
350b9c1b51eSKate Stone void ValueObjectDynamicValue::SetPreferredDisplayLanguage(
351b9c1b51eSKate Stone     lldb::LanguageType lang) {
35273e8c4d0SEnrico Granata   this->ValueObject::SetPreferredDisplayLanguage(lang);
35373e8c4d0SEnrico Granata   if (m_parent)
35473e8c4d0SEnrico Granata     m_parent->SetPreferredDisplayLanguage(lang);
35573e8c4d0SEnrico Granata }
35673e8c4d0SEnrico Granata 
357b9c1b51eSKate Stone lldb::LanguageType ValueObjectDynamicValue::GetPreferredDisplayLanguage() {
358b9c1b51eSKate Stone   if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
35973e8c4d0SEnrico Granata     if (m_parent)
36073e8c4d0SEnrico Granata       return m_parent->GetPreferredDisplayLanguage();
36173e8c4d0SEnrico Granata     return lldb::eLanguageTypeUnknown;
362b9c1b51eSKate Stone   } else
36373e8c4d0SEnrico Granata     return m_preferred_display_language;
36473e8c4d0SEnrico Granata }
36573e8c4d0SEnrico Granata 
366b9c1b51eSKate Stone bool ValueObjectDynamicValue::IsSyntheticChildrenGenerated() {
3673b207c66SEnrico Granata   if (m_parent)
3683b207c66SEnrico Granata     return m_parent->IsSyntheticChildrenGenerated();
3693b207c66SEnrico Granata   return false;
3703b207c66SEnrico Granata }
3713b207c66SEnrico Granata 
372b9c1b51eSKate Stone void ValueObjectDynamicValue::SetSyntheticChildrenGenerated(bool b) {
3733b207c66SEnrico Granata   if (m_parent)
3743b207c66SEnrico Granata     m_parent->SetSyntheticChildrenGenerated(b);
3753b207c66SEnrico Granata   this->ValueObject::SetSyntheticChildrenGenerated(b);
3763b207c66SEnrico Granata }
3773b207c66SEnrico Granata 
378b9c1b51eSKate Stone bool ValueObjectDynamicValue::GetDeclaration(Declaration &decl) {
3799851b1f6SSiva Chandra   if (m_parent)
3809851b1f6SSiva Chandra     return m_parent->GetDeclaration(decl);
3819851b1f6SSiva Chandra 
3829851b1f6SSiva Chandra   return ValueObject::GetDeclaration(decl);
3839851b1f6SSiva Chandra }
384dc62ffd3SEnrico Granata 
385b9c1b51eSKate Stone uint64_t ValueObjectDynamicValue::GetLanguageFlags() {
386dc62ffd3SEnrico Granata   if (m_parent)
387dc62ffd3SEnrico Granata     return m_parent->GetLanguageFlags();
388dc62ffd3SEnrico Granata   return this->ValueObject::GetLanguageFlags();
389dc62ffd3SEnrico Granata }
390dc62ffd3SEnrico Granata 
391b9c1b51eSKate Stone void ValueObjectDynamicValue::SetLanguageFlags(uint64_t flags) {
392dc62ffd3SEnrico Granata   if (m_parent)
393dc62ffd3SEnrico Granata     m_parent->SetLanguageFlags(flags);
394dc62ffd3SEnrico Granata   else
395dc62ffd3SEnrico Granata     this->ValueObject::SetLanguageFlags(flags);
396dc62ffd3SEnrico Granata }
397