diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:09:23 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:09:23 +0000 |
commit | f73363f1dd94996356cefbf24388f561891acf0b (patch) | |
tree | e3c31248bdb36eaec5fd833490d4278162dba2a0 /source/Commands | |
parent | 160ee69dd7ae18978f4068116777639ea98dc951 (diff) |
Notes
Diffstat (limited to 'source/Commands')
33 files changed, 1013 insertions, 1630 deletions
diff --git a/source/Commands/CMakeLists.txt b/source/Commands/CMakeLists.txt index 55b41b1050c5a..1dbaab5174e0d 100644 --- a/source/Commands/CMakeLists.txt +++ b/source/Commands/CMakeLists.txt @@ -1,7 +1,6 @@ add_lldb_library(lldbCommands CommandCompletions.cpp CommandObjectApropos.cpp - CommandObjectArgs.cpp CommandObjectBreakpoint.cpp CommandObjectBreakpointCommand.cpp CommandObjectBugreport.cpp @@ -21,7 +20,7 @@ add_lldb_library(lldbCommands CommandObjectRegister.cpp CommandObjectSettings.cpp CommandObjectSource.cpp - CommandObjectSyntax.cpp + CommandObjectStats.cpp CommandObjectTarget.cpp CommandObjectThread.cpp CommandObjectType.cpp diff --git a/source/Commands/CommandCompletions.cpp b/source/Commands/CommandCompletions.cpp index 34cad970ff6ed..bdfdbb83219bd 100644 --- a/source/Commands/CommandCompletions.cpp +++ b/source/Commands/CommandCompletions.cpp @@ -23,14 +23,13 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Host/FileSystem.h" -#include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Variable.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/CleanUp.h" +#include "lldb/Utility/Args.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/TildeExpressionResolver.h" @@ -58,9 +57,7 @@ CommandCompletions::CommonCompletionElement bool CommandCompletions::InvokeCommonCompletionCallbacks( CommandInterpreter &interpreter, uint32_t completion_mask, - llvm::StringRef completion_str, int match_start_point, - int max_return_elements, SearchFilter *searcher, bool &word_complete, - StringList &matches) { + CompletionRequest &request, SearchFilter *searcher) { bool handled = false; if (completion_mask & eCustomCompletion) @@ -73,25 +70,18 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks( g_common_completions[i].type && g_common_completions[i].callback != nullptr) { handled = true; - g_common_completions[i].callback(interpreter, completion_str, - match_start_point, max_return_elements, - searcher, word_complete, matches); + g_common_completions[i].callback(interpreter, request, searcher); } } return handled; } int CommandCompletions::SourceFiles(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, - int match_start_point, - int max_return_elements, - SearchFilter *searcher, bool &word_complete, - StringList &matches) { - word_complete = true; + CompletionRequest &request, + SearchFilter *searcher) { + request.SetWordComplete(true); // Find some way to switch "include support files..." - SourceFileCompleter completer(interpreter, false, partial_file_name, - match_start_point, max_return_elements, - matches); + SourceFileCompleter completer(interpreter, false, request); if (searcher == nullptr) { lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); @@ -100,12 +90,11 @@ int CommandCompletions::SourceFiles(CommandInterpreter &interpreter, } else { completer.DoCompletion(searcher); } - return matches.GetSize(); + return request.GetMatches().GetSize(); } static int DiskFilesOrDirectories(const llvm::Twine &partial_name, - bool only_directories, bool &saw_directory, - StringList &matches, + bool only_directories, StringList &matches, TildeExpressionResolver &Resolver) { matches.Clear(); @@ -139,24 +128,22 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, // but after that, we're done regardless of any matches. if (FirstSep == llvm::StringRef::npos) { llvm::StringSet<> MatchSet; - saw_directory = Resolver.ResolvePartial(Username, MatchSet); + Resolver.ResolvePartial(Username, MatchSet); for (const auto &S : MatchSet) { Resolved = S.getKey(); path::append(Resolved, path::get_separator()); matches.AppendString(Resolved); } - saw_directory = (matches.GetSize() > 0); } return matches.GetSize(); } - // If there was no trailing slash, then we're done as soon as we resolve the - // expression to the correct directory. Otherwise we need to continue + // If there was no trailing slash, then we're done as soon as we resolve + // the expression to the correct directory. Otherwise we need to continue // looking for matches within that directory. if (FirstSep == llvm::StringRef::npos) { // Make sure it ends with a separator. path::append(CompletionBuffer, path::get_separator()); - saw_directory = true; matches.AppendString(CompletionBuffer); return 1; } @@ -165,7 +152,13 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, // search in the fully resolved directory, but CompletionBuffer keeps the // unmodified form that the user typed. Storage = Resolved; - SearchDir = Resolved; + llvm::StringRef RemainderDir = path::parent_path(Remainder); + if (!RemainderDir.empty()) { + // Append the remaining path to the resolved directory. + Storage.append(path::get_separator()); + Storage.append(RemainderDir); + } + SearchDir = Storage; } else { SearchDir = path::parent_path(CompletionBuffer); } @@ -222,7 +215,6 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, CompletionBuffer.append(Name); if (is_dir) { - saw_directory = true; path::append(CompletionBuffer, path::get_separator()); } @@ -233,51 +225,40 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, } int CommandCompletions::DiskFiles(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, - int match_start_point, - int max_return_elements, - SearchFilter *searcher, bool &word_complete, - StringList &matches) { - word_complete = false; + CompletionRequest &request, + SearchFilter *searcher) { + request.SetWordComplete(false); StandardTildeExpressionResolver Resolver; - return DiskFiles(partial_file_name, matches, Resolver); + return DiskFiles(request.GetCursorArgumentPrefix(), request.GetMatches(), + Resolver); } int CommandCompletions::DiskFiles(const llvm::Twine &partial_file_name, StringList &matches, TildeExpressionResolver &Resolver) { - bool word_complete; - int ret_val = DiskFilesOrDirectories(partial_file_name, false, word_complete, - matches, Resolver); - return ret_val; + return DiskFilesOrDirectories(partial_file_name, false, matches, Resolver); } -int CommandCompletions::DiskDirectories( - CommandInterpreter &interpreter, llvm::StringRef partial_file_name, - int match_start_point, int max_return_elements, SearchFilter *searcher, - bool &word_complete, StringList &matches) { - word_complete = false; +int CommandCompletions::DiskDirectories(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + request.SetWordComplete(false); StandardTildeExpressionResolver Resolver; - return DiskDirectories(partial_file_name, matches, Resolver); + return DiskDirectories(request.GetCursorArgumentPrefix(), + request.GetMatches(), Resolver); } int CommandCompletions::DiskDirectories(const llvm::Twine &partial_file_name, StringList &matches, TildeExpressionResolver &Resolver) { - bool word_complete; - int ret_val = DiskFilesOrDirectories(partial_file_name, true, word_complete, - matches, Resolver); - return ret_val; + return DiskFilesOrDirectories(partial_file_name, true, matches, Resolver); } int CommandCompletions::Modules(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, - int match_start_point, int max_return_elements, - SearchFilter *searcher, bool &word_complete, - StringList &matches) { - word_complete = true; - ModuleCompleter completer(interpreter, partial_file_name, match_start_point, - max_return_elements, matches); + CompletionRequest &request, + SearchFilter *searcher) { + request.SetWordComplete(true); + ModuleCompleter completer(interpreter, request); if (searcher == nullptr) { lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); @@ -286,17 +267,14 @@ int CommandCompletions::Modules(CommandInterpreter &interpreter, } else { completer.DoCompletion(searcher); } - return matches.GetSize(); + return request.GetMatches().GetSize(); } int CommandCompletions::Symbols(CommandInterpreter &interpreter, - llvm::StringRef partial_file_name, - int match_start_point, int max_return_elements, - SearchFilter *searcher, bool &word_complete, - StringList &matches) { - word_complete = true; - SymbolCompleter completer(interpreter, partial_file_name, match_start_point, - max_return_elements, matches); + CompletionRequest &request, + SearchFilter *searcher) { + request.SetWordComplete(true); + SymbolCompleter completer(interpreter, request); if (searcher == nullptr) { lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); @@ -305,13 +283,12 @@ int CommandCompletions::Symbols(CommandInterpreter &interpreter, } else { completer.DoCompletion(searcher); } - return matches.GetSize(); + return request.GetMatches().GetSize(); } -int CommandCompletions::SettingsNames( - CommandInterpreter &interpreter, llvm::StringRef partial_setting_name, - int match_start_point, int max_return_elements, SearchFilter *searcher, - bool &word_complete, StringList &matches) { +int CommandCompletions::SettingsNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { // Cache the full setting name list static StringList g_property_names; if (g_property_names.GetSize() == 0) { @@ -327,47 +304,39 @@ int CommandCompletions::SettingsNames( } size_t exact_matches_idx = SIZE_MAX; - const size_t num_matches = g_property_names.AutoComplete( - partial_setting_name, matches, exact_matches_idx); - word_complete = exact_matches_idx != SIZE_MAX; + const size_t num_matches = + g_property_names.AutoComplete(request.GetCursorArgumentPrefix(), + request.GetMatches(), exact_matches_idx); + request.SetWordComplete(exact_matches_idx != SIZE_MAX); return num_matches; } -int CommandCompletions::PlatformPluginNames( - CommandInterpreter &interpreter, llvm::StringRef partial_name, - int match_start_point, int max_return_elements, SearchFilter *searcher, - bool &word_complete, lldb_private::StringList &matches) { - const uint32_t num_matches = - PluginManager::AutoCompletePlatformName(partial_name, matches); - word_complete = num_matches == 1; +int CommandCompletions::PlatformPluginNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + const uint32_t num_matches = PluginManager::AutoCompletePlatformName( + request.GetCursorArgumentPrefix(), request.GetMatches()); + request.SetWordComplete(num_matches == 1); return num_matches; } -int CommandCompletions::ArchitectureNames( - CommandInterpreter &interpreter, llvm::StringRef partial_name, - int match_start_point, int max_return_elements, SearchFilter *searcher, - bool &word_complete, lldb_private::StringList &matches) { - const uint32_t num_matches = ArchSpec::AutoComplete(partial_name, matches); - word_complete = num_matches == 1; +int CommandCompletions::ArchitectureNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + const uint32_t num_matches = ArchSpec::AutoComplete(request); + request.SetWordComplete(num_matches == 1); return num_matches; } -int CommandCompletions::VariablePath( - CommandInterpreter &interpreter, llvm::StringRef partial_name, - int match_start_point, int max_return_elements, SearchFilter *searcher, - bool &word_complete, lldb_private::StringList &matches) { - return Variable::AutoComplete(interpreter.GetExecutionContext(), partial_name, - matches, word_complete); +int CommandCompletions::VariablePath(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + return Variable::AutoComplete(interpreter.GetExecutionContext(), request); } CommandCompletions::Completer::Completer(CommandInterpreter &interpreter, - llvm::StringRef completion_str, - int match_start_point, - int max_return_elements, - StringList &matches) - : m_interpreter(interpreter), m_completion_str(completion_str), - m_match_start_point(match_start_point), - m_max_return_elements(max_return_elements), m_matches(matches) {} + CompletionRequest &request) + : m_interpreter(interpreter), m_request(request) {} CommandCompletions::Completer::~Completer() = default; @@ -377,13 +346,10 @@ CommandCompletions::Completer::~Completer() = default; CommandCompletions::SourceFileCompleter::SourceFileCompleter( CommandInterpreter &interpreter, bool include_support_files, - llvm::StringRef completion_str, int match_start_point, - int max_return_elements, StringList &matches) - : CommandCompletions::Completer(interpreter, completion_str, - match_start_point, max_return_elements, - matches), + CompletionRequest &request) + : CommandCompletions::Completer(interpreter, request), m_include_support_files(include_support_files), m_matching_files() { - FileSpec partial_spec(m_completion_str, false); + FileSpec partial_spec(m_request.GetCursorArgumentPrefix(), false); m_file_name = partial_spec.GetFilename().GetCString(); m_dir_name = partial_spec.GetDirectory().GetCString(); } @@ -443,10 +409,10 @@ CommandCompletions::SourceFileCompleter::DoCompletion(SearchFilter *filter) { filter->Search(*this); // Now convert the filelist to completions: for (size_t i = 0; i < m_matching_files.GetSize(); i++) { - m_matches.AppendString( + m_request.GetMatches().AppendString( m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString()); } - return m_matches.GetSize(); + return m_request.GetMatches().GetSize(); } //---------------------------------------------------------------------- @@ -461,15 +427,12 @@ static bool regex_chars(const char comp) { } CommandCompletions::SymbolCompleter::SymbolCompleter( - CommandInterpreter &interpreter, llvm::StringRef completion_str, - int match_start_point, int max_return_elements, StringList &matches) - : CommandCompletions::Completer(interpreter, completion_str, - match_start_point, max_return_elements, - matches) { + CommandInterpreter &interpreter, CompletionRequest &request) + : CommandCompletions::Completer(interpreter, request) { std::string regex_str; - if (!completion_str.empty()) { + if (!m_request.GetCursorArgumentPrefix().empty()) { regex_str.append("^"); - regex_str.append(completion_str); + regex_str.append(m_request.GetCursorArgumentPrefix()); } else { // Match anything since the completion string is empty regex_str.append("."); @@ -515,21 +478,18 @@ size_t CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) { filter->Search(*this); collection::iterator pos = m_match_set.begin(), end = m_match_set.end(); for (pos = m_match_set.begin(); pos != end; pos++) - m_matches.AppendString((*pos).GetCString()); + m_request.GetMatches().AppendString((*pos).GetCString()); - return m_matches.GetSize(); + return m_request.GetMatches().GetSize(); } //---------------------------------------------------------------------- // ModuleCompleter //---------------------------------------------------------------------- CommandCompletions::ModuleCompleter::ModuleCompleter( - CommandInterpreter &interpreter, llvm::StringRef completion_str, - int match_start_point, int max_return_elements, StringList &matches) - : CommandCompletions::Completer(interpreter, completion_str, - match_start_point, max_return_elements, - matches) { - FileSpec partial_spec(m_completion_str, false); + CommandInterpreter &interpreter, CompletionRequest &request) + : CommandCompletions::Completer(interpreter, request) { + FileSpec partial_spec(m_request.GetCursorArgumentPrefix(), false); m_file_name = partial_spec.GetFilename().GetCString(); m_dir_name = partial_spec.GetDirectory().GetCString(); } @@ -557,7 +517,7 @@ Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback( match = false; if (match) { - m_matches.AppendString(cur_file_name); + m_request.GetMatches().AppendString(cur_file_name); } } return Searcher::eCallbackReturnContinue; @@ -565,5 +525,5 @@ Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback( size_t CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) { filter->Search(*this); - return m_matches.GetSize(); + return m_request.GetMatches().GetSize(); } diff --git a/source/Commands/CommandObjectApropos.cpp b/source/Commands/CommandObjectApropos.cpp index 1114a511aa079..047575278faa1 100644 --- a/source/Commands/CommandObjectApropos.cpp +++ b/source/Commands/CommandObjectApropos.cpp @@ -13,11 +13,11 @@ // Other libraries and framework includes // Project includes #include "CommandObjectApropos.h" -#include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/Options.h" #include "lldb/Interpreter/Property.h" +#include "lldb/Utility/Args.h" using namespace lldb; using namespace lldb_private; @@ -53,8 +53,8 @@ bool CommandObjectApropos::DoExecute(Args &args, CommandReturnObject &result) { if (argc == 1) { auto search_word = args[0].ref; if (!search_word.empty()) { - // The bulk of the work must be done inside the Command Interpreter, since - // the command dictionary is private. + // The bulk of the work must be done inside the Command Interpreter, + // since the command dictionary is private. StringList commands_found; StringList commands_help; diff --git a/source/Commands/CommandObjectArgs.cpp b/source/Commands/CommandObjectArgs.cpp deleted file mode 100644 index 92c2107dc33c3..0000000000000 --- a/source/Commands/CommandObjectArgs.cpp +++ /dev/null @@ -1,234 +0,0 @@ -//===-- CommandObjectArgs.cpp -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "CommandObjectArgs.h" -#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/Value.h" -#include "lldb/Host/Host.h" -#include "lldb/Host/OptionParser.h" -#include "lldb/Interpreter/Args.h" -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/Variable.h" -#include "lldb/Target/ABI.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/StackFrame.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" - -#include "llvm/ADT/StringSwitch.h" - -using namespace lldb; -using namespace lldb_private; - -// This command is a toy. I'm just using it to have a way to construct the -// arguments to -// calling functions. -// - -static OptionDefinition g_arg_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation." }, - // clang-format on -}; - -CommandObjectArgs::CommandOptions::CommandOptions( - CommandInterpreter &interpreter) - : Options() { - // Keep only one place to reset the values to their defaults - OptionParsingStarting(nullptr); -} - -CommandObjectArgs::CommandOptions::~CommandOptions() = default; - -Status CommandObjectArgs::CommandOptions::SetOptionValue( - uint32_t option_idx, llvm::StringRef option_arg, - ExecutionContext *execution_context) { - Status error; - - const int short_option = m_getopt_table[option_idx].val; - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); - - return error; -} - -void CommandObjectArgs::CommandOptions::OptionParsingStarting( - ExecutionContext *execution_context) {} - -llvm::ArrayRef<OptionDefinition> -CommandObjectArgs::CommandOptions::GetDefinitions() { - return llvm::makeArrayRef(g_arg_options); -} - -CommandObjectArgs::CommandObjectArgs(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "args", - "When stopped at the start of a function, reads " - "function arguments of type (u?)int(8|16|32|64)_t, " - "(void|char)*", - "args"), - m_options(interpreter) {} - -CommandObjectArgs::~CommandObjectArgs() = default; - -Options *CommandObjectArgs::GetOptions() { return &m_options; } - -bool CommandObjectArgs::DoExecute(Args &args, CommandReturnObject &result) { - ConstString target_triple; - - Process *process = m_exe_ctx.GetProcessPtr(); - if (!process) { - result.AppendError("Args found no process."); - result.SetStatus(eReturnStatusFailed); - return false; - } - - const ABI *abi = process->GetABI().get(); - if (!abi) { - result.AppendError("The current process has no ABI."); - result.SetStatus(eReturnStatusFailed); - return false; - } - - if (args.empty()) { - result.AppendError("args requires at least one argument"); - result.SetStatus(eReturnStatusFailed); - return false; - } - - Thread *thread = m_exe_ctx.GetThreadPtr(); - - if (!thread) { - result.AppendError("args found no thread."); - result.SetStatus(eReturnStatusFailed); - return false; - } - - lldb::StackFrameSP thread_cur_frame = thread->GetSelectedFrame(); - if (!thread_cur_frame) { - result.AppendError("The current thread has no current frame."); - result.SetStatus(eReturnStatusFailed); - return false; - } - - ModuleSP thread_module_sp( - thread_cur_frame->GetFrameCodeAddress().GetModule()); - if (!thread_module_sp) { - result.AppendError("The PC has no associated module."); - result.SetStatus(eReturnStatusFailed); - return false; - } - - TypeSystem *type_system = - thread_module_sp->GetTypeSystemForLanguage(eLanguageTypeC); - if (type_system == nullptr) { - result.AppendError("Unable to create C type system."); - result.SetStatus(eReturnStatusFailed); - return false; - } - - ValueList value_list; - - for (auto &arg_entry : args.entries()) { - llvm::StringRef arg_type = arg_entry.ref; - Value value; - value.SetValueType(Value::eValueTypeScalar); - CompilerType compiler_type; - - std::size_t int_pos = arg_type.find("int"); - if (int_pos != llvm::StringRef::npos) { - Encoding encoding = eEncodingSint; - - int width = 0; - - if (int_pos > 1) { - result.AppendErrorWithFormat("Invalid format: %s.\n", - arg_entry.c_str()); - result.SetStatus(eReturnStatusFailed); - return false; - } - if (int_pos == 1 && arg_type[0] != 'u') { - result.AppendErrorWithFormat("Invalid format: %s.\n", - arg_entry.c_str()); - result.SetStatus(eReturnStatusFailed); - return false; - } - if (arg_type[0] == 'u') { - encoding = eEncodingUint; - } - - llvm::StringRef width_spec = arg_type.drop_front(int_pos + 3); - - auto exp_result = llvm::StringSwitch<llvm::Optional<int>>(width_spec) - .Case("8_t", 8) - .Case("16_t", 16) - .Case("32_t", 32) - .Case("64_t", 64) - .Default(llvm::None); - if (!exp_result.hasValue()) { - result.AppendErrorWithFormat("Invalid format: %s.\n", - arg_entry.c_str()); - result.SetStatus(eReturnStatusFailed); - return false; - } - width = *exp_result; - - compiler_type = - type_system->GetBuiltinTypeForEncodingAndBitSize(encoding, width); - - if (!compiler_type.IsValid()) { - result.AppendErrorWithFormat( - "Couldn't get Clang type for format %s (%s integer, width %d).\n", - arg_entry.c_str(), - (encoding == eEncodingSint ? "signed" : "unsigned"), width); - - result.SetStatus(eReturnStatusFailed); - return false; - } - } else if (arg_type == "void*") { - compiler_type = - type_system->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType(); - } else if (arg_type == "char*") { - compiler_type = - type_system->GetBasicTypeFromAST(eBasicTypeChar).GetPointerType(); - } else { - result.AppendErrorWithFormat("Invalid format: %s.\n", arg_entry.c_str()); - result.SetStatus(eReturnStatusFailed); - return false; - } - - value.SetCompilerType(compiler_type); - value_list.PushValue(value); - } - - if (!abi->GetArgumentValues(*thread, value_list)) { - result.AppendError("Couldn't get argument values"); - result.SetStatus(eReturnStatusFailed); - return false; - } - - result.GetOutputStream().Printf("Arguments : \n"); - - for (auto entry : llvm::enumerate(args.entries())) { - result.GetOutputStream().Printf( - "%" PRIu64 " (%s): ", (uint64_t)entry.index(), entry.value().c_str()); - value_list.GetValueAtIndex(entry.index())->Dump(&result.GetOutputStream()); - result.GetOutputStream().Printf("\n"); - } - - return result.Succeeded(); -} diff --git a/source/Commands/CommandObjectArgs.h b/source/Commands/CommandObjectArgs.h deleted file mode 100644 index aa7d2411adc82..0000000000000 --- a/source/Commands/CommandObjectArgs.h +++ /dev/null @@ -1,52 +0,0 @@ -//===-- CommandObjectArgs.h -------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_CommandObjectArgs_h_ -#define liblldb_CommandObjectArgs_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandObject.h" -#include "lldb/Interpreter/Options.h" - -namespace lldb_private { - -class CommandObjectArgs : public CommandObjectParsed { -public: - class CommandOptions : public Options { - public: - CommandOptions(CommandInterpreter &interpreter); - - ~CommandOptions() override; - - Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, - ExecutionContext *execution_context) override; - - void OptionParsingStarting(ExecutionContext *execution_context) override; - - llvm::ArrayRef<OptionDefinition> GetDefinitions() override; - }; - - CommandObjectArgs(CommandInterpreter &interpreter); - - ~CommandObjectArgs() override; - - Options *GetOptions() override; - -protected: - CommandOptions m_options; - - bool DoExecute(Args &command, CommandReturnObject &result) override; -}; - -} // namespace lldb_private - -#endif // liblldb_CommandObjectArgs_h_ diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp index 5a175d61060e3..fb0553e482db9 100644 --- a/source/Commands/CommandObjectBreakpoint.cpp +++ b/source/Commands/CommandObjectBreakpoint.cpp @@ -22,6 +22,7 @@ #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/OptionValueBoolean.h" #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Interpreter/OptionValueUInt64.h" @@ -84,8 +85,8 @@ public: switch (short_option) { case 'c': - // Normally an empty breakpoint condition marks is as unset. - // But we need to say it was passed in. + // Normally an empty breakpoint condition marks is as unset. But we need + // to say it was passed in. m_bp_opts.SetCondition(option_arg.str().c_str()); m_bp_opts.m_set_flags.Set(BreakpointOptions::eCondition); break; @@ -100,7 +101,7 @@ public: break; case 'G': { bool value, success; - value = Args::StringToBoolean(option_arg, false, &success); + value = OptionArgParser::ToBoolean(option_arg, false, &success); if (success) { m_bp_opts.SetAutoContinue(value); } else @@ -121,7 +122,7 @@ public: break; case 'o': { bool value, success; - value = Args::StringToBoolean(option_arg, false, &success); + value = OptionArgParser::ToBoolean(option_arg, false, &success); if (success) { m_bp_opts.SetOneShot(value); } else @@ -262,8 +263,9 @@ static OptionDefinition g_breakpoint_set_options[] = { "#included, set target.inline-breakpoint-strategy to \"always\"." }, { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specifies the line number on which to set this breakpoint." }, - // Comment out this option for the moment, as we don't actually use it, but will in the future. - // This way users won't see it, but the infrastructure is left in place. + // Comment out this option for the moment, as we don't actually use it, but + // will in the future. This way users won't see it, but the infrastructure is + // left in place. // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "<column>", // "Set the breakpoint by source location at this particular column."}, @@ -281,7 +283,7 @@ static OptionDefinition g_breakpoint_set_options[] = { { LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "When used with '-p' limits the source regex to source contained in the named " "functions. Can be repeated multiple times." }, { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFullName, "Set the breakpoint by fully qualified function names. For C++ this means " - "namespaces and all arguments, and for Objective C this means a full function " + "namespaces and all arguments, and for Objective-C this means a full function " "prototype with class and selector. Can be repeated multiple times to make " "one breakpoint for multiple names." }, { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSelector, "Set the breakpoint by ObjC selector name. Can be repeated multiple times to " @@ -377,8 +379,8 @@ public: switch (short_option) { case 'a': { - m_load_addr = Args::StringToAddress(execution_context, option_arg, - LLDB_INVALID_ADDRESS, &error); + m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg, + LLDB_INVALID_ADDRESS, &error); } break; case 'A': @@ -442,7 +444,7 @@ public: case 'h': { bool success; - m_catch_bp = Args::StringToBoolean(option_arg, true, &success); + m_catch_bp = OptionArgParser::ToBoolean(option_arg, true, &success); if (!success) error.SetErrorStringWithFormat( "Invalid boolean value for on-catch option: '%s'", @@ -456,7 +458,7 @@ public: case 'K': { bool success; bool value; - value = Args::StringToBoolean(option_arg, true, &success); + value = OptionArgParser::ToBoolean(option_arg, true, &success); if (value) m_skip_prologue = eLazyBoolYes; else @@ -485,7 +487,7 @@ public: case 'm': { bool success; bool value; - value = Args::StringToBoolean(option_arg, true, &success); + value = OptionArgParser::ToBoolean(option_arg, true, &success); if (value) m_move_to_nearest_code = eLazyBoolYes; else @@ -519,8 +521,8 @@ public: case 'R': { lldb::addr_t tmp_offset_addr; - tmp_offset_addr = - Args::StringToAddress(execution_context, option_arg, 0, &error); + tmp_offset_addr = OptionArgParser::ToAddress(execution_context, + option_arg, 0, &error); if (error.Success()) m_offset_addr = tmp_offset_addr; } break; @@ -549,7 +551,7 @@ public: case 'w': { bool success; - m_throw_bp = Args::StringToBoolean(option_arg, true, &success); + m_throw_bp = OptionArgParser::ToBoolean(option_arg, true, &success); if (!success) error.SetErrorStringWithFormat( "Invalid boolean value for on-throw option: '%s'", @@ -853,9 +855,9 @@ protected: output_stream.Printf("Breakpoint set in dummy target, will get copied " "into future targets.\n"); else { - // Don't print out this warning for exception breakpoints. They can get - // set before the target is set, but we won't know how to actually set - // the breakpoint till we run. + // Don't print out this warning for exception breakpoints. They can + // get set before the target is set, but we won't know how to actually + // set the breakpoint till we run. if (bp_sp->GetNumLocations() == 0 && break_type != eSetTypeException) { output_stream.Printf("WARNING: Unable to resolve breakpoint to any " "actual locations.\n"); @@ -874,8 +876,8 @@ private: bool GetDefaultFile(Target *target, FileSpec &file, CommandReturnObject &result) { uint32_t default_line; - // First use the Source Manager's default file. - // Then use the current stack frame's file. + // First use the Source Manager's default file. Then use the current stack + // frame's file. if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) { StackFrame *cur_frame = m_exe_ctx.GetFramePtr(); if (cur_frame == nullptr) { @@ -1451,7 +1453,8 @@ protected: return false; } - // The following are the various types of breakpoints that could be cleared: + // The following are the various types of breakpoints that could be + // cleared: // 1). -f -l (clearing breakpoint by source location) BreakpointClearType break_type = eClearTypeInvalid; @@ -1783,7 +1786,7 @@ public: switch (short_option) { case 'L': { bool value, success; - value = Args::StringToBoolean(option_arg, false, &success); + value = OptionArgParser::ToBoolean(option_arg, false, &success); if (success) { m_permissions.SetAllowList(value); } else @@ -1793,7 +1796,7 @@ public: } break; case 'A': { bool value, success; - value = Args::StringToBoolean(option_arg, false, &success); + value = OptionArgParser::ToBoolean(option_arg, false, &success); if (success) { m_permissions.SetAllowDisable(value); } else @@ -1803,7 +1806,7 @@ public: } break; case 'D': { bool value, success; - value = Args::StringToBoolean(option_arg, false, &success); + value = OptionArgParser::ToBoolean(option_arg, false, &success); if (success) { m_permissions.SetAllowDelete(value); } else @@ -1897,8 +1900,8 @@ protected: return false; } } - // Now configure them, we already pre-checked the names so we don't need - // to check the error: + // Now configure them, we already pre-checked the names so we don't need to + // check the error: BreakpointSP bp_sp; if (m_bp_id.m_breakpoint.OptionWasSet()) { @@ -2559,11 +2562,10 @@ void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target, } // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff - // directly from the old ARGS to - // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead - // generate a list of strings for - // all the breakpoint ids in the range, and shove all of those breakpoint id - // strings into TEMP_ARGS. + // directly from the old ARGS to the new TEMP_ARGS. Do not copy breakpoint + // id range strings over; instead generate a list of strings for all the + // breakpoint ids in the range, and shove all of those breakpoint id strings + // into TEMP_ARGS. BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations, purpose, result, temp_args); @@ -2571,18 +2573,15 @@ void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target, // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual // BreakpointIDList: - valid_ids->InsertStringArray(temp_args.GetConstArgumentVector(), - temp_args.GetArgumentCount(), result); + valid_ids->InsertStringArray(temp_args.GetArgumentArrayRef(), result); - // At this point, all of the breakpoint ids that the user passed in have been - // converted to breakpoint IDs - // and put into valid_ids. + // At this point, all of the breakpoint ids that the user passed in have + // been converted to breakpoint IDs and put into valid_ids. if (result.Succeeded()) { // Now that we've converted everything from args into a list of breakpoint - // ids, go through our tentative list - // of breakpoint id's and verify that they correspond to valid/currently set - // breakpoints. + // ids, go through our tentative list of breakpoint id's and verify that + // they correspond to valid/currently set breakpoints. const size_t count = valid_ids->GetSize(); for (size_t i = 0; i < count; ++i) { diff --git a/source/Commands/CommandObjectBreakpointCommand.cpp b/source/Commands/CommandObjectBreakpointCommand.cpp index 170cb85131160..f2546cbed848f 100644 --- a/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/source/Commands/CommandObjectBreakpointCommand.cpp @@ -22,6 +22,7 @@ #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" @@ -293,7 +294,7 @@ are no syntax errors may indicate that a function was declared but never called. break; case 's': - m_script_language = (lldb::ScriptLanguage)Args::StringToOptionEnum( + m_script_language = (lldb::ScriptLanguage)OptionArgParser::ToOptionEnum( option_arg, g_breakpoint_add_options[option_idx].enum_values, eScriptLanguageNone, error); @@ -307,7 +308,8 @@ are no syntax errors may indicate that a function was declared but never called. case 'e': { bool success = false; - m_stop_on_error = Args::StringToBoolean(option_arg, false, &success); + m_stop_on_error = + OptionArgParser::ToBoolean(option_arg, false, &success); if (!success) error.SetErrorStringWithFormat( "invalid value for stop-on-error: \"%s\"", @@ -410,8 +412,8 @@ protected: } else { BreakpointLocationSP bp_loc_sp( bp->FindLocationByID(cur_bp_id.GetLocationID())); - // This breakpoint does have an associated location. - // Get its breakpoint options. + // This breakpoint does have an associated location. Get its + // breakpoint options. if (bp_loc_sp) bp_options = bp_loc_sp->GetLocationOptions(); } @@ -420,9 +422,9 @@ protected: } } - // If we are using script language, get the script interpreter - // in order to set or collect command callback. Otherwise, call - // the methods associated with this object. + // If we are using script language, get the script interpreter in order + // to set or collect command callback. Otherwise, call the methods + // associated with this object. if (m_options.m_use_script_language) { ScriptInterpreter *script_interp = m_interpreter.GetScriptInterpreter(); // Special handling for one-liner specified inline. @@ -454,16 +456,15 @@ private: std::vector<BreakpointOptions *> m_bp_options_vec; // This stores the // breakpoint options that // we are currently - // collecting commands for. In the CollectData... calls we need - // to hand this off to the IOHandler, which may run asynchronously. - // So we have to have some way to keep it alive, and not leak it. - // Making it an ivar of the command object, which never goes away - // achieves this. Note that if we were able to run - // the same command concurrently in one interpreter we'd have to - // make this "per invocation". But there are many more reasons - // why it is not in general safe to do that in lldb at present, - // so it isn't worthwhile to come up with a more complex mechanism - // to address this particular weakness right now. + // collecting commands for. In the CollectData... calls we need to hand this + // off to the IOHandler, which may run asynchronously. So we have to have + // some way to keep it alive, and not leak it. Making it an ivar of the + // command object, which never goes away achieves this. Note that if we were + // able to run the same command concurrently in one interpreter we'd have to + // make this "per invocation". But there are many more reasons why it is not + // in general safe to do that in lldb at present, so it isn't worthwhile to + // come up with a more complex mechanism to address this particular weakness + // right now. static const char *g_reader_instructions; }; diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp index c9d71a65754b9..3012ee4a188d1 100644 --- a/source/Commands/CommandObjectCommands.cpp +++ b/source/Commands/CommandObjectCommands.cpp @@ -18,16 +18,17 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/IOHandler.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandHistory.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandObjectRegexCommand.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/OptionValueBoolean.h" #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Interpreter/OptionValueUInt64.h" #include "lldb/Interpreter/Options.h" #include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Utility/Args.h" #include "lldb/Utility/StringList.h" using namespace lldb; @@ -234,20 +235,13 @@ public: return ""; } - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - auto completion_str = input[cursor_index].ref; - completion_str = completion_str.take_front(cursor_char_position); - + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - completion_str, match_start_point, max_return_elements, nullptr, - word_complete, matches); - return matches.GetSize(); + request, nullptr); + return request.GetMatches().GetSize(); } Options *GetOptions() override { return &m_options; } @@ -330,9 +324,8 @@ protected: m_interpreter.HandleCommandsFromFile(cmd_file, exe_ctx, options, result); } else { - // No options were set, inherit any settings from nested "command - // source" commands, - // or set to sane default settings... + // No options were set, inherit any settings from nested "command source" + // commands, or set to sane default settings... CommandInterpreterRunOptions options; m_interpreter.HandleCommandsFromFile(cmd_file, exe_ctx, options, result); } @@ -543,9 +536,9 @@ rather than using a positional placeholder:" ~CommandObjectCommandsAlias() override = default; protected: - bool DoExecute(const char *raw_command_line, + bool DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override { - if (!raw_command_line || !raw_command_line[0]) { + if (raw_command_line.empty()) { result.AppendError("'command alias' requires at least two arguments"); return false; } @@ -553,42 +546,13 @@ protected: ExecutionContext exe_ctx = GetCommandInterpreter().GetExecutionContext(); m_option_group.NotifyOptionParsingStarting(&exe_ctx); - const char *remainder = nullptr; - - if (raw_command_line[0] == '-') { - // We have some options and these options MUST end with --. - const char *end_options = nullptr; - const char *s = raw_command_line; - while (s && s[0]) { - end_options = ::strstr(s, "--"); - if (end_options) { - end_options += 2; // Get past the "--" - if (::isspace(end_options[0])) { - remainder = end_options; - while (::isspace(*remainder)) - ++remainder; - break; - } - } - s = end_options; - } - - if (end_options) { - Args args( - llvm::StringRef(raw_command_line, end_options - raw_command_line)); - if (!ParseOptions(args, result)) - return false; + OptionsWithRaw args_with_suffix(raw_command_line); + const char *remainder = args_with_suffix.GetRawPart().c_str(); - Status error(m_option_group.NotifyOptionParsingFinished(&exe_ctx)); - if (error.Fail()) { - result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); - return false; - } - } - } - if (nullptr == remainder) - remainder = raw_command_line; + if (args_with_suffix.HasArgs()) + if (!ParseOptionsAndNotify(args_with_suffix.GetArgs(), result, + m_option_group, exe_ctx)) + return false; llvm::StringRef raw_command_string(remainder); Args args(raw_command_string); @@ -613,8 +577,7 @@ protected: } // Strip the new alias name off 'raw_command_string' (leave it on args, - // which gets passed to 'Execute', which - // does the stripping itself. + // which gets passed to 'Execute', which does the stripping itself. size_t pos = raw_command_string.find(alias_command); if (pos == 0) { raw_command_string = raw_command_string.substr(alias_command.size()); @@ -652,9 +615,8 @@ protected: return false; } else if (!cmd_obj->WantsRawCommandString()) { // Note that args was initialized with the original command, and has not - // been updated to this point. - // Therefore can we pass it to the version of Execute that does not - // need/expect raw input in the alias. + // been updated to this point. Therefore can we pass it to the version of + // Execute that does not need/expect raw input in the alias. return HandleAliasingNormalCommand(args, result); } else { return HandleAliasingRawCommand(alias_command, raw_command_string, @@ -1128,8 +1090,8 @@ protected: return error; } const size_t first_separator_char_pos = 1; - // use the char that follows 's' as the regex separator character - // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|" + // use the char that follows 's' as the regex separator character so we can + // have "s/<regex>/<subst>/" or "s|<regex>|<subst>|" const char separator_char = regex_sed[first_separator_char_pos]; const size_t second_separator_char_pos = regex_sed.find(separator_char, first_separator_char_pos + 1); @@ -1158,8 +1120,7 @@ protected: } if (third_separator_char_pos != regex_sed_size - 1) { - // Make sure that everything that follows the last regex - // separator char + // Make sure that everything that follows the last regex separator char if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos) { @@ -1307,7 +1268,7 @@ public: } protected: - bool DoExecute(const char *raw_command_line, + bool DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override { ScriptInterpreter *scripter = m_interpreter.GetScriptInterpreter(); @@ -1396,7 +1357,7 @@ public: } protected: - bool DoExecute(const char *raw_command_line, + bool DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override { ScriptInterpreter *scripter = m_interpreter.GetScriptInterpreter(); @@ -1462,20 +1423,13 @@ public: ~CommandObjectCommandsScriptImport() override = default; - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - llvm::StringRef completion_str = input[cursor_index].ref; - completion_str = completion_str.take_front(cursor_char_position); - + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - completion_str, match_start_point, max_return_elements, nullptr, - word_complete, matches); - return matches.GetSize(); + request, nullptr); + return request.GetMatches().GetSize(); } Options *GetOptions() override { return &m_options; } @@ -1540,10 +1494,11 @@ protected: // FIXME: this is necessary because CommandObject::CheckRequirements() // assumes that commands won't ever be recursively invoked, but it's // actually possible to craft a Python script that does other "command - // script imports" in __lldb_init_module the real fix is to have recursive - // commands possible with a CommandInvocation object separate from the - // CommandObject itself, so that recursive command invocations won't stomp - // on each other (wrt to execution contents, options, and more) + // script imports" in __lldb_init_module the real fix is to have + // recursive commands possible with a CommandInvocation object separate + // from the CommandObject itself, so that recursive command invocations + // won't stomp on each other (wrt to execution contents, options, and + // more) m_exe_ctx.Clear(); if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule( entry.c_str(), m_options.m_allow_reload, init_session, error)) { @@ -1639,7 +1594,7 @@ protected: break; case 's': m_synchronicity = - (ScriptedCommandSynchronicity)Args::StringToOptionEnum( + (ScriptedCommandSynchronicity)OptionArgParser::ToOptionEnum( option_arg, GetDefinitions()[option_idx].enum_values, 0, error); if (!error.Success()) error.SetErrorStringWithFormat( diff --git a/source/Commands/CommandObjectDisassemble.cpp b/source/Commands/CommandObjectDisassemble.cpp index 31c54b7d433b3..519e5e2dcdb0a 100644 --- a/source/Commands/CommandObjectDisassemble.cpp +++ b/source/Commands/CommandObjectDisassemble.cpp @@ -20,6 +20,7 @@ #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/Options.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" @@ -101,14 +102,14 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue( break; case 's': { - start_addr = Args::StringToAddress(execution_context, option_arg, - LLDB_INVALID_ADDRESS, &error); + start_addr = OptionArgParser::ToAddress(execution_context, option_arg, + LLDB_INVALID_ADDRESS, &error); if (start_addr != LLDB_INVALID_ADDRESS) some_location_specified = true; } break; case 'e': { - end_addr = Args::StringToAddress(execution_context, option_arg, - LLDB_INVALID_ADDRESS, &error); + end_addr = OptionArgParser::ToAddress(execution_context, option_arg, + LLDB_INVALID_ADDRESS, &error); if (end_addr != LLDB_INVALID_ADDRESS) some_location_specified = true; } break; @@ -125,8 +126,8 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue( case 'l': frame_line = true; - // Disassemble the current source line kind of implies showing mixed - // source code context. + // Disassemble the current source line kind of implies showing mixed source + // code context. show_mixed = true; some_location_specified = true; break; @@ -160,15 +161,14 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue( case 'A': if (execution_context) { - auto target_sp = - execution_context ? execution_context->GetTargetSP() : TargetSP(); - auto platform_sp = target_sp ? target_sp->GetPlatform() : PlatformSP(); - arch = Platform::GetAugmentedArchSpec(platform_sp.get(), option_arg); + const auto &target_sp = execution_context->GetTargetSP(); + auto platform_ptr = target_sp ? target_sp->GetPlatform().get() : nullptr; + arch = Platform::GetAugmentedArchSpec(platform_ptr, option_arg); } break; case 'a': { - symbol_containing_addr = Args::StringToAddress( + symbol_containing_addr = OptionArgParser::ToAddress( execution_context, option_arg, LLDB_INVALID_ADDRESS, &error); if (symbol_containing_addr != LLDB_INVALID_ADDRESS) { some_location_specified = true; @@ -204,10 +204,9 @@ void CommandObjectDisassemble::CommandOptions::OptionParsingStarting( execution_context ? execution_context->GetTargetPtr() : nullptr; // This is a hack till we get the ability to specify features based on - // architecture. For now GetDisassemblyFlavor - // is really only valid for x86 (and for the llvm assembler plugin, but I'm - // papering over that since that is the - // only disassembler plugin we have... + // architecture. For now GetDisassemblyFlavor is really only valid for x86 + // (and for the llvm assembler plugin, but I'm papering over that since that + // is the only disassembler plugin we have... if (target) { if (target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86 || target->GetArchitecture().GetTriple().getArch() == @@ -374,8 +373,8 @@ bool CommandObjectDisassemble::DoExecute(Args &command, } } - // Did the "m_options.frame_line" find a valid range already? If so - // skip the rest... + // Did the "m_options.frame_line" find a valid range already? If so skip + // the rest... if (range.GetByteSize() == 0) { if (m_options.at_pc) { if (frame == nullptr) { diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp index 01ca311115556..08959ff8473d0 100644 --- a/source/Commands/CommandObjectExpression.cpp +++ b/source/Commands/CommandObjectExpression.cpp @@ -27,6 +27,7 @@ #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/Variable.h" #include "lldb/Target/Language.h" @@ -88,7 +89,7 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue( case 'a': { bool success; bool result; - result = Args::StringToBoolean(option_arg, true, &success); + result = OptionArgParser::ToBoolean(option_arg, true, &success); if (!success) error.SetErrorStringWithFormat( "invalid all-threads value setting: \"%s\"", @@ -99,7 +100,7 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue( case 'i': { bool success; - bool tmp_value = Args::StringToBoolean(option_arg, true, &success); + bool tmp_value = OptionArgParser::ToBoolean(option_arg, true, &success); if (success) ignore_breakpoints = tmp_value; else @@ -111,7 +112,7 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue( case 'j': { bool success; - bool tmp_value = Args::StringToBoolean(option_arg, true, &success); + bool tmp_value = OptionArgParser::ToBoolean(option_arg, true, &success); if (success) allow_jit = tmp_value; else @@ -131,7 +132,7 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue( case 'u': { bool success; - bool tmp_value = Args::StringToBoolean(option_arg, true, &success); + bool tmp_value = OptionArgParser::ToBoolean(option_arg, true, &success); if (success) unwind_on_error = tmp_value; else @@ -146,8 +147,8 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue( m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull; break; } - m_verbosity = - (LanguageRuntimeDescriptionDisplayVerbosity)Args::StringToOptionEnum( + m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity) + OptionArgParser::ToOptionEnum( option_arg, GetDefinitions()[option_idx].enum_values, 0, error); if (!error.Success()) error.SetErrorStringWithFormat( @@ -167,7 +168,7 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue( case 'X': { bool success; - bool tmp_value = Args::StringToBoolean(option_arg, true, &success); + bool tmp_value = OptionArgParser::ToBoolean(option_arg, true, &success); if (success) auto_apply_fixits = tmp_value ? eLazyBoolYes : eLazyBoolNo; else @@ -317,13 +318,13 @@ CanBeUsedForElementCountPrinting(ValueObject &valobj) { return Status(); } -bool CommandObjectExpression::EvaluateExpression(const char *expr, +bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, Stream *output_stream, Stream *error_stream, CommandReturnObject *result) { - // Don't use m_exe_ctx as this might be called asynchronously - // after the command object DoExecute has finished when doing - // multi-line expression that use an input reader... + // Don't use m_exe_ctx as this might be called asynchronously after the + // command object DoExecute has finished when doing multi-line expression + // that use an input reader... ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); Target *target = exe_ctx.GetTargetPtr(); @@ -362,8 +363,8 @@ bool CommandObjectExpression::EvaluateExpression(const char *expr, if (m_command_options.top_level) options.SetExecutionPolicy(eExecutionPolicyTopLevel); - // If there is any chance we are going to stop and want to see - // what went wrong with our expression, we should generate debug info + // If there is any chance we are going to stop and want to see what went + // wrong with our expression, we should generate debug info if (!m_command_options.ignore_breakpoints || !m_command_options.unwind_on_error) options.SetGenerateDebugInfo(true); @@ -474,9 +475,8 @@ bool CommandObjectExpression::IOHandlerIsInputComplete(IOHandler &io_handler, // An empty lines is used to indicate the end of input const size_t num_lines = lines.GetSize(); if (num_lines > 0 && lines[num_lines - 1].empty()) { - // Remove the last empty line from "lines" so it doesn't appear - // in our resulting input and return true to indicate we are done - // getting lines + // Remove the last empty line from "lines" so it doesn't appear in our + // resulting input and return true to indicate we are done getting lines lines.PopBack(); return true; } @@ -508,125 +508,91 @@ void CommandObjectExpression::GetMultilineExpression() { debugger.PushIOHandler(io_handler_sp); } -bool CommandObjectExpression::DoExecute(const char *command, +bool CommandObjectExpression::DoExecute(llvm::StringRef command, CommandReturnObject &result) { m_fixed_expression.clear(); auto exe_ctx = GetCommandInterpreter().GetExecutionContext(); m_option_group.NotifyOptionParsingStarting(&exe_ctx); - const char *expr = nullptr; - - if (command[0] == '\0') { + if (command.empty()) { GetMultilineExpression(); return result.Succeeded(); } - if (command[0] == '-') { - // We have some options and these options MUST end with --. - const char *end_options = nullptr; - const char *s = command; - while (s && s[0]) { - end_options = ::strstr(s, "--"); - if (end_options) { - end_options += 2; // Get past the "--" - if (::isspace(end_options[0])) { - expr = end_options; - while (::isspace(*expr)) - ++expr; - break; - } - } - s = end_options; - } - - if (end_options) { - Args args(llvm::StringRef(command, end_options - command)); - if (!ParseOptions(args, result)) - return false; - - Status error(m_option_group.NotifyOptionParsingFinished(&exe_ctx)); - if (error.Fail()) { - result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); - return false; - } - - if (m_repl_option.GetOptionValue().GetCurrentValue()) { - Target *target = m_interpreter.GetExecutionContext().GetTargetPtr(); - if (target) { - // Drop into REPL - m_expr_lines.clear(); - m_expr_line_count = 0; - - Debugger &debugger = target->GetDebugger(); - - // Check if the LLDB command interpreter is sitting on top of a REPL - // that - // launched it... - if (debugger.CheckTopIOHandlerTypes( - IOHandler::Type::CommandInterpreter, IOHandler::Type::REPL)) { - // the LLDB command interpreter is sitting on top of a REPL that - // launched it, - // so just say the command interpreter is done and fall back to the - // existing REPL - m_interpreter.GetIOHandler(false)->SetIsDone(true); - } else { - // We are launching the REPL on top of the current LLDB command - // interpreter, - // so just push one - bool initialize = false; - Status repl_error; - REPLSP repl_sp(target->GetREPL( - repl_error, m_command_options.language, nullptr, false)); - - if (!repl_sp) { - initialize = true; - repl_sp = target->GetREPL(repl_error, m_command_options.language, - nullptr, true); - if (!repl_error.Success()) { - result.SetError(repl_error); - return result.Succeeded(); - } + OptionsWithRaw args(command); + llvm::StringRef expr = args.GetRawPart(); + + if (args.HasArgs()) { + if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group, exe_ctx)) + return false; + + if (m_repl_option.GetOptionValue().GetCurrentValue()) { + Target *target = m_interpreter.GetExecutionContext().GetTargetPtr(); + if (target) { + // Drop into REPL + m_expr_lines.clear(); + m_expr_line_count = 0; + + Debugger &debugger = target->GetDebugger(); + + // Check if the LLDB command interpreter is sitting on top of a REPL + // that launched it... + if (debugger.CheckTopIOHandlerTypes(IOHandler::Type::CommandInterpreter, + IOHandler::Type::REPL)) { + // the LLDB command interpreter is sitting on top of a REPL that + // launched it, so just say the command interpreter is done and + // fall back to the existing REPL + m_interpreter.GetIOHandler(false)->SetIsDone(true); + } else { + // We are launching the REPL on top of the current LLDB command + // interpreter, so just push one + bool initialize = false; + Status repl_error; + REPLSP repl_sp(target->GetREPL(repl_error, m_command_options.language, + nullptr, false)); + + if (!repl_sp) { + initialize = true; + repl_sp = target->GetREPL(repl_error, m_command_options.language, + nullptr, true); + if (!repl_error.Success()) { + result.SetError(repl_error); + return result.Succeeded(); } + } - if (repl_sp) { - if (initialize) { - repl_sp->SetCommandOptions(m_command_options); - repl_sp->SetFormatOptions(m_format_options); - repl_sp->SetValueObjectDisplayOptions(m_varobj_options); - } + if (repl_sp) { + if (initialize) { + repl_sp->SetCommandOptions(m_command_options); + repl_sp->SetFormatOptions(m_format_options); + repl_sp->SetValueObjectDisplayOptions(m_varobj_options); + } - IOHandlerSP io_handler_sp(repl_sp->GetIOHandler()); + IOHandlerSP io_handler_sp(repl_sp->GetIOHandler()); - io_handler_sp->SetIsDone(false); + io_handler_sp->SetIsDone(false); - debugger.PushIOHandler(io_handler_sp); - } else { - repl_error.SetErrorStringWithFormat( - "Couldn't create a REPL for %s", - Language::GetNameForLanguageType(m_command_options.language)); - result.SetError(repl_error); - return result.Succeeded(); - } + debugger.PushIOHandler(io_handler_sp); + } else { + repl_error.SetErrorStringWithFormat( + "Couldn't create a REPL for %s", + Language::GetNameForLanguageType(m_command_options.language)); + result.SetError(repl_error); + return result.Succeeded(); } } } - // No expression following options - else if (expr == nullptr || expr[0] == '\0') { - GetMultilineExpression(); - return result.Succeeded(); - } + } + // No expression following options + else if (expr.empty()) { + GetMultilineExpression(); + return result.Succeeded(); } } - if (expr == nullptr) - expr = command; - + Target *target = GetSelectedOrDummyTarget(); if (EvaluateExpression(expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result)) { - Target *target = m_interpreter.GetExecutionContext().GetTargetPtr(); - if (!target) - target = GetDummyTarget(); if (!m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts()) { CommandHistory &history = m_interpreter.GetCommandHistory(); @@ -634,18 +600,21 @@ bool CommandObjectExpression::DoExecute(const char *command, // for expr???) // If we can it would be nice to show that. std::string fixed_command("expression "); - if (expr == command) - fixed_command.append(m_fixed_expression); - else { + if (args.HasArgs()) { // Add in any options that might have been in the original command: - fixed_command.append(command, expr - command); + fixed_command.append(args.GetArgStringWithDelimiter()); + fixed_command.append(m_fixed_expression); + } else fixed_command.append(m_fixed_expression); - } history.AppendString(fixed_command); } + // Increment statistics to record this expression evaluation success. + target->IncrementStats(StatisticKind::ExpressionSuccessful); return true; } + // Increment statistics to record this expression evaluation failure. + target->IncrementStats(StatisticKind::ExpressionFailure); result.SetStatus(eReturnStatusFailed); return false; } diff --git a/source/Commands/CommandObjectExpression.h b/source/Commands/CommandObjectExpression.h index 0cf2a7263d52b..710f871409777 100644 --- a/source/Commands/CommandObjectExpression.h +++ b/source/Commands/CommandObjectExpression.h @@ -72,9 +72,9 @@ protected: bool IOHandlerIsInputComplete(IOHandler &io_handler, StringList &lines) override; - bool DoExecute(const char *command, CommandReturnObject &result) override; + bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override; - bool EvaluateExpression(const char *expr, Stream *output_stream, + bool EvaluateExpression(llvm::StringRef expr, Stream *output_stream, Stream *error_stream, CommandReturnObject *result = NULL); diff --git a/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp index 0bcc350629689..0183c43f85b55 100644 --- a/source/Commands/CommandObjectFrame.cpp +++ b/source/Commands/CommandObjectFrame.cpp @@ -24,7 +24,6 @@ #include "lldb/DataFormatters/ValueObjectPrinter.h" #include "lldb/Host/Host.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionGroupFormat.h" @@ -44,6 +43,7 @@ #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/Args.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" @@ -342,8 +342,8 @@ protected: frame_idx += m_options.relative_frame_offset; else { if (frame_idx == 0) { - // If you are already at the bottom of the stack, then just warn and - // don't reset the frame. + // If you are already at the bottom of the stack, then just warn + // and don't reset the frame. result.AppendError("Already at the bottom of the stack."); result.SetStatus(eReturnStatusFailed); return false; @@ -463,21 +463,14 @@ public: Options *GetOptions() override { return &m_option_group; } - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { // Arguments are the standard source file completer. - auto completion_str = input[cursor_index].ref; - completion_str = completion_str.take_front(cursor_char_position); - CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion, - completion_str, match_start_point, max_return_elements, nullptr, - word_complete, matches); - return matches.GetSize(); + request, nullptr); + return request.GetMatches().GetSize(); } protected: @@ -504,16 +497,15 @@ protected: } bool DoExecute(Args &command, CommandReturnObject &result) override { - // No need to check "frame" for validity as eCommandRequiresFrame ensures it - // is valid + // No need to check "frame" for validity as eCommandRequiresFrame ensures + // it is valid StackFrame *frame = m_exe_ctx.GetFramePtr(); Stream &s = result.GetOutputStream(); // Be careful about the stack frame, if any summary formatter runs code, it - // might clear the StackFrameList - // for the thread. So hold onto a shared pointer to the frame so it stays - // alive. + // might clear the StackFrameList for the thread. So hold onto a shared + // pointer to the frame so it stays alive. VariableList *variable_list = frame->GetVariableList(m_option_variable.show_globals); @@ -547,8 +539,8 @@ protected: if (!command.empty()) { VariableList regex_var_list; - // If we have any args to the variable command, we will make - // variable objects from them... + // If we have any args to the variable command, we will make variable + // objects from them... for (auto &entry : command) { if (m_option_variable.use_regex) { const size_t regex_start_index = regex_var_list.GetSize(); @@ -620,9 +612,6 @@ protected: if (!scope_string.empty()) s.PutCString(scope_string); - - // if (format != eFormatDefault) - // valobj_sp->SetFormat (format); if (m_option_variable.show_decl && var_sp && var_sp->GetDeclaration().GetFile()) { var_sp->GetDeclaration().DumpStopContext(&s, false); @@ -680,14 +669,13 @@ protected: if (m_option_variable.show_scope) scope_string = GetScopeString(var_sp).str(); - // Use the variable object code to make sure we are - // using the same APIs as the public API will be - // using... + // Use the variable object code to make sure we are using the same + // APIs as the public API will be using... valobj_sp = frame->GetValueObjectForFrameVariable( var_sp, m_varobj_options.use_dynamic); if (valobj_sp) { - // When dumping all variables, don't print any variables - // that are not in scope to avoid extra unneeded output + // When dumping all variables, don't print any variables that are + // not in scope to avoid extra unneeded output if (valobj_sp->IsInScope()) { if (!valobj_sp->GetTargetSP() ->GetDisplayRuntimeSupportValues() && @@ -723,7 +711,14 @@ protected: m_interpreter.TruncationWarningGiven(); } - return result.Succeeded(); + // Increment statistics. + bool res = result.Succeeded(); + Target *target = GetSelectedOrDummyTarget(); + if (res) + target->IncrementStats(StatisticKind::FrameVarSuccess); + else + target->IncrementStats(StatisticKind::FrameVarFailure); + return res; } protected: diff --git a/source/Commands/CommandObjectHelp.cpp b/source/Commands/CommandObjectHelp.cpp index 99e9d7b3abd4d..903c6011b03f1 100644 --- a/source/Commands/CommandObjectHelp.cpp +++ b/source/Commands/CommandObjectHelp.cpp @@ -89,10 +89,9 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) { CommandObject *cmd_obj; const size_t argc = command.GetArgumentCount(); - // 'help' doesn't take any arguments, other than command names. If argc is 0, - // we show the user - // all commands (aliases and user commands if asked for). Otherwise every - // argument must be the name of a command or a sub-command. + // 'help' doesn't take any arguments, other than command names. If argc is + // 0, we show the user all commands (aliases and user commands if asked for). + // Otherwise every argument must be the name of a command or a sub-command. if (argc == 0) { uint32_t cmd_types = CommandInterpreter::eCommandTypesBuiltin; if (m_options.m_show_aliases) @@ -210,34 +209,24 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) { return result.Succeeded(); } -int CommandObjectHelp::HandleCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - int match_start_point, - int max_return_elements, - bool &word_complete, - StringList &matches) { +int CommandObjectHelp::HandleCompletion(CompletionRequest &request) { // Return the completions of the commands in the help system: - if (cursor_index == 0) { - return m_interpreter.HandleCompletionMatches( - input, cursor_index, cursor_char_position, match_start_point, - max_return_elements, word_complete, matches); + if (request.GetCursorIndex() == 0) { + return m_interpreter.HandleCompletionMatches(request); } else { - CommandObject *cmd_obj = m_interpreter.GetCommandObject(input[0].ref); + CommandObject *cmd_obj = + m_interpreter.GetCommandObject(request.GetParsedLine()[0].ref); // The command that they are getting help on might be ambiguous, in which - // case we should complete that, - // otherwise complete with the command the user is getting help on... + // case we should complete that, otherwise complete with the command the + // user is getting help on... if (cmd_obj) { - input.Shift(); - cursor_index--; - return cmd_obj->HandleCompletion( - input, cursor_index, cursor_char_position, match_start_point, - max_return_elements, word_complete, matches); + request.GetParsedLine().Shift(); + request.SetCursorIndex(request.GetCursorIndex() - 1); + return cmd_obj->HandleCompletion(request); } else { - return m_interpreter.HandleCompletionMatches( - input, cursor_index, cursor_char_position, match_start_point, - max_return_elements, word_complete, matches); + return m_interpreter.HandleCompletionMatches(request); } } } diff --git a/source/Commands/CommandObjectHelp.h b/source/Commands/CommandObjectHelp.h index f1f87f8e63ccb..c78682dead1fb 100644 --- a/source/Commands/CommandObjectHelp.h +++ b/source/Commands/CommandObjectHelp.h @@ -30,10 +30,7 @@ public: ~CommandObjectHelp() override; - int HandleCompletion(Args &input, int &cursor_index, - int &cursor_char_position, int match_start_point, - int max_return_elements, bool &word_complete, - StringList &matches) override; + int HandleCompletion(CompletionRequest &request) override; static void GenerateAdditionalHelpAvenuesMessage( Stream *s, llvm::StringRef command, llvm::StringRef prefix, diff --git a/source/Commands/CommandObjectLog.cpp b/source/Commands/CommandObjectLog.cpp index ef82d07f15fbb..1389ff2bde027 100644 --- a/source/Commands/CommandObjectLog.cpp +++ b/source/Commands/CommandObjectLog.cpp @@ -16,9 +16,9 @@ #include "lldb/Core/Module.h" #include "lldb/Core/StreamFile.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/Options.h" #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/ObjectFile.h" @@ -26,6 +26,7 @@ #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/Args.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" @@ -100,7 +101,7 @@ public: switch (short_option) { case 'f': - log_file.SetFile(option_arg, true); + log_file.SetFile(option_arg, true, FileSpec::Style::native); break; case 't': log_options |= LLDB_LOG_OPTION_THREADSAFE; @@ -345,7 +346,7 @@ protected: } } else if (sub_command.equals_lower("increment")) { bool success; - bool increment = Args::StringToBoolean(param, false, &success); + bool increment = OptionArgParser::ToBoolean(param, false, &success); if (success) { Timer::SetQuiet(!increment); result.SetStatus(eReturnStatusSuccessFinishNoResult); diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp index 8f4c186a8d694..e4a49e55857d5 100644 --- a/source/Commands/CommandObjectMemory.cpp +++ b/source/Commands/CommandObjectMemory.cpp @@ -24,9 +24,9 @@ #include "lldb/Core/ValueObjectMemory.h" #include "lldb/DataFormatters/ValueObjectPrinter.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/OptionGroupFormat.h" #include "lldb/Interpreter/OptionGroupOutputFile.h" #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" @@ -40,6 +40,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/Args.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/StreamString.h" @@ -553,8 +554,8 @@ protected: lldb::addr_t addr; size_t total_byte_size = 0; if (argc == 0) { - // Use the last address and byte size and all options as they were - // if no options have been set + // Use the last address and byte size and all options as they were if no + // options have been set addr = m_next_addr; total_byte_size = m_prev_byte_size; clang_ast_type = m_prev_clang_ast_type; @@ -573,8 +574,8 @@ protected: // TODO For non-8-bit byte addressable architectures this needs to be // revisited to fully support all lldb's range of formatting options. - // Furthermore code memory reads (for those architectures) will not - // be correctly formatted even w/o formatting options. + // Furthermore code memory reads (for those architectures) will not be + // correctly formatted even w/o formatting options. size_t item_byte_size = target->GetArchitecture().GetDataByteSize() > 1 ? target->GetArchitecture().GetDataByteSize() @@ -590,8 +591,8 @@ protected: } if (argc > 0) - addr = Args::StringToAddress(&m_exe_ctx, command[0].ref, - LLDB_INVALID_ADDRESS, &error); + addr = OptionArgParser::ToAddress(&m_exe_ctx, command[0].ref, + LLDB_INVALID_ADDRESS, &error); if (addr == LLDB_INVALID_ADDRESS) { result.AppendError("invalid start address expression."); @@ -601,7 +602,7 @@ protected: } if (argc == 2) { - lldb::addr_t end_addr = Args::StringToAddress( + lldb::addr_t end_addr = OptionArgParser::ToAddress( &m_exe_ctx, command[1].ref, LLDB_INVALID_ADDRESS, nullptr); if (end_addr == LLDB_INVALID_ADDRESS) { result.AppendError("invalid end address expression."); @@ -843,16 +844,14 @@ protected: if (!m_format_options.GetCountValue().OptionWasSet() || item_count == 1) { // this turns requests such as // memory read -fc -s10 -c1 *charPtrPtr - // which make no sense (what is a char of size 10?) - // into a request for fetching 10 chars of size 1 from the same memory - // location + // which make no sense (what is a char of size 10?) into a request for + // fetching 10 chars of size 1 from the same memory location format = eFormatCharArray; item_count = item_byte_size; item_byte_size = 1; } else { - // here we passed a count, and it was not 1 - // so we have a byte_size and a count - // we could well multiply those, but instead let's just fail + // here we passed a count, and it was not 1 so we have a byte_size and + // a count we could well multiply those, but instead let's just fail result.AppendErrorWithFormat( "reading memory as characters of size %" PRIu64 " is not supported", (uint64_t)item_byte_size); @@ -1036,13 +1035,13 @@ protected: } Status error; - lldb::addr_t low_addr = Args::StringToAddress(&m_exe_ctx, command[0].ref, - LLDB_INVALID_ADDRESS, &error); + lldb::addr_t low_addr = OptionArgParser::ToAddress( + &m_exe_ctx, command[0].ref, LLDB_INVALID_ADDRESS, &error); if (low_addr == LLDB_INVALID_ADDRESS || error.Fail()) { result.AppendError("invalid low address"); return false; } - lldb::addr_t high_addr = Args::StringToAddress( + lldb::addr_t high_addr = OptionArgParser::ToAddress( &m_exe_ctx, command[1].ref, LLDB_INVALID_ADDRESS, &error); if (high_addr == LLDB_INVALID_ADDRESS || error.Fail()) { result.AppendError("invalid high address"); @@ -1210,7 +1209,7 @@ public: switch (short_option) { case 'i': - m_infile.SetFile(option_value, true); + m_infile.SetFile(option_value, true, FileSpec::Style::native); if (!m_infile.Exists()) { m_infile.Clear(); error.SetErrorStringWithFormat("input file does not exist: '%s'", @@ -1345,8 +1344,8 @@ protected: size_t item_byte_size = byte_size_value.GetCurrentValue(); Status error; - lldb::addr_t addr = Args::StringToAddress(&m_exe_ctx, command[0].ref, - LLDB_INVALID_ADDRESS, &error); + lldb::addr_t addr = OptionArgParser::ToAddress( + &m_exe_ctx, command[0].ref, LLDB_INVALID_ADDRESS, &error); if (addr == LLDB_INVALID_ADDRESS) { result.AppendError("invalid address expression\n"); @@ -1469,7 +1468,7 @@ protected: break; } case eFormatBoolean: - uval64 = Args::StringToBoolean(entry.ref, false, &success); + uval64 = OptionArgParser::ToBoolean(entry.ref, false, &success); if (!success) { result.AppendErrorWithFormat( "'%s' is not a valid boolean string value.\n", entry.c_str()); @@ -1642,8 +1641,8 @@ protected: } Status error; - lldb::addr_t addr = Args::StringToAddress(&m_exe_ctx, command[0].ref, - LLDB_INVALID_ADDRESS, &error); + lldb::addr_t addr = OptionArgParser::ToAddress( + &m_exe_ctx, command[0].ref, LLDB_INVALID_ADDRESS, &error); if (addr == LLDB_INVALID_ADDRESS) { result.AppendError("invalid address expression"); @@ -1709,10 +1708,10 @@ protected: m_cmd_name.c_str(), m_cmd_syntax.c_str()); result.SetStatus(eReturnStatusFailed); } else { - auto load_addr_str = command[0].ref; if (command.GetArgumentCount() == 1) { - load_addr = Args::StringToAddress(&m_exe_ctx, load_addr_str, - LLDB_INVALID_ADDRESS, &error); + auto load_addr_str = command[0].ref; + load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str, + LLDB_INVALID_ADDRESS, &error); if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS) { result.AppendErrorWithFormat( "invalid address argument \"%s\": %s\n", command[0].c_str(), diff --git a/source/Commands/CommandObjectMultiword.cpp b/source/Commands/CommandObjectMultiword.cpp index 0d0aa108a4ceb..ade1a2d01f382 100644 --- a/source/Commands/CommandObjectMultiword.cpp +++ b/source/Commands/CommandObjectMultiword.cpp @@ -55,8 +55,7 @@ CommandObjectSP CommandObjectMultiword::GetSubcommandSP(llvm::StringRef sub_cmd, if (num_matches == 1) { // Cleaner, but slightly less efficient would be to call back into this - // function, since I now - // know I have an exact match... + // function, since I now know I have an exact match... sub_cmd = matches->GetStringAtIndex(0); pos = m_subcommand_dict.find(sub_cmd); @@ -121,8 +120,8 @@ bool CommandObjectMultiword::Execute(const char *args_string, CommandObject *sub_cmd_obj = GetSubcommandObject(sub_command, &matches); if (sub_cmd_obj != nullptr) { // Now call CommandObject::Execute to process options in `rest_of_line`. - // From there the command-specific version of Execute will be called, - // with the processed arguments. + // From there the command-specific version of Execute will be called, with + // the processed arguments. args.Shift(); sub_cmd_obj->Execute(args_string, result); @@ -156,8 +155,8 @@ bool CommandObjectMultiword::Execute(const char *args_string, } void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) { - // First time through here, generate the help text for the object and - // push it to the return result object as well + // First time through here, generate the help text for the object and push it + // to the return result object as well CommandObject::GenerateHelpText(output_stream); output_stream.PutCString("\nThe following subcommands are supported:\n\n"); @@ -187,18 +186,14 @@ void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) { "'help <command> <subcommand>'.\n"); } -int CommandObjectMultiword::HandleCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - int match_start_point, - int max_return_elements, - bool &word_complete, - StringList &matches) { +int CommandObjectMultiword::HandleCompletion(CompletionRequest &request) { // Any of the command matches will provide a complete word, otherwise the // individual completers will override this. - word_complete = true; + request.SetWordComplete(true); + auto &matches = request.GetMatches(); - auto arg0 = input[0].ref; - if (cursor_index == 0) { + auto arg0 = request.GetParsedLine()[0].ref; + if (request.GetCursorIndex() == 0) { AddNamesMatchingPartialString(m_subcommand_dict, arg0, matches); if (matches.GetSize() == 1 && matches.GetStringAtIndex(0) != nullptr && @@ -206,16 +201,14 @@ int CommandObjectMultiword::HandleCompletion(Args &input, int &cursor_index, StringList temp_matches; CommandObject *cmd_obj = GetSubcommandObject(arg0, &temp_matches); if (cmd_obj != nullptr) { - if (input.GetArgumentCount() == 1) { - word_complete = true; + if (request.GetParsedLine().GetArgumentCount() == 1) { + request.SetWordComplete(true); } else { matches.DeleteStringAtIndex(0); - input.Shift(); - cursor_char_position = 0; - input.AppendArgument(llvm::StringRef()); - return cmd_obj->HandleCompletion( - input, cursor_index, cursor_char_position, match_start_point, - max_return_elements, word_complete, matches); + request.GetParsedLine().Shift(); + request.SetCursorCharPosition(0); + request.GetParsedLine().AppendArgument(llvm::StringRef()); + return cmd_obj->HandleCompletion(request); } } } @@ -227,11 +220,9 @@ int CommandObjectMultiword::HandleCompletion(Args &input, int &cursor_index, } else { // Remove the one match that we got from calling GetSubcommandObject. matches.DeleteStringAtIndex(0); - input.Shift(); - cursor_index--; - return sub_command_object->HandleCompletion( - input, cursor_index, cursor_char_position, match_start_point, - max_return_elements, word_complete, matches); + request.GetParsedLine().Shift(); + request.SetCursorIndex(request.GetCursorIndex() - 1); + return sub_command_object->HandleCompletion(request); } } } @@ -371,31 +362,20 @@ Options *CommandObjectProxy::GetOptions() { return nullptr; } -int CommandObjectProxy::HandleCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - int match_start_point, - int max_return_elements, - bool &word_complete, - StringList &matches) { +int CommandObjectProxy::HandleCompletion(CompletionRequest &request) { CommandObject *proxy_command = GetProxyCommandObject(); if (proxy_command) - return proxy_command->HandleCompletion( - input, cursor_index, cursor_char_position, match_start_point, - max_return_elements, word_complete, matches); - matches.Clear(); + return proxy_command->HandleCompletion(request); + request.GetMatches().Clear(); return 0; } int CommandObjectProxy::HandleArgumentCompletion( - Args &input, int &cursor_index, int &cursor_char_position, - OptionElementVector &opt_element_vector, int match_start_point, - int max_return_elements, bool &word_complete, StringList &matches) { + CompletionRequest &request, OptionElementVector &opt_element_vector) { CommandObject *proxy_command = GetProxyCommandObject(); if (proxy_command) - return proxy_command->HandleArgumentCompletion( - input, cursor_index, cursor_char_position, opt_element_vector, - match_start_point, max_return_elements, word_complete, matches); - matches.Clear(); + return proxy_command->HandleArgumentCompletion(request, opt_element_vector); + request.GetMatches().Clear(); return 0; } diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp index 8ed003767d588..f822a8b54cb09 100644 --- a/source/Commands/CommandObjectPlatform.cpp +++ b/source/Commands/CommandObjectPlatform.cpp @@ -18,7 +18,6 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Host/OptionParser.h" #include "lldb/Host/StringConvert.h" -#include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandOptionValidators.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -27,6 +26,7 @@ #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/Args.h" #include "lldb/Utility/DataExtractor.h" #include "llvm/ADT/SmallString.h" @@ -178,17 +178,10 @@ public: ~CommandObjectPlatformSelect() override = default; - int HandleCompletion(Args &input, int &cursor_index, - int &cursor_char_position, int match_start_point, - int max_return_elements, bool &word_complete, - StringList &matches) override { - std::string completion_str(input.GetArgumentAtIndex(cursor_index)); - completion_str.erase(cursor_char_position); - - CommandCompletions::PlatformPluginNames( - GetCommandInterpreter(), completion_str.c_str(), match_start_point, - max_return_elements, nullptr, word_complete, matches); - return matches.GetSize(); + int HandleCompletion(CompletionRequest &request) override { + CommandCompletions::PlatformPluginNames(GetCommandInterpreter(), request, + nullptr); + return request.GetMatches().GetSize(); } Options *GetOptions() override { return &m_option_group; } @@ -385,8 +378,8 @@ protected: Status error; if (platform_sp->IsConnected()) { - // Cache the instance name if there is one since we are - // about to disconnect and the name might go with it. + // Cache the instance name if there is one since we are about to + // disconnect and the name might go with it. const char *hostname_cstr = platform_sp->GetHostname(); std::string hostname; if (hostname_cstr) @@ -867,8 +860,8 @@ public: // argument entry. arg2.push_back(file_arg_host); - // Push the data for the first and the second arguments into the m_arguments - // vector. + // Push the data for the first and the second arguments into the + // m_arguments vector. m_arguments.push_back(arg1); m_arguments.push_back(arg2); } @@ -1059,8 +1052,8 @@ protected: if (argc > 0) { if (m_options.launch_info.GetExecutableFile()) { - // We already have an executable file, so we will use this - // and all arguments to this function are extra arguments + // We already have an executable file, so we will use this and all + // arguments to this function are extra arguments m_options.launch_info.GetArguments().AppendArguments(args); } else { // We don't have any file yet, so the first argument is our @@ -1342,32 +1335,32 @@ protected: } break; case 'n': - match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg, - false); + match_info.GetProcessInfo().GetExecutableFile().SetFile( + option_arg, false, FileSpec::Style::native); match_info.SetNameMatchType(NameMatch::Equals); break; case 'e': - match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg, - false); + match_info.GetProcessInfo().GetExecutableFile().SetFile( + option_arg, false, FileSpec::Style::native); match_info.SetNameMatchType(NameMatch::EndsWith); break; case 's': - match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg, - false); + match_info.GetProcessInfo().GetExecutableFile().SetFile( + option_arg, false, FileSpec::Style::native); match_info.SetNameMatchType(NameMatch::StartsWith); break; case 'c': - match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg, - false); + match_info.GetProcessInfo().GetExecutableFile().SetFile( + option_arg, false, FileSpec::Style::native); match_info.SetNameMatchType(NameMatch::Contains); break; case 'r': - match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg, - false); + match_info.GetProcessInfo().GetExecutableFile().SetFile( + option_arg, false, FileSpec::Style::native); match_info.SetNameMatchType(NameMatch::RegularExpression); break; @@ -1536,7 +1529,8 @@ public: break; case 'n': - attach_info.GetExecutableFile().SetFile(option_arg, false); + attach_info.GetExecutableFile().SetFile(option_arg, false, + FileSpec::Style::native); break; case 'w': @@ -1560,11 +1554,8 @@ public: } bool HandleOptionArgumentCompletion( - Args &input, int cursor_index, int char_pos, - OptionElementVector &opt_element_vector, int opt_element_index, - int match_start_point, int max_return_elements, - CommandInterpreter &interpreter, bool &word_complete, - StringList &matches) override { + CompletionRequest &request, OptionElementVector &opt_element_vector, + int opt_element_index, CommandInterpreter &interpreter) override { int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; @@ -1574,11 +1565,10 @@ public: // Are we in the name? // Look to see if there is a -P argument provided, and if so use that - // plugin, otherwise - // use the default plugin. + // plugin, otherwise use the default plugin. const char *partial_name = nullptr; - partial_name = input.GetArgumentAtIndex(opt_arg_pos); + partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos); PlatformSP platform_sp(interpreter.GetPlatform(true)); if (platform_sp) { @@ -1586,14 +1576,14 @@ public: ProcessInstanceInfoMatch match_info; if (partial_name) { match_info.GetProcessInfo().GetExecutableFile().SetFile( - partial_name, false); + partial_name, false, FileSpec::Style::native); match_info.SetNameMatchType(NameMatch::StartsWith); } platform_sp->FindProcesses(match_info, process_infos); const uint32_t num_matches = process_infos.GetSize(); if (num_matches > 0) { for (uint32_t i = 0; i < num_matches; ++i) { - matches.AppendString( + request.GetMatches().AppendString( process_infos.GetProcessNameAtIndex(i), process_infos.GetProcessNameLengthAtIndex(i)); } @@ -1693,7 +1683,7 @@ class CommandObjectPlatformShell : public CommandObjectRaw { public: class CommandOptions : public Options { public: - CommandOptions() : Options(), timeout(10) {} + CommandOptions() : Options() {} ~CommandOptions() override = default; @@ -1709,11 +1699,13 @@ public: switch (short_option) { case 't': - timeout = 10; - if (option_arg.getAsInteger(10, timeout)) + uint32_t timeout_sec; + if (option_arg.getAsInteger(10, timeout_sec)) error.SetErrorStringWithFormat( "could not convert \"%s\" to a numeric value.", option_arg.str().c_str()); + else + timeout = std::chrono::seconds(timeout_sec); break; default: error.SetErrorStringWithFormat("invalid short option character '%c'", @@ -1726,7 +1718,7 @@ public: void OptionParsingStarting(ExecutionContext *execution_context) override {} - uint32_t timeout; + Timeout<std::micro> timeout = std::chrono::seconds(10); }; CommandObjectPlatformShell(CommandInterpreter &interpreter) @@ -1739,47 +1731,24 @@ public: Options *GetOptions() override { return &m_options; } - bool DoExecute(const char *raw_command_line, + bool DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override { ExecutionContext exe_ctx = GetCommandInterpreter().GetExecutionContext(); m_options.NotifyOptionParsingStarting(&exe_ctx); - const char *expr = nullptr; // Print out an usage syntax on an empty command line. - if (raw_command_line[0] == '\0') { + if (raw_command_line.empty()) { result.GetOutputStream().Printf("%s\n", this->GetSyntax().str().c_str()); return true; } - if (raw_command_line[0] == '-') { - // We have some options and these options MUST end with --. - const char *end_options = nullptr; - const char *s = raw_command_line; - while (s && s[0]) { - end_options = ::strstr(s, "--"); - if (end_options) { - end_options += 2; // Get past the "--" - if (::isspace(end_options[0])) { - expr = end_options; - while (::isspace(*expr)) - ++expr; - break; - } - } - s = end_options; - } - - if (end_options) { - Args args( - llvm::StringRef(raw_command_line, end_options - raw_command_line)); - if (!ParseOptions(args, result)) - return false; - } - } + OptionsWithRaw args(raw_command_line); + const char *expr = args.GetRawPart().c_str(); - if (expr == nullptr) - expr = raw_command_line; + if (args.HasArgs()) + if (!ParseOptions(args.GetArgs(), result)) + return false; PlatformSP platform_sp( m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); diff --git a/source/Commands/CommandObjectPlugin.cpp b/source/Commands/CommandObjectPlugin.cpp index 7e1b7f61f766c..1f379a2660ed8 100644 --- a/source/Commands/CommandObjectPlugin.cpp +++ b/source/Commands/CommandObjectPlugin.cpp @@ -42,20 +42,13 @@ public: ~CommandObjectPluginLoad() override = default; - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - auto completion_str = input[cursor_index].ref; - completion_str = completion_str.take_front(cursor_char_position); - + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - completion_str, match_start_point, max_return_elements, nullptr, - word_complete, matches); - return matches.GetSize(); + request, nullptr); + return request.GetMatches().GetSize(); } protected: diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp index 9fbdd76305481..3ac27918df4cf 100644 --- a/source/Commands/CommandObjectProcess.cpp +++ b/source/Commands/CommandObjectProcess.cpp @@ -21,9 +21,9 @@ #include "lldb/Host/Host.h" #include "lldb/Host/OptionParser.h" #include "lldb/Host/StringConvert.h" -#include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/Options.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" @@ -31,6 +31,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/Args.h" using namespace lldb; using namespace lldb_private; @@ -133,20 +134,14 @@ public: ~CommandObjectProcessLaunch() override = default; - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - std::string completion_str(input.GetArgumentAtIndex(cursor_index)); - completion_str.erase(cursor_char_position); + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - completion_str.c_str(), match_start_point, max_return_elements, nullptr, - word_complete, matches); - return matches.GetSize(); + request, nullptr); + return request.GetMatches().GetSize(); } Options *GetOptions() override { return &m_options; } @@ -179,18 +174,18 @@ protected: llvm::StringRef target_settings_argv0 = target->GetArg0(); // Determine whether we will disable ASLR or leave it in the default state - // (i.e. enabled if the platform supports it). - // First check if the process launch options explicitly turn on/off + // (i.e. enabled if the platform supports it). First check if the process + // launch options explicitly turn on/off // disabling ASLR. If so, use that setting; // otherwise, use the 'settings target.disable-aslr' setting. bool disable_aslr = false; if (m_options.disable_aslr != eLazyBoolCalculate) { - // The user specified an explicit setting on the process launch line. Use - // it. + // The user specified an explicit setting on the process launch line. + // Use it. disable_aslr = (m_options.disable_aslr == eLazyBoolYes); } else { - // The user did not explicitly specify whether to disable ASLR. Fall back - // to the target.disable-aslr setting. + // The user did not explicitly specify whether to disable ASLR. Fall + // back to the target.disable-aslr setting. disable_aslr = target->GetDisableASLR(); } @@ -205,11 +200,7 @@ protected: if (target->GetDisableSTDIO()) m_options.launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO); - Args environment; - target->GetEnvironmentAsArgs(environment); - if (environment.GetArgumentCount() > 0) - m_options.launch_info.GetEnvironmentEntries().AppendArguments( - environment); + m_options.launch_info.GetEnvironment() = target->GetEnvironment(); if (!target_settings_argv0.empty()) { m_options.launch_info.GetArguments().AppendArgument( @@ -237,11 +228,10 @@ protected: ProcessSP process_sp(target->GetProcessSP()); if (process_sp) { // There is a race condition where this thread will return up the call - // stack to the main command - // handler and show an (lldb) prompt before HandlePrivateEvent (from - // PrivateStateThread) has - // a chance to call PushProcessIOHandler(). - process_sp->SyncIOHandler(0, 2000); + // stack to the main command handler and show an (lldb) prompt before + // HandlePrivateEvent (from PrivateStateThread) has a chance to call + // PushProcessIOHandler(). + process_sp->SyncIOHandler(0, std::chrono::seconds(2)); llvm::StringRef data = stream.GetString(); if (!data.empty()) @@ -362,7 +352,8 @@ public: break; case 'n': - attach_info.GetExecutableFile().SetFile(option_arg, false); + attach_info.GetExecutableFile().SetFile(option_arg, false, + FileSpec::Style::native); break; case 'w': @@ -390,11 +381,8 @@ public: } bool HandleOptionArgumentCompletion( - Args &input, int cursor_index, int char_pos, - OptionElementVector &opt_element_vector, int opt_element_index, - int match_start_point, int max_return_elements, - CommandInterpreter &interpreter, bool &word_complete, - StringList &matches) override { + CompletionRequest &request, OptionElementVector &opt_element_vector, + int opt_element_index, CommandInterpreter &interpreter) override { int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; @@ -404,11 +392,10 @@ public: // Are we in the name? // Look to see if there is a -P argument provided, and if so use that - // plugin, otherwise - // use the default plugin. + // plugin, otherwise use the default plugin. const char *partial_name = nullptr; - partial_name = input.GetArgumentAtIndex(opt_arg_pos); + partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos); PlatformSP platform_sp(interpreter.GetPlatform(true)); if (platform_sp) { @@ -416,14 +403,14 @@ public: ProcessInstanceInfoMatch match_info; if (partial_name) { match_info.GetProcessInfo().GetExecutableFile().SetFile( - partial_name, false); + partial_name, false, FileSpec::Style::native); match_info.SetNameMatchType(NameMatch::StartsWith); } platform_sp->FindProcesses(match_info, process_infos); const size_t num_matches = process_infos.GetSize(); if (num_matches > 0) { for (size_t i = 0; i < num_matches; ++i) { - matches.AppendString( + request.GetMatches().AppendString( process_infos.GetProcessNameAtIndex(i), process_infos.GetProcessNameLengthAtIndex(i)); } @@ -456,10 +443,9 @@ protected: Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); // N.B. The attach should be synchronous. It doesn't help much to get the - // prompt back between initiating the attach - // and the target actually stopping. So even if the interpreter is set to - // be asynchronous, we wait for the stop - // ourselves here. + // prompt back between initiating the attach and the target actually + // stopping. So even if the interpreter is set to be asynchronous, we wait + // for the stop ourselves here. StateType state = eStateInvalid; Process *process = m_exe_ctx.GetProcessPtr(); @@ -485,9 +471,8 @@ protected: } // Record the old executable module, we want to issue a warning if the - // process of attaching changed the - // current executable (like somebody said "file foo" then attached to a PID - // whose executable was bar.) + // process of attaching changed the current executable (like somebody said + // "file foo" then attached to a PID whose executable was bar.) ModuleSP old_exec_module_sp = target->GetExecutableModule(); ArchSpec old_arch_spec = target->GetArchitecture(); @@ -556,8 +541,8 @@ protected: target->GetArchitecture().GetTriple().getTriple().c_str()); } - // This supports the use-case scenario of immediately continuing the process - // once attached. + // This supports the use-case scenario of immediately continuing the + // process once attached. if (m_options.attach_info.GetContinueOnceAttached()) m_interpreter.HandleCommand("process continue", eLazyBoolNo, result); @@ -695,11 +680,10 @@ protected: if (error.Success()) { // There is a race condition where this thread will return up the call - // stack to the main command - // handler and show an (lldb) prompt before HandlePrivateEvent (from - // PrivateStateThread) has - // a chance to call PushProcessIOHandler(). - process->SyncIOHandler(iohandler_id, 2000); + // stack to the main command handler and show an (lldb) prompt before + // HandlePrivateEvent (from PrivateStateThread) has a chance to call + // PushProcessIOHandler(). + process->SyncIOHandler(iohandler_id, std::chrono::seconds(2)); result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n", process->GetID()); @@ -760,7 +744,7 @@ public: case 's': bool tmp_result; bool success; - tmp_result = Args::StringToBoolean(option_arg, false, &success); + tmp_result = OptionArgParser::ToBoolean(option_arg, false, &success); if (!success) error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", option_arg.str().c_str()); @@ -991,7 +975,7 @@ public: case 'i': do_install = true; if (!option_arg.empty()) - install_path.SetFile(option_arg, false); + install_path.SetFile(option_arg, false, FileSpec::Style::native); break; default: error.SetErrorStringWithFormat("invalid short option character '%c'", @@ -1444,7 +1428,7 @@ public: bool VerifyCommandOptionValue(const std::string &option, int &real_value) { bool okay = true; bool success = false; - bool tmp_value = Args::StringToBoolean(option, false, &success); + bool tmp_value = OptionArgParser::ToBoolean(option, false, &success); if (success && tmp_value) real_value = 1; @@ -1563,8 +1547,7 @@ protected: int32_t signo = signals_sp->GetSignalNumberFromName(arg.c_str()); if (signo != LLDB_INVALID_SIGNAL_NUMBER) { // Casting the actions as bools here should be okay, because - // VerifyCommandOptionValue guarantees - // the value is either 0 or 1. + // VerifyCommandOptionValue guarantees the value is either 0 or 1. if (stop_action != -1) signals_sp->SetShouldStop(signo, stop_action); if (pass_action != -1) { diff --git a/source/Commands/CommandObjectQuit.cpp b/source/Commands/CommandObjectQuit.cpp index be55dab61683a..37ed12be358f2 100644 --- a/source/Commands/CommandObjectQuit.cpp +++ b/source/Commands/CommandObjectQuit.cpp @@ -16,6 +16,7 @@ #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/StreamString.h" using namespace lldb; using namespace lldb_private; @@ -26,14 +27,13 @@ using namespace lldb_private; CommandObjectQuit::CommandObjectQuit(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "quit", "Quit the LLDB debugger.", - "quit") {} + "quit [exit-code]") {} CommandObjectQuit::~CommandObjectQuit() {} -// returns true if there is at least one alive process -// is_a_detach will be true if all alive processes will be detached when you -// quit -// and false if at least one process will be killed instead +// returns true if there is at least one alive process is_a_detach will be true +// if all alive processes will be detached when you quit and false if at least +// one process will be killed instead bool CommandObjectQuit::ShouldAskForConfirmation(bool &is_a_detach) { if (m_interpreter.GetPromptOnQuit() == false) return false; @@ -78,6 +78,41 @@ bool CommandObjectQuit::DoExecute(Args &command, CommandReturnObject &result) { return false; } } + + if (command.GetArgumentCount() > 1) { + result.AppendError("Too many arguments for 'quit'. Only an optional exit " + "code is allowed"); + result.SetStatus(eReturnStatusFailed); + return false; + } + + if (command.GetArgumentCount() > 1) { + result.AppendError("Too many arguments for 'quit'. Only an optional exit " + "code is allowed"); + result.SetStatus(eReturnStatusFailed); + return false; + } + + // We parse the exit code argument if there is one. + if (command.GetArgumentCount() == 1) { + llvm::StringRef arg = command.GetArgumentAtIndex(0); + int exit_code; + if (arg.getAsInteger(/*autodetect radix*/ 0, exit_code)) { + lldb_private::StreamString s; + std::string arg_str = arg.str(); + s.Printf("Couldn't parse '%s' as integer for exit code.", arg_str.data()); + result.AppendError(s.GetString()); + result.SetStatus(eReturnStatusFailed); + return false; + } + if (!m_interpreter.SetQuitExitCode(exit_code)) { + result.AppendError("The current driver doesn't allow custom exit codes" + " for the quit command."); + result.SetStatus(eReturnStatusFailed); + return false; + } + } + const uint32_t event_type = CommandInterpreter::eBroadcastBitQuitCommandReceived; m_interpreter.BroadcastEvent(event_type); diff --git a/source/Commands/CommandObjectRegister.cpp b/source/Commands/CommandObjectRegister.cpp index d535742016acb..4dadc5d68d203 100644 --- a/source/Commands/CommandObjectRegister.cpp +++ b/source/Commands/CommandObjectRegister.cpp @@ -9,10 +9,10 @@ #include "CommandObjectRegister.h" #include "lldb/Core/Debugger.h" +#include "lldb/Core/DumpRegisterValue.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionGroupFormat.h" @@ -25,6 +25,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/Args.h" #include "lldb/Utility/DataExtractor.h" #include "llvm/Support/Errno.h" @@ -92,8 +93,8 @@ public: bool prefix_with_altname = (bool)m_command_options.alternate_name; bool prefix_with_name = !prefix_with_altname; - reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname, - m_format_options.GetFormat(), 8); + DumpRegisterValue(reg_value, &strm, reg_info, prefix_with_name, + prefix_with_altname, m_format_options.GetFormat(), 8); if ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint)) { Process *process = exe_ctx.GetProcessPtr(); @@ -192,8 +193,8 @@ protected: num_register_sets = reg_ctx->GetRegisterSetCount(); for (set_idx = 0; set_idx < num_register_sets; ++set_idx) { - // When dump_all_sets option is set, dump primitive as well as derived - // registers. + // When dump_all_sets option is set, dump primitive as well as + // derived registers. DumpRegisterSet(m_exe_ctx, strm, reg_ctx, set_idx, !m_command_options.dump_all_sets.GetCurrentValue()); } @@ -209,8 +210,8 @@ protected: result.SetStatus(eReturnStatusFailed); } else { for (auto &entry : command) { - // in most LLDB commands we accept $rbx as the name for register RBX - - // and here we would reject it and non-existant. we should be more + // in most LLDB commands we accept $rbx as the name for register RBX + // - and here we would reject it and non-existant. we should be more // consistent towards the user and allow them to say reg read $rbx - // internally, however, we should be strict and not allow ourselves // to call our registers $rbx in our own API @@ -350,11 +351,11 @@ protected: auto reg_name = command[0].ref; auto value_str = command[1].ref; - // in most LLDB commands we accept $rbx as the name for register RBX - and - // here we would reject it and non-existant. we should be more consistent - // towards the user and allow them to say reg write $rbx - internally, - // however, we should be strict and not allow ourselves to call our - // registers $rbx in our own API + // in most LLDB commands we accept $rbx as the name for register RBX - + // and here we would reject it and non-existant. we should be more + // consistent towards the user and allow them to say reg write $rbx - + // internally, however, we should be strict and not allow ourselves to + // call our registers $rbx in our own API reg_name.consume_front("$"); const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); @@ -365,8 +366,8 @@ protected: Status error(reg_value.SetValueFromString(reg_info, value_str)); if (error.Success()) { if (reg_ctx->WriteRegister(reg_info, reg_value)) { - // Toss all frames and anything else in the thread - // after a register has been written. + // Toss all frames and anything else in the thread after a register + // has been written. m_exe_ctx.GetThreadRef().Flush(); result.SetStatus(eReturnStatusSuccessFinishNoResult); return true; diff --git a/source/Commands/CommandObjectSettings.cpp b/source/Commands/CommandObjectSettings.cpp index d42466cd13b13..f259f2fe200d5 100644 --- a/source/Commands/CommandObjectSettings.cpp +++ b/source/Commands/CommandObjectSettings.cpp @@ -133,32 +133,27 @@ insert-before or insert-after."); bool m_global; }; - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - std::string completion_str(input.GetArgumentAtIndex(cursor_index), - cursor_char_position); - - const size_t argc = input.GetArgumentCount(); + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + + const size_t argc = request.GetParsedLine().GetArgumentCount(); const char *arg = nullptr; int setting_var_idx; - for (setting_var_idx = 1; setting_var_idx < static_cast<int>(argc); + for (setting_var_idx = 0; setting_var_idx < static_cast<int>(argc); ++setting_var_idx) { - arg = input.GetArgumentAtIndex(setting_var_idx); + arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx); if (arg && arg[0] != '-') break; // We found our setting variable name index } - if (cursor_index == setting_var_idx) { + if (request.GetCursorIndex() == setting_var_idx) { // Attempting to complete setting variable name CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), match_start_point, max_return_elements, - nullptr, word_complete, matches); + request, nullptr); } else { - arg = input.GetArgumentAtIndex(cursor_index); + arg = + request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()); if (arg) { if (arg[0] == '-') { @@ -166,24 +161,23 @@ insert-before or insert-after."); } else { // Complete setting value const char *setting_var_name = - input.GetArgumentAtIndex(setting_var_idx); + request.GetParsedLine().GetArgumentAtIndex(setting_var_idx); Status error; lldb::OptionValueSP value_sp( m_interpreter.GetDebugger().GetPropertyValue( &m_exe_ctx, setting_var_name, false, error)); if (value_sp) { - value_sp->AutoComplete(m_interpreter, completion_str.c_str(), - match_start_point, max_return_elements, - word_complete, matches); + value_sp->AutoComplete(m_interpreter, request); } } } } - return matches.GetSize(); + return request.GetMatches().GetSize(); } protected: - bool DoExecute(const char *command, CommandReturnObject &result) override { + bool DoExecute(llvm::StringRef command, + CommandReturnObject &result) override { Args cmd_args(command); // Process possible options. @@ -220,10 +214,8 @@ protected: if (error.Success()) { // FIXME this is the same issue as the one in commands script import // we could be setting target.load-script-from-symbol-file which would - // cause - // Python scripts to be loaded, which could run LLDB commands - // (e.g. settings set target.process.python-os-plugin-path) and cause a - // crash + // cause Python scripts to be loaded, which could run LLDB commands (e.g. + // settings set target.process.python-os-plugin-path) and cause a crash // if we did not clear the command's exe_ctx first ExecutionContext exe_ctx(m_exe_ctx); m_exe_ctx.Clear(); @@ -274,20 +266,13 @@ public: ~CommandObjectSettingsShow() override = default; - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - std::string completion_str(input.GetArgumentAtIndex(cursor_index), - cursor_char_position); - + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), match_start_point, max_return_elements, nullptr, - word_complete, matches); - return matches.GetSize(); + request, nullptr); + return request.GetMatches().GetSize(); } protected: @@ -347,20 +332,13 @@ public: ~CommandObjectSettingsList() override = default; - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - std::string completion_str(input.GetArgumentAtIndex(cursor_index), - cursor_char_position); - + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), match_start_point, max_return_elements, nullptr, - word_complete, matches); - return matches.GetSize(); + request, nullptr); + return request.GetMatches().GetSize(); } protected: @@ -442,26 +420,19 @@ public: ~CommandObjectSettingsRemove() override = default; - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - std::string completion_str(input.GetArgumentAtIndex(cursor_index), - cursor_char_position); - - // Attempting to complete variable name - if (cursor_index < 2) + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), match_start_point, max_return_elements, - nullptr, word_complete, matches); - return matches.GetSize(); + request, nullptr); + return request.GetMatches().GetSize(); } protected: - bool DoExecute(const char *command, CommandReturnObject &result) override { + bool DoExecute(llvm::StringRef command, + CommandReturnObject &result) override { result.SetStatus(eReturnStatusSuccessFinishNoResult); Args cmd_args(command); @@ -564,27 +535,21 @@ public: // !WantsRawCommandString. bool WantsCompletion() override { return true; } - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - std::string completion_str(input.GetArgumentAtIndex(cursor_index), - cursor_char_position); - + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { // Attempting to complete variable name - if (cursor_index < 2) + if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), match_start_point, max_return_elements, - nullptr, word_complete, matches); + request, nullptr); - return matches.GetSize(); + return request.GetMatches().GetSize(); } protected: - bool DoExecute(const char *command, CommandReturnObject &result) override { + bool DoExecute(llvm::StringRef command, + CommandReturnObject &result) override { result.SetStatus(eReturnStatusSuccessFinishNoResult); Args cmd_args(command); @@ -670,27 +635,21 @@ public: // !WantsRawCommandString. bool WantsCompletion() override { return true; } - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - std::string completion_str(input.GetArgumentAtIndex(cursor_index), - cursor_char_position); - + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { // Attempting to complete variable name - if (cursor_index < 2) + if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), match_start_point, max_return_elements, - nullptr, word_complete, matches); + request, nullptr); - return matches.GetSize(); + return request.GetMatches().GetSize(); } protected: - bool DoExecute(const char *command, CommandReturnObject &result) override { + bool DoExecute(llvm::StringRef command, + CommandReturnObject &result) override { result.SetStatus(eReturnStatusSuccessFinishNoResult); Args cmd_args(command); @@ -781,27 +740,21 @@ public: // !WantsRawCommandString. bool WantsCompletion() override { return true; } - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - std::string completion_str(input.GetArgumentAtIndex(cursor_index), - cursor_char_position); - + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { // Attempting to complete variable name - if (cursor_index < 2) + if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), match_start_point, max_return_elements, - nullptr, word_complete, matches); + request, nullptr); - return matches.GetSize(); + return request.GetMatches().GetSize(); } protected: - bool DoExecute(const char *command, CommandReturnObject &result) override { + bool DoExecute(llvm::StringRef command, + CommandReturnObject &result) override { result.SetStatus(eReturnStatusSuccessFinishNoResult); Args cmd_args(command); @@ -881,27 +834,21 @@ public: // !WantsRawCommandString. bool WantsCompletion() override { return true; } - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - std::string completion_str(input.GetArgumentAtIndex(cursor_index), - cursor_char_position); - + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { // Attempting to complete variable name - if (cursor_index < 2) + if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), match_start_point, max_return_elements, - nullptr, word_complete, matches); + request, nullptr); - return matches.GetSize(); + return request.GetMatches().GetSize(); } protected: - bool DoExecute(const char *command, CommandReturnObject &result) override { + bool DoExecute(llvm::StringRef command, + CommandReturnObject &result) override { result.SetStatus(eReturnStatusSuccessFinishNoResult); Args cmd_args(command); const size_t argc = cmd_args.GetArgumentCount(); @@ -920,8 +867,8 @@ protected: return false; } - // Do not perform cmd_args.Shift() since StringRef is manipulating the - // raw character string later on. + // Do not perform cmd_args.Shift() since StringRef is manipulating the raw + // character string later on. // Split the raw command into var_name and value pair. llvm::StringRef raw_str(command); @@ -968,23 +915,16 @@ public: ~CommandObjectSettingsClear() override = default; - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - std::string completion_str(input.GetArgumentAtIndex(cursor_index), - cursor_char_position); - + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { // Attempting to complete variable name - if (cursor_index < 2) + if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - completion_str.c_str(), match_start_point, max_return_elements, - nullptr, word_complete, matches); + request, nullptr); - return matches.GetSize(); + return request.GetMatches().GetSize(); } protected: diff --git a/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp index 066cc59c5c315..19e2e441c2416 100644 --- a/source/Commands/CommandObjectSource.cpp +++ b/source/Commands/CommandObjectSource.cpp @@ -22,6 +22,7 @@ #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/Options.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" @@ -91,8 +92,8 @@ class CommandObjectSourceInfo : public CommandObjectParsed { break; case 'a': { - address = Args::StringToAddress(execution_context, option_arg, - LLDB_INVALID_ADDRESS, &error); + address = OptionArgParser::ToAddress(execution_context, option_arg, + LLDB_INVALID_ADDRESS, &error); } break; case 's': modules.push_back(std::string(option_arg)); @@ -147,16 +148,13 @@ public: Options *GetOptions() override { return &m_options; } protected: - // Dump the line entries in each symbol context. - // Return the number of entries found. - // If module_list is set, only dump lines contained in one of the modules. - // If file_spec is set, only dump lines in the file. - // If the start_line option was specified, don't print lines less than - // start_line. + // Dump the line entries in each symbol context. Return the number of entries + // found. If module_list is set, only dump lines contained in one of the + // modules. If file_spec is set, only dump lines in the file. If the + // start_line option was specified, don't print lines less than start_line. // If the end_line option was specified, don't print lines greater than - // end_line. - // If the num_lines option was specified, dont print more than num_lines - // entries. + // end_line. If the num_lines option was specified, dont print more than + // num_lines entries. uint32_t DumpLinesInSymbolContexts(Stream &strm, const SymbolContextList &sc_list, const ModuleList &module_list, @@ -221,14 +219,11 @@ protected: } // Dump the requested line entries for the file in the compilation unit. - // Return the number of entries found. - // If module_list is set, only dump lines contained in one of the modules. - // If the start_line option was specified, don't print lines less than - // start_line. - // If the end_line option was specified, don't print lines greater than - // end_line. - // If the num_lines option was specified, dont print more than num_lines - // entries. + // Return the number of entries found. If module_list is set, only dump lines + // contained in one of the modules. If the start_line option was specified, + // don't print lines less than start_line. If the end_line option was + // specified, don't print lines greater than end_line. If the num_lines + // option was specified, dont print more than num_lines entries. uint32_t DumpFileLinesInCompUnit(Stream &strm, Module *module, CompileUnit *cu, const FileSpec &file_spec) { uint32_t start_line = m_options.start_line; @@ -258,8 +253,8 @@ protected: while (true) { LineEntry line_entry; - // Find the lowest index of a line entry with a line equal to - // or higher than 'line'. + // Find the lowest index of a line entry with a line equal to or + // higher than 'line'. uint32_t start_idx = 0; start_idx = cu->FindLineEntry(start_idx, line, &cu_file_spec, /*exact=*/false, &line_entry); @@ -270,7 +265,8 @@ protected: if (end_line > 0 && line_entry.line > end_line) break; - // Loop through to find any other entries for this line, dumping each. + // Loop through to find any other entries for this line, dumping + // each. line = line_entry.line; do { num_matches++; @@ -304,22 +300,18 @@ protected: return num_matches; } - // Dump the requested line entries for the file in the module. - // Return the number of entries found. - // If module_list is set, only dump lines contained in one of the modules. - // If the start_line option was specified, don't print lines less than - // start_line. - // If the end_line option was specified, don't print lines greater than - // end_line. - // If the num_lines option was specified, dont print more than num_lines - // entries. + // Dump the requested line entries for the file in the module. Return the + // number of entries found. If module_list is set, only dump lines contained + // in one of the modules. If the start_line option was specified, don't print + // lines less than start_line. If the end_line option was specified, don't + // print lines greater than end_line. If the num_lines option was specified, + // dont print more than num_lines entries. uint32_t DumpFileLinesInModule(Stream &strm, Module *module, const FileSpec &file_spec) { uint32_t num_matches = 0; if (module) { // Look through all the compilation units (CUs) in this module for ones - // that - // contain lines of code from this source file. + // that contain lines of code from this source file. for (size_t i = 0; i < module->GetNumCompileUnits(); i++) { // Look for a matching source file in this CU. CompUnitSP cu_sp(module->GetCompileUnitAtIndex(i)); @@ -333,10 +325,8 @@ protected: } // Given an address and a list of modules, append the symbol contexts of all - // line entries - // containing the address found in the modules and return the count of - // matches. If none - // is found, return an error in 'error_strm'. + // line entries containing the address found in the modules and return the + // count of matches. If none is found, return an error in 'error_strm'. size_t GetSymbolContextsForAddress(const ModuleList &module_list, lldb::addr_t addr, SymbolContextList &sc_list, @@ -346,8 +336,8 @@ protected: assert(module_list.GetSize() > 0); Target *target = m_exe_ctx.GetTargetPtr(); if (target->GetSectionLoadList().IsEmpty()) { - // The target isn't loaded yet, we need to lookup the file address in - // all modules. Note: the module list option does not apply to addresses. + // The target isn't loaded yet, we need to lookup the file address in all + // modules. Note: the module list option does not apply to addresses. const size_t num_modules = module_list.GetSize(); for (size_t i = 0; i < num_modules; ++i) { ModuleSP module_sp(module_list.GetModuleAtIndex(i)); @@ -369,8 +359,8 @@ protected: " not found in any modules.\n", addr); } else { - // The target has some things loaded, resolve this address to a - // compile unit + file + line and display + // The target has some things loaded, resolve this address to a compile + // unit + file + line and display if (target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) { ModuleSP module_sp(so_addr.GetModule()); // Check to make sure this module is in our list. @@ -408,8 +398,8 @@ protected: return num_matches; } - // Dump the line entries found in functions matching the name specified in the - // option. + // Dump the line entries found in functions matching the name specified in + // the option. bool DumpLinesInFunctions(CommandReturnObject &result) { SymbolContextList sc_list_funcs; ConstString name(m_options.symbol_name.c_str()); @@ -709,8 +699,8 @@ class CommandObjectSourceList : public CommandObjectParsed { break; case 'a': { - address = Args::StringToAddress(execution_context, option_arg, - LLDB_INVALID_ADDRESS, &error); + address = OptionArgParser::ToAddress(execution_context, option_arg, + LLDB_INVALID_ADDRESS, &error); } break; case 's': modules.push_back(std::string(option_arg)); @@ -773,9 +763,9 @@ public: const char *GetRepeatCommand(Args ¤t_command_args, uint32_t index) override { - // This is kind of gross, but the command hasn't been parsed yet so we can't - // look at the option values for this invocation... I have to scan the - // arguments directly. + // This is kind of gross, but the command hasn't been parsed yet so we + // can't look at the option values for this invocation... I have to scan + // the arguments directly. auto iter = llvm::find_if(current_command_args, [](const Args::ArgEntry &e) { return e.ref == "-r" || e.ref == "--reverse"; @@ -863,11 +853,9 @@ protected: } // This is a little hacky, but the first line table entry for a function - // points to the "{" that - // starts the function block. It would be nice to actually get the - // function - // declaration in there too. So back up a bit, but not further than what - // you're going to display. + // points to the "{" that starts the function block. It would be nice to + // actually get the function declaration in there too. So back up a bit, + // but not further than what you're going to display. uint32_t extra_lines; if (m_options.num_lines >= 10) extra_lines = 5; @@ -880,8 +868,7 @@ protected: line_no = start_line - extra_lines; // For fun, if the function is shorter than the number of lines we're - // supposed to display, - // only display the function... + // supposed to display, only display the function... if (end_line != 0) { if (m_options.num_lines > end_line - line_no) m_options.num_lines = end_line - line_no + extra_lines; @@ -912,14 +899,13 @@ protected: return 0; } - // From Jim: The FindMatchingFunctions / FindMatchingFunctionSymbols functions - // "take a possibly empty vector of strings which are names of modules, and - // run the two search functions on the subset of the full module list that - // matches the strings in the input vector". If we wanted to put these - // somewhere, - // there should probably be a module-filter-list that can be passed to the - // various ModuleList::Find* calls, which would either be a vector of string - // names or a ModuleSpecList. + // From Jim: The FindMatchingFunctions / FindMatchingFunctionSymbols + // functions "take a possibly empty vector of strings which are names of + // modules, and run the two search functions on the subset of the full module + // list that matches the strings in the input vector". If we wanted to put + // these somewhere, there should probably be a module-filter-list that can be + // passed to the various ModuleList::Find* calls, which would either be a + // vector of string names or a ModuleSpecList. size_t FindMatchingFunctions(Target *target, const ConstString &name, SymbolContextList &sc_list) { // Displaying the source for a symbol: @@ -996,8 +982,7 @@ protected: size_t num_matches = FindMatchingFunctions(target, name, sc_list); if (!num_matches) { // If we didn't find any functions with that name, try searching for - // symbols - // that line up exactly with function addresses. + // symbols that line up exactly with function addresses. SymbolContextList sc_list_symbols; size_t num_symbol_matches = FindMatchingFunctionSymbols(target, name, sc_list_symbols); @@ -1064,8 +1049,8 @@ protected: SymbolContextList sc_list; if (target->GetSectionLoadList().IsEmpty()) { - // The target isn't loaded yet, we need to lookup the file address - // in all modules + // The target isn't loaded yet, we need to lookup the file address in + // all modules const ModuleList &module_list = target->GetImages(); const size_t num_modules = module_list.GetSize(); for (size_t i = 0; i < num_modules; ++i) { @@ -1090,8 +1075,8 @@ protected: return false; } } else { - // The target has some things loaded, resolve this address to a - // compile unit + file + line and display + // The target has some things loaded, resolve this address to a compile + // unit + file + line and display if (target->GetSectionLoadList().ResolveLoadAddress(m_options.address, so_addr)) { ModuleSP module_sp(so_addr.GetModule()); @@ -1168,11 +1153,10 @@ protected: } } } else if (m_options.file_name.empty()) { - // Last valid source manager context, or the current frame if no - // valid last context in source manager. - // One little trick here, if you type the exact same list command twice in - // a row, it is - // more likely because you typed it once, then typed it again + // Last valid source manager context, or the current frame if no valid + // last context in source manager. One little trick here, if you type the + // exact same list command twice in a row, it is more likely because you + // typed it once, then typed it again if (m_options.start_line == 0) { if (target->GetSourceManager().DisplayMoreWithLineNumbers( &result.GetOutputStream(), m_options.num_lines, diff --git a/source/Commands/CommandObjectStats.cpp b/source/Commands/CommandObjectStats.cpp new file mode 100644 index 0000000000000..9225a94b70d38 --- /dev/null +++ b/source/Commands/CommandObjectStats.cpp @@ -0,0 +1,107 @@ +//===-- CommandObjectStats.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "CommandObjectStats.h" +#include "lldb/Host/Host.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +class CommandObjectStatsEnable : public CommandObjectParsed { +public: + CommandObjectStatsEnable(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "enable", + "Enable statistics collection", nullptr, + eCommandProcessMustBePaused) {} + + ~CommandObjectStatsEnable() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + Target *target = GetSelectedOrDummyTarget(); + + if (target->GetCollectingStats()) { + result.AppendError("statistics already enabled"); + result.SetStatus(eReturnStatusFailed); + return false; + } + + target->SetCollectingStats(true); + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } +}; + +class CommandObjectStatsDisable : public CommandObjectParsed { +public: + CommandObjectStatsDisable(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "disable", + "Disable statistics collection", nullptr, + eCommandProcessMustBePaused) {} + + ~CommandObjectStatsDisable() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + Target *target = GetSelectedOrDummyTarget(); + + if (!target->GetCollectingStats()) { + result.AppendError("need to enable statistics before disabling them"); + result.SetStatus(eReturnStatusFailed); + return false; + } + + target->SetCollectingStats(false); + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } +}; + +class CommandObjectStatsDump : public CommandObjectParsed { +public: + CommandObjectStatsDump(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "dump", "Dump statistics results", + nullptr, eCommandProcessMustBePaused) {} + + ~CommandObjectStatsDump() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + Target *target = GetSelectedOrDummyTarget(); + + uint32_t i = 0; + for (auto &stat : target->GetStatistics()) { + result.AppendMessageWithFormat( + "%s : %u\n", + lldb_private::GetStatDescription(static_cast<lldb_private::StatisticKind>(i)) + .c_str(), + stat); + i += 1; + } + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } +}; + +CommandObjectStats::CommandObjectStats(CommandInterpreter &interpreter) + : CommandObjectMultiword(interpreter, "statistics", + "Print statistics about a debugging session", + "statistics <subcommand> [<subcommand-options>]") { + LoadSubCommand("enable", + CommandObjectSP(new CommandObjectStatsEnable(interpreter))); + LoadSubCommand("disable", + CommandObjectSP(new CommandObjectStatsDisable(interpreter))); + LoadSubCommand("dump", + CommandObjectSP(new CommandObjectStatsDump(interpreter))); +} + +CommandObjectStats::~CommandObjectStats() = default; diff --git a/source/Commands/CommandObjectStats.h b/source/Commands/CommandObjectStats.h new file mode 100644 index 0000000000000..3c5c2c04db1f6 --- /dev/null +++ b/source/Commands/CommandObjectStats.h @@ -0,0 +1,25 @@ +//===-- CommandObjectStats.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_CommandObjectStats_h_ +#define liblldb_CommandObjectStats_h_ + +#include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/CommandObjectMultiword.h" + +namespace lldb_private { +class CommandObjectStats : public CommandObjectMultiword { +public: + CommandObjectStats(CommandInterpreter &interpreter); + + ~CommandObjectStats() override; +}; +} // namespace lldb_private + +#endif // liblldb_CommandObjectLanguage_h_ diff --git a/source/Commands/CommandObjectSyntax.cpp b/source/Commands/CommandObjectSyntax.cpp deleted file mode 100644 index 2b83b1b8786b0..0000000000000 --- a/source/Commands/CommandObjectSyntax.cpp +++ /dev/null @@ -1,103 +0,0 @@ -//===-- CommandObjectSyntax.cpp ---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "CommandObjectSyntax.h" -#include "CommandObjectHelp.h" -#include "lldb/Interpreter/Args.h" -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandObjectMultiword.h" -#include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Interpreter/Options.h" - -using namespace lldb; -using namespace lldb_private; - -//------------------------------------------------------------------------- -// CommandObjectSyntax -//------------------------------------------------------------------------- - -CommandObjectSyntax::CommandObjectSyntax(CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "syntax", - "Shows the correct syntax for a given debugger command.", - "syntax <command>") { - CommandArgumentEntry arg; - CommandArgumentData command_arg; - - // Define the first (and only) variant of this arg. - command_arg.arg_type = eArgTypeCommandName; - command_arg.arg_repetition = eArgRepeatPlain; - - // There is only one variant this argument could be; put it into the argument - // entry. - arg.push_back(command_arg); - - // Push the data for the first argument into the m_arguments vector. - m_arguments.push_back(arg); -} - -CommandObjectSyntax::~CommandObjectSyntax() = default; - -bool CommandObjectSyntax::DoExecute(Args &command, - CommandReturnObject &result) { - CommandObject::CommandMap::iterator pos; - CommandObject *cmd_obj; - const size_t argc = command.GetArgumentCount(); - - if (argc == 0) { - result.AppendError("Must call 'syntax' with a valid command."); - result.SetStatus(eReturnStatusFailed); - return false; - } - - cmd_obj = m_interpreter.GetCommandObject(command[0].ref); - bool all_okay = llvm::all_of( - command.entries().drop_front(), [&cmd_obj](const Args::ArgEntry &e) { - if (!cmd_obj || !cmd_obj->IsMultiwordObject()) - return false; - - if (!(cmd_obj = cmd_obj->GetSubcommandObject(e.ref))) - return false; - - return true; - }); - - if (!all_okay) { - std::string cmd_string; - command.GetCommandString(cmd_string); - - StreamString error_msg_stream; - const bool generate_apropos = true; - const bool generate_type_lookup = false; - CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage( - &error_msg_stream, cmd_string, "", "", generate_apropos, - generate_type_lookup); - result.AppendErrorWithFormat("%s", error_msg_stream.GetData()); - result.SetStatus(eReturnStatusFailed); - return false; - } - - Stream &output_strm = result.GetOutputStream(); - if (cmd_obj->GetOptions() != nullptr) { - output_strm.Printf("\nSyntax: %s\n", cmd_obj->GetSyntax().str().c_str()); - output_strm.Printf( - "(Try 'help %s' for more information on command options syntax.)\n", - cmd_obj->GetCommandName().str().c_str()); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else { - output_strm.Printf("\nSyntax: %s\n", cmd_obj->GetSyntax().str().c_str()); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } - - return result.Succeeded(); -} diff --git a/source/Commands/CommandObjectSyntax.h b/source/Commands/CommandObjectSyntax.h deleted file mode 100644 index b65e9b1b750b2..0000000000000 --- a/source/Commands/CommandObjectSyntax.h +++ /dev/null @@ -1,37 +0,0 @@ -//===-- CommandObjectSyntax.h -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_CommandObjectSyntax_h_ -#define liblldb_CommandObjectSyntax_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandObject.h" - -namespace lldb_private { - -//------------------------------------------------------------------------- -// CommandObjectSyntax -//------------------------------------------------------------------------- - -class CommandObjectSyntax : public CommandObjectParsed { -public: - CommandObjectSyntax(CommandInterpreter &interpreter); - - ~CommandObjectSyntax() override; - -protected: - bool DoExecute(Args &command, CommandReturnObject &result) override; -}; - -} // namespace lldb_private - -#endif // liblldb_CommandObjectSyntax_h_ diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp index c83061d8de740..a9062c14b367c 100644 --- a/source/Commands/CommandObjectTarget.cpp +++ b/source/Commands/CommandObjectTarget.cpp @@ -21,9 +21,9 @@ #include "lldb/Host/OptionParser.h" #include "lldb/Host/StringConvert.h" #include "lldb/Host/Symbols.h" -#include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/OptionGroupArchitecture.h" #include "lldb/Interpreter/OptionGroupBoolean.h" #include "lldb/Interpreter/OptionGroupFile.h" @@ -45,10 +45,12 @@ #include "lldb/Symbol/VariableList.h" #include "lldb/Target/ABI.h" #include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Utility/Args.h" #include "lldb/Utility/Timer.h" #include "llvm/Support/FileSystem.h" @@ -193,20 +195,13 @@ public: Options *GetOptions() override { return &m_option_group; } - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - std::string completion_str(input.GetArgumentAtIndex(cursor_index)); - completion_str.erase(cursor_char_position); - + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - completion_str.c_str(), match_start_point, max_return_elements, nullptr, - word_complete, matches); - return matches.GetSize(); + request, nullptr); + return request.GetMatches().GetSize(); } protected: @@ -256,7 +251,7 @@ protected: FileSpec file_spec; if (file_path) - file_spec.SetFile(file_path, true); + file_spec.SetFile(file_path, true, FileSpec::Style::native); bool must_set_platform_path = false; @@ -272,10 +267,8 @@ protected: if (target_sp) { // Only get the platform after we create the target because we might - // have - // switched platforms depending on what the arguments were to - // CreateTarget() - // we can't rely on the selected platform. + // have switched platforms depending on what the arguments were to + // CreateTarget() we can't rely on the selected platform. PlatformSP platform_sp = target_sp->GetPlatform(); @@ -366,8 +359,8 @@ protected: &core_file)); if (process_sp) { - // Seems weird that we Launch a core file, but that is - // what we do! + // Seems weird that we Launch a core file, but that is what we + // do! error = process_sp->LoadCore(); if (error.Fail()) { @@ -616,8 +609,8 @@ protected: target_list.DeleteTarget(target_sp); target_sp->Destroy(); } - // If "--clean" was specified, prune any orphaned shared modules from - // the global shared module list + // If "--clean" was specified, prune any orphaned shared modules from the + // global shared module list if (m_cleanup_option.GetOptionValue()) { const bool mandatory = true; ModuleList::RemoveOrphanSharedModules(mandatory); @@ -752,7 +745,7 @@ public: VariableList &variable_list) { Target *target = static_cast<Target *>(baton); if (target) { - return target->GetImages().FindGlobalVariables(ConstString(name), true, + return target->GetImages().FindGlobalVariables(ConstString(name), UINT32_MAX, variable_list); } return 0; @@ -818,8 +811,8 @@ protected: return false; } use_var_name = true; - matches = target->GetImages().FindGlobalVariables( - regex, true, UINT32_MAX, variable_list); + matches = target->GetImages().FindGlobalVariables(regex, UINT32_MAX, + variable_list); } else { Status error(Variable::GetValuesForVariableExpressionPath( arg, m_exe_ctx.GetBestExecutionContextScope(), @@ -947,8 +940,8 @@ protected: llvm::StringRef( ".")); // Any global with at least one character VariableList variable_list; - sc.module_sp->FindGlobalVariables(all_globals_regex, append, - UINT32_MAX, variable_list); + sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX, + variable_list); DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s); } } @@ -995,10 +988,9 @@ public: new_prefix_arg.arg_type = eArgTypeNewPathPrefix; new_prefix_arg.arg_repetition = eArgRepeatPairPlus; - // There are two required arguments that must always occur together, i.e. an - // argument "pair". Because they - // must always occur together, they are treated as two variants of one - // argument rather than two independent + // There are two required arguments that must always occur together, i.e. + // an argument "pair". Because they must always occur together, they are + // treated as two variants of one argument rather than two independent // arguments. Push them both into the first argument position for // m_arguments... @@ -1109,10 +1101,9 @@ public: new_prefix_arg.arg_type = eArgTypeNewPathPrefix; new_prefix_arg.arg_repetition = eArgRepeatPairPlus; - // There are two required arguments that must always occur together, i.e. an - // argument "pair". Because they - // must always occur together, they are treated as two variants of one - // argument rather than two independent + // There are two required arguments that must always occur together, i.e. + // an argument "pair". Because they must always occur together, they are + // treated as two variants of one argument rather than two independent // arguments. Push them both into the same argument position for // m_arguments... @@ -1386,7 +1377,12 @@ static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) { strm.EOL(); } ObjectFile *objfile = module->GetObjectFile(); - objfile->Dump(&strm); + if (objfile) + objfile->Dump(&strm); + else { + strm.Format("No object file for module: {0:F}\n", + module->GetFileSpec()); + } } } strm.IndentLess(); @@ -1632,8 +1628,8 @@ static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm, strm.PutCString(":\n"); for (TypeSP type_sp : type_list.Types()) { if (type_sp) { - // Resolve the clang type so that any forward references - // to types that haven't yet been parsed will get parsed. + // Resolve the clang type so that any forward references to types + // that haven't yet been parsed will get parsed. type_sp->GetFullCompilerType(); type_sp->GetDescription(&strm, eDescriptionLevelFull, true); // Print all typedef chains @@ -1683,8 +1679,8 @@ static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm, TypeSP type_sp(type_list.GetTypeAtIndex(0)); if (type_sp) { - // Resolve the clang type so that any forward references - // to types that haven't yet been parsed will get parsed. + // Resolve the clang type so that any forward references to types that + // haven't yet been parsed will get parsed. type_sp->GetFullCompilerType(); type_sp->GetDescription(&strm, eDescriptionLevelFull, true); // Print all typedef chains @@ -1762,9 +1758,8 @@ static size_t FindModulesByName(Target *target, const char *module_name, const size_t num_matches = target->GetImages().FindModules(module_spec, module_list); - // Not found in our module list for our target, check the main - // shared module list in case it is a extra file used somewhere - // else + // Not found in our module list for our target, check the main shared + // module list in case it is a extra file used somewhere else if (num_matches == 0) { module_spec.GetArchitecture() = target->GetArchitecture(); ModuleList::FindSharedModules(module_spec, module_list); @@ -1809,21 +1804,13 @@ public: ~CommandObjectTargetModulesModuleAutoComplete() override = default; - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - // Arguments are the standard module completer. - std::string completion_str(input.GetArgumentAtIndex(cursor_index)); - completion_str.erase(cursor_char_position); - + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eModuleCompletion, - completion_str.c_str(), match_start_point, max_return_elements, nullptr, - word_complete, matches); - return matches.GetSize(); + GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request, + nullptr); + return request.GetMatches().GetSize(); } }; @@ -1858,21 +1845,13 @@ public: ~CommandObjectTargetModulesSourceFileAutoComplete() override = default; - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - // Arguments are the standard source file completer. - std::string completion_str(input.GetArgumentAtIndex(cursor_index)); - completion_str.erase(cursor_char_position); - + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion, - completion_str.c_str(), match_start_point, max_return_elements, nullptr, - word_complete, matches); - return matches.GetSize(); + request, nullptr); + return request.GetMatches().GetSize(); } }; @@ -1982,7 +1961,7 @@ public: switch (short_option) { case 's': - m_sort_order = (SortOrder)Args::StringToOptionEnum( + m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum( option_arg, GetDefinitions()[option_idx].enum_values, eSortOrderNone, error); break; @@ -2408,20 +2387,13 @@ public: Options *GetOptions() override { return &m_option_group; } - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - std::string completion_str(input.GetArgumentAtIndex(cursor_index)); - completion_str.erase(cursor_char_position); - + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - completion_str.c_str(), match_start_point, max_return_elements, nullptr, - word_complete, matches); - return matches.GetSize(); + request, nullptr); + return request.GetMatches().GetSize(); } protected: @@ -2604,8 +2576,7 @@ protected: ModuleSpec module_spec; bool search_using_module_spec = false; - // Allow "load" option to work without --file or --uuid - // option. + // Allow "load" option to work without --file or --uuid option. if (load) { if (!m_file_option.GetOptionValue().OptionWasSet() && !m_uuid_option_group.GetOptionValue().OptionWasSet()) { @@ -2746,11 +2717,34 @@ protected: process->Flush(); } if (load) { - Status error = module->LoadInMemory(*target, set_pc); + ProcessSP process = target->CalculateProcess(); + Address file_entry = objfile->GetEntryPointAddress(); + if (!process) { + result.AppendError("No process"); + return false; + } + if (set_pc && !file_entry.IsValid()) { + result.AppendError("No entry address in object file"); + return false; + } + std::vector<ObjectFile::LoadableData> loadables( + objfile->GetLoadableData(*target)); + if (loadables.size() == 0) { + result.AppendError("No loadable sections"); + return false; + } + Status error = process->WriteObjectFile(std::move(loadables)); if (error.Fail()) { result.AppendError(error.AsCString()); return false; } + if (set_pc) { + ThreadList &thread_list = process->GetThreadList(); + ThreadSP curr_thread(thread_list.GetSelectedThread()); + RegisterContextSP reg_context( + curr_thread->GetRegisterContext()); + reg_context->SetPC(file_entry.GetLoadAddress(target)); + } } } else { module->GetFileSpec().GetPath(path, sizeof(path)); @@ -2861,8 +2855,8 @@ public: if (short_option == 'g') { m_use_global_module_list = true; } else if (short_option == 'a') { - m_module_addr = Args::StringToAddress(execution_context, option_arg, - LLDB_INVALID_ADDRESS, &error); + m_module_addr = OptionArgParser::ToAddress( + execution_context, option_arg, LLDB_INVALID_ADDRESS, &error); } else { unsigned long width = 0; option_arg.getAsInteger(0, width); @@ -2904,9 +2898,8 @@ protected: Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); const bool use_global_module_list = m_options.m_use_global_module_list; // Define a local module list here to ensure it lives longer than any - // "locker" - // object which might lock its contents below (through the "module_list_ptr" - // variable). + // "locker" object which might lock its contents below (through the + // "module_list_ptr" variable). ModuleList module_list; if (target == nullptr && !use_global_module_list) { result.AppendError("invalid target, create a debug target using the " @@ -2954,10 +2947,9 @@ protected: size_t num_modules = 0; // This locker will be locked on the mutex in module_list_ptr if it is - // non-nullptr. - // Otherwise it will lock the AllocationModuleCollectionMutex when - // accessing - // the global module list directly. + // non-nullptr. Otherwise it will lock the + // AllocationModuleCollectionMutex when accessing the global module list + // directly. std::unique_lock<std::recursive_mutex> guard( Module::GetAllocationModuleCollectionMutex(), std::defer_lock); @@ -3227,8 +3219,8 @@ public: case 'a': { m_str = option_arg; m_type = eLookupTypeAddress; - m_addr = Args::StringToAddress(execution_context, option_arg, - LLDB_INVALID_ADDRESS, &error); + m_addr = OptionArgParser::ToAddress(execution_context, option_arg, + LLDB_INVALID_ADDRESS, &error); if (m_addr == LLDB_INVALID_ADDRESS) error.SetErrorStringWithFormat("invalid address string '%s'", option_arg.str().c_str()); @@ -3543,8 +3535,8 @@ public: switch (short_option) { case 'a': { m_type = eLookupTypeAddress; - m_addr = Args::StringToAddress(execution_context, option_arg, - LLDB_INVALID_ADDRESS, &error); + m_addr = OptionArgParser::ToAddress(execution_context, option_arg, + LLDB_INVALID_ADDRESS, &error); } break; case 'o': @@ -3559,7 +3551,7 @@ public: break; case 'f': - m_file.SetFile(option_arg, false); + m_file.SetFile(option_arg, false, FileSpec::Style::native); m_type = eLookupTypeFileLine; break; @@ -3805,9 +3797,9 @@ protected: if (command.GetArgumentCount() == 0) { ModuleSP current_module; - // Where it is possible to look in the current symbol context - // first, try that. If this search was successful and --all - // was not passed, don't print anything else. + // Where it is possible to look in the current symbol context first, + // try that. If this search was successful and --all was not passed, + // don't print anything else. if (LookupHere(m_interpreter, result, syntax_error)) { result.GetOutputStream().EOL(); num_successful_lookups++; @@ -3989,20 +3981,13 @@ public: ~CommandObjectTargetSymbolsAdd() override = default; - int HandleArgumentCompletion(Args &input, int &cursor_index, - int &cursor_char_position, - OptionElementVector &opt_element_vector, - int match_start_point, int max_return_elements, - bool &word_complete, - StringList &matches) override { - std::string completion_str(input.GetArgumentAtIndex(cursor_index)); - completion_str.erase(cursor_char_position); - + int HandleArgumentCompletion( + CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - completion_str.c_str(), match_start_point, max_return_elements, nullptr, - word_complete, matches); - return matches.GetSize(); + request, nullptr); + return request.GetMatches().GetSize(); } Options *GetOptions() override { return &m_option_group; } @@ -4019,10 +4004,9 @@ protected: if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec()) module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename(); } - // We now have a module that represents a symbol file - // that can be used for a module that might exist in the - // current target, so we need to find that module in the - // target + // We now have a module that represents a symbol file that can be used + // for a module that might exist in the current target, so we need to + // find that module in the target ModuleList matching_module_list; size_t num_matches = 0; @@ -4048,8 +4032,7 @@ protected: if (num_matches == 0) { // No matches yet, iterate through the module specs to find a UUID - // value that - // we can match up to an image in our target + // value that we can match up to an image in our target const size_t num_symfile_module_specs = symfile_module_specs.GetSize(); for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0; @@ -4069,8 +4052,8 @@ protected: } } - // Just try to match up the file by basename if we have no matches at this - // point + // Just try to match up the file by basename if we have no matches at + // this point if (num_matches == 0) num_matches = target->GetImages().FindModules(module_spec, matching_module_list); @@ -4082,7 +4065,8 @@ protected: if (!filename_no_extension) break; - // Check if there was no extension to strip and the basename is the same + // Check if there was no extension to strip and the basename is the + // same if (filename_no_extension == module_spec.GetFileSpec().GetFilename()) break; @@ -4101,9 +4085,9 @@ protected: } else if (num_matches == 1) { ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0)); - // The module has not yet created its symbol vendor, we can just - // give the existing target module the symfile path to use for - // when it decides to create it! + // The module has not yet created its symbol vendor, we can just give + // the existing target module the symfile path to use for when it + // decides to create it! module_sp->SetSymbolFileFileSpec(symbol_fspec); SymbolVendor *symbol_vendor = @@ -4121,8 +4105,8 @@ protected: "symbol file '%s' has been added to '%s'\n", symfile_path, module_fs.GetPath().c_str()); - // Let clients know something changed in the module - // if it is currently loaded + // Let clients know something changed in the module if it is + // currently loaded ModuleList module_list; module_list.Append(module_sp); target->SymbolsDidLoad(module_list); @@ -4298,7 +4282,8 @@ protected: for (auto &entry : args.entries()) { if (!entry.ref.empty()) { - module_spec.GetSymbolFileSpec().SetFile(entry.ref, true); + module_spec.GetSymbolFileSpec().SetFile(entry.ref, true, + FileSpec::Style::native); if (file_option_set) { module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp index b68aa920b5821..3be559963df13 100644 --- a/source/Commands/CommandObjectThread.cpp +++ b/source/Commands/CommandObjectThread.cpp @@ -21,6 +21,7 @@ #include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/Options.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" @@ -103,8 +104,8 @@ public: } // Use tids instead of ThreadSPs to prevent deadlocking problems which - // result from JIT-ing - // code while iterating over the (locked) ThreadSP list. + // result from JIT-ing code while iterating over the (locked) ThreadSP + // list. std::vector<lldb::tid_t> tids; if (all_threads || m_unique_stacks) { @@ -195,11 +196,10 @@ protected: // // If you return false, the iteration will stop, otherwise it will proceed. // The result is set to m_success_return (defaults to - // eReturnStatusSuccessFinishResult) before the iteration, - // so you only need to set the return status in HandleOneThread if you want to - // indicate an error. - // If m_add_return is true, a blank line will be inserted between each of the - // listings (except the last one.) + // eReturnStatusSuccessFinishResult) before the iteration, so you only need + // to set the return status in HandleOneThread if you want to indicate an + // error. If m_add_return is true, a blank line will be inserted between each + // of the listings (except the last one.) virtual bool HandleOneThread(lldb::tid_t, CommandReturnObject &result) = 0; @@ -290,7 +290,7 @@ public: case 'e': { bool success; m_extended_backtrace = - Args::StringToBoolean(option_arg, false, &success); + OptionArgParser::ToBoolean(option_arg, false, &success); if (!success) error.SetErrorStringWithFormat( "invalid boolean value for option '%c'", short_option); @@ -447,7 +447,8 @@ public: switch (short_option) { case 'a': { bool success; - bool avoid_no_debug = Args::StringToBoolean(option_arg, true, &success); + bool avoid_no_debug = + OptionArgParser::ToBoolean(option_arg, true, &success); if (!success) error.SetErrorStringWithFormat( "invalid boolean value for option '%c'", short_option); @@ -459,7 +460,8 @@ public: case 'A': { bool success; - bool avoid_no_debug = Args::StringToBoolean(option_arg, true, &success); + bool avoid_no_debug = + OptionArgParser::ToBoolean(option_arg, true, &success); if (!success) error.SetErrorStringWithFormat( "invalid boolean value for option '%c'", short_option); @@ -483,7 +485,7 @@ public: case 'm': { OptionEnumValueElement *enum_values = GetDefinitions()[option_idx].enum_values; - m_run_mode = (lldb::RunMode)Args::StringToOptionEnum( + m_run_mode = (lldb::RunMode)OptionArgParser::ToOptionEnum( option_arg, enum_values, eOnlyDuringStepping, error); } break; @@ -644,8 +646,7 @@ protected: const lldb::RunMode stop_other_threads = m_options.m_run_mode; // This is a bit unfortunate, but not all the commands in this command - // object support - // only while stepping, so I use the bool for them. + // object support only while stepping, so I use the bool for them. bool bool_stop_other_threads; if (m_options.m_run_mode == eAllThreads) bool_stop_other_threads = false; @@ -750,8 +751,8 @@ protected: } // If we got a new plan, then set it to be a master plan (User level Plans - // should be master plans - // so that they can be interruptible). Then resume the process. + // should be master plans so that they can be interruptible). Then resume + // the process. if (new_plan_sp) { new_plan_sp->SetIsMasterPlan(true); @@ -782,11 +783,10 @@ protected: } // There is a race condition where this thread will return up the call - // stack to the main command handler - // and show an (lldb) prompt before HandlePrivateEvent (from - // PrivateStateThread) has - // a chance to call PushProcessIOHandler(). - process->SyncIOHandler(iohandler_id, 2000); + // stack to the main command handler and show an (lldb) prompt before + // HandlePrivateEvent (from PrivateStateThread) has a chance to call + // PushProcessIOHandler(). + process->SyncIOHandler(iohandler_id, std::chrono::seconds(2)); if (synchronous_execution) { // If any state changed events had anything to say, add that to the @@ -867,9 +867,9 @@ public: (state == eStateSuspended)) { const size_t argc = command.GetArgumentCount(); if (argc > 0) { - // These two lines appear at the beginning of both blocks in - // this if..else, but that is because we need to release the - // lock before calling process->Resume below. + // These two lines appear at the beginning of both blocks in this + // if..else, but that is because we need to release the lock before + // calling process->Resume below. std::lock_guard<std::recursive_mutex> guard( process->GetThreadList().GetMutex()); const uint32_t num_threads = process->GetThreadList().GetSize(); @@ -928,9 +928,9 @@ public: process->GetID()); } } else { - // These two lines appear at the beginning of both blocks in - // this if..else, but that is because we need to release the - // lock before calling process->Resume below. + // These two lines appear at the beginning of both blocks in this + // if..else, but that is because we need to release the lock before + // calling process->Resume below. std::lock_guard<std::recursive_mutex> guard( process->GetThreadList().GetMutex()); const uint32_t num_threads = process->GetThreadList().GetSize(); @@ -1030,7 +1030,7 @@ public: switch (short_option) { case 'a': { - lldb::addr_t tmp_addr = Args::StringToAddress( + lldb::addr_t tmp_addr = OptionArgParser::ToAddress( execution_context, option_arg, LLDB_INVALID_ADDRESS, &error); if (error.Success()) m_until_addrs.push_back(tmp_addr); @@ -1052,7 +1052,7 @@ public: case 'm': { OptionEnumValueElement *enum_values = GetDefinitions()[option_idx].enum_values; - lldb::RunMode run_mode = (lldb::RunMode)Args::StringToOptionEnum( + lldb::RunMode run_mode = (lldb::RunMode)OptionArgParser::ToOptionEnum( option_arg, enum_values, eOnlyDuringStepping, error); if (error.Success()) { @@ -1192,8 +1192,8 @@ protected: ThreadPlanSP new_plan_sp; if (frame->HasDebugInformation()) { - // Finally we got here... Translate the given line number to a bunch of - // addresses: + // Finally we got here... Translate the given line number to a bunch + // of addresses: SymbolContext sc(frame->GetSymbolContext(eSymbolContextCompUnit)); LineTable *line_table = nullptr; if (sc.comp_unit) @@ -1272,10 +1272,9 @@ protected: abort_other_plans, &address_list.front(), address_list.size(), m_options.m_stop_others, m_options.m_frame_idx); // User level plans should be master plans so they can be interrupted - // (e.g. by hitting a breakpoint) - // and other plans executed by the user (stepping around the breakpoint) - // and then a "continue" - // will resume the original plan. + // (e.g. by hitting a breakpoint) and other plans executed by the user + // (stepping around the breakpoint) and then a "continue" will resume + // the original plan. new_plan_sp->SetIsMasterPlan(true); new_plan_sp->SetOkayToDiscard(false); } else { @@ -1541,7 +1540,8 @@ public: switch (short_option) { case 'x': { bool success; - bool tmp_value = Args::StringToBoolean(option_arg, false, &success); + bool tmp_value = + OptionArgParser::ToBoolean(option_arg, false, &success); if (success) m_from_expression = tmp_value; else { @@ -1603,12 +1603,13 @@ public: Options *GetOptions() override { return &m_options; } protected: - bool DoExecute(const char *command, CommandReturnObject &result) override { + bool DoExecute(llvm::StringRef command, + CommandReturnObject &result) override { // I am going to handle this by hand, because I don't want you to have to // say: // "thread return -- -5". - if (command[0] == '-' && command[1] == 'x') { - if (command && command[2] != '\0') + if (command.startswith("-x")) { + if (command.size() != 2U) result.AppendWarning("Return values ignored when returning from user " "called expressions"); @@ -1645,7 +1646,7 @@ protected: return false; } - if (command && command[0] != '\0') { + if (!command.empty()) { Target *target = m_exe_ctx.GetTargetPtr(); EvaluateExpressionOptions options; @@ -1737,8 +1738,8 @@ public: return Status("invalid line offset: '%s'.", option_arg.str().c_str()); break; case 'a': - m_load_addr = Args::StringToAddress(execution_context, option_arg, - LLDB_INVALID_ADDRESS, &error); + m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg, + LLDB_INVALID_ADDRESS, &error); break; case 'r': m_force = true; diff --git a/source/Commands/CommandObjectType.cpp b/source/Commands/CommandObjectType.cpp index 2d4271cab3627..6bcc334198fca 100644 --- a/source/Commands/CommandObjectType.cpp +++ b/source/Commands/CommandObjectType.cpp @@ -24,6 +24,7 @@ #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/OptionGroupFormat.h" #include "lldb/Interpreter/OptionValueBoolean.h" #include "lldb/Interpreter/OptionValueLanguage.h" @@ -329,7 +330,7 @@ private: switch (short_option) { case 'C': - m_cascade = Args::StringToBoolean(option_arg, true, &success); + m_cascade = OptionArgParser::ToBoolean(option_arg, true, &success); if (!success) error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg.str().c_str()); @@ -571,7 +572,7 @@ private: switch (short_option) { case 'C': - m_cascade = Args::StringToBoolean(option_value, true, &success); + m_cascade = OptionArgParser::ToBoolean(option_value, true, &success); if (!success) error.SetErrorStringWithFormat("invalid value for cascade: %s", option_value.str().c_str()); @@ -1252,7 +1253,7 @@ Status CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue( switch (short_option) { case 'C': - m_flags.SetCascades(Args::StringToBoolean(option_arg, true, &success)); + m_flags.SetCascades(OptionArgParser::ToBoolean(option_arg, true, &success)); if (!success) error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg.str().c_str()); @@ -1420,8 +1421,8 @@ bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary( return result.Succeeded(); } - // if I am here, script_format must point to something good, so I can add that - // as a script summary to all interested parties + // if I am here, script_format must point to something good, so I can add + // that as a script summary to all interested parties Status error; @@ -2520,7 +2521,7 @@ private: switch (short_option) { case 'C': - m_cascade = Args::StringToBoolean(option_arg, true, &success); + m_cascade = OptionArgParser::ToBoolean(option_arg, true, &success); if (!success) error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg.str().c_str()); @@ -2756,9 +2757,8 @@ static OptionDefinition g_type_lookup_options[] = { class CommandObjectTypeLookup : public CommandObjectRaw { protected: // this function is allowed to do a more aggressive job at guessing languages - // than the expression parser - // is comfortable with - so leave the original call alone and add one that is - // specific to type lookup + // than the expression parser is comfortable with - so leave the original + // call alone and add one that is specific to type lookup lldb::LanguageType GuessLanguage(StackFrame *frame) { lldb::LanguageType lang_type = lldb::eLanguageTypeUnknown; @@ -2862,9 +2862,9 @@ public: return m_cmd_help_long; } - bool DoExecute(const char *raw_command_line, + bool DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override { - if (!raw_command_line || !raw_command_line[0]) { + if (raw_command_line.empty()) { result.SetError( "type lookup cannot be invoked without a type name as argument"); return false; @@ -2873,42 +2873,13 @@ public: auto exe_ctx = GetCommandInterpreter().GetExecutionContext(); m_option_group.NotifyOptionParsingStarting(&exe_ctx); - const char *name_of_type = nullptr; - - if (raw_command_line[0] == '-') { - // We have some options and these options MUST end with --. - const char *end_options = nullptr; - const char *s = raw_command_line; - while (s && s[0]) { - end_options = ::strstr(s, "--"); - if (end_options) { - end_options += 2; // Get past the "--" - if (::isspace(end_options[0])) { - name_of_type = end_options; - while (::isspace(*name_of_type)) - ++name_of_type; - break; - } - } - s = end_options; - } + OptionsWithRaw args(raw_command_line); + const char *name_of_type = args.GetRawPart().c_str(); - if (end_options) { - Args args( - llvm::StringRef(raw_command_line, end_options - raw_command_line)); - if (!ParseOptions(args, result)) - return false; - - Status error(m_option_group.NotifyOptionParsingFinished(&exe_ctx)); - if (error.Fail()) { - result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); - return false; - } - } - } - if (nullptr == name_of_type) - name_of_type = raw_command_line; + if (args.HasArgs()) + if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group, + exe_ctx)) + return false; // TargetSP // target_sp(GetCommandInterpreter().GetDebugger().GetSelectedTarget()); @@ -2933,9 +2904,8 @@ public: } // This is not the most efficient way to do this, but we support very few - // languages - // so the cost of the sort is going to be dwarfed by the actual lookup - // anyway + // languages so the cost of the sort is going to be dwarfed by the actual + // lookup anyway if (StackFrame *frame = m_exe_ctx.GetFramePtr()) { guessed_language = GuessLanguage(frame); if (guessed_language != eLanguageTypeUnknown) { @@ -3024,7 +2994,8 @@ public: ~CommandObjectFormatterInfo() override = default; protected: - bool DoExecute(const char *command, CommandReturnObject &result) override { + bool DoExecute(llvm::StringRef command, + CommandReturnObject &result) override { TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); Thread *thread = GetDefaultThread(); if (!thread) { @@ -3047,16 +3018,16 @@ protected: m_discovery_function(*result_valobj_sp); if (formatter_sp) { std::string description(formatter_sp->GetDescription()); - result.AppendMessageWithFormat( - "%s applied to (%s) %s is: %s\n", m_formatter_name.c_str(), - result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"), - command, description.c_str()); + result.GetOutputStream() + << m_formatter_name << " applied to (" + << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>") + << ") " << command << " is: " << description << "\n"; result.SetStatus(lldb::eReturnStatusSuccessFinishResult); } else { - result.AppendMessageWithFormat( - "no %s applies to (%s) %s\n", m_formatter_name.c_str(), - result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"), - command); + result.GetOutputStream() + << "no " << m_formatter_name << " applies to (" + << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>") + << ") " << command << "\n"; result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult); } return true; diff --git a/source/Commands/CommandObjectWatchpoint.cpp b/source/Commands/CommandObjectWatchpoint.cpp index 9c84c992e7158..96ae18b35743f 100644 --- a/source/Commands/CommandObjectWatchpoint.cpp +++ b/source/Commands/CommandObjectWatchpoint.cpp @@ -74,8 +74,8 @@ static int32_t WithRSAIndex(llvm::StringRef Arg) { return -1; } -// Return true if wp_ids is successfully populated with the watch ids. -// False otherwise. +// Return true if wp_ids is successfully populated with the watch ids. False +// otherwise. bool CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs( Target *target, Args &args, std::vector<uint32_t> &wp_ids) { // Pre-condition: args.GetArgumentCount() > 0. @@ -111,8 +111,8 @@ bool CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs( if (!second.empty()) StrRefArgs.push_back(second); } - // Now process the canonical list and fill in the vector of uint32_t's. - // If there is any error, return false and the client should ignore wp_ids. + // Now process the canonical list and fill in the vector of uint32_t's. If + // there is any error, return false and the client should ignore wp_ids. uint32_t beg, end, id; size_t size = StrRefArgs.size(); bool in_range = false; @@ -838,7 +838,7 @@ protected: VariableList &variable_list) { Target *target = static_cast<Target *>(baton); if (target) { - return target->GetImages().FindGlobalVariables(ConstString(name), true, + return target->GetImages().FindGlobalVariables(ConstString(name), UINT32_MAX, variable_list); } return 0; @@ -848,8 +848,8 @@ protected: Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); StackFrame *frame = m_exe_ctx.GetFramePtr(); - // If no argument is present, issue an error message. There's no way to set - // a watchpoint. + // If no argument is present, issue an error message. There's no way to + // set a watchpoint. if (command.GetArgumentCount() <= 0) { result.GetErrorStream().Printf("error: required argument missing; " "specify your program variable to watch " @@ -863,8 +863,8 @@ protected: m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite; } - // We passed the sanity check for the command. - // Proceed to set the watchpoint now. + // We passed the sanity check for the command. Proceed to set the + // watchpoint now. lldb::addr_t addr = 0; size_t size = 0; @@ -1026,7 +1026,7 @@ Examples: Options *GetOptions() override { return &m_option_group; } protected: - bool DoExecute(const char *raw_command, + bool DoExecute(llvm::StringRef raw_command, CommandReturnObject &result) override { auto exe_ctx = GetCommandInterpreter().GetExecutionContext(); m_option_group.NotifyOptionParsingStarting( @@ -1035,46 +1035,18 @@ protected: Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); StackFrame *frame = m_exe_ctx.GetFramePtr(); - Args command(raw_command); - const char *expr = nullptr; - if (raw_command[0] == '-') { - // We have some options and these options MUST end with --. - const char *end_options = nullptr; - const char *s = raw_command; - while (s && s[0]) { - end_options = ::strstr(s, "--"); - if (end_options) { - end_options += 2; // Get past the "--" - if (::isspace(end_options[0])) { - expr = end_options; - while (::isspace(*expr)) - ++expr; - break; - } - } - s = end_options; - } + OptionsWithRaw args(raw_command); - if (end_options) { - Args args(llvm::StringRef(raw_command, end_options - raw_command)); - if (!ParseOptions(args, result)) - return false; - - Status error(m_option_group.NotifyOptionParsingFinished(&exe_ctx)); - if (error.Fail()) { - result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); - return false; - } - } - } + llvm::StringRef expr = args.GetRawPart(); - if (expr == nullptr) - expr = raw_command; + if (args.HasArgs()) + if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group, + exe_ctx)) + return false; - // If no argument is present, issue an error message. There's no way to set - // a watchpoint. - if (command.GetArgumentCount() == 0) { + // If no argument is present, issue an error message. There's no way to + // set a watchpoint. + if (raw_command.trim().empty()) { result.GetErrorStream().Printf("error: required argument missing; " "specify an expression to evaulate into " "the address to watch for\n"); @@ -1087,8 +1059,8 @@ protected: m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite; } - // We passed the sanity check for the command. - // Proceed to set the watchpoint now. + // We passed the sanity check for the command. Proceed to set the + // watchpoint now. lldb::addr_t addr = 0; size_t size = 0; @@ -1107,7 +1079,7 @@ protected: if (expr_result != eExpressionCompleted) { result.GetErrorStream().Printf( "error: expression evaluation of address to watch failed\n"); - result.GetErrorStream().Printf("expression evaluated: %s\n", expr); + result.GetErrorStream() << "expression evaluated: \n" << expr << "\n"; result.SetStatus(eReturnStatusFailed); return false; } diff --git a/source/Commands/CommandObjectWatchpointCommand.cpp b/source/Commands/CommandObjectWatchpointCommand.cpp index ec7e4a1f9cde1..74015a4338318 100644 --- a/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/source/Commands/CommandObjectWatchpointCommand.cpp @@ -22,6 +22,7 @@ #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" @@ -253,11 +254,10 @@ are no syntax errors may indicate that a function was declared but never called. std::unique_ptr<WatchpointOptions::CommandData> data_ap( new WatchpointOptions::CommandData()); - // It's necessary to set both user_source and script_source to the oneliner. - // The former is used to generate callback description (as in watchpoint - // command list) - // while the latter is used for Python to interpret during the actual - // callback. + // It's necessary to set both user_source and script_source to the + // oneliner. The former is used to generate callback description (as in + // watchpoint command list) while the latter is used for Python to + // interpret during the actual callback. data_ap->user_source.AppendString(oneliner); data_ap->script_source.assign(oneliner); data_ap->stop_on_error = m_options.m_stop_on_error; @@ -286,8 +286,8 @@ are no syntax errors may indicate that a function was declared but never called. CommandReturnObject result; Debugger &debugger = target->GetDebugger(); // Rig up the results secondary output stream to the debugger's, so the - // output will come out synchronously - // if the debugger is set up that way. + // output will come out synchronously if the debugger is set up that + // way. StreamSP output_stream(debugger.GetAsyncOutputStream()); StreamSP error_stream(debugger.GetAsyncErrorStream()); @@ -331,7 +331,7 @@ are no syntax errors may indicate that a function was declared but never called. break; case 's': - m_script_language = (lldb::ScriptLanguage)Args::StringToOptionEnum( + m_script_language = (lldb::ScriptLanguage)OptionArgParser::ToOptionEnum( option_arg, GetDefinitions()[option_idx].enum_values, eScriptLanguageNone, error); @@ -341,7 +341,8 @@ are no syntax errors may indicate that a function was declared but never called. case 'e': { bool success = false; - m_stop_on_error = Args::StringToBoolean(option_arg, false, &success); + m_stop_on_error = + OptionArgParser::ToBoolean(option_arg, false, &success); if (!success) error.SetErrorStringWithFormat( "invalid value for stop-on-error: \"%s\"", @@ -439,20 +440,19 @@ protected: if (wp_options == nullptr) continue; - // If we are using script language, get the script interpreter - // in order to set or collect command callback. Otherwise, call - // the methods associated with this object. + // If we are using script language, get the script interpreter in order + // to set or collect command callback. Otherwise, call the methods + // associated with this object. if (m_options.m_use_script_language) { // Special handling for one-liner specified inline. if (m_options.m_use_one_liner) { m_interpreter.GetScriptInterpreter()->SetWatchpointCommandCallback( wp_options, m_options.m_one_liner.c_str()); } - // Special handling for using a Python function by name - // instead of extending the watchpoint callback data structures, we - // just automatize - // what the user would do manually: make their watchpoint command be a - // function call + // Special handling for using a Python function by name instead of + // extending the watchpoint callback data structures, we just + // automatize what the user would do manually: make their watchpoint + // command be a function call else if (!m_options.m_function_name.empty()) { std::string oneliner(m_options.m_function_name); oneliner += "(frame, wp, internal_dict)"; @@ -669,7 +669,7 @@ CommandObjectWatchpointCommand::CommandObjectWatchpointCommand( : CommandObjectMultiword( interpreter, "command", "Commands for adding, removing and examining LLDB commands " - "executed when the watchpoint is hit (watchpoint 'commmands').", + "executed when the watchpoint is hit (watchpoint 'commands').", "command <sub-command> [<sub-command-options>] <watchpoint-id>") { CommandObjectSP add_command_object( new CommandObjectWatchpointCommandAdd(interpreter)); |