summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Core')
-rw-r--r--lldb/source/Core/Debugger.cpp12
-rw-r--r--lldb/source/Core/FormatClasses.cpp24
-rw-r--r--lldb/source/Core/ValueObject.cpp107
-rw-r--r--lldb/source/Core/ValueObjectSyntheticFilter.cpp170
4 files changed, 301 insertions, 12 deletions
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index cce768f8684..219fbfa8985 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -733,8 +733,12 @@ ScanFormatDescriptor(const char* var_name_begin,
// if this is a V, print the value using the default format
if (*format_name == 'V')
*val_obj_display = ValueObject::eDisplayValue;
+ // if this is an L, print the location of the value
if (*format_name == 'L')
*val_obj_display = ValueObject::eDisplayLocation;
+ // if this is an S, print the summary after all
+ if (*format_name == 'S')
+ *val_obj_display = ValueObject::eDisplaySummary;
}
// a good custom format tells us to print the value using it
else
@@ -1761,6 +1765,12 @@ Debugger::Formatting::GetSummaryFormat(ValueObject& vobj,
{
return GetFormatManager().Get(vobj, entry);
}
+bool
+Debugger::Formatting::GetSyntheticFilter(ValueObject& vobj,
+ lldb::SyntheticFilterSP& entry)
+{
+ return GetFormatManager().Get(vobj, entry);
+}
bool
Debugger::Formatting::Categories::Get(const ConstString &category, lldb::FormatCategorySP &entry)
@@ -1791,7 +1801,7 @@ Debugger::Formatting::Categories::Clear()
void
Debugger::Formatting::Categories::Clear(ConstString &category)
{
- GetFormatManager().Category(category.GetCString())->Clear();
+ GetFormatManager().Category(category.GetCString())->ClearSummaries();
}
void
diff --git a/lldb/source/Core/FormatClasses.cpp b/lldb/source/Core/FormatClasses.cpp
index 8ff237a603a..f301a7bbc3a 100644
--- a/lldb/source/Core/FormatClasses.cpp
+++ b/lldb/source/Core/FormatClasses.cpp
@@ -66,14 +66,15 @@ StringSummaryFormat::FormatObject(lldb::ValueObjectSP object)
if (m_show_members_oneliner)
{
- const uint32_t num_children = object->GetNumChildren();
+ ValueObjectSP synth_vobj = object->GetSyntheticValue(lldb::eUseSyntheticFilter);
+ const uint32_t num_children = synth_vobj->GetNumChildren();
if (num_children)
{
s.PutChar('(');
for (uint32_t idx=0; idx<num_children; ++idx)
{
- lldb::ValueObjectSP child_sp(object->GetChildAtIndex(idx, true));
+ lldb::ValueObjectSP child_sp(synth_vobj->GetChildAtIndex(idx, true));
if (child_sp.get())
{
if (idx)
@@ -137,4 +138,21 @@ ScriptSummaryFormat::GetDescription()
}
-
+std::string
+SyntheticFilter::GetDescription()
+{
+ StreamString sstr;
+ sstr.Printf("%s%s%s {\n",
+ m_cascades ? "" : " (not cascading)",
+ m_skip_pointers ? " (skip pointers)" : "",
+ m_skip_references ? " (skip references)" : "");
+
+ for (int i = 0; i < GetCount(); i++)
+ {
+ sstr.Printf(" %s\n",
+ GetExpressionPathAtIndex(i).c_str());
+ }
+
+ sstr.Printf("}");
+ return sstr.GetString();
+}
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 5721b40f548..acc85df556f 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -26,6 +26,7 @@
#include "lldb/Core/ValueObjectDynamicValue.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Core/ValueObjectSyntheticFilter.h"
#include "lldb/Host/Endian.h"
@@ -70,12 +71,14 @@ ValueObject::ValueObject (ValueObject &parent) :
m_children (),
m_synthetic_children (),
m_dynamic_value (NULL),
+ m_synthetic_value(NULL),
m_deref_valobj(NULL),
m_format (eFormatDefault),
m_last_format_mgr_revision(0),
m_last_summary_format(),
m_forced_summary_format(),
m_last_value_format(),
+ m_last_synthetic_filter(),
m_user_id_of_forced_summary(0),
m_value_is_valid (false),
m_value_did_change (false),
@@ -85,6 +88,7 @@ ValueObject::ValueObject (ValueObject &parent) :
m_is_deref_of_parent (false),
m_is_array_item_for_pointer(false),
m_is_bitfield_for_scalar(false),
+ m_is_expression_path_child(false),
m_dump_printable_counter(0)
{
m_manager->ManageObject(this);
@@ -110,12 +114,14 @@ ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
m_children (),
m_synthetic_children (),
m_dynamic_value (NULL),
+ m_synthetic_value(NULL),
m_deref_valobj(NULL),
m_format (eFormatDefault),
m_last_format_mgr_revision(0),
m_last_summary_format(),
m_forced_summary_format(),
m_last_value_format(),
+ m_last_synthetic_filter(),
m_user_id_of_forced_summary(0),
m_value_is_valid (false),
m_value_did_change (false),
@@ -125,6 +131,7 @@ ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
m_is_deref_of_parent (false),
m_is_array_item_for_pointer(false),
m_is_bitfield_for_scalar(false),
+ m_is_expression_path_child(false),
m_dump_printable_counter(0)
{
m_manager = new ValueObjectManager();
@@ -209,14 +216,13 @@ ValueObject::UpdateFormatsIfNeeded()
if (m_last_summary_format.get())
m_last_summary_format.reset((StringSummaryFormat*)NULL);
if (m_last_value_format.get())
- m_last_value_format.reset((ValueFormat*)NULL);
- Debugger::Formatting::ValueFormats::Get(*this, m_last_value_format);
- // to find a summary we look for a direct summary, then if there is none
- // we look for a regex summary. if there is none we look for a system
- // summary (direct), and if also that fails, we look for a system
- // regex summary
+ m_last_value_format.reset(/*(ValueFormat*)NULL*/);
+ if (m_last_synthetic_filter.get())
+ m_last_synthetic_filter.reset(/*(SyntheticFilter*)NULL*/);
+ Debugger::Formatting::ValueFormats::Get(*this, m_last_value_format);
Debugger::Formatting::GetSummaryFormat(*this, m_last_summary_format);
+ Debugger::Formatting::GetSyntheticFilter(*this, m_last_synthetic_filter);
m_last_format_mgr_revision = Debugger::Formatting::ValueFormats::GetCurrentRevision();
@@ -1423,6 +1429,63 @@ ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_cre
return synthetic_child_sp;
}
+// your expression path needs to have a leading . or ->
+// (unless it somehow "looks like" an array, in which case it has
+// a leading [ symbol). while the [ is meaningful and should be shown
+// to the user, . and -> are just parser design, but by no means
+// added information for the user.. strip them off
+static const char*
+SkipLeadingExpressionPathSeparators(const char* expression)
+{
+ if (!expression || !expression[0])
+ return expression;
+ if (expression[0] == '.')
+ return expression+1;
+ if (expression[0] == '-' && expression[1] == '>')
+ return expression+2;
+ return expression;
+}
+
+lldb::ValueObjectSP
+ValueObject::GetSyntheticExpressionPathChild(const char* expression, bool can_create)
+{
+ ValueObjectSP synthetic_child_sp;
+ ConstString name_const_string(expression);
+ // Check if we have already created a synthetic array member in this
+ // valid object. If we have we will re-use it.
+ synthetic_child_sp = GetSyntheticChild (name_const_string);
+ if (!synthetic_child_sp)
+ {
+ // We haven't made a synthetic array member for expression yet, so
+ // lets make one and cache it for any future reference.
+ synthetic_child_sp = GetValueForExpressionPath(expression);
+
+ // Cache the value if we got one back...
+ if (synthetic_child_sp.get())
+ {
+ AddSyntheticChild(name_const_string, synthetic_child_sp.get());
+ synthetic_child_sp->SetName(SkipLeadingExpressionPathSeparators(expression));
+ synthetic_child_sp->m_is_expression_path_child = true;
+ }
+ }
+ return synthetic_child_sp;
+}
+
+void
+ValueObject::CalculateSyntheticValue (lldb::SyntheticValueType use_synthetic)
+{
+ if (use_synthetic == lldb::eNoSyntheticFilter)
+ return;
+
+ UpdateFormatsIfNeeded();
+
+ if (m_last_synthetic_filter.get() == NULL)
+ return;
+
+ m_synthetic_value = new ValueObjectSyntheticFilter(*this, m_last_synthetic_filter);
+
+}
+
void
ValueObject::CalculateDynamicValue (lldb::DynamicValueType use_dynamic)
{
@@ -1483,6 +1546,29 @@ ValueObject::GetDynamicValue (DynamicValueType use_dynamic)
return ValueObjectSP();
}
+// GetDynamicValue() returns a NULL SharedPointer if the object is not dynamic
+// or we do not really want a dynamic VO. this method instead returns this object
+// itself when making it synthetic has no meaning. this makes it much simpler
+// to replace the SyntheticValue for the ValueObject
+ValueObjectSP
+ValueObject::GetSyntheticValue (SyntheticValueType use_synthetic)
+{
+ if (use_synthetic == lldb::eNoSyntheticFilter)
+ return GetSP();
+
+ UpdateFormatsIfNeeded();
+
+ if (m_last_synthetic_filter.get() == NULL)
+ return GetSP();
+
+ CalculateSyntheticValue(use_synthetic);
+
+ if (m_synthetic_value)
+ return m_synthetic_value->GetSP();
+ else
+ return GetSP();
+}
+
bool
ValueObject::GetBaseClassPath (Stream &s)
{
@@ -2398,6 +2484,7 @@ ValueObject::DumpValueObject
bool show_location,
bool use_objc,
lldb::DynamicValueType use_dynamic,
+ bool use_synth,
bool scope_already_checked,
bool flat_output,
uint32_t omit_summary_depth
@@ -2545,7 +2632,10 @@ ValueObject::DumpValueObject
if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr))
{
- const uint32_t num_children = valobj->GetNumChildren();
+ ValueObjectSP synth_vobj = valobj->GetSyntheticValue(use_synth ?
+ lldb::eUseSyntheticFilter :
+ lldb::eNoSyntheticFilter);
+ const uint32_t num_children = synth_vobj->GetNumChildren();
if (num_children)
{
if (flat_output)
@@ -2562,7 +2652,7 @@ ValueObject::DumpValueObject
for (uint32_t idx=0; idx<num_children; ++idx)
{
- ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
+ ValueObjectSP child_sp(synth_vobj->GetChildAtIndex(idx, true));
if (child_sp.get())
{
DumpValueObject (s,
@@ -2575,6 +2665,7 @@ ValueObject::DumpValueObject
show_location,
false,
use_dynamic,
+ use_synth,
true,
flat_output,
omit_summary_depth > 1 ? omit_summary_depth - 1 : 0);
diff --git a/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/lldb/source/Core/ValueObjectSyntheticFilter.cpp
new file mode 100644
index 00000000000..4756b1cea29
--- /dev/null
+++ b/lldb/source/Core/ValueObjectSyntheticFilter.cpp
@@ -0,0 +1,170 @@
+//===-- ValueObjectSyntheticFilter.cpp -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "lldb/Core/ValueObjectSyntheticFilter.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/FormatClasses.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ValueObjectList.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObject.h"
+
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/Variable.h"
+
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+
+
+using namespace lldb_private;
+
+ValueObjectSyntheticFilter::ValueObjectSyntheticFilter (ValueObject &parent, lldb::SyntheticFilterSP filter) :
+ ValueObject(parent),
+ m_address (),
+ m_type_sp(),
+m_use_synthetic (lldb::eUseSyntheticFilter),
+ m_synth_filter(filter)
+{
+ SetName (parent.GetName().AsCString());
+}
+
+ValueObjectSyntheticFilter::~ValueObjectSyntheticFilter()
+{
+ m_owning_valobj_sp.reset();
+}
+
+lldb::clang_type_t
+ValueObjectSyntheticFilter::GetClangType ()
+{
+ if (m_type_sp)
+ return m_value.GetClangType();
+ else
+ return m_parent->GetClangType();
+}
+
+ConstString
+ValueObjectSyntheticFilter::GetTypeName()
+{
+ const bool success = UpdateValueIfNeeded();
+ if (success && m_type_sp)
+ return ClangASTType::GetConstTypeName (GetClangType());
+ else
+ return m_parent->GetTypeName();
+}
+
+uint32_t
+ValueObjectSyntheticFilter::CalculateNumChildren()
+{
+ const bool success = UpdateValueIfNeeded();
+ if (!success)
+ return 0;
+ if (m_synth_filter.get())
+ return m_synth_filter->GetCount();
+ return 0;
+ if (success && m_type_sp)
+ return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
+ else
+ return m_parent->GetNumChildren();
+}
+
+clang::ASTContext *
+ValueObjectSyntheticFilter::GetClangAST ()
+{
+ const bool success = UpdateValueIfNeeded(false);
+ if (success && m_type_sp)
+ return m_type_sp->GetClangAST();
+ else
+ return m_parent->GetClangAST ();
+}
+
+size_t
+ValueObjectSyntheticFilter::GetByteSize()
+{
+ const bool success = UpdateValueIfNeeded();
+ if (success && m_type_sp)
+ return m_value.GetValueByteSize(GetClangAST(), NULL);
+ else
+ return m_parent->GetByteSize();
+}
+
+lldb::ValueType
+ValueObjectSyntheticFilter::GetValueType() const
+{
+ return m_parent->GetValueType();
+}
+
+bool
+ValueObjectSyntheticFilter::UpdateValue ()
+{
+ SetValueIsValid (false);
+ m_error.Clear();
+
+ if (!m_parent->UpdateValueIfNeeded())
+ {
+ // our parent could not update.. as we are meaningless without a parent, just stop
+ if (m_error.Success() && m_parent->GetError().Fail())
+ m_error = m_parent->GetError();
+ return false;
+ }
+
+ SetValueIsValid(true);
+ return true;
+}
+
+lldb::ValueObjectSP
+ValueObjectSyntheticFilter::GetChildAtIndex (uint32_t idx, bool can_create)
+{
+ if (!m_synth_filter.get())
+ return lldb::ValueObjectSP();
+ if (idx >= m_synth_filter->GetCount())
+ return lldb::ValueObjectSP();
+ return m_parent->GetSyntheticExpressionPathChild(m_synth_filter->GetExpressionPathAtIndex(idx).c_str(), can_create);
+}
+
+lldb::ValueObjectSP
+ValueObjectSyntheticFilter::GetChildMemberWithName (const ConstString &name, bool can_create)
+{
+ if (!m_synth_filter.get())
+ return lldb::ValueObjectSP();
+ uint32_t idx = GetIndexOfChildWithName(name);
+ if (idx >= m_synth_filter->GetCount())
+ return lldb::ValueObjectSP();
+ return m_parent->GetSyntheticExpressionPathChild(name.GetCString(), can_create);
+}
+
+uint32_t
+ValueObjectSyntheticFilter::GetIndexOfChildWithName (const ConstString &name)
+{
+ const char* name_cstr = name.GetCString();
+ for (int i = 0; i < m_synth_filter->GetCount(); i++)
+ {
+ const char* expr_cstr = m_synth_filter->GetExpressionPathAtIndex(i).c_str();
+ if (::strcmp(name_cstr, expr_cstr))
+ return i;
+ }
+ return UINT32_MAX;
+}
+
+bool
+ValueObjectSyntheticFilter::IsInScope ()
+{
+ return m_parent->IsInScope();
+}
+
OpenPOWER on IntegriCloud