1cfca06d7SDimitry Andric //===-- ValueObjectDynamicValue.cpp ---------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste
9f034231aSEd Maste #include "lldb/Core/ValueObjectDynamicValue.h"
10f034231aSEd Maste #include "lldb/Core/Value.h"
11f034231aSEd Maste #include "lldb/Core/ValueObject.h"
12e81d9d49SDimitry Andric #include "lldb/Symbol/CompilerType.h"
13f034231aSEd Maste #include "lldb/Symbol/Type.h"
14f034231aSEd Maste #include "lldb/Target/ExecutionContext.h"
15f034231aSEd Maste #include "lldb/Target/LanguageRuntime.h"
16f034231aSEd Maste #include "lldb/Target/Process.h"
17f034231aSEd Maste #include "lldb/Target/Target.h"
1894994d37SDimitry Andric #include "lldb/Utility/DataExtractor.h"
19145449b1SDimitry Andric #include "lldb/Utility/LLDBLog.h"
2074a628f7SDimitry Andric #include "lldb/Utility/Log.h"
2194994d37SDimitry Andric #include "lldb/Utility/Scalar.h"
2294994d37SDimitry Andric #include "lldb/Utility/Status.h"
2394994d37SDimitry Andric #include "lldb/lldb-types.h"
2474a628f7SDimitry Andric
25344a3780SDimitry Andric #include <cstring>
26e3b55780SDimitry Andric #include <optional>
2774a628f7SDimitry Andric namespace lldb_private {
2874a628f7SDimitry Andric class Declaration;
2974a628f7SDimitry Andric }
30f034231aSEd Maste
31f034231aSEd Maste using namespace lldb_private;
32f034231aSEd Maste
ValueObjectDynamicValue(ValueObject & parent,lldb::DynamicValueType use_dynamic)3314f1b3e8SDimitry Andric ValueObjectDynamicValue::ValueObjectDynamicValue(
3414f1b3e8SDimitry Andric ValueObject &parent, lldb::DynamicValueType use_dynamic)
3514f1b3e8SDimitry Andric : ValueObject(parent), m_address(), m_dynamic_type_info(),
3614f1b3e8SDimitry Andric m_use_dynamic(use_dynamic) {
37f034231aSEd Maste SetName(parent.GetName());
38f034231aSEd Maste }
39f034231aSEd Maste
GetCompilerTypeImpl()4014f1b3e8SDimitry Andric CompilerType ValueObjectDynamicValue::GetCompilerTypeImpl() {
41f21a844fSEd Maste const bool success = UpdateValueIfNeeded(false);
4214f1b3e8SDimitry Andric if (success) {
43f21a844fSEd Maste if (m_dynamic_type_info.HasType())
44e81d9d49SDimitry Andric return m_value.GetCompilerType();
45f034231aSEd Maste else
46e81d9d49SDimitry Andric return m_parent->GetCompilerType();
47f034231aSEd Maste }
48e81d9d49SDimitry Andric return m_parent->GetCompilerType();
49f21a844fSEd Maste }
50f034231aSEd Maste
GetTypeName()5114f1b3e8SDimitry Andric ConstString ValueObjectDynamicValue::GetTypeName() {
52f034231aSEd Maste const bool success = UpdateValueIfNeeded(false);
5314f1b3e8SDimitry Andric if (success) {
54f034231aSEd Maste if (m_dynamic_type_info.HasName())
55f034231aSEd Maste return m_dynamic_type_info.GetName();
56f034231aSEd Maste }
57f034231aSEd Maste return m_parent->GetTypeName();
58f034231aSEd Maste }
59f034231aSEd Maste
GetTypeImpl()6014f1b3e8SDimitry Andric TypeImpl ValueObjectDynamicValue::GetTypeImpl() {
61f21a844fSEd Maste const bool success = UpdateValueIfNeeded(false);
6214f1b3e8SDimitry Andric if (success && m_type_impl.IsValid()) {
63f21a844fSEd Maste return m_type_impl;
64f21a844fSEd Maste }
65f21a844fSEd Maste return m_parent->GetTypeImpl();
66f21a844fSEd Maste }
67f21a844fSEd Maste
GetQualifiedTypeName()6814f1b3e8SDimitry Andric ConstString ValueObjectDynamicValue::GetQualifiedTypeName() {
69f034231aSEd Maste const bool success = UpdateValueIfNeeded(false);
7014f1b3e8SDimitry Andric if (success) {
71f034231aSEd Maste if (m_dynamic_type_info.HasName())
72f034231aSEd Maste return m_dynamic_type_info.GetName();
73f034231aSEd Maste }
740cac4ca3SEd Maste return m_parent->GetQualifiedTypeName();
750cac4ca3SEd Maste }
760cac4ca3SEd Maste
GetDisplayTypeName()7714f1b3e8SDimitry Andric ConstString ValueObjectDynamicValue::GetDisplayTypeName() {
780cac4ca3SEd Maste const bool success = UpdateValueIfNeeded(false);
7914f1b3e8SDimitry Andric if (success) {
800cac4ca3SEd Maste if (m_dynamic_type_info.HasType())
81e81d9d49SDimitry Andric return GetCompilerType().GetDisplayTypeName();
820cac4ca3SEd Maste if (m_dynamic_type_info.HasName())
830cac4ca3SEd Maste return m_dynamic_type_info.GetName();
840cac4ca3SEd Maste }
850cac4ca3SEd Maste return m_parent->GetDisplayTypeName();
86f034231aSEd Maste }
87f034231aSEd Maste
88ac9a064cSDimitry Andric llvm::Expected<uint32_t>
CalculateNumChildren(uint32_t max)89ac9a064cSDimitry Andric ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) {
90f034231aSEd Maste const bool success = UpdateValueIfNeeded(false);
9114f1b3e8SDimitry Andric if (success && m_dynamic_type_info.HasType()) {
9294994d37SDimitry Andric ExecutionContext exe_ctx(GetExecutionContextRef());
9394994d37SDimitry Andric auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
94ac9a064cSDimitry Andric if (!children_count)
95ac9a064cSDimitry Andric return children_count;
96ac9a064cSDimitry Andric return *children_count <= max ? *children_count : max;
9714f1b3e8SDimitry Andric } else
98e81d9d49SDimitry Andric return m_parent->GetNumChildren(max);
99f034231aSEd Maste }
100f034231aSEd Maste
GetByteSize()101e3b55780SDimitry Andric std::optional<uint64_t> ValueObjectDynamicValue::GetByteSize() {
102f034231aSEd Maste const bool success = UpdateValueIfNeeded(false);
10314f1b3e8SDimitry Andric if (success && m_dynamic_type_info.HasType()) {
104e81d9d49SDimitry Andric ExecutionContext exe_ctx(GetExecutionContextRef());
105e81d9d49SDimitry Andric return m_value.GetValueByteSize(nullptr, &exe_ctx);
10614f1b3e8SDimitry Andric } else
107f034231aSEd Maste return m_parent->GetByteSize();
108f034231aSEd Maste }
109f034231aSEd Maste
GetValueType() const11014f1b3e8SDimitry Andric lldb::ValueType ValueObjectDynamicValue::GetValueType() const {
111f034231aSEd Maste return m_parent->GetValueType();
112f034231aSEd Maste }
113f034231aSEd Maste
UpdateValue()11414f1b3e8SDimitry Andric bool ValueObjectDynamicValue::UpdateValue() {
115f034231aSEd Maste SetValueIsValid(false);
116f034231aSEd Maste m_error.Clear();
117f034231aSEd Maste
11814f1b3e8SDimitry Andric if (!m_parent->UpdateValueIfNeeded(false)) {
119f034231aSEd Maste // The dynamic value failed to get an error, pass the error along
120f034231aSEd Maste if (m_error.Success() && m_parent->GetError().Fail())
121f034231aSEd Maste m_error = m_parent->GetError();
122f034231aSEd Maste return false;
123f034231aSEd Maste }
124f034231aSEd Maste
125f73363f1SDimitry Andric // Setting our type_sp to NULL will route everything back through our parent
126f73363f1SDimitry Andric // which is equivalent to not using dynamic values.
12714f1b3e8SDimitry Andric if (m_use_dynamic == lldb::eNoDynamicValues) {
128f034231aSEd Maste m_dynamic_type_info.Clear();
129f034231aSEd Maste return true;
130f034231aSEd Maste }
131f034231aSEd Maste
132f034231aSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
133f034231aSEd Maste Target *target = exe_ctx.GetTargetPtr();
13414f1b3e8SDimitry Andric if (target) {
135f034231aSEd Maste m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
136f034231aSEd Maste m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
137f034231aSEd Maste }
138f034231aSEd Maste
139f034231aSEd Maste // First make sure our Type and/or Address haven't changed:
140f034231aSEd Maste Process *process = exe_ctx.GetProcessPtr();
141f034231aSEd Maste if (!process)
142f034231aSEd Maste return false;
143f034231aSEd Maste
144f034231aSEd Maste TypeAndOrName class_type_or_name;
145f034231aSEd Maste Address dynamic_address;
146f034231aSEd Maste bool found_dynamic_type = false;
147e81d9d49SDimitry Andric Value::ValueType value_type;
148e81d9d49SDimitry Andric
149e81d9d49SDimitry Andric LanguageRuntime *runtime = nullptr;
150f034231aSEd Maste
151f034231aSEd Maste lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
15214f1b3e8SDimitry Andric if (known_type != lldb::eLanguageTypeUnknown &&
15314f1b3e8SDimitry Andric known_type != lldb::eLanguageTypeC) {
154e81d9d49SDimitry Andric runtime = process->GetLanguageRuntime(known_type);
1557fa27ce4SDimitry Andric if (auto *preferred_runtime =
1567fa27ce4SDimitry Andric runtime->GetPreferredLanguageRuntime(*m_parent)) {
1577fa27ce4SDimitry Andric // Try the preferred runtime first.
1587fa27ce4SDimitry Andric found_dynamic_type = preferred_runtime->GetDynamicTypeAndAddress(
1597fa27ce4SDimitry Andric *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
1607fa27ce4SDimitry Andric value_type);
1617fa27ce4SDimitry Andric if (found_dynamic_type)
1627fa27ce4SDimitry Andric // Set the operative `runtime` for later use in this function.
1637fa27ce4SDimitry Andric runtime = preferred_runtime;
1647fa27ce4SDimitry Andric }
1657fa27ce4SDimitry Andric if (!found_dynamic_type)
1667fa27ce4SDimitry Andric // Fallback to the runtime for `known_type`.
16714f1b3e8SDimitry Andric found_dynamic_type = runtime->GetDynamicTypeAndAddress(
16814f1b3e8SDimitry Andric *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
16914f1b3e8SDimitry Andric value_type);
17014f1b3e8SDimitry Andric } else {
171e81d9d49SDimitry Andric runtime = process->GetLanguageRuntime(lldb::eLanguageTypeC_plus_plus);
172e81d9d49SDimitry Andric if (runtime)
17314f1b3e8SDimitry Andric found_dynamic_type = runtime->GetDynamicTypeAndAddress(
17414f1b3e8SDimitry Andric *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
17514f1b3e8SDimitry Andric value_type);
176f034231aSEd Maste
17714f1b3e8SDimitry Andric if (!found_dynamic_type) {
178e81d9d49SDimitry Andric runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
179e81d9d49SDimitry Andric if (runtime)
18014f1b3e8SDimitry Andric found_dynamic_type = runtime->GetDynamicTypeAndAddress(
18114f1b3e8SDimitry Andric *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
18214f1b3e8SDimitry Andric value_type);
183f034231aSEd Maste }
184f034231aSEd Maste }
185f034231aSEd Maste
18614f1b3e8SDimitry Andric // Getting the dynamic value may have run the program a bit, and so marked us
187f73363f1SDimitry Andric // as needing updating, but we really don't...
188f034231aSEd Maste
189f034231aSEd Maste m_update_point.SetUpdated();
190f034231aSEd Maste
19114f1b3e8SDimitry Andric if (runtime && found_dynamic_type) {
19214f1b3e8SDimitry Andric if (class_type_or_name.HasType()) {
19314f1b3e8SDimitry Andric m_type_impl =
19414f1b3e8SDimitry Andric TypeImpl(m_parent->GetCompilerType(),
19514f1b3e8SDimitry Andric runtime->FixUpDynamicType(class_type_or_name, *m_parent)
19614f1b3e8SDimitry Andric .GetCompilerType());
19714f1b3e8SDimitry Andric } else {
198f21a844fSEd Maste m_type_impl.Clear();
199f21a844fSEd Maste }
20014f1b3e8SDimitry Andric } else {
201f21a844fSEd Maste m_type_impl.Clear();
202f21a844fSEd Maste }
203f21a844fSEd Maste
2047fa27ce4SDimitry Andric // If we don't have a dynamic type, set ourselves to be invalid and return
2057fa27ce4SDimitry Andric // false. We used to try to produce a dynamic ValueObject that behaved "like"
2067fa27ce4SDimitry Andric // its parent, but that failed for ValueObjectConstResult, which is too
2077fa27ce4SDimitry Andric // complex a beast to try to emulate. If we return an invalid ValueObject,
2087fa27ce4SDimitry Andric // clients will end up getting the static value instead, which behaves
2097fa27ce4SDimitry Andric // correctly.
21014f1b3e8SDimitry Andric if (!found_dynamic_type) {
211f034231aSEd Maste if (m_dynamic_type_info)
212f034231aSEd Maste SetValueDidChange(true);
213f034231aSEd Maste ClearDynamicTypeInformation();
214f034231aSEd Maste m_dynamic_type_info.Clear();
2157fa27ce4SDimitry Andric m_error.SetErrorString("no dynamic type found");
2167fa27ce4SDimitry Andric return false;
217f034231aSEd Maste }
218f034231aSEd Maste
219f034231aSEd Maste Value old_value(m_value);
220f034231aSEd Maste
221145449b1SDimitry Andric Log *log = GetLog(LLDBLog::Types);
222f034231aSEd Maste
223f034231aSEd Maste bool has_changed_type = false;
224f034231aSEd Maste
22514f1b3e8SDimitry Andric if (!m_dynamic_type_info) {
226f034231aSEd Maste m_dynamic_type_info = class_type_or_name;
227f034231aSEd Maste has_changed_type = true;
22814f1b3e8SDimitry Andric } else if (class_type_or_name != m_dynamic_type_info) {
229f034231aSEd Maste // We are another type, we need to tear down our children...
230f034231aSEd Maste m_dynamic_type_info = class_type_or_name;
231f034231aSEd Maste SetValueDidChange(true);
232f034231aSEd Maste has_changed_type = true;
233f034231aSEd Maste }
234f034231aSEd Maste
235f034231aSEd Maste if (has_changed_type)
236f034231aSEd Maste ClearDynamicTypeInformation();
237f034231aSEd Maste
23814f1b3e8SDimitry Andric if (!m_address.IsValid() || m_address != dynamic_address) {
239f034231aSEd Maste if (m_address.IsValid())
240f034231aSEd Maste SetValueDidChange(true);
241f034231aSEd Maste
242f034231aSEd Maste // We've moved, so we should be fine...
243f034231aSEd Maste m_address = dynamic_address;
244f034231aSEd Maste lldb::TargetSP target_sp(GetTargetSP());
245f034231aSEd Maste lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
246f034231aSEd Maste m_value.GetScalar() = load_address;
247f034231aSEd Maste }
248f034231aSEd Maste
249e81d9d49SDimitry Andric if (runtime)
25014f1b3e8SDimitry Andric m_dynamic_type_info =
25114f1b3e8SDimitry Andric runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent);
252f034231aSEd Maste
253e81d9d49SDimitry Andric m_value.SetCompilerType(m_dynamic_type_info.GetCompilerType());
254f034231aSEd Maste
255e81d9d49SDimitry Andric m_value.SetValueType(value_type);
256f034231aSEd Maste
257f034231aSEd Maste if (has_changed_type && log)
258ead24645SDimitry Andric LLDB_LOGF(log, "[%s %p] has a new dynamic type %s", GetName().GetCString(),
2590cac4ca3SEd Maste static_cast<void *>(this), GetTypeName().GetCString());
260f034231aSEd Maste
26114f1b3e8SDimitry Andric if (m_address.IsValid() && m_dynamic_type_info) {
262f73363f1SDimitry Andric // The variable value is in the Scalar value inside the m_value. We can
263f73363f1SDimitry Andric // point our m_data right to it.
264ead24645SDimitry Andric m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
26514f1b3e8SDimitry Andric if (m_error.Success()) {
26614f1b3e8SDimitry Andric if (!CanProvideValue()) {
267f73363f1SDimitry Andric // this value object represents an aggregate type whose children have
268f73363f1SDimitry Andric // values, but this object does not. So we say we are changed if our
269f73363f1SDimitry Andric // location has changed.
27014f1b3e8SDimitry Andric SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
27114f1b3e8SDimitry Andric m_value.GetScalar() != old_value.GetScalar());
272f034231aSEd Maste }
273f034231aSEd Maste
274f034231aSEd Maste SetValueIsValid(true);
275f034231aSEd Maste return true;
276f034231aSEd Maste }
277f034231aSEd Maste }
278f034231aSEd Maste
279f034231aSEd Maste // We get here if we've failed above...
280f034231aSEd Maste SetValueIsValid(false);
281f034231aSEd Maste return false;
282f034231aSEd Maste }
283f034231aSEd Maste
IsInScope()28414f1b3e8SDimitry Andric bool ValueObjectDynamicValue::IsInScope() { return m_parent->IsInScope(); }
285f034231aSEd Maste
SetValueFromCString(const char * value_str,Status & error)28614f1b3e8SDimitry Andric bool ValueObjectDynamicValue::SetValueFromCString(const char *value_str,
287b76161e4SDimitry Andric Status &error) {
28814f1b3e8SDimitry Andric if (!UpdateValueIfNeeded(false)) {
289f034231aSEd Maste error.SetErrorString("unable to read value");
290f034231aSEd Maste return false;
291f034231aSEd Maste }
292f034231aSEd Maste
293f034231aSEd Maste uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
294f034231aSEd Maste uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
295f034231aSEd Maste
29614f1b3e8SDimitry Andric if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
297f034231aSEd Maste error.SetErrorString("unable to read value");
298f034231aSEd Maste return false;
299f034231aSEd Maste }
300f034231aSEd Maste
301f73363f1SDimitry Andric // if we are at an offset from our parent, in order to set ourselves
302f73363f1SDimitry Andric // correctly we would need to change the new value so that it refers to the
303f73363f1SDimitry Andric // correct dynamic type. we choose not to deal with that - if anything more
304f73363f1SDimitry Andric // than a value overwrite is required, you should be using the expression
305f73363f1SDimitry Andric // parser instead of the value editing facility
30614f1b3e8SDimitry Andric if (my_value != parent_value) {
307f034231aSEd Maste // but NULL'ing out a value should always be allowed
30814f1b3e8SDimitry Andric if (strcmp(value_str, "0")) {
30914f1b3e8SDimitry Andric error.SetErrorString(
31014f1b3e8SDimitry Andric "unable to modify dynamic value, use 'expression' command");
311f034231aSEd Maste return false;
312f034231aSEd Maste }
313f034231aSEd Maste }
314f034231aSEd Maste
315f034231aSEd Maste bool ret_val = m_parent->SetValueFromCString(value_str, error);
316f034231aSEd Maste SetNeedsUpdate();
317f034231aSEd Maste return ret_val;
318f034231aSEd Maste }
319f034231aSEd Maste
SetData(DataExtractor & data,Status & error)320b76161e4SDimitry Andric bool ValueObjectDynamicValue::SetData(DataExtractor &data, Status &error) {
32114f1b3e8SDimitry Andric if (!UpdateValueIfNeeded(false)) {
322f034231aSEd Maste error.SetErrorString("unable to read value");
323f034231aSEd Maste return false;
324f034231aSEd Maste }
325f034231aSEd Maste
326f034231aSEd Maste uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
327f034231aSEd Maste uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
328f034231aSEd Maste
32914f1b3e8SDimitry Andric if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
330f034231aSEd Maste error.SetErrorString("unable to read value");
331f034231aSEd Maste return false;
332f034231aSEd Maste }
333f034231aSEd Maste
334f73363f1SDimitry Andric // if we are at an offset from our parent, in order to set ourselves
335f73363f1SDimitry Andric // correctly we would need to change the new value so that it refers to the
336f73363f1SDimitry Andric // correct dynamic type. we choose not to deal with that - if anything more
337f73363f1SDimitry Andric // than a value overwrite is required, you should be using the expression
338f73363f1SDimitry Andric // parser instead of the value editing facility
33914f1b3e8SDimitry Andric if (my_value != parent_value) {
340f034231aSEd Maste // but NULL'ing out a value should always be allowed
341f034231aSEd Maste lldb::offset_t offset = 0;
342f034231aSEd Maste
343cfca06d7SDimitry Andric if (data.GetAddress(&offset) != 0) {
34414f1b3e8SDimitry Andric error.SetErrorString(
34514f1b3e8SDimitry Andric "unable to modify dynamic value, use 'expression' command");
346f034231aSEd Maste return false;
347f034231aSEd Maste }
348f034231aSEd Maste }
349f034231aSEd Maste
350f034231aSEd Maste bool ret_val = m_parent->SetData(data, error);
351f034231aSEd Maste SetNeedsUpdate();
352f034231aSEd Maste return ret_val;
353f034231aSEd Maste }
354e81d9d49SDimitry Andric
SetPreferredDisplayLanguage(lldb::LanguageType lang)35514f1b3e8SDimitry Andric void ValueObjectDynamicValue::SetPreferredDisplayLanguage(
35614f1b3e8SDimitry Andric lldb::LanguageType lang) {
357e81d9d49SDimitry Andric this->ValueObject::SetPreferredDisplayLanguage(lang);
358e81d9d49SDimitry Andric if (m_parent)
359e81d9d49SDimitry Andric m_parent->SetPreferredDisplayLanguage(lang);
360e81d9d49SDimitry Andric }
361e81d9d49SDimitry Andric
GetPreferredDisplayLanguage()36214f1b3e8SDimitry Andric lldb::LanguageType ValueObjectDynamicValue::GetPreferredDisplayLanguage() {
36314f1b3e8SDimitry Andric if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
364e81d9d49SDimitry Andric if (m_parent)
365e81d9d49SDimitry Andric return m_parent->GetPreferredDisplayLanguage();
366e81d9d49SDimitry Andric return lldb::eLanguageTypeUnknown;
36714f1b3e8SDimitry Andric } else
368e81d9d49SDimitry Andric return m_preferred_display_language;
369e81d9d49SDimitry Andric }
370e81d9d49SDimitry Andric
IsSyntheticChildrenGenerated()37114f1b3e8SDimitry Andric bool ValueObjectDynamicValue::IsSyntheticChildrenGenerated() {
372f3fbd1c0SDimitry Andric if (m_parent)
373f3fbd1c0SDimitry Andric return m_parent->IsSyntheticChildrenGenerated();
374f3fbd1c0SDimitry Andric return false;
375f3fbd1c0SDimitry Andric }
376f3fbd1c0SDimitry Andric
SetSyntheticChildrenGenerated(bool b)37714f1b3e8SDimitry Andric void ValueObjectDynamicValue::SetSyntheticChildrenGenerated(bool b) {
378f3fbd1c0SDimitry Andric if (m_parent)
379f3fbd1c0SDimitry Andric m_parent->SetSyntheticChildrenGenerated(b);
380f3fbd1c0SDimitry Andric this->ValueObject::SetSyntheticChildrenGenerated(b);
381f3fbd1c0SDimitry Andric }
382f3fbd1c0SDimitry Andric
GetDeclaration(Declaration & decl)38314f1b3e8SDimitry Andric bool ValueObjectDynamicValue::GetDeclaration(Declaration &decl) {
384e81d9d49SDimitry Andric if (m_parent)
385e81d9d49SDimitry Andric return m_parent->GetDeclaration(decl);
386e81d9d49SDimitry Andric
387e81d9d49SDimitry Andric return ValueObject::GetDeclaration(decl);
388e81d9d49SDimitry Andric }
389e81d9d49SDimitry Andric
GetLanguageFlags()39014f1b3e8SDimitry Andric uint64_t ValueObjectDynamicValue::GetLanguageFlags() {
391e81d9d49SDimitry Andric if (m_parent)
392e81d9d49SDimitry Andric return m_parent->GetLanguageFlags();
393e81d9d49SDimitry Andric return this->ValueObject::GetLanguageFlags();
394e81d9d49SDimitry Andric }
395e81d9d49SDimitry Andric
SetLanguageFlags(uint64_t flags)39614f1b3e8SDimitry Andric void ValueObjectDynamicValue::SetLanguageFlags(uint64_t flags) {
397e81d9d49SDimitry Andric if (m_parent)
398e81d9d49SDimitry Andric m_parent->SetLanguageFlags(flags);
399e81d9d49SDimitry Andric else
400e81d9d49SDimitry Andric this->ValueObject::SetLanguageFlags(flags);
401e81d9d49SDimitry Andric }
402