summaryrefslogtreecommitdiffstats
path: root/lldb
diff options
context:
space:
mode:
Diffstat (limited to 'lldb')
-rw-r--r--lldb/include/lldb/API/SBValue.h47
-rw-r--r--lldb/include/lldb/Core/ValueObject.h2
-rw-r--r--lldb/include/lldb/Core/ValueObjectSyntheticFilter.h3
-rw-r--r--lldb/scripts/Python/interface/SBValue.i15
-rw-r--r--lldb/scripts/Python/python-wrapper.swig1
-rw-r--r--lldb/source/API/SBBlock.cpp7
-rw-r--r--lldb/source/API/SBFrame.cpp23
-rw-r--r--lldb/source/API/SBValue.cpp307
-rw-r--r--lldb/source/Core/FormatManager.cpp20
-rw-r--r--lldb/source/Core/ValueObject.cpp14
-rw-r--r--lldb/source/Core/ValueObjectDynamicValue.cpp25
-rw-r--r--lldb/source/Core/ValueObjectSyntheticFilter.cpp11
-rw-r--r--lldb/source/Interpreter/ScriptInterpreterPython.cpp37
-rw-r--r--lldb/test/functionalities/data-formatter/rdar-12437442/Makefile9
-rw-r--r--lldb/test/functionalities/data-formatter/rdar-12437442/TestRdar12437442.py91
-rw-r--r--lldb/test/functionalities/data-formatter/rdar-12437442/main.m25
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;
+}
+
OpenPOWER on IntegriCloud