diff options
Diffstat (limited to 'source/Breakpoint/BreakpointOptions.cpp')
-rw-r--r-- | source/Breakpoint/BreakpointOptions.cpp | 231 |
1 files changed, 179 insertions, 52 deletions
diff --git a/source/Breakpoint/BreakpointOptions.cpp b/source/Breakpoint/BreakpointOptions.cpp index bef63cc0f222..662b288794d3 100644 --- a/source/Breakpoint/BreakpointOptions.cpp +++ b/source/Breakpoint/BreakpointOptions.cpp @@ -114,7 +114,8 @@ BreakpointOptions::CommandData::CreateFromStructuredData( const char *BreakpointOptions::g_option_names[( size_t)BreakpointOptions::OptionNames::LastOptionName]{ - "ConditionText", "IgnoreCount", "EnabledState", "OneShotState"}; + "ConditionText", "IgnoreCount", + "EnabledState", "OneShotState", "AutoContinue"}; bool BreakpointOptions::NullCallback(void *baton, StoppointCallbackContext *context, @@ -126,20 +127,30 @@ bool BreakpointOptions::NullCallback(void *baton, //---------------------------------------------------------------------- // BreakpointOptions constructor //---------------------------------------------------------------------- -BreakpointOptions::BreakpointOptions() +BreakpointOptions::BreakpointOptions(bool all_flags_set) : m_callback(BreakpointOptions::NullCallback), m_callback_baton_sp(), m_baton_is_command_baton(false), m_callback_is_synchronous(false), m_enabled(true), m_one_shot(false), m_ignore_count(0), m_thread_spec_ap(), - m_condition_text(), m_condition_text_hash(0) {} + m_condition_text(), m_condition_text_hash(0), m_auto_continue(false), + m_set_flags(0) { + if (all_flags_set) + m_set_flags.Set(~((Flags::ValueType) 0)); + } BreakpointOptions::BreakpointOptions(const char *condition, bool enabled, - int32_t ignore, bool one_shot) + int32_t ignore, bool one_shot, + bool auto_continue) : m_callback(nullptr), m_baton_is_command_baton(false), m_callback_is_synchronous(false), m_enabled(enabled), - m_one_shot(one_shot), m_ignore_count(ignore), m_condition_text(condition), - m_condition_text_hash(0) - -{} + m_one_shot(one_shot), m_ignore_count(ignore), + m_condition_text_hash(0), m_auto_continue(auto_continue) +{ + m_set_flags.Set(eEnabled | eIgnoreCount | eOneShot + | eAutoContinue); + if (condition && *condition != '\0') { + SetCondition(condition); + } +} //---------------------------------------------------------------------- // BreakpointOptions copy constructor @@ -149,7 +160,9 @@ BreakpointOptions::BreakpointOptions(const BreakpointOptions &rhs) m_baton_is_command_baton(rhs.m_baton_is_command_baton), m_callback_is_synchronous(rhs.m_callback_is_synchronous), m_enabled(rhs.m_enabled), m_one_shot(rhs.m_one_shot), - m_ignore_count(rhs.m_ignore_count), m_thread_spec_ap() { + m_ignore_count(rhs.m_ignore_count), m_thread_spec_ap(), + m_auto_continue(rhs.m_auto_continue), + m_set_flags(rhs.m_set_flags) { if (rhs.m_thread_spec_ap.get() != nullptr) m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get())); m_condition_text = rhs.m_condition_text; @@ -172,21 +185,62 @@ operator=(const BreakpointOptions &rhs) { m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get())); m_condition_text = rhs.m_condition_text; m_condition_text_hash = rhs.m_condition_text_hash; + m_auto_continue = rhs.m_auto_continue; + m_set_flags = rhs.m_set_flags; return *this; } -BreakpointOptions * -BreakpointOptions::CopyOptionsNoCallback(BreakpointOptions &orig) { - BreakpointHitCallback orig_callback = orig.m_callback; - lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp; - bool orig_is_sync = orig.m_callback_is_synchronous; - - orig.ClearCallback(); - BreakpointOptions *ret_val = new BreakpointOptions(orig); - - orig.SetCallback(orig_callback, orig_callback_baton_sp, orig_is_sync); - - return ret_val; +void BreakpointOptions::CopyOverSetOptions(const BreakpointOptions &incoming) +{ + if (incoming.m_set_flags.Test(eEnabled)) + { + m_enabled = incoming.m_enabled; + m_set_flags.Set(eEnabled); + } + if (incoming.m_set_flags.Test(eOneShot)) + { + m_one_shot = incoming.m_one_shot; + m_set_flags.Set(eOneShot); + } + if (incoming.m_set_flags.Test(eCallback)) + { + m_callback = incoming.m_callback; + m_callback_baton_sp = incoming.m_callback_baton_sp; + m_callback_is_synchronous = incoming.m_callback_is_synchronous; + m_baton_is_command_baton = incoming.m_baton_is_command_baton; + m_set_flags.Set(eCallback); + } + if (incoming.m_set_flags.Test(eIgnoreCount)) + { + m_ignore_count = incoming.m_ignore_count; + m_set_flags.Set(eIgnoreCount); + } + if (incoming.m_set_flags.Test(eCondition)) + { + // If we're copying over an empty condition, mark it as unset. + if (incoming.m_condition_text.empty()) { + m_condition_text.clear(); + m_condition_text_hash = 0; + m_set_flags.Clear(eCondition); + } else { + m_condition_text = incoming.m_condition_text; + m_condition_text_hash = incoming.m_condition_text_hash; + m_set_flags.Set(eCondition); + } + } + if (incoming.m_set_flags.Test(eAutoContinue)) + { + m_auto_continue = incoming.m_auto_continue; + m_set_flags.Set(eAutoContinue); + } + if (incoming.m_set_flags.Test(eThreadSpec) && incoming.m_thread_spec_ap) + { + if (!m_thread_spec_ap) + m_thread_spec_ap.reset(new ThreadSpec(*incoming.m_thread_spec_ap.get())); + else + *m_thread_spec_ap.get() = *incoming.m_thread_spec_ap.get(); + m_set_flags.Set(eThreadSpec); + } } //---------------------------------------------------------------------- @@ -199,30 +253,65 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData( Status &error) { bool enabled = true; bool one_shot = false; + bool auto_continue = false; int32_t ignore_count = 0; - std::string condition_text; - - bool success = options_dict.GetValueForKeyAsBoolean( - GetKey(OptionNames::EnabledState), enabled); - if (!success) { - error.SetErrorStringWithFormat("%s key is not a boolean.", + llvm::StringRef condition_ref(""); + Flags set_options; + + const char *key = GetKey(OptionNames::EnabledState); + bool success; + if (key) { + success = options_dict.GetValueForKeyAsBoolean(key, enabled); + if (!success) { + error.SetErrorStringWithFormat("%s key is not a boolean.", GetKey(OptionNames::EnabledState)); - return nullptr; + return nullptr; + } + set_options.Set(eEnabled); } - success = options_dict.GetValueForKeyAsBoolean( - GetKey(OptionNames::OneShotState), one_shot); - if (!success) { - error.SetErrorStringWithFormat("%s key is not a boolean.", - GetKey(OptionNames::OneShotState)); - return nullptr; + key = GetKey(OptionNames::OneShotState); + if (key) { + success = options_dict.GetValueForKeyAsBoolean(key, one_shot); + if (!success) { + error.SetErrorStringWithFormat("%s key is not a boolean.", + GetKey(OptionNames::OneShotState)); + return nullptr; + } + set_options.Set(eOneShot); } - success = options_dict.GetValueForKeyAsInteger( - GetKey(OptionNames::IgnoreCount), ignore_count); - if (!success) { - error.SetErrorStringWithFormat("%s key is not an integer.", - GetKey(OptionNames::IgnoreCount)); - return nullptr; + + key = GetKey(OptionNames::AutoContinue); + if (key) { + success = options_dict.GetValueForKeyAsBoolean(key, auto_continue); + if (!success) { + error.SetErrorStringWithFormat("%s key is not a boolean.", + GetKey(OptionNames::AutoContinue)); + return nullptr; + } + set_options.Set(eAutoContinue); + } + + key = GetKey(OptionNames::IgnoreCount); + if (key) { + success = options_dict.GetValueForKeyAsInteger(key, ignore_count); + if (!success) { + error.SetErrorStringWithFormat("%s key is not an integer.", + GetKey(OptionNames::IgnoreCount)); + return nullptr; + } + set_options.Set(eIgnoreCount); + } + + key = GetKey(OptionNames::ConditionText); + if (key) { + success = options_dict.GetValueForKeyAsString(key, condition_ref); + if (!success) { + error.SetErrorStringWithFormat("%s key is not an string.", + GetKey(OptionNames::ConditionText)); + return nullptr; + } + set_options.Set(eCondition); } std::unique_ptr<CommandData> cmd_data_up; @@ -241,7 +330,8 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData( } auto bp_options = llvm::make_unique<BreakpointOptions>( - condition_text.c_str(), enabled, ignore_count, one_shot); + condition_ref.str().c_str(), enabled, + ignore_count, one_shot, auto_continue); if (cmd_data_up.get()) { if (cmd_data_up->interpreter == eScriptLanguageNone) bp_options->SetCommandDataCallback(cmd_data_up); @@ -293,14 +383,23 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData( StructuredData::ObjectSP BreakpointOptions::SerializeToStructuredData() { StructuredData::DictionarySP options_dict_sp( new StructuredData::Dictionary()); - options_dict_sp->AddBooleanItem(GetKey(OptionNames::EnabledState), m_enabled); - options_dict_sp->AddBooleanItem(GetKey(OptionNames::OneShotState), - m_one_shot); - options_dict_sp->AddIntegerItem(GetKey(OptionNames::IgnoreCount), - m_ignore_count); - options_dict_sp->AddStringItem(GetKey(OptionNames::ConditionText), - m_condition_text); - if (m_baton_is_command_baton) { + if (m_set_flags.Test(eEnabled)) + options_dict_sp->AddBooleanItem(GetKey(OptionNames::EnabledState), + m_enabled); + if (m_set_flags.Test(eOneShot)) + options_dict_sp->AddBooleanItem(GetKey(OptionNames::OneShotState), + m_one_shot); + if (m_set_flags.Test(eAutoContinue)) + options_dict_sp->AddBooleanItem(GetKey(OptionNames::AutoContinue), + m_auto_continue); + if (m_set_flags.Test(eIgnoreCount)) + options_dict_sp->AddIntegerItem(GetKey(OptionNames::IgnoreCount), + m_ignore_count); + if (m_set_flags.Test(eCondition)) + options_dict_sp->AddStringItem(GetKey(OptionNames::ConditionText), + m_condition_text); + + if (m_set_flags.Test(eCallback) && m_baton_is_command_baton) { auto cmd_baton = std::static_pointer_cast<CommandBaton>(m_callback_baton_sp); StructuredData::ObjectSP commands_sp = @@ -310,7 +409,7 @@ StructuredData::ObjectSP BreakpointOptions::SerializeToStructuredData() { BreakpointOptions::CommandData::GetSerializationKey(), commands_sp); } } - if (m_thread_spec_ap) { + if (m_set_flags.Test(eThreadSpec) && m_thread_spec_ap) { StructuredData::ObjectSP thread_spec_sp = m_thread_spec_ap->SerializeToStructuredData(); options_dict_sp->AddItem(ThreadSpec::GetSerializationKey(), thread_spec_sp); @@ -340,6 +439,7 @@ void BreakpointOptions::SetCallback(BreakpointHitCallback callback, m_callback = callback; m_callback_baton_sp = callback_baton_sp; m_baton_is_command_baton = false; + m_set_flags.Set(eCallback); } void BreakpointOptions::SetCallback( @@ -350,6 +450,7 @@ void BreakpointOptions::SetCallback( m_callback = callback; m_callback_baton_sp = callback_baton_sp; m_baton_is_command_baton = true; + m_set_flags.Set(eCallback); } void BreakpointOptions::ClearCallback() { @@ -357,6 +458,7 @@ void BreakpointOptions::ClearCallback() { m_callback_is_synchronous = false; m_callback_baton_sp.reset(); m_baton_is_command_baton = false; + m_set_flags.Clear(eCallback); } Baton *BreakpointOptions::GetBaton() { return m_callback_baton_sp.get(); } @@ -395,8 +497,12 @@ bool BreakpointOptions::GetCommandLineCallbacks(StringList &command_list) { } void BreakpointOptions::SetCondition(const char *condition) { - if (!condition) + if (!condition || condition[0] == '\0') { condition = ""; + m_set_flags.Clear(eCondition); + } + else + m_set_flags.Set(eCondition); m_condition_text.assign(condition); std::hash<std::string> hasher; @@ -427,11 +533,13 @@ ThreadSpec *BreakpointOptions::GetThreadSpec() { void BreakpointOptions::SetThreadID(lldb::tid_t thread_id) { GetThreadSpec()->SetTID(thread_id); + m_set_flags.Set(eThreadSpec); } void BreakpointOptions::SetThreadSpec( std::unique_ptr<ThreadSpec> &thread_spec_up) { m_thread_spec_ap = std::move(thread_spec_up); + m_set_flags.Set(eThreadSpec); } void BreakpointOptions::GetDescription(Stream *s, @@ -440,7 +548,7 @@ void BreakpointOptions::GetDescription(Stream *s, // print // anything if there are: - if (m_ignore_count != 0 || !m_enabled || m_one_shot || + if (m_ignore_count != 0 || !m_enabled || m_one_shot || m_auto_continue || (GetThreadSpecNoCreate() != nullptr && GetThreadSpecNoCreate()->HasSpecification())) { if (level == lldb::eDescriptionLevelVerbose) { @@ -460,6 +568,9 @@ void BreakpointOptions::GetDescription(Stream *s, if (m_one_shot) s->Printf("one-shot "); + if (m_auto_continue) + s->Printf("auto-continue "); + if (m_thread_spec_ap.get()) m_thread_spec_ap->GetDescription(s, level); @@ -520,6 +631,7 @@ void BreakpointOptions::SetCommandDataCallback( cmd_data->interpreter = eScriptLanguageNone; auto baton_sp = std::make_shared<CommandBaton>(std::move(cmd_data)); SetCallback(BreakpointOptions::BreakpointOptionsCallbackFunction, baton_sp); + m_set_flags.Set(eCallback); } bool BreakpointOptions::BreakpointOptionsCallbackFunction( @@ -562,3 +674,18 @@ bool BreakpointOptions::BreakpointOptionsCallbackFunction( } return ret_value; } + +void BreakpointOptions::Clear() +{ + m_set_flags.Clear(); + m_thread_spec_ap.release(); + m_one_shot = false; + m_ignore_count = 0; + m_auto_continue = false; + m_callback = nullptr; + m_callback_baton_sp.reset(); + m_baton_is_command_baton = false; + m_callback_is_synchronous = false; + m_enabled = false; + m_condition_text.clear(); +} |