180814287SRaphael Isemann //===-- ValueObjectDynamicValue.cpp ---------------------------------------===// 278a685aaSJim Ingham // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 678a685aaSJim Ingham // 778a685aaSJim Ingham //===----------------------------------------------------------------------===// 878a685aaSJim Ingham 978a685aaSJim Ingham #include "lldb/Core/ValueObjectDynamicValue.h" 1078a685aaSJim Ingham #include "lldb/Core/Value.h" 1178a685aaSJim Ingham #include "lldb/Core/ValueObject.h" 12a1e5dc86SGreg Clayton #include "lldb/Symbol/CompilerType.h" 1378a685aaSJim Ingham #include "lldb/Symbol/Type.h" 1478a685aaSJim Ingham #include "lldb/Target/ExecutionContext.h" 1578a685aaSJim Ingham #include "lldb/Target/LanguageRuntime.h" 1678a685aaSJim Ingham #include "lldb/Target/Process.h" 1778a685aaSJim Ingham #include "lldb/Target/Target.h" 18672d2c12SJonas Devlieghere #include "lldb/Utility/DataExtractor.h" 19*c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h" 202f3df613SZachary Turner #include "lldb/Utility/Log.h" 21672d2c12SJonas Devlieghere #include "lldb/Utility/Scalar.h" 22672d2c12SJonas Devlieghere #include "lldb/Utility/Status.h" 23672d2c12SJonas Devlieghere #include "lldb/lldb-types.h" 242f3df613SZachary Turner 2576e47d48SRaphael Isemann #include <cstring> 262f3df613SZachary Turner namespace lldb_private { 272f3df613SZachary Turner class Declaration; 282f3df613SZachary Turner } 2978a685aaSJim Ingham 3078a685aaSJim Ingham using namespace lldb_private; 3178a685aaSJim Ingham 32b9c1b51eSKate Stone ValueObjectDynamicValue::ValueObjectDynamicValue( 33b9c1b51eSKate Stone ValueObject &parent, lldb::DynamicValueType use_dynamic) 34b9c1b51eSKate Stone : ValueObject(parent), m_address(), m_dynamic_type_info(), 35b9c1b51eSKate Stone m_use_dynamic(use_dynamic) { 366f3533fbSEnrico Granata SetName(parent.GetName()); 3778a685aaSJim Ingham } 3878a685aaSJim Ingham 39b9c1b51eSKate Stone CompilerType ValueObjectDynamicValue::GetCompilerTypeImpl() { 40dc4db5a6SEnrico Granata const bool success = UpdateValueIfNeeded(false); 41b9c1b51eSKate Stone if (success) { 42dc4db5a6SEnrico Granata if (m_dynamic_type_info.HasType()) 4399558cc4SGreg Clayton return m_value.GetCompilerType(); 4478a685aaSJim Ingham else 4599558cc4SGreg Clayton return m_parent->GetCompilerType(); 4678a685aaSJim Ingham } 4799558cc4SGreg Clayton return m_parent->GetCompilerType(); 48dc4db5a6SEnrico Granata } 4978a685aaSJim Ingham 50b9c1b51eSKate Stone ConstString ValueObjectDynamicValue::GetTypeName() { 51c3e320a7SEnrico Granata const bool success = UpdateValueIfNeeded(false); 52b9c1b51eSKate Stone if (success) { 53f7b1a34eSEnrico Granata if (m_dynamic_type_info.HasName()) 54f7b1a34eSEnrico Granata return m_dynamic_type_info.GetName(); 55f7b1a34eSEnrico Granata } 56f7b1a34eSEnrico Granata return m_parent->GetTypeName(); 57f7b1a34eSEnrico Granata } 58f7b1a34eSEnrico Granata 59b9c1b51eSKate Stone TypeImpl ValueObjectDynamicValue::GetTypeImpl() { 60dc4db5a6SEnrico Granata const bool success = UpdateValueIfNeeded(false); 61b9c1b51eSKate Stone if (success && m_type_impl.IsValid()) { 62dc4db5a6SEnrico Granata return m_type_impl; 63dc4db5a6SEnrico Granata } 64dc4db5a6SEnrico Granata return m_parent->GetTypeImpl(); 65dc4db5a6SEnrico Granata } 66dc4db5a6SEnrico Granata 67b9c1b51eSKate Stone ConstString ValueObjectDynamicValue::GetQualifiedTypeName() { 68f7b1a34eSEnrico Granata const bool success = UpdateValueIfNeeded(false); 69b9c1b51eSKate Stone if (success) { 70f7b1a34eSEnrico Granata if (m_dynamic_type_info.HasName()) 71f7b1a34eSEnrico Granata return m_dynamic_type_info.GetName(); 72f7b1a34eSEnrico Granata } 73e8daa2f8SEnrico Granata return m_parent->GetQualifiedTypeName(); 74e8daa2f8SEnrico Granata } 75e8daa2f8SEnrico Granata 76b9c1b51eSKate Stone ConstString ValueObjectDynamicValue::GetDisplayTypeName() { 77e8daa2f8SEnrico Granata const bool success = UpdateValueIfNeeded(false); 78b9c1b51eSKate Stone if (success) { 79e8daa2f8SEnrico Granata if (m_dynamic_type_info.HasType()) 8099558cc4SGreg Clayton return GetCompilerType().GetDisplayTypeName(); 81e8daa2f8SEnrico Granata if (m_dynamic_type_info.HasName()) 82e8daa2f8SEnrico Granata return m_dynamic_type_info.GetName(); 83e8daa2f8SEnrico Granata } 84e8daa2f8SEnrico Granata return m_parent->GetDisplayTypeName(); 8578a685aaSJim Ingham } 8678a685aaSJim Ingham 87b9c1b51eSKate Stone size_t ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) { 88c3e320a7SEnrico Granata const bool success = UpdateValueIfNeeded(false); 89b9c1b51eSKate Stone if (success && m_dynamic_type_info.HasType()) { 90eca07c59SAdrian Prantl ExecutionContext exe_ctx(GetExecutionContextRef()); 91eca07c59SAdrian Prantl auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx); 929ac7a6c5SSiva Chandra return children_count <= max ? children_count : max; 93b9c1b51eSKate Stone } else 949ac7a6c5SSiva Chandra return m_parent->GetNumChildren(max); 9578a685aaSJim Ingham } 9678a685aaSJim Ingham 97113f56fbSAdrian Prantl llvm::Optional<uint64_t> ValueObjectDynamicValue::GetByteSize() { 98c3e320a7SEnrico Granata const bool success = UpdateValueIfNeeded(false); 99b9c1b51eSKate Stone if (success && m_dynamic_type_info.HasType()) { 10095438038SEnrico Granata ExecutionContext exe_ctx(GetExecutionContextRef()); 10195438038SEnrico Granata return m_value.GetValueByteSize(nullptr, &exe_ctx); 102b9c1b51eSKate Stone } else 10378a685aaSJim Ingham return m_parent->GetByteSize(); 10478a685aaSJim Ingham } 10578a685aaSJim Ingham 106b9c1b51eSKate Stone lldb::ValueType ValueObjectDynamicValue::GetValueType() const { 10778a685aaSJim Ingham return m_parent->GetValueType(); 10878a685aaSJim Ingham } 10978a685aaSJim Ingham 110b9c1b51eSKate Stone bool ValueObjectDynamicValue::UpdateValue() { 11178a685aaSJim Ingham SetValueIsValid(false); 11278a685aaSJim Ingham m_error.Clear(); 11378a685aaSJim Ingham 114b9c1b51eSKate Stone if (!m_parent->UpdateValueIfNeeded(false)) { 115007d5be6SGreg Clayton // The dynamic value failed to get an error, pass the error along 116007d5be6SGreg Clayton if (m_error.Success() && m_parent->GetError().Fail()) 117007d5be6SGreg Clayton m_error = m_parent->GetError(); 11878a685aaSJim Ingham return false; 11978a685aaSJim Ingham } 12078a685aaSJim Ingham 12105097246SAdrian Prantl // Setting our type_sp to NULL will route everything back through our parent 12205097246SAdrian Prantl // which is equivalent to not using dynamic values. 123b9c1b51eSKate Stone if (m_use_dynamic == lldb::eNoDynamicValues) { 124f7b1a34eSEnrico Granata m_dynamic_type_info.Clear(); 1252837b766SJim Ingham return true; 1262837b766SJim Ingham } 1272837b766SJim Ingham 128cc4d0146SGreg Clayton ExecutionContext exe_ctx(GetExecutionContextRef()); 129c14ee32dSGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 130b9c1b51eSKate Stone if (target) { 131c14ee32dSGreg Clayton m_data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 132c14ee32dSGreg Clayton m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 13378a685aaSJim Ingham } 13478a685aaSJim Ingham 13578a685aaSJim Ingham // First make sure our Type and/or Address haven't changed: 136cc4d0146SGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 13778a685aaSJim Ingham if (!process) 13878a685aaSJim Ingham return false; 13978a685aaSJim Ingham 14061be0903SJim Ingham TypeAndOrName class_type_or_name; 14178a685aaSJim Ingham Address dynamic_address; 14278a685aaSJim Ingham bool found_dynamic_type = false; 1430b6003f3SEnrico Granata Value::ValueType value_type; 14478a685aaSJim Ingham 145c74275bcSEnrico Granata LanguageRuntime *runtime = nullptr; 146c74275bcSEnrico Granata 14778a685aaSJim Ingham lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage(); 148b9c1b51eSKate Stone if (known_type != lldb::eLanguageTypeUnknown && 149b9c1b51eSKate Stone known_type != lldb::eLanguageTypeC) { 150c74275bcSEnrico Granata runtime = process->GetLanguageRuntime(known_type); 15178a685aaSJim Ingham if (runtime) 152b9c1b51eSKate Stone found_dynamic_type = runtime->GetDynamicTypeAndAddress( 153b9c1b51eSKate Stone *m_parent, m_use_dynamic, class_type_or_name, dynamic_address, 154b9c1b51eSKate Stone value_type); 155b9c1b51eSKate Stone } else { 156c74275bcSEnrico Granata runtime = process->GetLanguageRuntime(lldb::eLanguageTypeC_plus_plus); 157c74275bcSEnrico Granata 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); 16178a685aaSJim Ingham 162b9c1b51eSKate Stone if (!found_dynamic_type) { 163c74275bcSEnrico Granata runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC); 164c74275bcSEnrico Granata if (runtime) 165b9c1b51eSKate Stone found_dynamic_type = runtime->GetDynamicTypeAndAddress( 166b9c1b51eSKate Stone *m_parent, m_use_dynamic, class_type_or_name, dynamic_address, 167b9c1b51eSKate Stone value_type); 16878a685aaSJim Ingham } 16978a685aaSJim Ingham } 17078a685aaSJim Ingham 171b9c1b51eSKate Stone // Getting the dynamic value may have run the program a bit, and so marked us 17205097246SAdrian Prantl // as needing updating, but we really don't... 17361be0903SJim Ingham 17461be0903SJim Ingham m_update_point.SetUpdated(); 17561be0903SJim Ingham 176b9c1b51eSKate Stone if (runtime && found_dynamic_type) { 177b9c1b51eSKate Stone if (class_type_or_name.HasType()) { 178b9c1b51eSKate Stone m_type_impl = 179b9c1b51eSKate Stone TypeImpl(m_parent->GetCompilerType(), 180b9c1b51eSKate Stone runtime->FixUpDynamicType(class_type_or_name, *m_parent) 181b9c1b51eSKate Stone .GetCompilerType()); 182b9c1b51eSKate Stone } else { 183df7c7f99SEnrico Granata m_type_impl.Clear(); 184df7c7f99SEnrico Granata } 185b9c1b51eSKate Stone } else { 186df7c7f99SEnrico Granata m_type_impl.Clear(); 187df7c7f99SEnrico Granata } 188dc4db5a6SEnrico Granata 189b9c1b51eSKate Stone // If we don't have a dynamic type, then make ourselves just a echo of our 19005097246SAdrian Prantl // parent. Or we could return false, and make ourselves an echo of our 19105097246SAdrian Prantl // parent? 192b9c1b51eSKate Stone if (!found_dynamic_type) { 193f7b1a34eSEnrico Granata if (m_dynamic_type_info) 19475badc46SEnrico Granata SetValueDidChange(true); 195bd83b87dSEnrico Granata ClearDynamicTypeInformation(); 196f7b1a34eSEnrico Granata m_dynamic_type_info.Clear(); 19778a685aaSJim Ingham m_value = m_parent->GetValue(); 198d9cbd2acSAdrian Prantl m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get()); 19978a685aaSJim Ingham return m_error.Success(); 20078a685aaSJim Ingham } 20178a685aaSJim Ingham 20278a685aaSJim Ingham Value old_value(m_value); 20378a685aaSJim Ingham 204a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Commands); 205d228483dSEnrico Granata 206e3e91517SEnrico Granata bool has_changed_type = false; 207e3e91517SEnrico Granata 208b9c1b51eSKate Stone if (!m_dynamic_type_info) { 209f7b1a34eSEnrico Granata m_dynamic_type_info = class_type_or_name; 210e3e91517SEnrico Granata has_changed_type = true; 211b9c1b51eSKate Stone } else if (class_type_or_name != m_dynamic_type_info) { 21278a685aaSJim Ingham // We are another type, we need to tear down our children... 213f7b1a34eSEnrico Granata m_dynamic_type_info = class_type_or_name; 21478a685aaSJim Ingham SetValueDidChange(true); 215e3e91517SEnrico Granata has_changed_type = true; 21678a685aaSJim Ingham } 21778a685aaSJim Ingham 218e3e91517SEnrico Granata if (has_changed_type) 219e3e91517SEnrico Granata ClearDynamicTypeInformation(); 220e3e91517SEnrico Granata 221b9c1b51eSKate Stone if (!m_address.IsValid() || m_address != dynamic_address) { 22278a685aaSJim Ingham if (m_address.IsValid()) 22378a685aaSJim Ingham SetValueDidChange(true); 22478a685aaSJim Ingham 22578a685aaSJim Ingham // We've moved, so we should be fine... 22678a685aaSJim Ingham m_address = dynamic_address; 227cc4d0146SGreg Clayton lldb::TargetSP target_sp(GetTargetSP()); 228cc4d0146SGreg Clayton lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get()); 22978a685aaSJim Ingham m_value.GetScalar() = load_address; 23078a685aaSJim Ingham } 23178a685aaSJim Ingham 232c74275bcSEnrico Granata if (runtime) 233b9c1b51eSKate Stone m_dynamic_type_info = 234b9c1b51eSKate Stone runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent); 23578a685aaSJim Ingham 23699558cc4SGreg Clayton m_value.SetCompilerType(m_dynamic_type_info.GetCompilerType()); 23778a685aaSJim Ingham 2380b6003f3SEnrico Granata m_value.SetValueType(value_type); 23978a685aaSJim Ingham 240e3e91517SEnrico Granata if (has_changed_type && log) 24163e5fb76SJonas Devlieghere LLDB_LOGF(log, "[%s %p] has a new dynamic type %s", GetName().GetCString(), 242324a1036SSaleem Abdulrasool static_cast<void *>(this), GetTypeName().GetCString()); 243e3e91517SEnrico Granata 244b9c1b51eSKate Stone if (m_address.IsValid() && m_dynamic_type_info) { 24505097246SAdrian Prantl // The variable value is in the Scalar value inside the m_value. We can 24605097246SAdrian Prantl // point our m_data right to it. 247d9cbd2acSAdrian Prantl m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get()); 248b9c1b51eSKate Stone if (m_error.Success()) { 249b9c1b51eSKate Stone if (!CanProvideValue()) { 25005097246SAdrian Prantl // this value object represents an aggregate type whose children have 25105097246SAdrian Prantl // values, but this object does not. So we say we are changed if our 25205097246SAdrian Prantl // location has changed. 253b9c1b51eSKate Stone SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() || 254b9c1b51eSKate Stone m_value.GetScalar() != old_value.GetScalar()); 25578a685aaSJim Ingham } 25678a685aaSJim Ingham 25778a685aaSJim Ingham SetValueIsValid(true); 25878a685aaSJim Ingham return true; 25978a685aaSJim Ingham } 26078a685aaSJim Ingham } 26178a685aaSJim Ingham 26278a685aaSJim Ingham // We get here if we've failed above... 26378a685aaSJim Ingham SetValueIsValid(false); 26478a685aaSJim Ingham return false; 26578a685aaSJim Ingham } 26678a685aaSJim Ingham 267b9c1b51eSKate Stone bool ValueObjectDynamicValue::IsInScope() { return m_parent->IsInScope(); } 26878a685aaSJim Ingham 269b9c1b51eSKate Stone bool ValueObjectDynamicValue::SetValueFromCString(const char *value_str, 27097206d57SZachary Turner Status &error) { 271b9c1b51eSKate Stone if (!UpdateValueIfNeeded(false)) { 27207a4ac22SEnrico Granata error.SetErrorString("unable to read value"); 27307a4ac22SEnrico Granata return false; 27407a4ac22SEnrico Granata } 27507a4ac22SEnrico Granata 27607a4ac22SEnrico Granata uint64_t my_value = GetValueAsUnsigned(UINT64_MAX); 27707a4ac22SEnrico Granata uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX); 27807a4ac22SEnrico Granata 279b9c1b51eSKate Stone if (my_value == UINT64_MAX || parent_value == UINT64_MAX) { 28007a4ac22SEnrico Granata error.SetErrorString("unable to read value"); 28107a4ac22SEnrico Granata return false; 28207a4ac22SEnrico Granata } 28307a4ac22SEnrico Granata 28405097246SAdrian Prantl // if we are at an offset from our parent, in order to set ourselves 28505097246SAdrian Prantl // correctly we would need to change the new value so that it refers to the 28605097246SAdrian Prantl // correct dynamic type. we choose not to deal with that - if anything more 28705097246SAdrian Prantl // than a value overwrite is required, you should be using the expression 28805097246SAdrian Prantl // parser instead of the value editing facility 289b9c1b51eSKate Stone if (my_value != parent_value) { 29007a4ac22SEnrico Granata // but NULL'ing out a value should always be allowed 291b9c1b51eSKate Stone if (strcmp(value_str, "0")) { 292b9c1b51eSKate Stone error.SetErrorString( 293b9c1b51eSKate Stone "unable to modify dynamic value, use 'expression' command"); 29407a4ac22SEnrico Granata return false; 29507a4ac22SEnrico Granata } 29607a4ac22SEnrico Granata } 29707a4ac22SEnrico Granata 29807a4ac22SEnrico Granata bool ret_val = m_parent->SetValueFromCString(value_str, error); 29907a4ac22SEnrico Granata SetNeedsUpdate(); 30007a4ac22SEnrico Granata return ret_val; 30107a4ac22SEnrico Granata } 302389823e9SSean Callanan 30397206d57SZachary Turner bool ValueObjectDynamicValue::SetData(DataExtractor &data, Status &error) { 304b9c1b51eSKate Stone if (!UpdateValueIfNeeded(false)) { 305389823e9SSean Callanan error.SetErrorString("unable to read value"); 306389823e9SSean Callanan return false; 307389823e9SSean Callanan } 308389823e9SSean Callanan 309389823e9SSean Callanan uint64_t my_value = GetValueAsUnsigned(UINT64_MAX); 310389823e9SSean Callanan uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX); 311389823e9SSean Callanan 312b9c1b51eSKate Stone if (my_value == UINT64_MAX || parent_value == UINT64_MAX) { 313389823e9SSean Callanan error.SetErrorString("unable to read value"); 314389823e9SSean Callanan return false; 315389823e9SSean Callanan } 316389823e9SSean Callanan 31705097246SAdrian Prantl // if we are at an offset from our parent, in order to set ourselves 31805097246SAdrian Prantl // correctly we would need to change the new value so that it refers to the 31905097246SAdrian Prantl // correct dynamic type. we choose not to deal with that - if anything more 32005097246SAdrian Prantl // than a value overwrite is required, you should be using the expression 32105097246SAdrian Prantl // parser instead of the value editing facility 322b9c1b51eSKate Stone if (my_value != parent_value) { 323389823e9SSean Callanan // but NULL'ing out a value should always be allowed 324389823e9SSean Callanan lldb::offset_t offset = 0; 325389823e9SSean Callanan 3260863f675SPavel Labath if (data.GetAddress(&offset) != 0) { 327b9c1b51eSKate Stone error.SetErrorString( 328b9c1b51eSKate Stone "unable to modify dynamic value, use 'expression' command"); 329389823e9SSean Callanan return false; 330389823e9SSean Callanan } 331389823e9SSean Callanan } 332389823e9SSean Callanan 333389823e9SSean Callanan bool ret_val = m_parent->SetData(data, error); 334389823e9SSean Callanan SetNeedsUpdate(); 335389823e9SSean Callanan return ret_val; 336389823e9SSean Callanan } 3379851b1f6SSiva Chandra 338b9c1b51eSKate Stone void ValueObjectDynamicValue::SetPreferredDisplayLanguage( 339b9c1b51eSKate Stone lldb::LanguageType lang) { 34073e8c4d0SEnrico Granata this->ValueObject::SetPreferredDisplayLanguage(lang); 34173e8c4d0SEnrico Granata if (m_parent) 34273e8c4d0SEnrico Granata m_parent->SetPreferredDisplayLanguage(lang); 34373e8c4d0SEnrico Granata } 34473e8c4d0SEnrico Granata 345b9c1b51eSKate Stone lldb::LanguageType ValueObjectDynamicValue::GetPreferredDisplayLanguage() { 346b9c1b51eSKate Stone if (m_preferred_display_language == lldb::eLanguageTypeUnknown) { 34773e8c4d0SEnrico Granata if (m_parent) 34873e8c4d0SEnrico Granata return m_parent->GetPreferredDisplayLanguage(); 34973e8c4d0SEnrico Granata return lldb::eLanguageTypeUnknown; 350b9c1b51eSKate Stone } else 35173e8c4d0SEnrico Granata return m_preferred_display_language; 35273e8c4d0SEnrico Granata } 35373e8c4d0SEnrico Granata 354b9c1b51eSKate Stone bool ValueObjectDynamicValue::IsSyntheticChildrenGenerated() { 3553b207c66SEnrico Granata if (m_parent) 3563b207c66SEnrico Granata return m_parent->IsSyntheticChildrenGenerated(); 3573b207c66SEnrico Granata return false; 3583b207c66SEnrico Granata } 3593b207c66SEnrico Granata 360b9c1b51eSKate Stone void ValueObjectDynamicValue::SetSyntheticChildrenGenerated(bool b) { 3613b207c66SEnrico Granata if (m_parent) 3623b207c66SEnrico Granata m_parent->SetSyntheticChildrenGenerated(b); 3633b207c66SEnrico Granata this->ValueObject::SetSyntheticChildrenGenerated(b); 3643b207c66SEnrico Granata } 3653b207c66SEnrico Granata 366b9c1b51eSKate Stone bool ValueObjectDynamicValue::GetDeclaration(Declaration &decl) { 3679851b1f6SSiva Chandra if (m_parent) 3689851b1f6SSiva Chandra return m_parent->GetDeclaration(decl); 3699851b1f6SSiva Chandra 3709851b1f6SSiva Chandra return ValueObject::GetDeclaration(decl); 3719851b1f6SSiva Chandra } 372dc62ffd3SEnrico Granata 373b9c1b51eSKate Stone uint64_t ValueObjectDynamicValue::GetLanguageFlags() { 374dc62ffd3SEnrico Granata if (m_parent) 375dc62ffd3SEnrico Granata return m_parent->GetLanguageFlags(); 376dc62ffd3SEnrico Granata return this->ValueObject::GetLanguageFlags(); 377dc62ffd3SEnrico Granata } 378dc62ffd3SEnrico Granata 379b9c1b51eSKate Stone void ValueObjectDynamicValue::SetLanguageFlags(uint64_t flags) { 380dc62ffd3SEnrico Granata if (m_parent) 381dc62ffd3SEnrico Granata m_parent->SetLanguageFlags(flags); 382dc62ffd3SEnrico Granata else 383dc62ffd3SEnrico Granata this->ValueObject::SetLanguageFlags(flags); 384dc62ffd3SEnrico Granata } 385