summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/API/SBValue.cpp38
-rw-r--r--lldb/source/Core/Debugger.cpp3
-rw-r--r--lldb/source/Core/FormatManager.cpp26
-rw-r--r--lldb/source/Core/ValueObject.cpp9
-rw-r--r--lldb/source/Core/ValueObjectSyntheticFilter.cpp14
-rw-r--r--lldb/source/Interpreter/ScriptInterpreterPython.cpp23
-rw-r--r--lldb/source/Target/Target.cpp30
7 files changed, 121 insertions, 22 deletions
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index c5a5fd27294..b28004ccf70 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -51,21 +51,23 @@ SBValue::SBValue () :
{
}
-SBValue::SBValue (const lldb::ValueObjectSP &value_sp) :
- m_opaque_sp (value_sp)
+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
}
-SBValue::SBValue(const SBValue &rhs) :
- m_opaque_sp (rhs.m_opaque_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
}
SBValue &
SBValue::operator = (const SBValue &rhs)
{
if (this != &rhs)
- m_opaque_sp = rhs.m_opaque_sp;
+ {
+ SetSP(rhs.m_opaque_sp); // whenever setting the SP call SetSP() since it knows how to deal with synthetic values properly
+ }
return *this;
}
@@ -809,6 +811,30 @@ SBValue::GetStaticValue ()
return SBValue();
}
+lldb::SBValue
+SBValue::GetNonSyntheticValue ()
+{
+ SBValue sb_value;
+ lldb::ValueObjectSP value_sp(GetSP());
+ if (value_sp)
+ {
+ if (value_sp->IsSynthetic())
+ {
+ 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->GetParent())
+ sb_value.m_opaque_sp = value_sp->GetParent()->GetSP();
+ }
+ }
+ }
+ return sb_value;
+}
+
bool
SBValue::IsDynamic()
{
@@ -1124,6 +1150,8 @@ void
SBValue::SetSP (const lldb::ValueObjectSP &sp)
{
m_opaque_sp = sp;
+ if (IsValid() && m_opaque_sp->HasSyntheticValue())
+ m_opaque_sp = m_opaque_sp->GetSyntheticValue();
}
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 6b93aa971a0..d7f1460e7fb 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -1164,7 +1164,8 @@ Debugger::FormatPrompt
if (*var_name_begin == 's')
{
- valobj = valobj->GetSyntheticValue().get();
+ if (!valobj->IsSynthetic())
+ valobj = valobj->GetSyntheticValue().get();
if (!valobj)
break;
var_name_begin++;
diff --git a/lldb/source/Core/FormatManager.cpp b/lldb/source/Core/FormatManager.cpp
index 0496780724a..693ae263c96 100644
--- a/lldb/source/Core/FormatManager.cpp
+++ b/lldb/source/Core/FormatManager.cpp
@@ -639,18 +639,24 @@ FormatManager::LoadSTLFormatters()
SyntheticChildren::Flags stl_synth_flags;
stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
- gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?vector<.+>$")),
+ gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")),
SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
"gnu_libstdcpp.StdVectorSynthProvider")));
- gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?map<.+> >$")),
+ gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")),
SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
"gnu_libstdcpp.StdMapSynthProvider")));
- gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?list<.+>$")),
+ gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::list<.+>(( )?&)?$")),
SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
"gnu_libstdcpp.StdListSynthProvider")));
stl_summary_flags.SetDontShowChildren(false);
- gnu_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?vector<.+>$")),
+ gnu_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")),
+ TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
+ "size=${svar%#}")));
+ gnu_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")),
+ TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
+ "size=${svar%#}")));
+ gnu_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::list<.+>(( )?&)?$")),
TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
"size=${svar%#}")));
#endif
@@ -682,22 +688,22 @@ FormatManager::LoadLibcxxFormatters()
SyntheticChildren::Flags stl_synth_flags;
stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)vector<.+>$")),
+ libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::vector<.+>(( )?&)?$")),
SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
"libcxx.stdvector_SynthProvider")));
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)list<.+>$")),
+ libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::list<.+>(( )?&)?$")),
SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
"libcxx.stdlist_SynthProvider")));
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)map<.+> >$")),
+ libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::map<.+> >(( )?&)?$")),
SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
"libcxx.stdmap_SynthProvider")));
stl_summary_flags.SetDontShowChildren(false);
- libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)vector<.+>$")),
+ libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::vector<.+>(( )?&)?")),
TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
- libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)list<.+>$")),
+ libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::list<.+>(( )?&)?$")),
TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
- libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)map<.+> >$")),
+ libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::map<.+> >(( )?&)?$")),
TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
#endif
}
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index e072b491652..57f887b20f6 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -572,6 +572,7 @@ ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
uint32_t
ValueObject::GetNumChildren ()
{
+ UpdateValueIfNeeded();
if (!m_children_count_valid)
{
SetNumChildren (CalculateNumChildren());
@@ -2009,6 +2010,13 @@ ValueObject::CalculateSyntheticValue (bool use_synthetic)
if (use_synthetic == false)
return;
+ TargetSP target_sp(GetTargetSP());
+ if (target_sp && (target_sp->GetEnableSyntheticValue() == false || target_sp->GetSuppressSyntheticValue() == true))
+ {
+ m_synthetic_value = NULL;
+ return;
+ }
+
if (!UpdateFormatsIfNeeded(m_last_format_mgr_dynamic) && m_synthetic_value)
return;
@@ -3317,6 +3325,7 @@ DumpValueObject_Impl (Stream &s,
ValueObject* synth_valobj;
ValueObjectSP synth_valobj_sp = valobj->GetSyntheticValue (options.m_use_synthetic);
synth_valobj = (synth_valobj_sp ? synth_valobj_sp.get() : valobj);
+
uint32_t num_children = synth_valobj->GetNumChildren();
bool print_dotdotdot = false;
if (num_children)
diff --git a/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/lldb/source/Core/ValueObjectSyntheticFilter.cpp
index 6d9337b623c..56eb9f6c56e 100644
--- a/lldb/source/Core/ValueObjectSyntheticFilter.cpp
+++ b/lldb/source/Core/ValueObjectSyntheticFilter.cpp
@@ -25,7 +25,7 @@ ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::Synthetic
m_synth_filter_ap(filter->GetFrontEnd(parent)),
m_children_byindex(),
m_name_toindex(),
- m_children_count(UINT32_MAX)
+ m_synthetic_children_count(UINT32_MAX)
{
#ifdef LLDB_CONFIGURATION_DEBUG
std::string new_name(parent.GetName().AsCString());
@@ -56,9 +56,9 @@ uint32_t
ValueObjectSynthetic::CalculateNumChildren()
{
UpdateValueIfNeeded();
- if (m_children_count < UINT32_MAX)
- return m_children_count;
- return (m_children_count = m_synth_filter_ap->CalculateNumChildren());
+ if (m_synthetic_children_count < UINT32_MAX)
+ return m_synthetic_children_count;
+ return (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren());
}
clang::ASTContext *
@@ -99,7 +99,11 @@ ValueObjectSynthetic::UpdateValue ()
// filter said that cached values are stale
m_children_byindex.clear();
m_name_toindex.clear();
- m_children_count = UINT32_MAX;
+ // usually, an object's value can change but this does not alter its children count
+ // for a synthetic VO that might indeed happen, so we need to tell the upper echelons
+ // that they need to come back to us asking for children
+ m_children_count_valid = false;
+ m_synthetic_children_count = UINT32_MAX;
}
SetValueIsValid(true);
diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp
index 81bbf3f11ac..9c84eab00d2 100644
--- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp
+++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp
@@ -234,6 +234,24 @@ 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::ScriptInterpreterPython (CommandInterpreter &interpreter) :
ScriptInterpreter (interpreter, eScriptLanguagePython),
m_embedded_python_pty (),
@@ -1328,6 +1346,7 @@ 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);
@@ -1586,6 +1605,7 @@ ScriptInterpreterPython::CalculateNumChildren (const lldb::ScriptInterpreterObje
{
Locker py_lock(this);
+ ForceDisableSyntheticChildren no_synthetics(GetCommandInterpreter().GetDebugger().GetSelectedTarget().get());
ret_val = g_swig_calc_children (implementor);
}
@@ -1612,6 +1632,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);
if (child_ptr != NULL && child_ptr != Py_None)
{
@@ -1648,6 +1669,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);
}
@@ -1672,6 +1694,7 @@ ScriptInterpreterPython::UpdateSynthProviderInstance (const lldb::ScriptInterpre
{
Locker py_lock(this);
+ ForceDisableSyntheticChildren no_synthetics(GetCommandInterpreter().GetDebugger().GetSelectedTarget().get());
ret_val = g_swig_update_provider (implementor);
}
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 6648d4c86be..34fb4b8f426 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -73,7 +73,8 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::Plat
m_source_manager(*this),
m_stop_hooks (),
m_stop_hook_next_id (0),
- m_suppress_stop_hooks (false)
+ m_suppress_stop_hooks (false),
+ m_suppress_synthetic_value(false)
{
SetEventName (eBroadcastBitBreakpointChanged, "breakpoint-changed");
SetEventName (eBroadcastBitModulesLoaded, "modules-loaded");
@@ -183,6 +184,7 @@ Target::Destroy()
m_stop_hooks.clear();
m_stop_hook_next_id = 0;
m_suppress_stop_hooks = false;
+ m_suppress_synthetic_value = false;
}
@@ -2106,6 +2108,7 @@ Target::SettingsController::CreateInstanceSettings (const char *instance_name)
#define TSC_DEFAULT_ARCH "default-arch"
#define TSC_EXPR_PREFIX "expr-prefix"
#define TSC_PREFER_DYNAMIC "prefer-dynamic-value"
+#define TSC_ENABLE_SYNTHETIC "enable-synthetic-value"
#define TSC_SKIP_PROLOGUE "skip-prologue"
#define TSC_SOURCE_MAP "source-map"
#define TSC_EXE_SEARCH_PATHS "exec-search-paths"
@@ -2144,6 +2147,13 @@ GetSettingNameForPreferDynamicValue ()
}
static const ConstString &
+GetSettingNameForEnableSyntheticValue ()
+{
+ static ConstString g_const_string (TSC_ENABLE_SYNTHETIC);
+ return g_const_string;
+}
+
+static const ConstString &
GetSettingNameForSourcePathMap ()
{
static ConstString g_const_string (TSC_SOURCE_MAP);
@@ -2291,6 +2301,7 @@ TargetInstanceSettings::TargetInstanceSettings
m_expr_prefix_file (),
m_expr_prefix_contents (),
m_prefer_dynamic_value (2),
+ m_enable_synthetic_value(true, true),
m_skip_prologue (true, true),
m_source_map (NULL, NULL),
m_exe_search_paths (),
@@ -2330,6 +2341,7 @@ TargetInstanceSettings::TargetInstanceSettings (const TargetInstanceSettings &rh
m_expr_prefix_file (rhs.m_expr_prefix_file),
m_expr_prefix_contents (rhs.m_expr_prefix_contents),
m_prefer_dynamic_value (rhs.m_prefer_dynamic_value),
+ m_enable_synthetic_value(rhs.m_enable_synthetic_value),
m_skip_prologue (rhs.m_skip_prologue),
m_source_map (rhs.m_source_map),
m_exe_search_paths (rhs.m_exe_search_paths),
@@ -2365,6 +2377,7 @@ TargetInstanceSettings::operator= (const TargetInstanceSettings &rhs)
m_expr_prefix_file = rhs.m_expr_prefix_file;
m_expr_prefix_contents = rhs.m_expr_prefix_contents;
m_prefer_dynamic_value = rhs.m_prefer_dynamic_value;
+ m_enable_synthetic_value = rhs.m_enable_synthetic_value;
m_skip_prologue = rhs.m_skip_prologue;
m_source_map = rhs.m_source_map;
m_exe_search_paths = rhs.m_exe_search_paths;
@@ -2442,6 +2455,13 @@ TargetInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_n
if (err.Success())
m_prefer_dynamic_value = new_value;
}
+ else if (var_name == GetSettingNameForEnableSyntheticValue())
+ {
+ bool ok;
+ bool new_value = Args::StringToBoolean(value, true, &ok);
+ if (ok)
+ m_enable_synthetic_value.SetCurrentValue(new_value);
+ }
else if (var_name == GetSettingNameForSkipPrologue())
{
err = UserSettingsController::UpdateBooleanOptionValue (value, op, m_skip_prologue);
@@ -2626,6 +2646,13 @@ TargetInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
{
value.AppendString (g_dynamic_value_types[m_prefer_dynamic_value].string_value);
}
+ else if (var_name == GetSettingNameForEnableSyntheticValue())
+ {
+ if (m_skip_prologue)
+ value.AppendString ("true");
+ else
+ value.AppendString ("false");
+ }
else if (var_name == GetSettingNameForSkipPrologue())
{
if (m_skip_prologue)
@@ -2824,6 +2851,7 @@ Target::SettingsController::instance_settings_table[] =
// ================= ================== =============== ======================= ====== ====== =========================================================================
{ TSC_EXPR_PREFIX , eSetVarTypeString , NULL , NULL, false, false, "Path to a file containing expressions to be prepended to all expressions." },
{ TSC_PREFER_DYNAMIC , eSetVarTypeEnum , NULL , g_dynamic_value_types, false, false, "Should printed values be shown as their dynamic value." },
+ { TSC_ENABLE_SYNTHETIC , eSetVarTypeBoolean, "true" , NULL, false, false, "Should synthetic values be used by default whenever available." },
{ TSC_SKIP_PROLOGUE , eSetVarTypeBoolean, "true" , NULL, false, false, "Skip function prologues when setting breakpoints by name." },
{ TSC_SOURCE_MAP , eSetVarTypeArray , NULL , NULL, false, false, "Source path remappings to use when locating source files from debug information." },
{ TSC_EXE_SEARCH_PATHS , eSetVarTypeArray , NULL , NULL, false, false, "Executable search paths to use when locating executable files whose paths don't match the local file system." },
OpenPOWER on IntegriCloud