diff options
Diffstat (limited to 'source/Core/ValueObject.cpp')
-rw-r--r-- | source/Core/ValueObject.cpp | 242 |
1 files changed, 135 insertions, 107 deletions
diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp index b72e5c3..8718b37 100644 --- a/source/Core/ValueObject.cpp +++ b/source/Core/ValueObject.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// -#include "lldb/lldb-python.h" - #include "lldb/Core/ValueObject.h" // C Includes @@ -43,7 +41,6 @@ #include "lldb/Host/Endian.h" #include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/ScriptInterpreterPython.h" #include "lldb/Symbol/ClangASTType.h" #include "lldb/Symbol/ClangASTContext.h" @@ -198,7 +195,7 @@ ValueObject::UpdateValueIfNeeded (bool update_format) bool first_update = IsChecksumEmpty(); - if (m_update_point.NeedsUpdating()) + if (NeedsUpdating()) { m_update_point.SetUpdated(); @@ -973,7 +970,7 @@ ValueObject::GetPointeeData (DataExtractor& data, ExecutionContext exe_ctx (GetExecutionContextRef()); - const uint64_t item_type_size = pointee_or_element_clang_type.GetByteSize(&exe_ctx); + const uint64_t item_type_size = pointee_or_element_clang_type.GetByteSize(exe_ctx.GetBestExecutionContextScope()); const uint64_t bytes = item_count * item_type_size; const uint64_t offset = item_idx * item_type_size; @@ -1049,10 +1046,13 @@ ValueObject::GetPointeeData (DataExtractor& data, break; case eAddressTypeHost: { - const uint64_t max_bytes = GetClangType().GetByteSize(&exe_ctx); + const uint64_t max_bytes = GetClangType().GetByteSize(exe_ctx.GetBestExecutionContextScope()); if (max_bytes > offset) { size_t bytes_read = std::min<uint64_t>(max_bytes - offset, bytes); + addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); + if (addr == LLDB_INVALID_ADDRESS) + break; heap_buf_ptr->CopyData((uint8_t*)(addr + offset), bytes_read); data.SetData(data_sp); return bytes_read; @@ -1821,13 +1821,19 @@ ValueObject::GetAddressOf (bool scalar_is_load_address, AddressType *address_typ case Value::eValueTypeLoadAddress: case Value::eValueTypeFileAddress: - case Value::eValueTypeHostAddress: { if(address_type) *address_type = m_value.GetValueAddressType (); return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); } break; + case Value::eValueTypeHostAddress: + { + if(address_type) + *address_type = m_value.GetValueAddressType (); + return LLDB_INVALID_ADDRESS; + } + break; } if (address_type) *address_type = eAddressTypeInvalid; @@ -2064,6 +2070,21 @@ ValueObject::IsPossibleDynamicType () } bool +ValueObject::IsRuntimeSupportValue () +{ + Process *process(GetProcessSP().get()); + if (process) + { + LanguageRuntime *runtime = process->GetLanguageRuntime(GetObjectRuntimeLanguage()); + if (!runtime) + runtime = process->GetObjCLanguageRuntime(); + if (runtime) + return runtime->IsRuntimeSupportValue(*this); + } + return false; +} + +bool ValueObject::IsObjCNil () { const uint32_t mask = eTypeIsObjC | eTypeIsPointer; @@ -2075,52 +2096,6 @@ ValueObject::IsObjCNil () return canReadValue && isZero; } -ValueObjectSP -ValueObject::GetSyntheticArrayMember (size_t index, bool can_create) -{ - const uint32_t type_info = GetTypeInfo (); - if (type_info & eTypeIsArray) - return GetSyntheticArrayMemberFromArray(index, can_create); - - if (type_info & eTypeIsPointer) - return GetSyntheticArrayMemberFromPointer(index, can_create); - - return ValueObjectSP(); - -} - -ValueObjectSP -ValueObject::GetSyntheticArrayMemberFromPointer (size_t index, bool can_create) -{ - ValueObjectSP synthetic_child_sp; - if (IsPointerType ()) - { - char index_str[64]; - snprintf(index_str, sizeof(index_str), "[%" PRIu64 "]", (uint64_t)index); - ConstString index_const_str(index_str); - // Check if we have already created a synthetic array member in this - // valid object. If we have we will re-use it. - synthetic_child_sp = GetSyntheticChild (index_const_str); - if (!synthetic_child_sp) - { - ValueObject *synthetic_child; - // We haven't made a synthetic array member for INDEX yet, so - // lets make one and cache it for any future reference. - synthetic_child = CreateChildAtIndex(0, true, index); - - // Cache the value if we got one back... - if (synthetic_child) - { - AddSyntheticChild(index_const_str, synthetic_child); - synthetic_child_sp = synthetic_child->GetSP(); - synthetic_child_sp->SetName(ConstString(index_str)); - synthetic_child_sp->m_is_array_item_for_pointer = true; - } - } - } - return synthetic_child_sp; -} - // This allows you to create an array member using and index // that doesn't not fall in the normal bounds of the array. // Many times structure can be defined as: @@ -2133,10 +2108,10 @@ ValueObject::GetSyntheticArrayMemberFromPointer (size_t index, bool can_create) // there are more items in "item_array". ValueObjectSP -ValueObject::GetSyntheticArrayMemberFromArray (size_t index, bool can_create) +ValueObject::GetSyntheticArrayMember (size_t index, bool can_create) { ValueObjectSP synthetic_child_sp; - if (IsArrayType ()) + if (IsPointerType () || IsArrayType()) { char index_str[64]; snprintf(index_str, sizeof(index_str), "[%" PRIu64 "]", (uint64_t)index); @@ -2150,7 +2125,7 @@ ValueObject::GetSyntheticArrayMemberFromArray (size_t index, bool can_create) // We haven't made a synthetic array member for INDEX yet, so // lets make one and cache it for any future reference. synthetic_child = CreateChildAtIndex(0, true, index); - + // Cache the value if we got one back... if (synthetic_child) { @@ -2229,7 +2204,7 @@ ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type ValueObjectChild *synthetic_child = new ValueObjectChild(*this, type, name_const_str, - type.GetByteSize(&exe_ctx), + type.GetByteSize(exe_ctx.GetBestExecutionContextScope()), offset, 0, 0, @@ -2272,7 +2247,7 @@ ValueObject::GetSyntheticBase (uint32_t offset, const ClangASTType& type, bool c ValueObjectChild *synthetic_child = new ValueObjectChild(*this, type, name_const_str, - type.GetByteSize(&exe_ctx), + type.GetByteSize(exe_ctx.GetBestExecutionContextScope()), offset, 0, 0, @@ -2320,7 +2295,7 @@ ValueObject::GetSyntheticExpressionPathChild(const char* expression, bool can_cr // lets make one and cache it for any future reference. synthetic_child_sp = GetValueForExpressionPath(expression, NULL, NULL, NULL, - GetValueForExpressionPathOptions().DontAllowSyntheticChildren()); + GetValueForExpressionPathOptions().SetSyntheticChildrenTraversal(GetValueForExpressionPathOptions::SyntheticChildrenTraversal::None)); // Cache the value if we got one back... if (synthetic_child_sp.get()) @@ -2851,19 +2826,43 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, *final_result = ValueObject::eExpressionPathEndResultTypePlain; return child_valobj_sp; } - else if (options.m_no_synthetic_children == false) // let's try with synthetic children + else { - if (root->IsSynthetic()) + switch (options.m_synthetic_children_traversal) { - *first_unparsed = expression_cstr; - *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchSyntheticChild; - *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; - return ValueObjectSP(); + case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::None: + break; + case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::FromSynthetic: + if (root->IsSynthetic()) + { + child_valobj_sp = root->GetNonSyntheticValue(); + if (child_valobj_sp.get()) + child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true); + } + break; + case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::ToSynthetic: + if (!root->IsSynthetic()) + { + child_valobj_sp = root->GetSyntheticValue(); + if (child_valobj_sp.get()) + child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true); + } + break; + case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::Both: + if (root->IsSynthetic()) + { + child_valobj_sp = root->GetNonSyntheticValue(); + if (child_valobj_sp.get()) + child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true); + } + else + { + child_valobj_sp = root->GetSyntheticValue(); + if (child_valobj_sp.get()) + child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true); + } + break; } - - child_valobj_sp = root->GetSyntheticValue(); - if (child_valobj_sp.get()) - child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true); } // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP, @@ -2894,19 +2893,43 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, *final_result = ValueObject::eExpressionPathEndResultTypePlain; continue; } - else if (options.m_no_synthetic_children == false) // let's try with synthetic children + else { - if (root->IsSynthetic()) + switch (options.m_synthetic_children_traversal) { - *first_unparsed = expression_cstr; - *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; - *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; - return ValueObjectSP(); + case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::None: + break; + case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::FromSynthetic: + if (root->IsSynthetic()) + { + child_valobj_sp = root->GetNonSyntheticValue(); + if (child_valobj_sp.get()) + child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true); + } + break; + case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::ToSynthetic: + if (!root->IsSynthetic()) + { + child_valobj_sp = root->GetSyntheticValue(); + if (child_valobj_sp.get()) + child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true); + } + break; + case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::Both: + if (root->IsSynthetic()) + { + child_valobj_sp = root->GetNonSyntheticValue(); + if (child_valobj_sp.get()) + child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true); + } + else + { + child_valobj_sp = root->GetSyntheticValue(); + if (child_valobj_sp.get()) + child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true); + } + break; } - - child_valobj_sp = root->GetSyntheticValue(true); - if (child_valobj_sp) - child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true); } // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP, @@ -2934,7 +2957,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, { if (!root_clang_type_info.Test(eTypeIsScalar)) // if this is not even a scalar... { - if (options.m_no_synthetic_children) // ...only chance left is synthetic + if (options.m_synthetic_children_traversal == GetValueForExpressionPathOptions::SyntheticChildrenTraversal::None) // ...only chance left is synthetic { *first_unparsed = expression_cstr; *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid; @@ -3009,7 +3032,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, { ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true); if (!child_valobj_sp) - child_valobj_sp = root->GetSyntheticArrayMemberFromArray(index, true); + child_valobj_sp = root->GetSyntheticArrayMember(index, true); if (!child_valobj_sp) if (root->HasSyntheticValue() && root->GetSyntheticValue()->GetNumChildren() > index) child_valobj_sp = root->GetSyntheticValue()->GetChildAtIndex(index, true); @@ -3053,12 +3076,13 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, if (root->GetClangType().GetMinimumLanguage() == eLanguageTypeObjC && pointee_clang_type_info.AllClear(eTypeIsPointer) && root->HasSyntheticValue() - && options.m_no_synthetic_children == false) + && (options.m_synthetic_children_traversal == GetValueForExpressionPathOptions::SyntheticChildrenTraversal::ToSynthetic || + options.m_synthetic_children_traversal == GetValueForExpressionPathOptions::SyntheticChildrenTraversal::Both)) { root = root->GetSyntheticValue()->GetChildAtIndex(index, true); } else - root = root->GetSyntheticArrayMemberFromPointer(index, true); + root = root->GetSyntheticArrayMember(index, true); if (!root.get()) { *first_unparsed = expression_cstr; @@ -3109,7 +3133,8 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, continue; } } - else if (options.m_no_synthetic_children == false) + else if (options.m_synthetic_children_traversal == GetValueForExpressionPathOptions::SyntheticChildrenTraversal::ToSynthetic || + options.m_synthetic_children_traversal == GetValueForExpressionPathOptions::SyntheticChildrenTraversal::Both) { if (root->HasSyntheticValue()) root = root->GetSyntheticValue(); @@ -3401,7 +3426,7 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, } else { - root = root->GetSyntheticArrayMemberFromPointer(index, true); + root = root->GetSyntheticArrayMember(index, true); if (!root.get()) { *first_unparsed = expression_cstr; @@ -3535,7 +3560,7 @@ void ValueObject::LogValueObject (Log *log) { if (log) - return LogValueObject (log, DumpValueObjectOptions::DefaultOptions()); + return LogValueObject (log, DumpValueObjectOptions(*this)); } void @@ -3553,7 +3578,7 @@ ValueObject::LogValueObject (Log *log, const DumpValueObjectOptions& options) void ValueObject::Dump (Stream &s) { - Dump (s, DumpValueObjectOptions::DefaultOptions()); + Dump (s, DumpValueObjectOptions(*this)); } void @@ -3766,7 +3791,7 @@ ValueObject::AddressOf (Error &error) const bool scalar_is_load_address = false; addr_t addr = GetAddressOf (scalar_is_load_address, &address_type); error.Clear(); - if (addr != LLDB_INVALID_ADDRESS) + if (addr != LLDB_INVALID_ADDRESS && address_type != eAddressTypeHost) { switch (address_type) { @@ -3780,7 +3805,6 @@ ValueObject::AddressOf (Error &error) case eAddressTypeFile: case eAddressTypeLoad: - case eAddressTypeHost: { ClangASTType clang_type = GetClangType(); if (clang_type) @@ -3797,6 +3821,8 @@ ValueObject::AddressOf (Error &error) } } break; + default: + break; } } else @@ -3923,9 +3949,8 @@ ValueObject::EvaluationPoint::~EvaluationPoint () // exe_scope will be set to the current execution context scope. bool -ValueObject::EvaluationPoint::SyncWithProcessState() +ValueObject::EvaluationPoint::SyncWithProcessState(bool accept_invalid_exe_ctx) { - // Start with the target, if it is NULL, then we're obviously not going to get any further: const bool thread_and_frame_only_if_stopped = true; ExecutionContext exe_ctx(m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped)); @@ -3968,30 +3993,33 @@ ValueObject::EvaluationPoint::SyncWithProcessState() // That way we'll be sure to return a valid exe_scope. // If we used to have a thread or a frame but can't find it anymore, then mark ourselves as invalid. - if (m_exe_ctx_ref.HasThreadRef()) + if (!accept_invalid_exe_ctx) { - ThreadSP thread_sp (m_exe_ctx_ref.GetThreadSP()); - if (thread_sp) + if (m_exe_ctx_ref.HasThreadRef()) { - if (m_exe_ctx_ref.HasFrameRef()) + ThreadSP thread_sp (m_exe_ctx_ref.GetThreadSP()); + if (thread_sp) { - StackFrameSP frame_sp (m_exe_ctx_ref.GetFrameSP()); - if (!frame_sp) + if (m_exe_ctx_ref.HasFrameRef()) { - // We used to have a frame, but now it is gone - SetInvalid(); - changed = was_valid; + StackFrameSP frame_sp (m_exe_ctx_ref.GetFrameSP()); + if (!frame_sp) + { + // We used to have a frame, but now it is gone + SetInvalid(); + changed = was_valid; + } } } + else + { + // We used to have a thread, but now it is gone + SetInvalid(); + changed = was_valid; + } } - else - { - // We used to have a thread, but now it is gone - SetInvalid(); - changed = was_valid; - } - } + return changed; } |