summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/examples/summaries/cocoa/objc_runtime.py29
-rw-r--r--lldb/include/lldb/Core/ValueObject.h213
-rw-r--r--lldb/source/Commands/CommandObjectExpression.cpp29
-rw-r--r--lldb/source/Commands/CommandObjectFrame.cpp29
-rw-r--r--lldb/source/Commands/CommandObjectMemory.cpp28
-rw-r--r--lldb/source/Commands/CommandObjectTarget.cpp10
-rw-r--r--lldb/source/Core/ValueObject.cpp494
-rw-r--r--lldb/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py4
-rw-r--r--lldb/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py20
-rw-r--r--lldb/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py11
10 files changed, 408 insertions, 459 deletions
diff --git a/lldb/examples/summaries/cocoa/objc_runtime.py b/lldb/examples/summaries/cocoa/objc_runtime.py
index 02b9ebebe1f..4593306943b 100644
--- a/lldb/examples/summaries/cocoa/objc_runtime.py
+++ b/lldb/examples/summaries/cocoa/objc_runtime.py
@@ -327,17 +327,22 @@ class Class_Data_V1:
return self.instanceSize
# these are the only tagged pointers values for current versions
-# of OSX - this might change in future OS releases, and no-one is
+# of OSX - they might change in future OS releases, and no-one is
# advised to rely on these values, or any of the bitmasking formulas
# in TaggedClass_Data. doing otherwise is at your own risk
-TaggedClass_Values = {3 : 'NSNumber', \
- 5: 'NSManagedObject', \
- 6: 'NSDate', \
- 7: 'NSDateTS' };
+TaggedClass_Values_Lion = {1 : 'NSNumber', \
+ 5: 'NSManagedObject', \
+ 6: 'NSDate', \
+ 7: 'NSDateTS' };
+TaggedClass_Values_NMOS = {0: 'NSAtom', \
+ 3 : 'NSNumber', \
+ 4: 'NSDateTS', \
+ 5: 'NSManagedObject', \
+ 6: 'NSDate' };
class TaggedClass_Data:
def __init__(self,pointer,params):
- global TaggedClass_Values
+ global TaggedClass_Values_Lion,TaggedClass_Values_NMOS
self.valid = True
self.name = None
self.sys_params = params
@@ -346,10 +351,16 @@ class TaggedClass_Data:
self.class_bits = (pointer & 0xE) >> 1
self.i_bits = (pointer & 0xF0) >> 4
- if self.class_bits in TaggedClass_Values:
- self.name = TaggedClass_Values[self.class_bits]
+ if self.sys_params.is_lion:
+ if self.class_bits in TaggedClass_Values_Lion:
+ self.name = TaggedClass_Values_Lion[self.class_bits]
+ else:
+ self.valid = False
else:
- self.valid = False
+ if self.class_bits in TaggedClass_Values_NMOS:
+ self.name = TaggedClass_Values_NMOS[self.class_bits]
+ else:
+ self.valid = False
def is_valid(self):
diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h
index c4ba4b88646..f3542d04d93 100644
--- a/lldb/include/lldb/Core/ValueObject.h
+++ b/lldb/include/lldb/Core/ValueObject.h
@@ -205,7 +205,7 @@ public:
struct DumpValueObjectOptions
{
- uint32_t m_ptr_depth;
+ uint32_t m_max_ptr_depth;
uint32_t m_max_depth;
bool m_show_types;
bool m_show_location;
@@ -216,10 +216,12 @@ public:
bool m_flat_output;
uint32_t m_omit_summary_depth;
bool m_ignore_cap;
- lldb::Format m_override_format;
+ lldb::Format m_format;
+ lldb::TypeSummaryImplSP m_summary_sp;
+ std::string m_root_valobj_name;
DumpValueObjectOptions() :
- m_ptr_depth(0),
+ m_max_ptr_depth(0),
m_max_depth(UINT32_MAX),
m_show_types(false),
m_show_location(false),
@@ -230,7 +232,9 @@ public:
m_flat_output(false),
m_omit_summary_depth(0),
m_ignore_cap(false),
- m_override_format (lldb::eFormatDefault)
+ m_format (lldb::eFormatDefault),
+ m_summary_sp(),
+ m_root_valobj_name()
{}
static const DumpValueObjectOptions
@@ -241,10 +245,27 @@ public:
return g_default_options;
}
+ DumpValueObjectOptions (const DumpValueObjectOptions& rhs) :
+ m_max_ptr_depth(rhs.m_max_ptr_depth),
+ m_max_depth(rhs.m_max_depth),
+ m_show_types(rhs.m_show_types),
+ m_show_location(rhs.m_show_location),
+ m_use_objc(rhs.m_use_objc),
+ m_use_dynamic(rhs.m_use_dynamic),
+ m_use_synthetic(rhs.m_use_synthetic),
+ m_scope_already_checked(rhs.m_scope_already_checked),
+ m_flat_output(rhs.m_flat_output),
+ m_omit_summary_depth(rhs.m_omit_summary_depth),
+ m_ignore_cap(rhs.m_ignore_cap),
+ m_format(rhs.m_format),
+ m_summary_sp(rhs.m_summary_sp),
+ m_root_valobj_name(rhs.m_root_valobj_name)
+ {}
+
DumpValueObjectOptions&
- SetPointerDepth(uint32_t depth = 0)
+ SetMaximumPointerDepth(uint32_t depth = 0)
{
- m_ptr_depth = depth;
+ m_max_ptr_depth = depth;
return *this;
}
@@ -336,6 +357,30 @@ public:
return *this;
}
+ DumpValueObjectOptions&
+ SetFormat (lldb::Format format = lldb::eFormatDefault)
+ {
+ m_format = format;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetSummary (lldb::TypeSummaryImplSP summary = lldb::TypeSummaryImplSP())
+ {
+ m_summary_sp = summary;
+ return *this;
+ }
+
+ DumpValueObjectOptions&
+ SetRootValueObjectName (const char* name = NULL)
+ {
+ if (name)
+ m_root_valobj_name.assign(name);
+ else
+ m_root_valobj_name.clear();
+ return *this;
+ }
+
};
class EvaluationPoint
@@ -612,6 +657,10 @@ public:
virtual const char *
GetValueAsCString ();
+ virtual bool
+ GetValueAsCString (lldb::Format format,
+ std::string& destination);
+
virtual uint64_t
GetValueAsUnsigned (uint64_t fail_value);
@@ -668,6 +717,10 @@ public:
const char *
GetSummaryAsCString ();
+ bool
+ GetSummaryAsCString (TypeSummaryImpl* summary_ptr,
+ std::string& destination);
+
const char *
GetObjectDescription ();
@@ -805,106 +858,11 @@ public:
static void
DumpValueObject (Stream &s,
- ValueObject *valobj)
- {
-
- if (!valobj)
- return;
-
- ValueObject::DumpValueObject(s,
- valobj,
- DumpValueObjectOptions::DefaultOptions());
- }
-
- static void
- DumpValueObject (Stream &s,
- ValueObject *valobj,
- const char *root_valobj_name)
- {
-
- if (!valobj)
- return;
-
- ValueObject::DumpValueObject(s,
- valobj,
- root_valobj_name,
- DumpValueObjectOptions::DefaultOptions());
- }
-
+ ValueObject *valobj);
static void
DumpValueObject (Stream &s,
ValueObject *valobj,
- const DumpValueObjectOptions& options,
- lldb::Format format = lldb::eFormatDefault)
- {
-
- if (!valobj)
- return;
-
- ValueObject::DumpValueObject(s,
- valobj,
- valobj->GetName().AsCString(),
- options.m_ptr_depth,
- 0,
- options.m_max_depth,
- options.m_show_types,
- options.m_show_location,
- options.m_use_objc,
- options.m_use_dynamic,
- options.m_use_synthetic,
- options.m_scope_already_checked,
- options.m_flat_output,
- options.m_omit_summary_depth,
- options.m_ignore_cap,
- format);
- }
-
- static void
- DumpValueObject (Stream &s,
- ValueObject *valobj,
- const char *root_valobj_name,
- const DumpValueObjectOptions& options,
- lldb::Format format = lldb::eFormatDefault)
- {
-
- if (!valobj)
- return;
-
- ValueObject::DumpValueObject(s,
- valobj,
- root_valobj_name,
- options.m_ptr_depth,
- 0,
- options.m_max_depth,
- options.m_show_types,
- options.m_show_location,
- options.m_use_objc,
- options.m_use_dynamic,
- options.m_use_synthetic,
- options.m_scope_already_checked,
- options.m_flat_output,
- options.m_omit_summary_depth,
- options.m_ignore_cap,
- format);
- }
-
- static void
- DumpValueObject (Stream &s,
- ValueObject *valobj,
- const char *root_valobj_name,
- uint32_t ptr_depth,
- uint32_t curr_depth,
- uint32_t max_depth,
- bool show_types,
- bool show_location,
- bool use_objc,
- lldb::DynamicValueType use_dynamic,
- bool use_synthetic,
- bool scope_already_checked,
- bool flat_output,
- uint32_t omit_summary_depth,
- bool ignore_cap,
- lldb::Format format = lldb::eFormatDefault);
+ const DumpValueObjectOptions& options);
// returns true if this is a char* or a char[]
// if it is a char* and check_pointer is true,
@@ -955,47 +913,17 @@ public:
m_format = format;
}
- void
- SetCustomSummaryFormat(lldb::TypeSummaryImplSP format)
- {
- m_forced_summary_format = format;
- m_user_id_of_forced_summary = m_update_point.GetModID();
- m_summary_str.clear();
- m_is_getting_summary = false;
- }
-
- lldb::TypeSummaryImplSP
- GetCustomSummaryFormat()
- {
- return m_forced_summary_format;
- }
-
- void
- ClearCustomSummaryFormat()
- {
- m_forced_summary_format.reset();
- m_summary_str.clear();
- }
-
- bool
- HasCustomSummaryFormat()
- {
- return (m_forced_summary_format.get());
- }
-
lldb::TypeSummaryImplSP
GetSummaryFormat()
{
UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
- if (HasCustomSummaryFormat())
- return m_forced_summary_format;
- return m_last_summary_format;
+ return m_type_summary_sp;
}
void
SetSummaryFormat(lldb::TypeSummaryImplSP format)
{
- m_last_summary_format = format;
+ m_type_summary_sp = format;
m_summary_str.clear();
m_is_getting_summary = false;
}
@@ -1003,7 +931,7 @@ public:
void
SetValueFormat(lldb::TypeFormatImplSP format)
{
- m_last_value_format = format;
+ m_type_format_sp = format;
m_value_str.clear();
}
@@ -1011,13 +939,13 @@ public:
GetValueFormat()
{
UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
- return m_last_value_format;
+ return m_type_format_sp;
}
void
SetSyntheticChildren(lldb::SyntheticChildrenSP synth)
{
- m_last_synthetic_filter = synth;
+ m_synthetic_children_sp = synth;
m_synthetic_value = NULL;
}
@@ -1025,7 +953,7 @@ public:
GetSyntheticChildren()
{
UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
- return m_last_synthetic_filter;
+ return m_synthetic_children_sp;
}
// Use GetParent for display purposes, but if you want to tell the parent to update itself
@@ -1105,10 +1033,9 @@ protected:
lldb::Format m_format;
uint32_t m_last_format_mgr_revision;
lldb::DynamicValueType m_last_format_mgr_dynamic;
- lldb::TypeSummaryImplSP m_last_summary_format;
- lldb::TypeSummaryImplSP m_forced_summary_format;
- lldb::TypeFormatImplSP m_last_value_format;
- lldb::SyntheticChildrenSP m_last_synthetic_filter;
+ lldb::TypeSummaryImplSP m_type_summary_sp;
+ lldb::TypeFormatImplSP m_type_format_sp;
+ lldb::SyntheticChildrenSP m_synthetic_children_sp;
ProcessModID m_user_id_of_forced_summary;
AddressType m_address_type_of_ptr_or_ref_children;
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index 262d0b58dcf..b8c3c92f438 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -354,22 +354,23 @@ CommandObjectExpression::EvaluateExpression
if (format != eFormatDefault)
result_valobj_sp->SetFormat (format);
+ ValueObject::DumpValueObjectOptions options;
+ options.SetMaximumPointerDepth(0)
+ .SetMaximumDepth(UINT32_MAX)
+ .SetShowLocation(false)
+ .SetShowTypes(m_command_options.show_types)
+ .SetUseObjectiveC(m_command_options.print_object)
+ .SetUseDynamicType(use_dynamic)
+ .SetScopeChecked(true)
+ .SetFlatOutput(false)
+ .SetUseSyntheticValue(lldb::eUseSyntheticFilter)
+ .SetOmitSummaryDepth(0)
+ .SetIgnoreCap(false)
+ .SetFormat(format)
+ .SetSummary();
ValueObject::DumpValueObject (*(output_stream),
result_valobj_sp.get(), // Variable object to dump
- result_valobj_sp->GetName().GetCString(),// Root object name
- 0, // Pointer depth to traverse (zero means stop at pointers)
- 0, // Current depth, this is the top most, so zero...
- UINT32_MAX, // Max depth to go when dumping concrete types, dump everything...
- m_command_options.show_types, // Show types when dumping?
- false, // Show locations of variables, no since this is a host address which we don't care to see
- m_command_options.print_object, // Print the objective C object?
- use_dynamic,
- true, // Use synthetic children if available
- true, // Scope is already checked. Const results are always in scope.
- false, // Don't flatten output
- 0, // Always use summaries (you might want an option --no-summary like there is for frame variable)
- false, // Do not show more children than settings allow
- format); // Format override
+ options);
if (result)
result->SetStatus (eReturnStatusSuccessFinishResult);
}
diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp
index 409cb6dd136..a57a835de87 100644
--- a/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/lldb/source/Commands/CommandObjectFrame.cpp
@@ -408,7 +408,7 @@ public:
ValueObject::DumpValueObjectOptions options;
- options.SetPointerDepth(m_varobj_options.ptr_depth)
+ options.SetMaximumPointerDepth(m_varobj_options.ptr_depth)
.SetMaximumDepth(m_varobj_options.max_depth)
.SetShowTypes(m_varobj_options.show_types)
.SetShowLocation(m_varobj_options.show_location)
@@ -417,7 +417,8 @@ public:
.SetUseSyntheticValue((lldb::SyntheticValueType)m_varobj_options.use_synth)
.SetFlatOutput(m_varobj_options.flat_output)
.SetOmitSummaryDepth(m_varobj_options.no_summary_depth)
- .SetIgnoreCap(m_varobj_options.ignore_cap);
+ .SetIgnoreCap(m_varobj_options.ignore_cap)
+ .SetSummary(summary_format_sp);
if (m_varobj_options.be_raw)
options.SetRawDisplay(true);
@@ -425,6 +426,7 @@ public:
if (variable_list)
{
const Format format = m_option_format.GetFormat();
+ options.SetFormat(format);
if (command.GetArgumentCount() > 0)
{
@@ -466,12 +468,9 @@ public:
if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
s.PutCString (": ");
}
- if (summary_format_sp)
- valobj_sp->SetCustomSummaryFormat(summary_format_sp);
ValueObject::DumpValueObject (result.GetOutputStream(),
valobj_sp.get(),
- options,
- format);
+ options);
}
}
}
@@ -509,15 +508,14 @@ public:
var_sp->GetDeclaration ().DumpStopContext (&s, false);
s.PutCString (": ");
}
- if (summary_format_sp)
- valobj_sp->SetCustomSummaryFormat(summary_format_sp);
+
+ options.SetFormat(format);
Stream &output_stream = result.GetOutputStream();
+ options.SetRootValueObjectName(valobj_sp->GetParent() ? name_cstr : NULL);
ValueObject::DumpValueObject (output_stream,
valobj_sp.get(),
- valobj_sp->GetParent() ? name_cstr : NULL,
- options,
- format);
+ options);
}
else
{
@@ -590,13 +588,12 @@ public:
var_sp->GetDeclaration ().DumpStopContext (&s, false);
s.PutCString (": ");
}
- if (summary_format_sp)
- valobj_sp->SetCustomSummaryFormat(summary_format_sp);
+
+ options.SetFormat(format);
+ options.SetRootValueObjectName(name_cstr);
ValueObject::DumpValueObject (result.GetOutputStream(),
valobj_sp.get(),
- name_cstr,
- options,
- format);
+ options);
}
}
}
diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp
index 402809443a8..87c0d198716 100644
--- a/lldb/source/Commands/CommandObjectMemory.cpp
+++ b/lldb/source/Commands/CommandObjectMemory.cpp
@@ -691,22 +691,22 @@ public:
bool scope_already_checked = true;
+ ValueObject::DumpValueObjectOptions options;
+ options.SetMaximumPointerDepth(m_varobj_options.ptr_depth)
+ .SetMaximumDepth(m_varobj_options.max_depth)
+ .SetShowLocation(m_varobj_options.show_location)
+ .SetShowTypes(m_varobj_options.show_types)
+ .SetUseObjectiveC(m_varobj_options.use_objc)
+ .SetScopeChecked(scope_already_checked)
+ .SetFlatOutput(m_varobj_options.flat_output)
+ .SetUseSyntheticValue(m_varobj_options.be_raw ? lldb::eNoSyntheticFilter : (m_varobj_options.use_synth ? lldb::eUseSyntheticFilter : lldb::eNoSyntheticFilter) )
+ .SetOmitSummaryDepth(m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth)
+ .SetIgnoreCap(m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap)
+ .SetFormat(format)
+ .SetSummary();
ValueObject::DumpValueObject (*output_stream,
valobj_sp.get(),
- NULL,
- m_varobj_options.ptr_depth,
- 0,
- m_varobj_options.max_depth,
- m_varobj_options.show_types,
- m_varobj_options.show_location,
- m_varobj_options.use_objc,
- m_varobj_options.use_dynamic,
- m_varobj_options.be_raw ? false : m_varobj_options.use_synth,
- scope_already_checked,
- m_varobj_options.flat_output,
- m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth,
- m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap,
- format);
+ options);
}
else
{
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index e396a8b27e3..1b74e08c0ca 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -594,7 +594,7 @@ public:
{
ValueObject::DumpValueObjectOptions options;
- options.SetPointerDepth(m_varobj_options.ptr_depth)
+ options.SetMaximumPointerDepth(m_varobj_options.ptr_depth)
.SetMaximumDepth(m_varobj_options.max_depth)
.SetShowTypes(m_varobj_options.show_types)
.SetShowLocation(m_varobj_options.show_location)
@@ -641,13 +641,13 @@ public:
const Format format = m_option_format.GetFormat();
if (format != eFormatDefault)
- valobj_sp->SetFormat (format);
+ options.SetFormat(format);
+
+ options.SetRootValueObjectName(root_name);
ValueObject::DumpValueObject (s,
valobj_sp.get(),
- root_name,
- options,
- format);
+ options);
}
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 3986246e55d..bb6e3905a21 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -80,10 +80,9 @@ ValueObject::ValueObject (ValueObject &parent) :
m_format (eFormatDefault),
m_last_format_mgr_revision(0),
m_last_format_mgr_dynamic(parent.m_last_format_mgr_dynamic),
- m_last_summary_format(),
- m_forced_summary_format(),
- m_last_value_format(),
- m_last_synthetic_filter(),
+ m_type_summary_sp(),
+ m_type_format_sp(),
+ m_synthetic_children_sp(),
m_user_id_of_forced_summary(),
m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid),
m_value_is_valid (false),
@@ -127,10 +126,9 @@ ValueObject::ValueObject (ExecutionContextScope *exe_scope,
m_format (eFormatDefault),
m_last_format_mgr_revision(0),
m_last_format_mgr_dynamic(eNoDynamicValues),
- m_last_summary_format(),
- m_forced_summary_format(),
- m_last_value_format(),
- m_last_synthetic_filter(),
+ m_type_summary_sp(),
+ m_type_format_sp(),
+ m_synthetic_children_sp(),
m_user_id_of_forced_summary(),
m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type),
m_value_is_valid (false),
@@ -240,13 +238,6 @@ ValueObject::UpdateFormatsIfNeeded(DynamicValueType use_dynamic)
bool any_change = false;
- if (HasCustomSummaryFormat() && m_update_point.GetModID() != m_user_id_of_forced_summary)
- {
- ClearCustomSummaryFormat();
-
- any_change = true;
- }
-
if ( (m_last_format_mgr_revision != DataVisualization::GetCurrentRevision()) ||
m_last_format_mgr_dynamic != use_dynamic)
{
@@ -656,87 +647,94 @@ ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int3
return valobj;
}
-const char *
-ValueObject::GetSummaryAsCString ()
+bool
+ValueObject::GetSummaryAsCString (TypeSummaryImpl* summary_ptr,
+ std::string& destination)
{
- // Watch for recursion which can happen with summary strings and other
- // variable formatting options.
- if (m_is_getting_summary)
- return NULL;
+ destination.clear();
+
+ // ideally we would like to bail out if passing NULL, but if we do so
+ // we end up not providing the summary for function pointers anymore
+ if (/*summary_ptr == NULL ||*/ m_is_getting_summary)
+ return false;
m_is_getting_summary = true;
-
- if (UpdateValueIfNeeded (true))
- {
- if (m_summary_str.empty())
+ if (UpdateValueIfNeeded (false))
+ {
+ if (summary_ptr)
{
- TypeSummaryImpl *summary_format = GetSummaryFormat().get();
-
- if (summary_format)
- {
- summary_format->FormatObject(GetSP(),
- m_summary_str);
- }
- else
+ summary_ptr->FormatObject(GetSP(), destination);
+ }
+ else
+ {
+ clang_type_t clang_type = GetClangType();
+
+ // Do some default printout for function pointers
+ if (clang_type)
{
- clang_type_t clang_type = GetClangType();
-
- // Do some default printout for function pointers
- if (clang_type)
+ StreamString sstr;
+ clang_type_t elem_or_pointee_clang_type;
+ const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
+ GetClangAST(),
+ &elem_or_pointee_clang_type));
+
+ if (ClangASTContext::IsFunctionPointerType (clang_type))
{
- StreamString sstr;
- clang_type_t elem_or_pointee_clang_type;
- const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
- GetClangAST(),
- &elem_or_pointee_clang_type));
-
- if (ClangASTContext::IsFunctionPointerType (clang_type))
+ AddressType func_ptr_address_type = eAddressTypeInvalid;
+ addr_t func_ptr_address = GetPointerValue (&func_ptr_address_type);
+ if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
{
- AddressType func_ptr_address_type = eAddressTypeInvalid;
- addr_t func_ptr_address = GetPointerValue (&func_ptr_address_type);
- if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
+ switch (func_ptr_address_type)
{
- switch (func_ptr_address_type)
- {
case eAddressTypeInvalid:
case eAddressTypeFile:
break;
-
+
case eAddressTypeLoad:
+ {
+ ExecutionContext exe_ctx (GetExecutionContextRef());
+
+ Address so_addr;
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target && target->GetSectionLoadList().IsEmpty() == false)
{
- ExecutionContext exe_ctx (GetExecutionContextRef());
-
- Address so_addr;
- Target *target = exe_ctx.GetTargetPtr();
- if (target && target->GetSectionLoadList().IsEmpty() == false)
+ if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
{
- if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
- {
- so_addr.Dump (&sstr,
- exe_ctx.GetBestExecutionContextScope(),
- Address::DumpStyleResolvedDescription,
- Address::DumpStyleSectionNameOffset);
- }
+ so_addr.Dump (&sstr,
+ exe_ctx.GetBestExecutionContextScope(),
+ Address::DumpStyleResolvedDescription,
+ Address::DumpStyleSectionNameOffset);
}
}
+ }
break;
-
+
case eAddressTypeHost:
break;
- }
- }
- if (sstr.GetSize() > 0)
- {
- m_summary_str.assign (1, '(');
- m_summary_str.append (sstr.GetData(), sstr.GetSize());
- m_summary_str.append (1, ')');
}
}
+ if (sstr.GetSize() > 0)
+ {
+ destination.assign (1, '(');
+ destination.append (sstr.GetData(), sstr.GetSize());
+ destination.append (1, ')');
+ }
}
}
}
}
m_is_getting_summary = false;
+ return !destination.empty();
+}
+
+const char *
+ValueObject::GetSummaryAsCString ()
+{
+ if (UpdateValueIfNeeded(true) && m_summary_str.empty())
+ {
+ GetSummaryAsCString(GetSummaryFormat().get(),
+ m_summary_str);
+ }
if (m_summary_str.empty())
return NULL;
return m_summary_str.c_str();
@@ -1100,110 +1098,113 @@ ValueObject::GetObjectDescription ()
return m_object_desc_str.c_str();
}
+bool
+ValueObject::GetValueAsCString (lldb::Format format,
+ std::string& destination)
+{
+ if (ClangASTContext::IsAggregateType (GetClangType()) == false &&
+ UpdateValueIfNeeded(false))
+ {
+ const Value::ContextType context_type = m_value.GetContextType();
+
+ switch (context_type)
+ {
+ case Value::eContextTypeClangType:
+ case Value::eContextTypeLLDBType:
+ case Value::eContextTypeVariable:
+ {
+ clang_type_t clang_type = GetClangType ();
+ if (clang_type)
+ {
+ StreamString sstr;
+ ExecutionContext exe_ctx (GetExecutionContextRef());
+ ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
+ clang_type, // The clang type to display
+ &sstr,
+ format, // Format to display this type with
+ m_data, // Data to extract from
+ 0, // Byte offset into "m_data"
+ GetByteSize(), // Byte size of item in "m_data"
+ GetBitfieldBitSize(), // Bitfield bit size
+ GetBitfieldBitOffset(), // Bitfield bit offset
+ exe_ctx.GetBestExecutionContextScope());
+ // Don't set the m_error to anything here otherwise
+ // we won't be able to re-format as anything else. The
+ // code for ClangASTType::DumpTypeValue() should always
+ // return something, even if that something contains
+ // an error messsage. "m_error" is used to detect errors
+ // when reading the valid object, not for formatting errors.
+ if (sstr.GetString().empty())
+ destination.clear();
+ else
+ destination.swap(sstr.GetString());
+ }
+ }
+ break;
+
+ case Value::eContextTypeRegisterInfo:
+ {
+ const RegisterInfo *reg_info = m_value.GetRegisterInfo();
+ if (reg_info)
+ {
+ ExecutionContext exe_ctx (GetExecutionContextRef());
+
+ StreamString reg_sstr;
+ m_data.Dump (&reg_sstr,
+ 0,
+ format,
+ reg_info->byte_size,
+ 1,
+ UINT32_MAX,
+ LLDB_INVALID_ADDRESS,
+ 0,
+ 0,
+ exe_ctx.GetBestExecutionContextScope());
+ destination.swap(reg_sstr.GetString());
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return !destination.empty();
+ }
+ else
+ return false;
+}
+
const char *
ValueObject::GetValueAsCString ()
{
- // If our byte size is zero this is an aggregate type that has children
- if (ClangASTContext::IsAggregateType (GetClangType()) == false)
+ if (UpdateValueIfNeeded(true) && m_value_str.empty())
{
- if (UpdateValueIfNeeded(true))
+ lldb::Format my_format = GetFormat();
+ if (m_format == lldb::eFormatDefault)
{
- if (m_value_str.empty())
+ if (m_type_format_sp)
+ my_format = m_type_format_sp->GetFormat();
+ else
{
- const Value::ContextType context_type = m_value.GetContextType();
-
- switch (context_type)
+ if (m_is_bitfield_for_scalar)
+ my_format = eFormatUnsigned;
+ else
{
- case Value::eContextTypeClangType:
- case Value::eContextTypeLLDBType:
- case Value::eContextTypeVariable:
- {
- lldb::Format my_format = GetFormat();
- clang_type_t clang_type = GetClangType ();
- if (clang_type)
- {
- if (m_format == lldb::eFormatDefault)
- {
- if (m_last_value_format)
- my_format = m_last_value_format->GetFormat();
- else
- {
- if (m_is_bitfield_for_scalar)
- my_format = eFormatUnsigned;
- else
- my_format = ClangASTType::GetFormat(clang_type);
- }
- }
- StreamString sstr;
- ExecutionContext exe_ctx (GetExecutionContextRef());
- ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
- clang_type, // The clang type to display
- &sstr,
- my_format, // Format to display this type with
- m_data, // Data to extract from
- 0, // Byte offset into "m_data"
- GetByteSize(), // Byte size of item in "m_data"
- GetBitfieldBitSize(), // Bitfield bit size
- GetBitfieldBitOffset(), // Bitfield bit offset
- exe_ctx.GetBestExecutionContextScope());
- // Don't set the m_error to anything here otherwise
- // we won't be able to re-format as anything else. The
- // code for ClangASTType::DumpTypeValue() should always
- // return something, even if that something contains
- // an error messsage. "m_error" is used to detect errors
- // when reading the valid object, not for formatting errors.
- if (sstr.GetString().empty())
- m_value_str.clear();
- else
- m_value_str.swap(sstr.GetString());
- }
- }
- break;
-
- case Value::eContextTypeRegisterInfo:
+ if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
{
const RegisterInfo *reg_info = m_value.GetRegisterInfo();
if (reg_info)
- {
- lldb::Format my_format = GetFormat();
- if (m_format == lldb::eFormatDefault)
- {
- if (m_last_value_format)
- my_format = m_last_value_format->GetFormat();
- else
- my_format = reg_info->format;
- }
-
- ExecutionContext exe_ctx (GetExecutionContextRef());
-
- StreamString reg_sstr;
- m_data.Dump (&reg_sstr,
- 0,
- my_format,
- reg_info->byte_size,
- 1,
- UINT32_MAX,
- LLDB_INVALID_ADDRESS,
- 0,
- 0,
- exe_ctx.GetBestExecutionContextScope());
- m_value_str.swap(reg_sstr.GetString());
- }
+ my_format = reg_info->format;
+ }
+ else
+ {
+ clang_type_t clang_type = GetClangType ();
+ my_format = ClangASTType::GetFormat(clang_type);
}
- break;
-
- default:
- break;
}
}
-
- if (!m_value_did_change && m_old_value_valid)
- {
- // The value was gotten successfully, so we consider the
- // value as changed if the value string differs
- SetValueDidChange (m_old_value_str != m_value_str);
- }
}
+ GetValueAsCString(my_format, m_value_str);
}
if (m_value_str.empty())
return NULL;
@@ -1977,11 +1978,11 @@ ValueObject::CalculateSyntheticValue (SyntheticValueType use_synthetic)
UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
- if (m_last_synthetic_filter.get() == NULL)
+ if (m_synthetic_children_sp.get() == NULL)
return;
if (m_synthetic_value == NULL)
- m_synthetic_value = new ValueObjectSynthetic(*this, m_last_synthetic_filter);
+ m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp);
}
@@ -2063,7 +2064,7 @@ ValueObject::GetSyntheticValue (SyntheticValueType use_synthetic)
UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
- if (m_last_synthetic_filter.get() == NULL)
+ if (m_synthetic_children_sp.get() == NULL)
return GetSP();
CalculateSyntheticValue(use_synthetic);
@@ -2079,7 +2080,7 @@ ValueObject::HasSyntheticValue()
{
UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
- if (m_last_synthetic_filter.get() == NULL)
+ if (m_synthetic_children_sp.get() == NULL)
return false;
CalculateSyntheticValue(eUseSyntheticFilter);
@@ -3066,34 +3067,25 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
}
}
-void
-ValueObject::DumpValueObject
-(
- Stream &s,
- ValueObject *valobj,
- const char *root_valobj_name,
- uint32_t ptr_depth,
- uint32_t curr_depth,
- uint32_t max_depth,
- bool show_types,
- bool show_location,
- bool use_objc,
- DynamicValueType use_dynamic,
- bool use_synth,
- bool scope_already_checked,
- bool flat_output,
- uint32_t omit_summary_depth,
- bool ignore_cap,
- Format format_override // Normally the format is in the valobj, but we might want to override this
-)
+static void
+DumpValueObject_Impl (Stream &s,
+ ValueObject *valobj,
+ const ValueObject::DumpValueObjectOptions& options,
+ uint32_t ptr_depth,
+ uint32_t curr_depth)
{
if (valobj)
{
- bool update_success = valobj->UpdateValueIfNeeded (use_dynamic, true);
+ bool update_success = valobj->UpdateValueIfNeeded (options.m_use_dynamic, true);
- if (update_success && use_dynamic != eNoDynamicValues)
+ const char *root_valobj_name =
+ options.m_root_valobj_name.empty() ?
+ valobj->GetName().AsCString() :
+ options.m_root_valobj_name.c_str();
+
+ if (update_success && options.m_use_dynamic != eNoDynamicValues)
{
- ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get();
+ ValueObject *dynamic_value = valobj->GetDynamicValue(options.m_use_dynamic).get();
if (dynamic_value)
valobj = dynamic_value;
}
@@ -3105,11 +3097,11 @@ ValueObject::DumpValueObject
const bool has_children = type_flags.Test (ClangASTContext::eTypeHasChildren);
const bool has_value = type_flags.Test (ClangASTContext::eTypeHasValue);
- const bool print_valobj = flat_output == false || has_value;
+ const bool print_valobj = options.m_flat_output == false || has_value;
if (print_valobj)
{
- if (show_location)
+ if (options.m_show_location)
{
s.Printf("%s: ", valobj->GetLocationAsCString());
}
@@ -3117,12 +3109,12 @@ ValueObject::DumpValueObject
s.Indent();
// Always show the type for the top level items.
- if (show_types || (curr_depth == 0 && !flat_output))
+ if (options.m_show_types || (curr_depth == 0 && !options.m_flat_output))
{
const char* typeName = valobj->GetTypeName().AsCString("<invalid type>");
s.Printf("(%s", typeName);
// only show dynamic types if the user really wants to see types
- if (show_types && use_dynamic != eNoDynamicValues &&
+ if (options.m_show_types && options.m_use_dynamic != eNoDynamicValues &&
(/*strstr(typeName, "id") == typeName ||*/
ClangASTType::GetMinimumLanguage(valobj->GetClangAST(), valobj->GetClangType()) == eLanguageTypeObjC))
{
@@ -3151,10 +3143,10 @@ ValueObject::DumpValueObject
}
- if (flat_output)
+ if (options.m_flat_output)
{
// If we are showing types, also qualify the C++ base classes
- const bool qualify_cxx_base_classes = show_types;
+ const bool qualify_cxx_base_classes = options.m_show_types;
valobj->GetExpressionPath(s, qualify_cxx_base_classes);
s.PutCString(" =");
}
@@ -3164,39 +3156,33 @@ ValueObject::DumpValueObject
s.Printf ("%s =", name_cstr);
}
- if (!scope_already_checked && !valobj->IsInScope())
+ if (!options.m_scope_already_checked && !valobj->IsInScope())
{
err_cstr = "out of scope";
}
}
+ std::string summary_str;
std::string value_str;
const char *val_cstr = NULL;
const char *sum_cstr = NULL;
- TypeSummaryImpl* entry = valobj->GetSummaryFormat().get();
+ TypeSummaryImpl* entry = options.m_summary_sp ? options.m_summary_sp.get() : valobj->GetSummaryFormat().get();
- if (omit_summary_depth > 0)
+ if (options.m_omit_summary_depth > 0)
entry = NULL;
- Format orig_format = kNumFormats;
if (err_cstr == NULL)
{
- if (format_override != eFormatDefault)
- {
- orig_format = valobj->GetFormat();
- valobj->SetFormat (format_override);
- }
- val_cstr = valobj->GetValueAsCString();
- if (val_cstr)
+ if (options.m_format != eFormatDefault && options.m_format != valobj->GetFormat())
{
- // Cache the value in our own storage as running summaries might
- // change our value from underneath us
- value_str = val_cstr;
+ valobj->GetValueAsCString(options.m_format,
+ value_str);
}
- if (orig_format != kNumFormats && orig_format != format_override)
+ else
{
- valobj->SetFormat (orig_format);
- orig_format = kNumFormats;
+ val_cstr = valobj->GetValueAsCString();
+ if (val_cstr)
+ value_str = val_cstr;
}
err_cstr = valobj->GetError().AsCString();
}
@@ -3210,8 +3196,16 @@ ValueObject::DumpValueObject
const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
if (print_valobj)
{
- if (omit_summary_depth == 0)
- sum_cstr = valobj->GetSummaryAsCString();
+ if (options.m_omit_summary_depth == 0)
+ {
+ if (options.m_summary_sp)
+ {
+ valobj->GetSummaryAsCString(entry, summary_str);
+ sum_cstr = summary_str.c_str();
+ }
+ else
+ sum_cstr = valobj->GetSummaryAsCString();
+ }
// Make sure we have a value and make sure the summary didn't
// specify that the value should not be printed
@@ -3219,18 +3213,9 @@ ValueObject::DumpValueObject
s.Printf(" %s", value_str.c_str());
if (sum_cstr)
- {
- // for some reason, using %@ (ObjC description) in a summary string, makes
- // us believe we need to reset ourselves, thus invalidating the content of
- // sum_cstr. Thus, IF we had a valid sum_cstr before, but it is now empty
- // let us recalculate it!
- if (sum_cstr[0] == '\0')
- s.Printf(" %s", valobj->GetSummaryAsCString());
- else
- s.Printf(" %s", sum_cstr);
- }
+ s.Printf(" %s", sum_cstr);
- if (use_objc)
+ if (options.m_use_objc)
{
const char *object_desc = valobj->GetObjectDescription();
if (object_desc)
@@ -3241,7 +3226,7 @@ ValueObject::DumpValueObject
}
}
- if (curr_depth < max_depth)
+ if (curr_depth < options.m_max_depth)
{
// We will show children for all concrete types. We won't show
// pointer contents unless a pointer depth has been specified.
@@ -3277,14 +3262,14 @@ ValueObject::DumpValueObject
if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr))
{
- ValueObjectSP synth_valobj = valobj->GetSyntheticValue (use_synth ?
+ ValueObjectSP synth_valobj = valobj->GetSyntheticValue (options.m_use_synthetic ?
eUseSyntheticFilter :
eNoSyntheticFilter);
uint32_t num_children = synth_valobj->GetNumChildren();
bool print_dotdotdot = false;
if (num_children)
{
- if (flat_output)
+ if (options.m_flat_output)
{
if (print_valobj)
s.EOL();
@@ -3298,37 +3283,30 @@ ValueObject::DumpValueObject
uint32_t max_num_children = valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
- if (num_children > max_num_children && !ignore_cap)
+ if (num_children > max_num_children && !options.m_ignore_cap)
{
num_children = max_num_children;
print_dotdotdot = true;
}
+ ValueObject::DumpValueObjectOptions child_options(options);
+ child_options.SetFormat().SetSummary().SetRootValueObjectName();
+ child_options.SetScopeChecked(true)
+ .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0);
for (uint32_t idx=0; idx<num_children; ++idx)
{
ValueObjectSP child_sp(synth_valobj->GetChildAtIndex(idx, true));
if (child_sp.get())
{
- DumpValueObject (s,
- child_sp.get(),
- NULL,
- (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
- curr_depth + 1,
- max_depth,
- show_types,
- show_location,
- false,
- use_dynamic,
- use_synth,
- true,
- flat_output,
- omit_summary_depth > 1 ? omit_summary_depth - 1 : 0,
- ignore_cap,
- format_override);
+ DumpValueObject_Impl (s,
+ child_sp.get(),
+ child_options,
+ (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
+ curr_depth + 1);
}
}
- if (!flat_output)
+ if (!options.m_flat_output)
{
if (print_dotdotdot)
{
@@ -3371,6 +3349,33 @@ ValueObject::DumpValueObject
}
}
+void
+ValueObject::DumpValueObject (Stream &s,
+ ValueObject *valobj)
+{
+
+ if (!valobj)
+ return;
+
+ DumpValueObject_Impl(s,
+ valobj,
+ DumpValueObjectOptions::DefaultOptions(),
+ 0,
+ 0);
+}
+
+void
+ValueObject::DumpValueObject (Stream &s,
+ ValueObject *valobj,
+ const DumpValueObjectOptions& options)
+{
+ DumpValueObject_Impl(s,
+ valobj,
+ options,
+ options.m_max_ptr_depth, // max pointer depth allowed, we will go down from here
+ 0 // current object depth is 0 since we are just starting
+ );
+}
ValueObjectSP
ValueObject::CreateConstantValue (const ConstString &name)
@@ -3833,6 +3838,7 @@ ValueObject::ClearUserVisibleData()
m_value_str.clear();
m_summary_str.clear();
m_object_desc_str.clear();
+ m_synthetic_value = NULL;
m_is_getting_summary = false;
}
diff --git a/lldb/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py b/lldb/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
index 5eff106a14c..78213c629fc 100644
--- a/lldb/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
+++ b/lldb/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
@@ -267,6 +267,10 @@ class CppDataFormatterTestCase(TestBase):
self.expect("frame variable the_coolest_guy", matching=False,
substrs = ['(i_am_cooler) the_coolest_guy = goofy'])
+ # check that formats are not sticking since that is the behavior we want
+ self.expect("frame variable iAmInt --format hex", substrs = ['(int) iAmInt = 0x00000001'])
+ self.expect("frame variable iAmInt", matching=False, substrs = ['(int) iAmInt = 0x00000001'])
+ self.expect("frame variable iAmInt", substrs = ['(int) iAmInt = 1'])
if __name__ == '__main__':
import atexit
diff --git a/lldb/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py b/lldb/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py
index 9dee06eb2eb..f0576f63f48 100644
--- a/lldb/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py
+++ b/lldb/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py
@@ -64,13 +64,14 @@ class NamedSummariesDataFormatterTestCase(TestBase):
self.expect("frame variable first --summary AllUseIt",
substrs = ['AllUseIt: x=12'])
- # We remember the summary choice...
- self.expect("frame variable first",
+ # We *DO NOT* remember the summary choice anymore
+ self.expect("frame variable first", matching=False,
substrs = ['AllUseIt: x=12'])
-
+ self.expect("frame variable first",
+ substrs = ['First: x=12'])
+
self.runCmd("thread step-over") # 2
- # ...but not after a stoppoint
self.expect("frame variable first",
substrs = ['First: x=12'])
@@ -111,17 +112,16 @@ class NamedSummariesDataFormatterTestCase(TestBase):
substrs = ['FirstAndFriends: x=12',
'y=34'])
- self.expect("frame variable first",
- substrs = ['FirstAndFriends: x=12',
- 'y=34'])
+ self.expect("frame variable first", matching=True,
+ substrs = ['x = 12',
+ 'y = 34'])
self.runCmd("type summary delete FirstAndFriends")
self.expect("type summary delete NoSuchSummary", error=True)
self.runCmd("type summary delete AllUseIt")
- self.expect("frame variable first",
- substrs = ['FirstAndFriends: x=12',
- 'y=34'])
+ self.expect("frame variable first", matching=False,
+ substrs = ['FirstAndFriends'])
self.runCmd("thread step-over") # 4
diff --git a/lldb/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py b/lldb/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py
index 74b6452f4d1..161fcf6427a 100644
--- a/lldb/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py
+++ b/lldb/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py
@@ -111,18 +111,21 @@ class ScriptDataFormatterTestCase(TestBase):
self.runCmd("type summary add --name test_summary --python-script \"%s\"" % script)
# attach the Python named summary to someone
- self.runCmd("frame variable one --summary test_summary")
-
- self.expect("frame variable one",
+ self.expect("frame variable one --summary test_summary",
substrs = ['Python summary'])
# should not bind to the type
self.expect("frame variable two", matching=False,
substrs = ['Python summary'])
+ # and should not stick to the variable
+ self.expect("frame variable one",matching=False,
+ substrs = ['Python summary'])
+
self.runCmd("type summary add i_am_cool --summary-string \"Text summary\"")
- self.expect("frame variable one",
+ # should be temporary only
+ self.expect("frame variable one",matching=False,
substrs = ['Python summary'])
# use the type summary
OpenPOWER on IntegriCloud