diff options
Diffstat (limited to 'lldb')
| -rw-r--r-- | lldb/include/lldb/API/SBValue.h | 47 | ||||
| -rw-r--r-- | lldb/include/lldb/Core/ValueObject.h | 2 | ||||
| -rw-r--r-- | lldb/include/lldb/Core/ValueObjectSyntheticFilter.h | 3 | ||||
| -rw-r--r-- | lldb/scripts/Python/interface/SBValue.i | 15 | ||||
| -rw-r--r-- | lldb/scripts/Python/python-wrapper.swig | 1 | ||||
| -rw-r--r-- | lldb/source/API/SBBlock.cpp | 7 | ||||
| -rw-r--r-- | lldb/source/API/SBFrame.cpp | 23 | ||||
| -rw-r--r-- | lldb/source/API/SBValue.cpp | 307 | ||||
| -rw-r--r-- | lldb/source/Core/FormatManager.cpp | 20 | ||||
| -rw-r--r-- | lldb/source/Core/ValueObject.cpp | 14 | ||||
| -rw-r--r-- | lldb/source/Core/ValueObjectDynamicValue.cpp | 25 | ||||
| -rw-r--r-- | lldb/source/Core/ValueObjectSyntheticFilter.cpp | 11 | ||||
| -rw-r--r-- | lldb/source/Interpreter/ScriptInterpreterPython.cpp | 37 | ||||
| -rw-r--r-- | lldb/test/functionalities/data-formatter/rdar-12437442/Makefile | 9 | ||||
| -rw-r--r-- | lldb/test/functionalities/data-formatter/rdar-12437442/TestRdar12437442.py | 91 | ||||
| -rw-r--r-- | lldb/test/functionalities/data-formatter/rdar-12437442/main.m | 25 |
16 files changed, 490 insertions, 147 deletions
diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h index 0502074d42d..2c02a7c938e 100644 --- a/lldb/include/lldb/API/SBValue.h +++ b/lldb/include/lldb/API/SBValue.h @@ -14,6 +14,9 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBType.h" +namespace { + class ValueImpl; +} namespace lldb { @@ -95,8 +98,23 @@ public: lldb::SBValue GetNonSyntheticValue (); + lldb::DynamicValueType + GetPreferDynamicValue (); + + void + SetPreferDynamicValue (lldb::DynamicValueType use_dynamic); + + bool + GetPreferSyntheticValue (); + + void + SetPreferSyntheticValue (bool use_synthetic); + bool - IsDynamic(); + IsDynamic (); + + bool + IsSynthetic (); const char * GetLocation (); @@ -380,29 +398,40 @@ public: // currently rely on being able to extract the SharedPointer out of an SBValue. if the implementation // is deferred to the .cpp file instead of being inlined here, the platform will fail to link // correctly. however, this is temporary till a better general solution is found. FIXME - lldb::ValueObjectSP& + lldb::ValueObjectSP get_sp() { - return m_opaque_sp; + return GetSP(); } protected: - friend class SBValueList; + friend class SBBlock; friend class SBFrame; friend class SBThread; + friend class SBValueList; lldb::ValueObjectSP GetSP () const; - // anyone who needs to set the value of the SP on this SBValue should rely on SetSP() exclusively - // since this function contains logic to "do the right thing" with regard to providing to the user - // a synthetic value when possible - in the future the same should automatically occur with - // dynamic values + // these calls do the right thing WRT adjusting their settings according to the target's preferences void SetSP (const lldb::ValueObjectSP &sp); + + void + SetSP (const lldb::ValueObjectSP &sp, bool use_synthetic); + + void + SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic); + + void + SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic, bool use_synthetic); private: - lldb::ValueObjectSP m_opaque_sp; + typedef STD_SHARED_PTR(ValueImpl) ValueImplSP; + ValueImplSP m_opaque_sp; + + void + SetSP (ValueImplSP impl_sp); }; } // namespace lldb diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h index 4c594b6f2a2..cbb62346661 100644 --- a/lldb/include/lldb/Core/ValueObject.h +++ b/lldb/include/lldb/Core/ValueObject.h @@ -1266,7 +1266,7 @@ protected: GetDataExtractor (); void - ResetCompleteTypeInfo (); + ClearDynamicTypeInformation (); //------------------------------------------------------------------ // Sublasses must implement the functions below. diff --git a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h index 02fd87a5a62..dbe9b83f309 100644 --- a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h +++ b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h @@ -142,6 +142,9 @@ private: friend class ValueObject; ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter); + void + CopyParentData (); + //------------------------------------------------------------------ // For ValueObject only //------------------------------------------------------------------ diff --git a/lldb/scripts/Python/interface/SBValue.i b/lldb/scripts/Python/interface/SBValue.i index 70c3d807453..00d9b567d83 100644 --- a/lldb/scripts/Python/interface/SBValue.i +++ b/lldb/scripts/Python/interface/SBValue.i @@ -129,9 +129,24 @@ public: lldb::SBValue GetNonSyntheticValue (); + + lldb::DynamicValueType + GetPreferDynamicValue (); + + void + SetPreferDynamicValue (lldb::DynamicValueType use_dynamic); + + bool + GetPreferSyntheticValue (); + + void + SetPreferSyntheticValue (bool use_synthetic); bool IsDynamic(); + + bool + IsSynthetic (); const char * GetLocation (); diff --git a/lldb/scripts/Python/python-wrapper.swig b/lldb/scripts/Python/python-wrapper.swig index 113447ee910..a3aeefb1f77 100644 --- a/lldb/scripts/Python/python-wrapper.swig +++ b/lldb/scripts/Python/python-wrapper.swig @@ -336,6 +336,7 @@ LLDBSwigPythonCreateSyntheticProvider // I do not want the SBValue to be deallocated when going out of scope because python // has ownership of it and will manage memory for this object by itself lldb::SBValue *valobj_sb = new lldb::SBValue(valobj_sp); + valobj_sb->SetPreferSyntheticValue(false); PyObject *ValObj_PyObj = SWIG_NewPointerObj((void *)valobj_sb, SWIGTYPE_p_lldb__SBValue, 0); diff --git a/lldb/source/API/SBBlock.cpp b/lldb/source/API/SBBlock.cpp index 8f325f472bc..91324ed8538 100644 --- a/lldb/source/API/SBBlock.cpp +++ b/lldb/source/API/SBBlock.cpp @@ -299,7 +299,12 @@ SBBlock::GetVariables (lldb::SBFrame& frame, if (add_variable) { if (frame_sp) - value_list.Append (frame_sp->GetValueObjectForFrameVariable (variable_sp, use_dynamic)); + { + lldb::ValueObjectSP valobj_sp(frame_sp->GetValueObjectForFrameVariable (variable_sp,eNoDynamicValues)); + SBValue value_sb; + value_sb.SetSP(valobj_sp, use_dynamic); + value_list.Append (value_sb); + } } } } diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp index 3fdadde1534..3f66623cb9f 100644 --- a/lldb/source/API/SBFrame.cpp +++ b/lldb/source/API/SBFrame.cpp @@ -549,12 +549,12 @@ SBFrame::GetValueForVariablePath (const char *var_path, DynamicValueType use_dyn { VariableSP var_sp; Error error; - ValueObjectSP value_sp (frame->GetValueForVariableExpressionPath (var_path, - use_dynamic, + ValueObjectSP value_sp (frame->GetValueForVariableExpressionPath (var_path, + eNoDynamicValues, StackFrame::eExpressionPathOptionCheckPtrVsMember | StackFrame::eExpressionPathOptionsAllowDirectIVarAccess, var_sp, error)); - sb_value.SetSP(value_sp); + sb_value.SetSP(value_sp, use_dynamic); } else { @@ -619,8 +619,8 @@ SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic) if (var_sp) { - value_sp = frame->GetValueObjectForFrameVariable(var_sp, use_dynamic); - sb_value.SetSP(value_sp); + value_sp = frame->GetValueObjectForFrameVariable(var_sp, eNoDynamicValues); + sb_value.SetSP(value_sp, use_dynamic); } } else @@ -697,8 +697,8 @@ SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueTy variable_sp->GetScope() == value_type && variable_sp->GetName() == const_name) { - value_sp = frame->GetValueObjectForFrameVariable (variable_sp, use_dynamic); - sb_value.SetSP (value_sp); + value_sp = frame->GetValueObjectForFrameVariable (variable_sp, eNoDynamicValues); + sb_value.SetSP (value_sp, use_dynamic); break; } } @@ -757,7 +757,7 @@ SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueTy if (expr_var_sp) { value_sp = expr_var_sp->GetValueObject(); - sb_value.SetSP (value_sp); + sb_value.SetSP (value_sp, use_dynamic); } } break; @@ -939,7 +939,10 @@ SBFrame::GetVariables (bool arguments, if (in_scope_only && !variable_sp->IsInScope(frame)) continue; - value_list.Append(frame->GetValueObjectForFrameVariable (variable_sp, use_dynamic)); + ValueObjectSP valobj_sp(frame->GetValueObjectForFrameVariable (variable_sp, eNoDynamicValues)); + SBValue value_sb; + value_sb.SetSP(valobj_sp,use_dynamic); + value_list.Append(value_sb); } } } @@ -1102,7 +1105,7 @@ SBFrame::EvaluateExpression (const char *expr, const SBExpressionOptions &option frame, expr_value_sp, options.ref()); - expr_result.SetSP(expr_value_sp); + expr_result.SetSP(expr_value_sp,options.GetFetchDynamicValue()); #ifdef LLDB_CONFIGURATION_DEBUG Host::SetCrashDescription (NULL); #endif diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index 5b38bc5e14a..318029fdc43 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -50,6 +50,98 @@ using namespace lldb; using namespace lldb_private; +namespace { + class ValueImpl + { + public: + ValueImpl () + { + } + + ValueImpl (lldb::ValueObjectSP opaque_sp, + lldb::DynamicValueType use_dynamic, + bool use_synthetic) : + m_opaque_sp(opaque_sp), + m_use_dynamic(use_dynamic), + m_use_synthetic(use_synthetic) + { + } + + ValueImpl (const ValueImpl& rhs) : + m_opaque_sp(rhs.m_opaque_sp), + m_use_dynamic(rhs.m_use_dynamic), + m_use_synthetic(rhs.m_use_synthetic) + { + } + + ValueImpl & + operator = (const ValueImpl &rhs) + { + if (this != &rhs) + { + m_opaque_sp = rhs.m_opaque_sp; + m_use_dynamic = rhs.m_use_dynamic; + m_use_synthetic = rhs.m_use_synthetic; + } + return *this; + } + + bool + IsValid () + { + return m_opaque_sp.get() != NULL; + } + + lldb::ValueObjectSP + GetRootSP () + { + return m_opaque_sp; + } + + lldb::ValueObjectSP + GetSP () + { + if (!m_opaque_sp) + return m_opaque_sp; + lldb::ValueObjectSP value_sp = m_opaque_sp; + if (value_sp->GetDynamicValue(m_use_dynamic)) + value_sp = value_sp->GetDynamicValue(m_use_dynamic); + if (value_sp->GetSyntheticValue(m_use_synthetic)) + value_sp = value_sp->GetSyntheticValue(m_use_synthetic); + return value_sp; + } + + void + SetUseDynamic (lldb::DynamicValueType use_dynamic) + { + m_use_dynamic = use_dynamic; + } + + void + SetUseSynthetic (bool use_synthetic) + { + m_use_synthetic = use_synthetic; + } + + lldb::DynamicValueType + GetUseDynamic () + { + return m_use_dynamic; + } + + bool + GetUseSynthetic () + { + return m_use_synthetic; + } + + private: + lldb::ValueObjectSP m_opaque_sp; + lldb::DynamicValueType m_use_dynamic; + bool m_use_synthetic; + }; +} + SBValue::SBValue () : m_opaque_sp () { @@ -57,12 +149,12 @@ SBValue::SBValue () : SBValue::SBValue (const lldb::ValueObjectSP &value_sp) { - SetSP(value_sp); // whenever setting the SP call SetSP() since it knows how to deal with synthetic values properly + SetSP(value_sp); } SBValue::SBValue(const SBValue &rhs) { - SetSP(rhs.m_opaque_sp); // whenever setting the SP call SetSP() since it knows how to deal with synthetic values properly + SetSP(rhs.m_opaque_sp); } SBValue & @@ -70,7 +162,7 @@ SBValue::operator = (const SBValue &rhs) { if (this != &rhs) { - SetSP(rhs.m_opaque_sp); // whenever setting the SP call SetSP() since it knows how to deal with synthetic values properly + SetSP(rhs.m_opaque_sp); } return *this; } @@ -85,7 +177,7 @@ SBValue::IsValid () // If this function ever changes to anything that does more than just // check if the opaque shared pointer is non NULL, then we need to update // all "if (m_opaque_sp)" code in this file. - return m_opaque_sp.get() != NULL; + return m_opaque_sp.get() != NULL && m_opaque_sp->GetRootSP().get() != NULL; } void @@ -683,7 +775,7 @@ SBValue::CreateChildAtOffset (const char *name, uint32_t offset, SBType type) TypeImplSP type_sp (type.GetSP()); if (type.IsValid()) { - sb_value = SBValue(value_sp->GetSyntheticChildAtOffset(offset, type_sp->GetClangASTType(), true)); + sb_value.SetSP(value_sp->GetSyntheticChildAtOffset(offset, type_sp->GetClangASTType(), true),GetPreferDynamicValue(),GetPreferSyntheticValue()); new_value_sp = sb_value.GetSP(); if (new_value_sp) new_value_sp->SetName(ConstString(name)); @@ -712,7 +804,7 @@ SBValue::Cast (SBType type) lldb::ValueObjectSP value_sp(GetSP()); TypeImplSP type_sp (type.GetSP()); if (value_sp && type_sp) - sb_value.SetSP(value_sp->Cast(type_sp->GetClangASTType())); + sb_value.SetSP(value_sp->Cast(type_sp->GetClangASTType()),GetPreferDynamicValue(),GetPreferSyntheticValue()); return sb_value; } @@ -904,20 +996,12 @@ SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool } } - if (child_sp) - { - if (use_dynamic != lldb::eNoDynamicValues) - { - lldb::ValueObjectSP dynamic_sp(child_sp->GetDynamicValue (use_dynamic)); - if (dynamic_sp) - child_sp = dynamic_sp; - } - } } } } - SBValue sb_value (child_sp); + SBValue sb_value; + sb_value.SetSP (child_sp, use_dynamic, GetPreferSyntheticValue()); if (log) log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", value_sp.get(), idx, value_sp.get()); @@ -993,20 +1077,12 @@ SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dy { Mutex::Locker api_locker (target_sp->GetAPIMutex()); child_sp = value_sp->GetChildMemberWithName (str_name, true); - if (use_dynamic_value != lldb::eNoDynamicValues) - { - if (child_sp) - { - lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic_value); - if (dynamic_sp) - child_sp = dynamic_sp; - } - } } } } - SBValue sb_value (child_sp); + SBValue sb_value; + sb_value.SetSP(child_sp, use_dynamic_value, GetPreferSyntheticValue()); if (log) log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", value_sp.get(), name, value_sp.get()); @@ -1017,74 +1093,87 @@ SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dy lldb::SBValue SBValue::GetDynamicValue (lldb::DynamicValueType use_dynamic) { - lldb::ValueObjectSP value_sp(GetSP()); - if (value_sp) + SBValue value_sb; + if (IsValid()) { - ProcessSP process_sp(value_sp->GetProcessSP()); - Process::StopLocker stop_locker; - if (process_sp && !stop_locker.TryLock(&process_sp->GetRunLock())) - { - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - if (log) - log->Printf ("SBValue(%p)::GetDynamicValue() => error: process is running", value_sp.get()); - } - else - { - TargetSP target_sp(value_sp->GetTargetSP()); - if (target_sp) - { - Mutex::Locker api_locker (target_sp->GetAPIMutex()); - return SBValue (value_sp->GetDynamicValue(use_dynamic)); - } - } + ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),use_dynamic,m_opaque_sp->GetUseSynthetic())); + value_sb.SetSP(proxy_sp); } - - return SBValue(); + return value_sb; } lldb::SBValue SBValue::GetStaticValue () { - lldb::ValueObjectSP value_sp(GetSP()); - if (value_sp) + SBValue value_sb; + if (IsValid()) { - TargetSP target_sp(value_sp->GetTargetSP()); - if (target_sp) - { - Mutex::Locker api_locker (target_sp->GetAPIMutex()); - return SBValue(value_sp->GetStaticValue()); - } + ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),eNoDynamicValues,m_opaque_sp->GetUseSynthetic())); + value_sb.SetSP(proxy_sp); } - - return SBValue(); + return value_sb; } lldb::SBValue SBValue::GetNonSyntheticValue () { - SBValue sb_value; + SBValue value_sb; + if (IsValid()) + { + ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),m_opaque_sp->GetUseDynamic(),false)); + value_sb.SetSP(proxy_sp); + } + return value_sb; +} + +lldb::DynamicValueType +SBValue::GetPreferDynamicValue () +{ + if (!IsValid()) + return eNoDynamicValues; + return m_opaque_sp->GetUseDynamic(); +} + +void +SBValue::SetPreferDynamicValue (lldb::DynamicValueType use_dynamic) +{ + if (IsValid()) + return m_opaque_sp->SetUseDynamic (use_dynamic); +} + +bool +SBValue::GetPreferSyntheticValue () +{ + if (!IsValid()) + return false; + return m_opaque_sp->GetUseSynthetic(); +} + +void +SBValue::SetPreferSyntheticValue (bool use_synthetic) +{ + if (IsValid()) + return m_opaque_sp->SetUseSynthetic (use_synthetic); +} + +bool +SBValue::IsDynamic() +{ lldb::ValueObjectSP value_sp(GetSP()); if (value_sp) { - if (value_sp->IsSynthetic()) + TargetSP target_sp(value_sp->GetTargetSP()); + if (target_sp) { - TargetSP target_sp(value_sp->GetTargetSP()); - if (target_sp) - { - Mutex::Locker api_locker (target_sp->GetAPIMutex()); - // deliberately breaking the rules here to optimize the case where we DO NOT want - // the synthetic value to be returned to the user - if we did not do this, we would have to tell - // the target to suppress the synthetic value, and then return the flag to its original value - if (value_sp->GetNonSyntheticValue()) - sb_value.m_opaque_sp = value_sp->GetNonSyntheticValue(); - } + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + return value_sp->IsDynamic(); } } - return sb_value; + return false; } bool -SBValue::IsDynamic() +SBValue::IsSynthetic () { lldb::ValueObjectSP value_sp(GetSP()); if (value_sp) @@ -1093,7 +1182,7 @@ SBValue::IsDynamic() if (target_sp) { Mutex::Locker api_locker (target_sp->GetAPIMutex()); - return value_sp->IsDynamic(); + return value_sp->IsSynthetic(); } } return false; @@ -1126,7 +1215,8 @@ SBValue::GetValueForExpressionPath(const char* expr_path) } } - SBValue sb_value (child_sp); + SBValue sb_value; + sb_value.SetSP(child_sp,GetPreferDynamicValue(),GetPreferSyntheticValue()); if (log) log->Printf ("SBValue(%p)::GetValueForExpressionPath (expr_path=\"%s\") => SBValue(%p)", value_sp.get(), expr_path, value_sp.get()); @@ -1457,17 +1547,77 @@ SBValue::GetFrame() lldb::ValueObjectSP SBValue::GetSP () const { - return m_opaque_sp; + if (!m_opaque_sp || !m_opaque_sp->IsValid()) + return ValueObjectSP(); + return m_opaque_sp->GetSP(); +} + +void +SBValue::SetSP (ValueImplSP impl_sp) +{ + m_opaque_sp = impl_sp; } void SBValue::SetSP (const lldb::ValueObjectSP &sp) { - m_opaque_sp = sp; - if (IsValid() && m_opaque_sp->HasSyntheticValue()) - m_opaque_sp = m_opaque_sp->GetSyntheticValue(); + if (sp) + { + lldb::TargetSP target_sp(sp->GetTargetSP()); + if (target_sp) + { + lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue(); + bool use_synthetic = target_sp->TargetProperties::GetEnableSyntheticValue(); + m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic)); + } + else + m_opaque_sp = ValueImplSP(new ValueImpl(sp,eNoDynamicValues,true)); + } + else + m_opaque_sp = ValueImplSP(new ValueImpl(sp,eNoDynamicValues,false)); } +void +SBValue::SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic) +{ + if (sp) + { + lldb::TargetSP target_sp(sp->GetTargetSP()); + if (target_sp) + { + bool use_synthetic = target_sp->TargetProperties::GetEnableSyntheticValue(); + SetSP (sp, use_dynamic, use_synthetic); + } + else + SetSP (sp, use_dynamic, true); + } + else + SetSP (sp, use_dynamic, false); +} + +void +SBValue::SetSP (const lldb::ValueObjectSP &sp, bool use_synthetic) +{ + if (sp) + { + lldb::TargetSP target_sp(sp->GetTargetSP()); + if (target_sp) + { + lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue(); + SetSP (sp, use_dynamic, use_synthetic); + } + else + SetSP (sp, eNoDynamicValues, use_synthetic); + } + else + SetSP (sp, eNoDynamicValues, use_synthetic); +} + +void +SBValue::SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic, bool use_synthetic) +{ + m_opaque_sp = ValueImplSP(new ValueImpl(sp,use_dynamic,use_synthetic)); +} bool SBValue::GetExpressionPath (SBStream &description) @@ -1549,7 +1699,7 @@ SBValue::AddressOf() { Mutex::Locker api_locker (target_sp->GetAPIMutex()); Error error; - sb_value = value_sp->AddressOf (error); + sb_value.SetSP(value_sp->AddressOf (error),GetPreferDynamicValue(), GetPreferSyntheticValue()); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -1805,4 +1955,3 @@ SBValue::WatchPointee (bool resolve_location, bool read, bool write, SBError &er sb_watchpoint = Dereference().Watch (resolve_location, read, write, error); return sb_watchpoint; } - diff --git a/lldb/source/Core/FormatManager.cpp b/lldb/source/Core/FormatManager.cpp index deb1169eb99..d80b46cba98 100644 --- a/lldb/source/Core/FormatManager.cpp +++ b/lldb/source/Core/FormatManager.cpp @@ -437,14 +437,20 @@ CategoryMap::GetSummaryFormat (ValueObject& valobj, uint32_t reason_why; ActiveCategoriesIterator begin, end = m_active_categories.end(); + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); + for (begin = m_active_categories.begin(); begin != end; begin++) { - lldb::TypeCategoryImplSP category = *begin; + lldb::TypeCategoryImplSP category_sp = *begin; lldb::TypeSummaryImplSP current_format; - if (!category->Get(valobj, current_format, use_dynamic, &reason_why)) + if (log) + log->Printf("[CategoryMap::GetSummaryFormat] Trying to use category %s\n", category_sp->GetName()); + if (!category_sp->Get(valobj, current_format, use_dynamic, &reason_why)) continue; return current_format; } + if (log) + log->Printf("[CategoryMap::GetSummaryFormat] nothing found - returning empty SP\n"); return lldb::TypeSummaryImplSP(); } @@ -554,14 +560,20 @@ CategoryMap::GetSyntheticChildren (ValueObject& valobj, ActiveCategoriesIterator begin, end = m_active_categories.end(); + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); + for (begin = m_active_categories.begin(); begin != end; begin++) { - lldb::TypeCategoryImplSP category = *begin; + lldb::TypeCategoryImplSP category_sp = *begin; lldb::SyntheticChildrenSP current_format; - if (!category->Get(valobj, current_format, use_dynamic, &reason_why)) + if (log) + log->Printf("[CategoryMap::GetSyntheticChildren] Trying to use category %s\n", category_sp->GetName()); + if (!category_sp->Get(valobj, current_format, use_dynamic, &reason_why)) continue; return current_format; } + if (log) + log->Printf("[CategoryMap::GetSyntheticChildren] nothing found - returning empty SP\n"); return lldb::SyntheticChildrenSP(); } #endif diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 0edc8be5ef0..b5b55c9e24b 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -276,10 +276,14 @@ ValueObject::SetNeedsUpdate () } void -ValueObject::ResetCompleteTypeInfo () +ValueObject::ClearDynamicTypeInformation () { m_did_calculate_complete_objc_class_type = false; + m_last_format_mgr_revision = 0; m_override_type = ClangASTType(); + SetValueFormat(lldb::TypeFormatImplSP()); + SetSummaryFormat(lldb::TypeSummaryImplSP()); + SetSyntheticChildren(lldb::SyntheticChildrenSP()); } ClangASTType @@ -2059,12 +2063,17 @@ ValueObject::CalculateSyntheticValue (bool use_synthetic) return; } + lldb::SyntheticChildrenSP current_synth_sp(m_synthetic_children_sp); + if (!UpdateFormatsIfNeeded(m_last_format_mgr_dynamic) && m_synthetic_value) return; if (m_synthetic_children_sp.get() == NULL) return; + if (current_synth_sp == m_synthetic_children_sp && m_synthetic_value) + return; + m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp); } @@ -2079,7 +2088,10 @@ ValueObject::CalculateDynamicValue (DynamicValueType use_dynamic) ExecutionContext exe_ctx (GetExecutionContextRef()); Process *process = exe_ctx.GetProcessPtr(); if (process && process->IsPossibleDynamicValue(*this)) + { + ClearDynamicTypeInformation (); m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic); + } } } diff --git a/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp index 2921e9d1bf9..dfddbd97c95 100644 --- a/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -290,29 +290,24 @@ ValueObjectDynamicValue::UpdateValue () lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); + bool has_changed_type = false; + if (!m_type_sp) { m_type_sp = dynamic_type_sp; - ResetCompleteTypeInfo (); - if (log) - log->Printf("[%s %p] now has a dynamic type %s", - GetName().GetCString(), - this, - GetTypeName().AsCString("")); + has_changed_type = true; } else if (dynamic_type_sp != m_type_sp) { // We are another type, we need to tear down our children... m_type_sp = dynamic_type_sp; SetValueDidChange (true); - ResetCompleteTypeInfo (); - if (log) - log->Printf("[%s %p] has a new dynamic type %s", - GetName().GetCString(), - this, - GetTypeName().AsCString("")); + has_changed_type = true; } + if (has_changed_type) + ClearDynamicTypeInformation (); + if (!m_address.IsValid() || m_address != dynamic_address) { if (m_address.IsValid()) @@ -341,6 +336,12 @@ ValueObjectDynamicValue::UpdateValue () // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us... m_value.SetValueType(Value::eValueTypeScalar); + if (has_changed_type && log) + log->Printf("[%s %p] has a new dynamic type %s", + GetName().GetCString(), + this, + GetTypeName().GetCString()); + if (m_address.IsValid() && m_type_sp) { // The variable value is in the Scalar value inside the m_value. diff --git a/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/lldb/source/Core/ValueObjectSyntheticFilter.cpp index 5f58b4d6940..284515ab592 100644 --- a/lldb/source/Core/ValueObjectSyntheticFilter.cpp +++ b/lldb/source/Core/ValueObjectSyntheticFilter.cpp @@ -67,6 +67,7 @@ ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::Synthetic #else SetName(parent.GetName()); #endif + CopyParentData(); CreateSynthFilter(); } @@ -157,6 +158,8 @@ ValueObjectSynthetic::UpdateValue () m_synthetic_children_count = UINT32_MAX; } + CopyParentData(); + SetValueIsValid(true); return true; } @@ -230,3 +233,11 @@ ValueObjectSynthetic::GetNonSyntheticValue () { return m_parent->GetSP(); } + +void +ValueObjectSynthetic::CopyParentData () +{ + m_value = m_parent->GetValue(); + ExecutionContext exe_ctx (GetExecutionContextRef()); + m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get()); +} diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp index efb884135fd..a6a94f4f55a 100644 --- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp +++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp @@ -197,24 +197,6 @@ ScriptInterpreterPython::Locker::~Locker() DoFreeLock(); } -class ForceDisableSyntheticChildren -{ -public: - ForceDisableSyntheticChildren (Target* target) : - m_target(target) - { - m_old_value = target->GetSuppressSyntheticValue(); - target->SetSuppressSyntheticValue(true); - } - ~ForceDisableSyntheticChildren () - { - m_target->SetSuppressSyntheticValue(m_old_value); - } -private: - Target* m_target; - bool m_old_value; -}; - ScriptInterpreterPython::PythonInputReaderManager::PythonInputReaderManager (ScriptInterpreterPython *interpreter) : m_interpreter(interpreter), m_debugger_sp(), @@ -1933,10 +1915,9 @@ ScriptInterpreterPython::CreateSyntheticScriptedProvider (std::string class_name { Locker py_lock(this); - ForceDisableSyntheticChildren no_synthetics(target); - ret_val = g_swig_synthetic_script (class_name, - python_interpreter->m_dictionary_name.c_str(), - valobj); + ret_val = g_swig_synthetic_script (class_name, + python_interpreter->m_dictionary_name.c_str(), + valobj); } return MakeScriptObject(ret_val); @@ -2275,8 +2256,7 @@ ScriptInterpreterPython::CalculateNumChildren (const lldb::ScriptInterpreterObje { Locker py_lock(this); - ForceDisableSyntheticChildren no_synthetics(GetCommandInterpreter().GetDebugger().GetSelectedTarget().get()); - ret_val = g_swig_calc_children (implementor); + ret_val = g_swig_calc_children (implementor); } return ret_val; @@ -2302,8 +2282,7 @@ ScriptInterpreterPython::GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& { Locker py_lock(this); - ForceDisableSyntheticChildren no_synthetics(GetCommandInterpreter().GetDebugger().GetSelectedTarget().get()); - child_ptr = g_swig_get_child_index (implementor,idx); + child_ptr = g_swig_get_child_index (implementor,idx); if (child_ptr != NULL && child_ptr != Py_None) { value_sb = (lldb::SBValue*)g_swig_cast_to_sbvalue(child_ptr); @@ -2339,8 +2318,7 @@ ScriptInterpreterPython::GetIndexOfChildWithName (const lldb::ScriptInterpreterO { Locker py_lock(this); - ForceDisableSyntheticChildren no_synthetics(GetCommandInterpreter().GetDebugger().GetSelectedTarget().get()); - ret_val = g_swig_get_index_child (implementor, child_name); + ret_val = g_swig_get_index_child (implementor, child_name); } return ret_val; @@ -2364,8 +2342,7 @@ ScriptInterpreterPython::UpdateSynthProviderInstance (const lldb::ScriptInterpre { Locker py_lock(this); - ForceDisableSyntheticChildren no_synthetics(GetCommandInterpreter().GetDebugger().GetSelectedTarget().get()); - ret_val = g_swig_update_provider (implementor); + ret_val = g_swig_update_provider (implementor); } return ret_val; diff --git a/lldb/test/functionalities/data-formatter/rdar-12437442/Makefile b/lldb/test/functionalities/data-formatter/rdar-12437442/Makefile new file mode 100644 index 00000000000..9f7fb1ca623 --- /dev/null +++ b/lldb/test/functionalities/data-formatter/rdar-12437442/Makefile @@ -0,0 +1,9 @@ +LEVEL = ../../../make + +OBJC_SOURCES := main.m + +CFLAGS_EXTRAS += -w + +include $(LEVEL)/Makefile.rules + +LDFLAGS += -framework Foundation diff --git a/lldb/test/functionalities/data-formatter/rdar-12437442/TestRdar12437442.py b/lldb/test/functionalities/data-formatter/rdar-12437442/TestRdar12437442.py new file mode 100644 index 00000000000..aa3c6b018e9 --- /dev/null +++ b/lldb/test/functionalities/data-formatter/rdar-12437442/TestRdar12437442.py @@ -0,0 +1,91 @@ +""" +Test lldb data formatter subsystem. +""" + +import os, time +import unittest2 +import lldb +from lldbtest import * +import datetime +import lldbutil + +class DataFormatterRdar12437442TestCase(TestBase): + + mydir = os.path.join("functionalities", "data-formatter", "rdar-12437442") + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @dsym_test + def test_rdar12437442_with_dsym_and_run_command(self): + """Test that we update SBValues correctly as dynamic types change.""" + self.buildDsym() + self.rdar12437442_tester() + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @dwarf_test + def test_rdar12437442_with_dwarf_and_run_command(self): + """Test that we update SBValues correctly as dynamic types change.""" + self.buildDwarf() + self.rdar12437442_tester() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break at. + self.line = line_number('main.m', '// Set break point at this line.') + + def rdar12437442_tester(self): + """Test that we update SBValues correctly as dynamic types change.""" + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # This is the function to remove the custom formats in order to have a + # clean slate for the next test case. + def cleanup(): + self.runCmd('type format clear', check=False) + self.runCmd('type summary clear', check=False) + self.runCmd('type synth clear', check=False) + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + self.runCmd("log enable lldb types -f types.log") + + # Now run the bulk of the test + id_x = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable("x") + id_x.SetPreferDynamicValue(lldb.eDynamicCanRunTarget) + id_x.SetPreferSyntheticValue(True) + + if self.TraceOn(): + self.runCmd("frame variable x -d run-target --ptr-depth 1") + + self.assertTrue(id_x.GetSummary() == '@"5 objects"', "array does not get correct summary") + + self.runCmd("next") + + id_x = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable("x") + id_x.SetPreferDynamicValue(lldb.eDynamicCanRunTarget) + id_x.SetPreferSyntheticValue(True) + + if self.TraceOn(): + self.runCmd("frame variable x -d run-target --ptr-depth 1") + + self.assertTrue(id_x.GetNumChildren() == 7, "dictionary does not have 7 children") + id_x.SetPreferSyntheticValue(False) + self.assertFalse(id_x.GetNumChildren() == 7, "dictionary still looks synthetic") + id_x.SetPreferSyntheticValue(True) + self.assertTrue(id_x.GetSummary() == "7 key/value pairs", "dictionary does not get correct summary") + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/functionalities/data-formatter/rdar-12437442/main.m b/lldb/test/functionalities/data-formatter/rdar-12437442/main.m new file mode 100644 index 00000000000..a7e94d29d46 --- /dev/null +++ b/lldb/test/functionalities/data-formatter/rdar-12437442/main.m @@ -0,0 +1,25 @@ +//===-- main.m ------------------------------------------------*- ObjC -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#import <Foundation/Foundation.h> + +int main (int argc, const char * argv[]) +{ + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + NSArray* foo = [NSArray arrayWithObjects:@1,@2,@3,@4,@5, nil]; + NSDictionary *bar = @{@1 : @"one",@2 : @"two", @3 : @"three", @4 : @"four", @5 : @"five", @6 : @"six", @7 : @"seven"}; + id x = foo; + x = bar; // Set break point at this line. + + [pool drain]; + return 0; +} + |

