diff options
author | Adrian Prantl <aprantl@apple.com> | 2024-08-27 10:59:31 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-27 10:59:31 -0700 |
commit | 0642cd768b80665585c8500bed2933a3b99123dc (patch) | |
tree | a412a5eafff54ef9a7cb884e01907a4f521f5140 /lldb/source/Commands/CommandObjectCommands.cpp | |
parent | acb33a0c9bc902dc1aef703c02b8fd3a1132cb14 (diff) | |
download | llvm-0642cd768b80665585c8500bed2933a3b99123dc.zip llvm-0642cd768b80665585c8500bed2933a3b99123dc.tar.gz llvm-0642cd768b80665585c8500bed2933a3b99123dc.tar.bz2 |
[lldb] Turn lldb_private::Status into a value type. (#106163)
This patch removes all of the Set.* methods from Status.
This cleanup is part of a series of patches that make it harder use the
anti-pattern of keeping a long-lives Status object around and updating
it while dropping any errors it contains on the floor.
This patch is largely NFC, the more interesting next steps this enables
is to:
1. remove Status.Clear()
2. assert that Status::operator=() never overwrites an error
3. remove Status::operator=()
Note that step (2) will bring 90% of the benefits for users, and step
(3) will dramatically clean up the error handling code in various
places. In the end my goal is to convert all APIs that are of the form
` ResultTy DoFoo(Status& error)
`
to
` llvm::Expected<ResultTy> DoFoo()
`
How to read this patch?
The interesting changes are in Status.h and Status.cpp, all other
changes are mostly
` perl -pi -e 's/\.SetErrorString/ = Status::FromErrorString/g' $(git
grep -l SetErrorString lldb/source)
`
plus the occasional manual cleanup.
Diffstat (limited to 'lldb/source/Commands/CommandObjectCommands.cpp')
-rw-r--r-- | lldb/source/Commands/CommandObjectCommands.cpp | 184 |
1 files changed, 111 insertions, 73 deletions
diff --git a/lldb/source/Commands/CommandObjectCommands.cpp b/lldb/source/Commands/CommandObjectCommands.cpp index 7c439f4..f8f2b97 100644 --- a/lldb/source/Commands/CommandObjectCommands.cpp +++ b/lldb/source/Commands/CommandObjectCommands.cpp @@ -878,7 +878,7 @@ protected: Status error; if (!m_regex_cmd_up) { - error.SetErrorStringWithFormat( + return Status::FromErrorStringWithFormat( "invalid regular expression command object for: '%.*s'", (int)regex_sed.size(), regex_sed.data()); return error; @@ -887,16 +887,17 @@ protected: size_t regex_sed_size = regex_sed.size(); if (regex_sed_size <= 1) { - error.SetErrorStringWithFormat( + return Status::FromErrorStringWithFormat( "regular expression substitution string is too short: '%.*s'", (int)regex_sed.size(), regex_sed.data()); return error; } if (regex_sed[0] != 's') { - error.SetErrorStringWithFormat("regular expression substitution string " - "doesn't start with 's': '%.*s'", - (int)regex_sed.size(), regex_sed.data()); + return Status::FromErrorStringWithFormat( + "regular expression substitution string " + "doesn't start with 's': '%.*s'", + (int)regex_sed.size(), regex_sed.data()); return error; } const size_t first_separator_char_pos = 1; @@ -907,7 +908,7 @@ protected: regex_sed.find(separator_char, first_separator_char_pos + 1); if (second_separator_char_pos == std::string::npos) { - error.SetErrorStringWithFormat( + return Status::FromErrorStringWithFormat( "missing second '%c' separator char after '%.*s' in '%.*s'", separator_char, (int)(regex_sed.size() - first_separator_char_pos - 1), @@ -920,7 +921,7 @@ protected: regex_sed.find(separator_char, second_separator_char_pos + 1); if (third_separator_char_pos == std::string::npos) { - error.SetErrorStringWithFormat( + return Status::FromErrorStringWithFormat( "missing third '%c' separator char after '%.*s' in '%.*s'", separator_char, (int)(regex_sed.size() - second_separator_char_pos - 1), @@ -934,7 +935,7 @@ protected: if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos) { - error.SetErrorStringWithFormat( + return Status::FromErrorStringWithFormat( "extra data found after the '%.*s' regular expression substitution " "string: '%.*s'", (int)third_separator_char_pos + 1, regex_sed.data(), @@ -943,13 +944,13 @@ protected: return error; } } else if (first_separator_char_pos + 1 == second_separator_char_pos) { - error.SetErrorStringWithFormat( + return Status::FromErrorStringWithFormat( "<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", separator_char, separator_char, separator_char, (int)regex_sed.size(), regex_sed.data()); return error; } else if (second_separator_char_pos + 1 == third_separator_char_pos) { - error.SetErrorStringWithFormat( + return Status::FromErrorStringWithFormat( "<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", separator_char, separator_char, separator_char, (int)regex_sed.size(), regex_sed.data()); @@ -1249,16 +1250,19 @@ private: ScriptInterpreter *scripter = m_interpreter.GetDebugger().GetScriptInterpreter(); if (!scripter) { - error.SetErrorString("No script interpreter for SetOptionValue."); + return Status::FromErrorString( + "No script interpreter for SetOptionValue."); return error; } if (!m_cmd_obj_sp) { - error.SetErrorString("SetOptionValue called with empty cmd_obj."); + return Status::FromErrorString( + "SetOptionValue called with empty cmd_obj."); return error; } if (!m_options_definition_up) { - error.SetErrorString("SetOptionValue called before options definitions " - "were created."); + return Status::FromErrorString( + "SetOptionValue called before options definitions " + "were created."); return error; } // Pass the long option, since you aren't actually required to have a @@ -1269,8 +1273,8 @@ private: bool success = scripter->SetOptionValueForCommandObject(m_cmd_obj_sp, execution_context, long_option, option_arg); if (!success) - error.SetErrorStringWithFormatv("Error setting option: {0} to {1}", - long_option, option_arg); + return Status::FromErrorStringWithFormatv( + "Error setting option: {0} to {1}", long_option, option_arg); return error; } @@ -1311,9 +1315,8 @@ private: // If this is an integer, then this specifies a single group: uint32_t value = uint_val->GetValue(); if (value == 0) { - error.SetErrorStringWithFormatv( + return Status::FromErrorStringWithFormatv( "0 is not a valid group for option {0}", counter); - return error; } usage_mask = (1 << (value - 1)); return error; @@ -1321,9 +1324,8 @@ private: // Otherwise it has to be an array: StructuredData::Array *array_val = obj_sp->GetAsArray(); if (!array_val) { - error.SetErrorStringWithFormatv( + return Status::FromErrorStringWithFormatv( "required field is not a array for option {0}", counter); - return error; } // This is the array ForEach for accumulating a group usage mask from // an array of string descriptions of groups. @@ -1334,7 +1336,7 @@ private: if (int_val) { uint32_t value = int_val->GetValue(); if (value == 0) { - error.SetErrorStringWithFormatv( + error = Status::FromErrorStringWithFormatv( "0 is not a valid group for element {0}", counter); return false; } @@ -1343,35 +1345,41 @@ private: } StructuredData::Array *arr_val = obj->GetAsArray(); if (!arr_val) { - error.SetErrorStringWithFormatv( - "Group element not an int or array of integers for element {0}", + error = Status::FromErrorStringWithFormatv( + "Group element not an int or array of integers for element {0}", counter); return false; } size_t num_range_elem = arr_val->GetSize(); if (num_range_elem != 2) { - error.SetErrorStringWithFormatv( - "Subranges of a group not a start and a stop for element {0}", + error = Status::FromErrorStringWithFormatv( + "Subranges of a group not a start and a stop for element {0}", counter); return false; } int_val = arr_val->GetItemAtIndex(0)->GetAsUnsignedInteger(); if (!int_val) { - error.SetErrorStringWithFormatv("Start element of a subrange of a " - "group not unsigned int for element {0}", counter); + error = Status::FromErrorStringWithFormatv( + "Start element of a subrange of a " + "group not unsigned int for element {0}", + counter); return false; } uint32_t start = int_val->GetValue(); int_val = arr_val->GetItemAtIndex(1)->GetAsUnsignedInteger(); if (!int_val) { - error.SetErrorStringWithFormatv("End element of a subrange of a group" - " not unsigned int for element {0}", counter); + error = Status::FromErrorStringWithFormatv( + "End element of a subrange of a group" + " not unsigned int for element {0}", + counter); return false; } uint32_t end = int_val->GetValue(); if (start == 0 || end == 0 || start > end) { - error.SetErrorStringWithFormatv("Invalid subrange of a group: {0} - " - "{1} for element {2}", start, end, counter); + error = Status::FromErrorStringWithFormatv( + "Invalid subrange of a group: {0} - " + "{1} for element {2}", + start, end, counter); return false; } for (uint32_t i = start; i <= end; i++) { @@ -1401,7 +1409,8 @@ private: (llvm::StringRef long_option, StructuredData::Object *object) -> bool { StructuredData::Dictionary *opt_dict = object->GetAsDictionary(); if (!opt_dict) { - error.SetErrorString("Value in options dictionary is not a dictionary"); + error = Status::FromErrorString( + "Value in options dictionary is not a dictionary"); return false; } OptionDefinition &option_def = m_options_definition_up.get()[counter]; @@ -1432,8 +1441,10 @@ private: if (obj_sp) { StructuredData::Boolean *boolean_val = obj_sp->GetAsBoolean(); if (!boolean_val) { - error.SetErrorStringWithFormatv("'required' field is not a boolean " - "for option {0}", counter); + error = Status::FromErrorStringWithFormatv( + "'required' field is not a boolean " + "for option {0}", + counter); return false; } option_def.required = boolean_val->GetValue(); @@ -1446,12 +1457,16 @@ private: // The value is a string, so pull the llvm::StringRef short_str = obj_sp->GetStringValue(); if (short_str.empty()) { - error.SetErrorStringWithFormatv("short_option field empty for " - "option {0}", counter); + error = Status::FromErrorStringWithFormatv( + "short_option field empty for " + "option {0}", + counter); return false; } else if (short_str.size() != 1) { - error.SetErrorStringWithFormatv("short_option field has extra " - "characters for option {0}", counter); + error = Status::FromErrorStringWithFormatv( + "short_option field has extra " + "characters for option {0}", + counter); return false; } short_option = (int) short_str[0]; @@ -1464,8 +1479,8 @@ private: // Long Option is the key from the outer dict: if (long_option.empty()) { - error.SetErrorStringWithFormatv("empty long_option for option {0}", - counter); + error = Status::FromErrorStringWithFormatv( + "empty long_option for option {0}", counter); return false; } auto inserted = g_string_storer.insert(long_option.str()); @@ -1477,14 +1492,17 @@ private: StructuredData::UnsignedInteger *uint_val = obj_sp->GetAsUnsignedInteger(); if (!uint_val) { - error.SetErrorStringWithFormatv("Value type must be an unsigned " + error = Status::FromErrorStringWithFormatv( + "Value type must be an unsigned " "integer"); return false; } uint64_t val_type = uint_val->GetValue(); if (val_type >= eArgTypeLastArg) { - error.SetErrorStringWithFormatv("Value type {0} beyond the " - "CommandArgumentType bounds", val_type); + error = + Status::FromErrorStringWithFormatv("Value type {0} beyond the " + "CommandArgumentType bounds", + val_type); return false; } option_def.argument_type = (CommandArgumentType) val_type; @@ -1499,14 +1517,18 @@ private: if (obj_sp) { StructuredData::UnsignedInteger *uint_val = obj_sp->GetAsUnsignedInteger(); if (!uint_val) { - error.SetErrorStringWithFormatv("Completion type must be an " - "unsigned integer for option {0}", counter); + error = Status::FromErrorStringWithFormatv( + "Completion type must be an " + "unsigned integer for option {0}", + counter); return false; } uint64_t completion_type = uint_val->GetValue(); if (completion_type > eCustomCompletion) { - error.SetErrorStringWithFormatv("Completion type for option {0} " - "beyond the CompletionType bounds", completion_type); + error = Status::FromErrorStringWithFormatv( + "Completion type for option {0} " + "beyond the CompletionType bounds", + completion_type); return false; } option_def.completion_type = (CommandArgumentType) completion_type; @@ -1517,15 +1539,17 @@ private: std::string usage_text; obj_sp = opt_dict->GetValueForKey("help"); if (!obj_sp) { - error.SetErrorStringWithFormatv("required usage missing from option " - "{0}", counter); + error = Status::FromErrorStringWithFormatv( + "required usage missing from option " + "{0}", + counter); return false; } llvm::StringRef usage_stref; usage_stref = obj_sp->GetStringValue(); if (usage_stref.empty()) { - error.SetErrorStringWithFormatv("empty usage text for option {0}", - counter); + error = Status::FromErrorStringWithFormatv( + "empty usage text for option {0}", counter); return false; } m_usage_container[counter] = usage_stref.str().c_str(); @@ -1537,8 +1561,10 @@ private: if (obj_sp) { StructuredData::Array *array = obj_sp->GetAsArray(); if (!array) { - error.SetErrorStringWithFormatv("enum values must be an array for " - "option {0}", counter); + error = Status::FromErrorStringWithFormatv( + "enum values must be an array for " + "option {0}", + counter); return false; } size_t num_elem = array->GetSize(); @@ -1554,13 +1580,16 @@ private: (StructuredData::Object *object) -> bool { StructuredData::Array *enum_arr = object->GetAsArray(); if (!enum_arr) { - error.SetErrorStringWithFormatv("Enum values for option {0} not " - "an array", counter); + error = Status::FromErrorStringWithFormatv( + "Enum values for option {0} not " + "an array", + counter); return false; } size_t num_enum_elements = enum_arr->GetSize(); if (num_enum_elements != 2) { - error.SetErrorStringWithFormatv("Wrong number of elements: {0} " + error = Status::FromErrorStringWithFormatv( + "Wrong number of elements: {0} " "for enum {1} in option {2}", num_enum_elements, enum_ctr, counter); return false; @@ -1573,8 +1602,10 @@ private: // Enum Usage: obj_sp = enum_arr->GetItemAtIndex(1); if (!obj_sp) { - error.SetErrorStringWithFormatv("No usage for enum {0} in option " - "{1}", enum_ctr, counter); + error = Status::FromErrorStringWithFormatv( + "No usage for enum {0} in option " + "{1}", + enum_ctr, counter); return false; } llvm::StringRef usage_stref = obj_sp->GetStringValue(); @@ -1701,7 +1732,7 @@ public: StreamString stream; ScriptInterpreter *scripter = GetDebugger().GetScriptInterpreter(); if (!scripter) { - m_options_error.SetErrorString("No script interpreter"); + m_options_error = Status::FromErrorString("No script interpreter"); return; } @@ -1725,7 +1756,7 @@ public: if (m_options_error.Fail()) return; } else { - m_options_error.SetErrorString("Options array not an array"); + m_options_error = Status::FromErrorString("Options array not an array"); return; } } @@ -1736,7 +1767,8 @@ public: if (args_object_sp) { StructuredData::Array *args_array = args_object_sp->GetAsArray(); if (!args_array) { - m_args_error.SetErrorString("Argument specification is not an array"); + m_args_error = + Status::FromErrorString("Argument specification is not an array"); return; } size_t counter = 0; @@ -1755,14 +1787,16 @@ public: CommandArgumentType arg_type = eArgTypeNone; ArgumentRepetitionType arg_repetition = eArgRepeatOptional; uint32_t arg_opt_set_association; - - auto report_error = [this, elem_counter, counter] - (const char *err_txt) -> bool { - m_args_error.SetErrorStringWithFormatv("Element {0} of arguments " - "list element {1}: %s.", elem_counter, counter, err_txt); + + auto report_error = [this, elem_counter, + counter](const char *err_txt) -> bool { + m_args_error = Status::FromErrorStringWithFormatv( + "Element {0} of arguments " + "list element {1}: %s.", + elem_counter, counter, err_txt); return false; }; - + StructuredData::Dictionary *arg_dict = object->GetAsDictionary(); if (!arg_dict) { report_error("is not a dictionary."); @@ -1813,16 +1847,20 @@ public: }; StructuredData::Array *args_array = object->GetAsArray(); if (!args_array) { - m_args_error.SetErrorStringWithFormatv("Argument definition element " - "{0} is not an array", counter); + m_args_error = + Status::FromErrorStringWithFormatv("Argument definition element " + "{0} is not an array", + counter); } args_array->ForEach(args_adder); if (m_args_error.Fail()) return false; if (this_entry.empty()) { - m_args_error.SetErrorStringWithFormatv("Argument definition element " - "{0} is empty", counter); + m_args_error = + Status::FromErrorStringWithFormatv("Argument definition element " + "{0} is empty", + counter); return false; } m_arguments.push_back(this_entry); @@ -2098,7 +2136,7 @@ protected: (ScriptedCommandSynchronicity)OptionArgParser::ToOptionEnum( option_arg, GetDefinitions()[option_idx].enum_values, 0, error); if (!error.Success()) - error.SetErrorStringWithFormat( + return Status::FromErrorStringWithFormat( "unrecognized value for synchronicity '%s'", option_arg.str().c_str()); break; @@ -2109,7 +2147,7 @@ protected: static_cast<lldb::CompletionType>(OptionArgParser::ToOptionEnum( option_arg, definition.enum_values, eNoCompletion, error)); if (!error.Success()) - error.SetErrorStringWithFormat( + return Status::FromErrorStringWithFormat( "unrecognized value for command completion type '%s'", option_arg.str().c_str()); m_completion_type = completion_type; |