summaryrefslogtreecommitdiff
path: root/source/Breakpoint/BreakpointOptions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Breakpoint/BreakpointOptions.cpp')
-rw-r--r--source/Breakpoint/BreakpointOptions.cpp231
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();
+}