diff options
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/API/SBValue.cpp | 38 | ||||
-rw-r--r-- | lldb/source/Core/Debugger.cpp | 3 | ||||
-rw-r--r-- | lldb/source/Core/FormatManager.cpp | 26 | ||||
-rw-r--r-- | lldb/source/Core/ValueObject.cpp | 9 | ||||
-rw-r--r-- | lldb/source/Core/ValueObjectSyntheticFilter.cpp | 14 | ||||
-rw-r--r-- | lldb/source/Interpreter/ScriptInterpreterPython.cpp | 23 | ||||
-rw-r--r-- | lldb/source/Target/Target.cpp | 30 |
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." }, |