1f678e45dSDimitry Andric //===-- ValueObjectDynamicValue.cpp ------------------------------*- C++-*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste // The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste
10ac7ddfbfSEd Maste #include "lldb/Core/ValueObjectDynamicValue.h"
11ac7ddfbfSEd Maste #include "lldb/Core/Value.h"
12ac7ddfbfSEd Maste #include "lldb/Core/ValueObject.h"
139f2f44ceSEd Maste #include "lldb/Symbol/CompilerType.h"
14ac7ddfbfSEd Maste #include "lldb/Symbol/Type.h"
15ac7ddfbfSEd Maste #include "lldb/Target/ExecutionContext.h"
16ac7ddfbfSEd Maste #include "lldb/Target/LanguageRuntime.h"
17ac7ddfbfSEd Maste #include "lldb/Target/Process.h"
18ac7ddfbfSEd Maste #include "lldb/Target/Target.h"
19*b5893f02SDimitry Andric #include "lldb/Utility/DataExtractor.h"
20f678e45dSDimitry Andric #include "lldb/Utility/Log.h"
21*b5893f02SDimitry Andric #include "lldb/Utility/Logging.h"
22*b5893f02SDimitry Andric #include "lldb/Utility/Scalar.h"
23*b5893f02SDimitry Andric #include "lldb/Utility/Status.h"
24*b5893f02SDimitry Andric #include "lldb/lldb-types.h"
25f678e45dSDimitry Andric
26*b5893f02SDimitry Andric #include <string.h>
27f678e45dSDimitry Andric namespace lldb_private {
28f678e45dSDimitry Andric class Declaration;
29f678e45dSDimitry Andric }
30ac7ddfbfSEd Maste
31ac7ddfbfSEd Maste using namespace lldb_private;
32ac7ddfbfSEd Maste
ValueObjectDynamicValue(ValueObject & parent,lldb::DynamicValueType use_dynamic)33435933ddSDimitry Andric ValueObjectDynamicValue::ValueObjectDynamicValue(
34435933ddSDimitry Andric ValueObject &parent, lldb::DynamicValueType use_dynamic)
35435933ddSDimitry Andric : ValueObject(parent), m_address(), m_dynamic_type_info(),
36435933ddSDimitry Andric m_use_dynamic(use_dynamic) {
37ac7ddfbfSEd Maste SetName(parent.GetName());
38ac7ddfbfSEd Maste }
39ac7ddfbfSEd Maste
~ValueObjectDynamicValue()40435933ddSDimitry Andric ValueObjectDynamicValue::~ValueObjectDynamicValue() {
41ac7ddfbfSEd Maste m_owning_valobj_sp.reset();
42ac7ddfbfSEd Maste }
43ac7ddfbfSEd Maste
GetCompilerTypeImpl()44435933ddSDimitry Andric CompilerType ValueObjectDynamicValue::GetCompilerTypeImpl() {
4535617911SEd Maste const bool success = UpdateValueIfNeeded(false);
46435933ddSDimitry Andric if (success) {
4735617911SEd Maste if (m_dynamic_type_info.HasType())
489f2f44ceSEd Maste return m_value.GetCompilerType();
49ac7ddfbfSEd Maste else
509f2f44ceSEd Maste return m_parent->GetCompilerType();
51ac7ddfbfSEd Maste }
529f2f44ceSEd Maste return m_parent->GetCompilerType();
5335617911SEd Maste }
54ac7ddfbfSEd Maste
GetTypeName()55435933ddSDimitry Andric ConstString ValueObjectDynamicValue::GetTypeName() {
56ac7ddfbfSEd Maste const bool success = UpdateValueIfNeeded(false);
57435933ddSDimitry Andric if (success) {
58ac7ddfbfSEd Maste if (m_dynamic_type_info.HasName())
59ac7ddfbfSEd Maste return m_dynamic_type_info.GetName();
60ac7ddfbfSEd Maste }
61ac7ddfbfSEd Maste return m_parent->GetTypeName();
62ac7ddfbfSEd Maste }
63ac7ddfbfSEd Maste
GetTypeImpl()64435933ddSDimitry Andric TypeImpl ValueObjectDynamicValue::GetTypeImpl() {
6535617911SEd Maste const bool success = UpdateValueIfNeeded(false);
66435933ddSDimitry Andric if (success && m_type_impl.IsValid()) {
6735617911SEd Maste return m_type_impl;
6835617911SEd Maste }
6935617911SEd Maste return m_parent->GetTypeImpl();
7035617911SEd Maste }
7135617911SEd Maste
GetQualifiedTypeName()72435933ddSDimitry Andric ConstString ValueObjectDynamicValue::GetQualifiedTypeName() {
73ac7ddfbfSEd Maste const bool success = UpdateValueIfNeeded(false);
74435933ddSDimitry Andric if (success) {
75ac7ddfbfSEd Maste if (m_dynamic_type_info.HasName())
76ac7ddfbfSEd Maste return m_dynamic_type_info.GetName();
77ac7ddfbfSEd Maste }
780127ef0fSEd Maste return m_parent->GetQualifiedTypeName();
790127ef0fSEd Maste }
800127ef0fSEd Maste
GetDisplayTypeName()81435933ddSDimitry Andric ConstString ValueObjectDynamicValue::GetDisplayTypeName() {
820127ef0fSEd Maste const bool success = UpdateValueIfNeeded(false);
83435933ddSDimitry Andric if (success) {
840127ef0fSEd Maste if (m_dynamic_type_info.HasType())
859f2f44ceSEd Maste return GetCompilerType().GetDisplayTypeName();
860127ef0fSEd Maste if (m_dynamic_type_info.HasName())
870127ef0fSEd Maste return m_dynamic_type_info.GetName();
880127ef0fSEd Maste }
890127ef0fSEd Maste return m_parent->GetDisplayTypeName();
90ac7ddfbfSEd Maste }
91ac7ddfbfSEd Maste
CalculateNumChildren(uint32_t max)92435933ddSDimitry Andric size_t ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) {
93ac7ddfbfSEd Maste const bool success = UpdateValueIfNeeded(false);
94435933ddSDimitry Andric if (success && m_dynamic_type_info.HasType()) {
95*b5893f02SDimitry Andric ExecutionContext exe_ctx(GetExecutionContextRef());
96*b5893f02SDimitry Andric auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
979f2f44ceSEd Maste return children_count <= max ? children_count : max;
98435933ddSDimitry Andric } else
999f2f44ceSEd Maste return m_parent->GetNumChildren(max);
100ac7ddfbfSEd Maste }
101ac7ddfbfSEd Maste
GetByteSize()102435933ddSDimitry Andric uint64_t ValueObjectDynamicValue::GetByteSize() {
103ac7ddfbfSEd Maste const bool success = UpdateValueIfNeeded(false);
104435933ddSDimitry Andric if (success && m_dynamic_type_info.HasType()) {
1059f2f44ceSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
1069f2f44ceSEd Maste return m_value.GetValueByteSize(nullptr, &exe_ctx);
107435933ddSDimitry Andric } else
108ac7ddfbfSEd Maste return m_parent->GetByteSize();
109ac7ddfbfSEd Maste }
110ac7ddfbfSEd Maste
GetValueType() const111435933ddSDimitry Andric lldb::ValueType ValueObjectDynamicValue::GetValueType() const {
112ac7ddfbfSEd Maste return m_parent->GetValueType();
113ac7ddfbfSEd Maste }
114ac7ddfbfSEd Maste
UpdateValue()115435933ddSDimitry Andric bool ValueObjectDynamicValue::UpdateValue() {
116ac7ddfbfSEd Maste SetValueIsValid(false);
117ac7ddfbfSEd Maste m_error.Clear();
118ac7ddfbfSEd Maste
119435933ddSDimitry Andric if (!m_parent->UpdateValueIfNeeded(false)) {
120ac7ddfbfSEd Maste // The dynamic value failed to get an error, pass the error along
121ac7ddfbfSEd Maste if (m_error.Success() && m_parent->GetError().Fail())
122ac7ddfbfSEd Maste m_error = m_parent->GetError();
123ac7ddfbfSEd Maste return false;
124ac7ddfbfSEd Maste }
125ac7ddfbfSEd Maste
1264ba319b5SDimitry Andric // Setting our type_sp to NULL will route everything back through our parent
1274ba319b5SDimitry Andric // which is equivalent to not using dynamic values.
128435933ddSDimitry Andric if (m_use_dynamic == lldb::eNoDynamicValues) {
129ac7ddfbfSEd Maste m_dynamic_type_info.Clear();
130ac7ddfbfSEd Maste return true;
131ac7ddfbfSEd Maste }
132ac7ddfbfSEd Maste
133ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
134ac7ddfbfSEd Maste Target *target = exe_ctx.GetTargetPtr();
135435933ddSDimitry Andric if (target) {
136ac7ddfbfSEd Maste m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
137ac7ddfbfSEd Maste m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
138ac7ddfbfSEd Maste }
139ac7ddfbfSEd Maste
140ac7ddfbfSEd Maste // First make sure our Type and/or Address haven't changed:
141ac7ddfbfSEd Maste Process *process = exe_ctx.GetProcessPtr();
142ac7ddfbfSEd Maste if (!process)
143ac7ddfbfSEd Maste return false;
144ac7ddfbfSEd Maste
145ac7ddfbfSEd Maste TypeAndOrName class_type_or_name;
146ac7ddfbfSEd Maste Address dynamic_address;
147ac7ddfbfSEd Maste bool found_dynamic_type = false;
1489f2f44ceSEd Maste Value::ValueType value_type;
1499f2f44ceSEd Maste
1509f2f44ceSEd Maste LanguageRuntime *runtime = nullptr;
151ac7ddfbfSEd Maste
152ac7ddfbfSEd Maste lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
153435933ddSDimitry Andric if (known_type != lldb::eLanguageTypeUnknown &&
154435933ddSDimitry Andric known_type != lldb::eLanguageTypeC) {
1559f2f44ceSEd Maste runtime = process->GetLanguageRuntime(known_type);
156ac7ddfbfSEd Maste if (runtime)
157435933ddSDimitry Andric found_dynamic_type = runtime->GetDynamicTypeAndAddress(
158435933ddSDimitry Andric *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
159435933ddSDimitry Andric value_type);
160435933ddSDimitry Andric } else {
1619f2f44ceSEd Maste runtime = process->GetLanguageRuntime(lldb::eLanguageTypeC_plus_plus);
1629f2f44ceSEd Maste if (runtime)
163435933ddSDimitry Andric found_dynamic_type = runtime->GetDynamicTypeAndAddress(
164435933ddSDimitry Andric *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
165435933ddSDimitry Andric value_type);
166ac7ddfbfSEd Maste
167435933ddSDimitry Andric if (!found_dynamic_type) {
1689f2f44ceSEd Maste runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
1699f2f44ceSEd Maste if (runtime)
170435933ddSDimitry Andric found_dynamic_type = runtime->GetDynamicTypeAndAddress(
171435933ddSDimitry Andric *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
172435933ddSDimitry Andric value_type);
173ac7ddfbfSEd Maste }
174ac7ddfbfSEd Maste }
175ac7ddfbfSEd Maste
176435933ddSDimitry Andric // Getting the dynamic value may have run the program a bit, and so marked us
1774ba319b5SDimitry Andric // as needing updating, but we really don't...
178ac7ddfbfSEd Maste
179ac7ddfbfSEd Maste m_update_point.SetUpdated();
180ac7ddfbfSEd Maste
181435933ddSDimitry Andric if (runtime && found_dynamic_type) {
182435933ddSDimitry Andric if (class_type_or_name.HasType()) {
183435933ddSDimitry Andric m_type_impl =
184435933ddSDimitry Andric TypeImpl(m_parent->GetCompilerType(),
185435933ddSDimitry Andric runtime->FixUpDynamicType(class_type_or_name, *m_parent)
186435933ddSDimitry Andric .GetCompilerType());
187435933ddSDimitry Andric } else {
18835617911SEd Maste m_type_impl.Clear();
18935617911SEd Maste }
190435933ddSDimitry Andric } else {
19135617911SEd Maste m_type_impl.Clear();
19235617911SEd Maste }
19335617911SEd Maste
194435933ddSDimitry Andric // If we don't have a dynamic type, then make ourselves just a echo of our
1954ba319b5SDimitry Andric // parent. Or we could return false, and make ourselves an echo of our
1964ba319b5SDimitry Andric // parent?
197435933ddSDimitry Andric if (!found_dynamic_type) {
198ac7ddfbfSEd Maste if (m_dynamic_type_info)
199ac7ddfbfSEd Maste SetValueDidChange(true);
200ac7ddfbfSEd Maste ClearDynamicTypeInformation();
201ac7ddfbfSEd Maste m_dynamic_type_info.Clear();
202ac7ddfbfSEd Maste m_value = m_parent->GetValue();
203ac7ddfbfSEd Maste m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
204ac7ddfbfSEd Maste return m_error.Success();
205ac7ddfbfSEd Maste }
206ac7ddfbfSEd Maste
207ac7ddfbfSEd Maste Value old_value(m_value);
208ac7ddfbfSEd Maste
209ac7ddfbfSEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES));
210ac7ddfbfSEd Maste
211ac7ddfbfSEd Maste bool has_changed_type = false;
212ac7ddfbfSEd Maste
213435933ddSDimitry Andric if (!m_dynamic_type_info) {
214ac7ddfbfSEd Maste m_dynamic_type_info = class_type_or_name;
215ac7ddfbfSEd Maste has_changed_type = true;
216435933ddSDimitry Andric } else if (class_type_or_name != m_dynamic_type_info) {
217ac7ddfbfSEd Maste // We are another type, we need to tear down our children...
218ac7ddfbfSEd Maste m_dynamic_type_info = class_type_or_name;
219ac7ddfbfSEd Maste SetValueDidChange(true);
220ac7ddfbfSEd Maste has_changed_type = true;
221ac7ddfbfSEd Maste }
222ac7ddfbfSEd Maste
223ac7ddfbfSEd Maste if (has_changed_type)
224ac7ddfbfSEd Maste ClearDynamicTypeInformation();
225ac7ddfbfSEd Maste
226435933ddSDimitry Andric if (!m_address.IsValid() || m_address != dynamic_address) {
227ac7ddfbfSEd Maste if (m_address.IsValid())
228ac7ddfbfSEd Maste SetValueDidChange(true);
229ac7ddfbfSEd Maste
230ac7ddfbfSEd Maste // We've moved, so we should be fine...
231ac7ddfbfSEd Maste m_address = dynamic_address;
232ac7ddfbfSEd Maste lldb::TargetSP target_sp(GetTargetSP());
233ac7ddfbfSEd Maste lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
234ac7ddfbfSEd Maste m_value.GetScalar() = load_address;
235ac7ddfbfSEd Maste }
236ac7ddfbfSEd Maste
2379f2f44ceSEd Maste if (runtime)
238435933ddSDimitry Andric m_dynamic_type_info =
239435933ddSDimitry Andric runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent);
240ac7ddfbfSEd Maste
241ac7ddfbfSEd Maste // m_value.SetContext (Value::eContextTypeClangType, corrected_type);
2429f2f44ceSEd Maste m_value.SetCompilerType(m_dynamic_type_info.GetCompilerType());
243ac7ddfbfSEd Maste
2449f2f44ceSEd Maste m_value.SetValueType(value_type);
245ac7ddfbfSEd Maste
246ac7ddfbfSEd Maste if (has_changed_type && log)
2470127ef0fSEd Maste log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(),
2480127ef0fSEd Maste static_cast<void *>(this), GetTypeName().GetCString());
249ac7ddfbfSEd Maste
250435933ddSDimitry Andric if (m_address.IsValid() && m_dynamic_type_info) {
2514ba319b5SDimitry Andric // The variable value is in the Scalar value inside the m_value. We can
2524ba319b5SDimitry Andric // point our m_data right to it.
253ac7ddfbfSEd Maste m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
254435933ddSDimitry Andric if (m_error.Success()) {
255435933ddSDimitry Andric if (!CanProvideValue()) {
2564ba319b5SDimitry Andric // this value object represents an aggregate type whose children have
2574ba319b5SDimitry Andric // values, but this object does not. So we say we are changed if our
2584ba319b5SDimitry Andric // location has changed.
259435933ddSDimitry Andric SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
260435933ddSDimitry Andric m_value.GetScalar() != old_value.GetScalar());
261ac7ddfbfSEd Maste }
262ac7ddfbfSEd Maste
263ac7ddfbfSEd Maste SetValueIsValid(true);
264ac7ddfbfSEd Maste return true;
265ac7ddfbfSEd Maste }
266ac7ddfbfSEd Maste }
267ac7ddfbfSEd Maste
268ac7ddfbfSEd Maste // We get here if we've failed above...
269ac7ddfbfSEd Maste SetValueIsValid(false);
270ac7ddfbfSEd Maste return false;
271ac7ddfbfSEd Maste }
272ac7ddfbfSEd Maste
IsInScope()273435933ddSDimitry Andric bool ValueObjectDynamicValue::IsInScope() { return m_parent->IsInScope(); }
274ac7ddfbfSEd Maste
SetValueFromCString(const char * value_str,Status & error)275435933ddSDimitry Andric bool ValueObjectDynamicValue::SetValueFromCString(const char *value_str,
2765517e702SDimitry Andric Status &error) {
277435933ddSDimitry Andric if (!UpdateValueIfNeeded(false)) {
278ac7ddfbfSEd Maste error.SetErrorString("unable to read value");
279ac7ddfbfSEd Maste return false;
280ac7ddfbfSEd Maste }
281ac7ddfbfSEd Maste
282ac7ddfbfSEd Maste uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
283ac7ddfbfSEd Maste uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
284ac7ddfbfSEd Maste
285435933ddSDimitry Andric if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
286ac7ddfbfSEd Maste error.SetErrorString("unable to read value");
287ac7ddfbfSEd Maste return false;
288ac7ddfbfSEd Maste }
289ac7ddfbfSEd Maste
2904ba319b5SDimitry Andric // if we are at an offset from our parent, in order to set ourselves
2914ba319b5SDimitry Andric // correctly we would need to change the new value so that it refers to the
2924ba319b5SDimitry Andric // correct dynamic type. we choose not to deal with that - if anything more
2934ba319b5SDimitry Andric // than a value overwrite is required, you should be using the expression
2944ba319b5SDimitry Andric // parser instead of the value editing facility
295435933ddSDimitry Andric if (my_value != parent_value) {
296ac7ddfbfSEd Maste // but NULL'ing out a value should always be allowed
297435933ddSDimitry Andric if (strcmp(value_str, "0")) {
298435933ddSDimitry Andric error.SetErrorString(
299435933ddSDimitry Andric "unable to modify dynamic value, use 'expression' command");
300ac7ddfbfSEd Maste return false;
301ac7ddfbfSEd Maste }
302ac7ddfbfSEd Maste }
303ac7ddfbfSEd Maste
304ac7ddfbfSEd Maste bool ret_val = m_parent->SetValueFromCString(value_str, error);
305ac7ddfbfSEd Maste SetNeedsUpdate();
306ac7ddfbfSEd Maste return ret_val;
307ac7ddfbfSEd Maste }
308ac7ddfbfSEd Maste
SetData(DataExtractor & data,Status & error)3095517e702SDimitry Andric bool ValueObjectDynamicValue::SetData(DataExtractor &data, Status &error) {
310435933ddSDimitry Andric if (!UpdateValueIfNeeded(false)) {
311ac7ddfbfSEd Maste error.SetErrorString("unable to read value");
312ac7ddfbfSEd Maste return false;
313ac7ddfbfSEd Maste }
314ac7ddfbfSEd Maste
315ac7ddfbfSEd Maste uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
316ac7ddfbfSEd Maste uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
317ac7ddfbfSEd Maste
318435933ddSDimitry Andric if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
319ac7ddfbfSEd Maste error.SetErrorString("unable to read value");
320ac7ddfbfSEd Maste return false;
321ac7ddfbfSEd Maste }
322ac7ddfbfSEd Maste
3234ba319b5SDimitry Andric // if we are at an offset from our parent, in order to set ourselves
3244ba319b5SDimitry Andric // correctly we would need to change the new value so that it refers to the
3254ba319b5SDimitry Andric // correct dynamic type. we choose not to deal with that - if anything more
3264ba319b5SDimitry Andric // than a value overwrite is required, you should be using the expression
3274ba319b5SDimitry Andric // parser instead of the value editing facility
328435933ddSDimitry Andric if (my_value != parent_value) {
329ac7ddfbfSEd Maste // but NULL'ing out a value should always be allowed
330ac7ddfbfSEd Maste lldb::offset_t offset = 0;
331ac7ddfbfSEd Maste
332435933ddSDimitry Andric if (data.GetPointer(&offset) != 0) {
333435933ddSDimitry Andric error.SetErrorString(
334435933ddSDimitry Andric "unable to modify dynamic value, use 'expression' command");
335ac7ddfbfSEd Maste return false;
336ac7ddfbfSEd Maste }
337ac7ddfbfSEd Maste }
338ac7ddfbfSEd Maste
339ac7ddfbfSEd Maste bool ret_val = m_parent->SetData(data, error);
340ac7ddfbfSEd Maste SetNeedsUpdate();
341ac7ddfbfSEd Maste return ret_val;
342ac7ddfbfSEd Maste }
3439f2f44ceSEd Maste
SetPreferredDisplayLanguage(lldb::LanguageType lang)344435933ddSDimitry Andric void ValueObjectDynamicValue::SetPreferredDisplayLanguage(
345435933ddSDimitry Andric lldb::LanguageType lang) {
3469f2f44ceSEd Maste this->ValueObject::SetPreferredDisplayLanguage(lang);
3479f2f44ceSEd Maste if (m_parent)
3489f2f44ceSEd Maste m_parent->SetPreferredDisplayLanguage(lang);
3499f2f44ceSEd Maste }
3509f2f44ceSEd Maste
GetPreferredDisplayLanguage()351435933ddSDimitry Andric lldb::LanguageType ValueObjectDynamicValue::GetPreferredDisplayLanguage() {
352435933ddSDimitry Andric if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
3539f2f44ceSEd Maste if (m_parent)
3549f2f44ceSEd Maste return m_parent->GetPreferredDisplayLanguage();
3559f2f44ceSEd Maste return lldb::eLanguageTypeUnknown;
356435933ddSDimitry Andric } else
3579f2f44ceSEd Maste return m_preferred_display_language;
3589f2f44ceSEd Maste }
3599f2f44ceSEd Maste
IsSyntheticChildrenGenerated()360435933ddSDimitry Andric bool ValueObjectDynamicValue::IsSyntheticChildrenGenerated() {
3614bb0738eSEd Maste if (m_parent)
3624bb0738eSEd Maste return m_parent->IsSyntheticChildrenGenerated();
3634bb0738eSEd Maste return false;
3644bb0738eSEd Maste }
3654bb0738eSEd Maste
SetSyntheticChildrenGenerated(bool b)366435933ddSDimitry Andric void ValueObjectDynamicValue::SetSyntheticChildrenGenerated(bool b) {
3674bb0738eSEd Maste if (m_parent)
3684bb0738eSEd Maste m_parent->SetSyntheticChildrenGenerated(b);
3694bb0738eSEd Maste this->ValueObject::SetSyntheticChildrenGenerated(b);
3704bb0738eSEd Maste }
3714bb0738eSEd Maste
GetDeclaration(Declaration & decl)372435933ddSDimitry Andric bool ValueObjectDynamicValue::GetDeclaration(Declaration &decl) {
3739f2f44ceSEd Maste if (m_parent)
3749f2f44ceSEd Maste return m_parent->GetDeclaration(decl);
3759f2f44ceSEd Maste
3769f2f44ceSEd Maste return ValueObject::GetDeclaration(decl);
3779f2f44ceSEd Maste }
3789f2f44ceSEd Maste
GetLanguageFlags()379435933ddSDimitry Andric uint64_t ValueObjectDynamicValue::GetLanguageFlags() {
3809f2f44ceSEd Maste if (m_parent)
3819f2f44ceSEd Maste return m_parent->GetLanguageFlags();
3829f2f44ceSEd Maste return this->ValueObject::GetLanguageFlags();
3839f2f44ceSEd Maste }
3849f2f44ceSEd Maste
SetLanguageFlags(uint64_t flags)385435933ddSDimitry Andric void ValueObjectDynamicValue::SetLanguageFlags(uint64_t flags) {
3869f2f44ceSEd Maste if (m_parent)
3879f2f44ceSEd Maste m_parent->SetLanguageFlags(flags);
3889f2f44ceSEd Maste else
3899f2f44ceSEd Maste this->ValueObject::SetLanguageFlags(flags);
3909f2f44ceSEd Maste }
391