diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:04:10 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:04:10 +0000 |
commit | 74a628f776edb588bff8f8f5cc16eac947c9d631 (patch) | |
tree | dc32e010ac4902621e5a279bfeb48628f7f0e166 /source/Commands | |
parent | afed7be32164a598f8172282c249af7266c48b46 (diff) |
Notes
Diffstat (limited to 'source/Commands')
22 files changed, 307 insertions, 277 deletions
diff --git a/source/Commands/CMakeLists.txt b/source/Commands/CMakeLists.txt index 8805bbf6dc944..55b41b1050c5a 100644 --- a/source/Commands/CMakeLists.txt +++ b/source/Commands/CMakeLists.txt @@ -29,4 +29,20 @@ add_lldb_library(lldbCommands CommandObjectWatchpoint.cpp CommandObjectWatchpointCommand.cpp CommandObjectLanguage.cpp + + LINK_LIBS + lldbBase + lldbBreakpoint + lldbCore + lldbDataFormatters + lldbExpression + lldbHost + lldbInterpreter + lldbSymbol + lldbTarget + lldbUtility + lldbPluginExpressionParserClang + + LINK_COMPONENTS + Support ) diff --git a/source/Commands/CommandCompletions.cpp b/source/Commands/CommandCompletions.cpp index 10c1a2429bbeb..fd84e1c4f8573 100644 --- a/source/Commands/CommandCompletions.cpp +++ b/source/Commands/CommandCompletions.cpp @@ -16,12 +16,12 @@ // C++ Includes // Other libraries and framework includes #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringSet.h" // Project includes #include "lldb/Core/FileSpecList.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Host/FileSpec.h" #include "lldb/Host/FileSystem.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandCompletions.h" @@ -31,8 +31,13 @@ #include "lldb/Symbol/Variable.h" #include "lldb/Target/Target.h" #include "lldb/Utility/CleanUp.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/TildeExpressionResolver.h" #include "llvm/ADT/SmallString.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" using namespace lldb_private; @@ -98,181 +103,131 @@ int CommandCompletions::SourceFiles(CommandInterpreter &interpreter, return matches.GetSize(); } -typedef struct DiskFilesOrDirectoriesBaton { - const char *remainder; - char *partial_name_copy; - bool only_directories; - bool *saw_directory; - StringList *matches; - char *end_ptr; - size_t baselen; -} DiskFilesOrDirectoriesBaton; - -FileSpec::EnumerateDirectoryResult -DiskFilesOrDirectoriesCallback(void *baton, FileSpec::FileType file_type, - const FileSpec &spec) { - const char *name = spec.GetFilename().AsCString(); - - const DiskFilesOrDirectoriesBaton *parameters = - (DiskFilesOrDirectoriesBaton *)baton; - char *end_ptr = parameters->end_ptr; - char *partial_name_copy = parameters->partial_name_copy; - const char *remainder = parameters->remainder; - - // Omit ".", ".." and any . files if the match string doesn't start with . - if (name[0] == '.') { - if (name[1] == '\0') - return FileSpec::eEnumerateDirectoryResultNext; - else if (name[1] == '.' && name[2] == '\0') - return FileSpec::eEnumerateDirectoryResultNext; - else if (remainder[0] != '.') - return FileSpec::eEnumerateDirectoryResultNext; - } +static int DiskFilesOrDirectories(const llvm::Twine &partial_name, + bool only_directories, bool &saw_directory, + StringList &matches, + TildeExpressionResolver &Resolver) { + matches.Clear(); + + llvm::SmallString<256> CompletionBuffer; + llvm::SmallString<256> Storage; + partial_name.toVector(CompletionBuffer); + + if (CompletionBuffer.size() >= PATH_MAX) + return 0; + + namespace fs = llvm::sys::fs; + namespace path = llvm::sys::path; + + llvm::StringRef SearchDir; + llvm::StringRef PartialItem; + + if (CompletionBuffer.startswith("~")) { + llvm::StringRef Buffer(CompletionBuffer); + size_t FirstSep = + Buffer.find_if([](char c) { return path::is_separator(c); }); + + llvm::StringRef Username = Buffer.take_front(FirstSep); + llvm::StringRef Remainder; + if (FirstSep != llvm::StringRef::npos) + Remainder = Buffer.drop_front(FirstSep + 1); + + llvm::SmallString<PATH_MAX> Resolved; + if (!Resolver.ResolveExact(Username, Resolved)) { + // We couldn't resolve it as a full username. If there were no slashes + // then this might be a partial username. We try to resolve it as such + // but after that, we're done regardless of any matches. + if (FirstSep == llvm::StringRef::npos) { + llvm::StringSet<> MatchSet; + saw_directory = 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 we found a directory, we put a "/" at the end of the name. + // 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; + } - if (remainder[0] == '\0' || strstr(name, remainder) == name) { - if (strlen(name) + parameters->baselen >= PATH_MAX) - return FileSpec::eEnumerateDirectoryResultNext; + // We want to keep the form the user typed, so we special case this to + // search in the fully resolved directory, but CompletionBuffer keeps the + // unmodified form that the user typed. + Storage = Resolved; + SearchDir = Resolved; + } else { + SearchDir = path::parent_path(CompletionBuffer); + } - strcpy(end_ptr, name); + size_t FullPrefixLen = CompletionBuffer.size(); - bool isa_directory = false; - if (file_type == FileSpec::eFileTypeDirectory) - isa_directory = true; - else if (file_type == FileSpec::eFileTypeSymbolicLink) { - if (FileSpec(partial_name_copy, false).IsDirectory()) - isa_directory = true; - } + PartialItem = path::filename(CompletionBuffer); + if (PartialItem == ".") + PartialItem = llvm::StringRef(); - if (isa_directory) { - *parameters->saw_directory = true; - size_t len = strlen(parameters->partial_name_copy); - partial_name_copy[len] = '/'; - partial_name_copy[len + 1] = '\0'; - } - if (parameters->only_directories && !isa_directory) - return FileSpec::eEnumerateDirectoryResultNext; - parameters->matches->AppendString(partial_name_copy); + if (SearchDir.empty()) { + llvm::sys::fs::current_path(Storage); + SearchDir = Storage; } + assert(!PartialItem.contains(path::get_separator())); - return FileSpec::eEnumerateDirectoryResultNext; -} + // SearchDir now contains the directory to search in, and Prefix contains the + // text we want to match against items in that directory. -static int DiskFilesOrDirectories(llvm::StringRef partial_file_name, - bool only_directories, bool &saw_directory, - StringList &matches) { - // I'm going to use the "glob" function with GLOB_TILDE for user directory - // expansion. - // If it is not defined on your host system, you'll need to implement it - // yourself... - - size_t partial_name_len = partial_file_name.size(); - - if (partial_name_len >= PATH_MAX) - return matches.GetSize(); - - // This copy of the string will be cut up into the directory part, and the - // remainder. end_ptr below will point to the place of the remainder in this - // string. Then when we've resolved the containing directory, and opened it, - // we'll read the directory contents and overwrite the partial_name_copy - // starting from end_ptr with each of the matches. Thus we will preserve the - // form the user originally typed. - - char partial_name_copy[PATH_MAX]; - memcpy(partial_name_copy, partial_file_name.data(), partial_name_len); - partial_name_copy[partial_name_len] = '\0'; - - // We'll need to save a copy of the remainder for comparison, which we do - // here. - char remainder[PATH_MAX]; - - // end_ptr will point past the last / in partial_name_copy, or if there is no - // slash to the beginning of the string. - char *end_ptr; - - end_ptr = strrchr(partial_name_copy, '/'); - - // This will store the resolved form of the containing directory - llvm::SmallString<64> containing_part; - - if (end_ptr == nullptr) { - // There's no directory. If the thing begins with a "~" then this is a bare - // user name. - if (*partial_name_copy == '~') { - // Nothing here but the user name. We could just put a slash on the end, - // but for completeness sake we'll resolve the user name and only put a - // slash - // on the end if it exists. - llvm::SmallString<64> resolved_username(partial_name_copy); - FileSpec::ResolveUsername(resolved_username); - - // Not sure how this would happen, a username longer than PATH_MAX? - // Still... - if (resolved_username.size() == 0) { - // The user name didn't resolve, let's look in the password database for - // matches. - // The user name database contains duplicates, and is not in - // alphabetical order, so - // we'll use a set to manage that for us. - FileSpec::ResolvePartialUsername(partial_name_copy, matches); - if (matches.GetSize() > 0) - saw_directory = true; - return matches.GetSize(); - } else { - // The thing exists, put a '/' on the end, and return it... - // FIXME: complete user names here: - partial_name_copy[partial_name_len] = '/'; - partial_name_copy[partial_name_len + 1] = '\0'; - matches.AppendString(partial_name_copy); - saw_directory = true; - return matches.GetSize(); - } - } else { - // The containing part is the CWD, and the whole string is the remainder. - containing_part = "."; - strcpy(remainder, partial_name_copy); - end_ptr = partial_name_copy; - } - } else { - if (end_ptr == partial_name_copy) { - // We're completing a file or directory in the root volume. - containing_part = "/"; - } else { - containing_part.append(partial_name_copy, end_ptr); - } - // Push end_ptr past the final "/" and set remainder. - end_ptr++; - strcpy(remainder, end_ptr); - } + std::error_code EC; + fs::directory_iterator Iter(SearchDir, EC, false); + fs::directory_iterator End; + for (; Iter != End && !EC; Iter.increment(EC)) { + auto &Entry = *Iter; - // Look for a user name in the containing part, and if it's there, resolve it - // and stick the - // result back into the containing_part: + auto Name = path::filename(Entry.path()); - if (*partial_name_copy == '~') { - FileSpec::ResolveUsername(containing_part); - // User name doesn't exist, we're not getting any further... - if (containing_part.empty()) - return matches.GetSize(); - } + // Omit ".", ".." + if (Name == "." || Name == ".." || !Name.startswith(PartialItem)) + continue; - // Okay, containing_part is now the directory we want to open and look for - // files: + // We have a match. - size_t baselen = end_ptr - partial_name_copy; + fs::file_status st; + if ((EC = Entry.status(st))) + continue; - DiskFilesOrDirectoriesBaton parameters; - parameters.remainder = remainder; - parameters.partial_name_copy = partial_name_copy; - parameters.only_directories = only_directories; - parameters.saw_directory = &saw_directory; - parameters.matches = &matches; - parameters.end_ptr = end_ptr; - parameters.baselen = baselen; + // If it's a symlink, then we treat it as a directory as long as the target + // is a directory. + bool is_dir = fs::is_directory(st); + if (fs::is_symlink_file(st)) { + fs::file_status target_st; + if (!fs::status(Entry.path(), target_st)) + is_dir = fs::is_directory(target_st); + } + if (only_directories && !is_dir) + continue; + + // Shrink it back down so that it just has the original prefix the user + // typed and remove the part of the name which is common to the located + // item and what the user typed. + CompletionBuffer.resize(FullPrefixLen); + Name = Name.drop_front(PartialItem.size()); + CompletionBuffer.append(Name); + + if (is_dir) { + saw_directory = true; + path::append(CompletionBuffer, path::get_separator()); + } - FileSpec::EnumerateDirectory(containing_part.c_str(), true, true, true, - DiskFilesOrDirectoriesCallback, ¶meters); + matches.AppendString(CompletionBuffer); + } return matches.GetSize(); } @@ -283,9 +238,17 @@ int CommandCompletions::DiskFiles(CommandInterpreter &interpreter, int max_return_elements, SearchFilter *searcher, bool &word_complete, StringList &matches) { - int ret_val = - DiskFilesOrDirectories(partial_file_name, false, word_complete, matches); - word_complete = !word_complete; + word_complete = false; + StandardTildeExpressionResolver Resolver; + return DiskFiles(partial_file_name, matches, 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; } @@ -293,9 +256,17 @@ 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) { - int ret_val = - DiskFilesOrDirectories(partial_file_name, true, word_complete, matches); word_complete = false; + StandardTildeExpressionResolver Resolver; + return DiskDirectories(partial_file_name, matches, 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; } diff --git a/source/Commands/CommandObjectArgs.cpp b/source/Commands/CommandObjectArgs.cpp index d98a246e96841..8042aa9d81dbc 100644 --- a/source/Commands/CommandObjectArgs.cpp +++ b/source/Commands/CommandObjectArgs.cpp @@ -17,6 +17,7 @@ #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" @@ -223,9 +224,9 @@ bool CommandObjectArgs::DoExecute(Args &args, CommandReturnObject &result) { 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( + "%" PRIu64 " (%s): ", (uint64_t)entry.index(), entry.value().c_str()); + value_list.GetValueAtIndex(entry.index())->Dump(&result.GetOutputStream()); result.GetOutputStream().Printf("\n"); } diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp index 941dd9a7849af..d77cf55b60e9f 100644 --- a/source/Commands/CommandObjectBreakpoint.cpp +++ b/source/Commands/CommandObjectBreakpoint.cpp @@ -18,9 +18,7 @@ #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointIDList.h" #include "lldb/Breakpoint/BreakpointLocation.h" -#include "lldb/Core/RegularExpression.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Host/StringConvert.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -33,6 +31,8 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/StreamString.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Commands/CommandObjectBreakpointCommand.cpp b/source/Commands/CommandObjectBreakpointCommand.cpp index 5e4ee0ba07006..73c0c314533cb 100644 --- a/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/source/Commands/CommandObjectBreakpointCommand.cpp @@ -19,6 +19,7 @@ #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/IOHandler.h" #include "lldb/Core/State.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Target/Target.h" diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp index aa07c104846f5..102010e8e6f69 100644 --- a/source/Commands/CommandObjectCommands.cpp +++ b/source/Commands/CommandObjectCommands.cpp @@ -17,7 +17,7 @@ #include "CommandObjectHelp.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/IOHandler.h" -#include "lldb/Core/StringList.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandHistory.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -28,6 +28,7 @@ #include "lldb/Interpreter/OptionValueUInt64.h" #include "lldb/Interpreter/Options.h" #include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Utility/StringList.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Commands/CommandObjectDisassemble.cpp b/source/Commands/CommandObjectDisassemble.cpp index fa3a1440ffc0a..4496462476b4e 100644 --- a/source/Commands/CommandObjectDisassemble.cpp +++ b/source/Commands/CommandObjectDisassemble.cpp @@ -16,7 +16,7 @@ #include "lldb/Core/Disassembler.h" #include "lldb/Core/Module.h" #include "lldb/Core/SourceManager.h" -#include "lldb/Host/StringConvert.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp index cfb3a6dd51174..8a0afce741e9c 100644 --- a/source/Commands/CommandObjectExpression.cpp +++ b/source/Commands/CommandObjectExpression.cpp @@ -24,7 +24,7 @@ #include "lldb/Expression/REPL.h" #include "lldb/Expression/UserExpression.h" #include "lldb/Host/Host.h" -#include "lldb/Host/StringConvert.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Symbol/ObjectFile.h" diff --git a/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp index 5a350545763db..8be9b6f9b7a62 100644 --- a/source/Commands/CommandObjectFrame.cpp +++ b/source/Commands/CommandObjectFrame.cpp @@ -17,7 +17,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Core/StreamString.h" #include "lldb/Core/Timer.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" @@ -25,7 +24,7 @@ #include "lldb/DataFormatters/DataVisualization.h" #include "lldb/DataFormatters/ValueObjectPrinter.h" #include "lldb/Host/Host.h" -#include "lldb/Host/StringConvert.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -47,6 +46,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/StreamString.h" using namespace lldb; using namespace lldb_private; @@ -192,14 +192,13 @@ protected: return false; } - const bool qualify_cxx_base_classes = false; - DumpValueObjectOptions::DeclPrintingHelper helper = - [&valobj_sp, qualify_cxx_base_classes]( - ConstString type, ConstString var, - const DumpValueObjectOptions &opts, Stream &stream) -> bool { + DumpValueObjectOptions::DeclPrintingHelper helper = [&valobj_sp]( + ConstString type, ConstString var, const DumpValueObjectOptions &opts, + Stream &stream) -> bool { const ValueObject::GetExpressionPathFormat format = ValueObject:: GetExpressionPathFormat::eGetExpressionPathFormatHonorPointers; + const bool qualify_cxx_base_classes = false; valobj_sp->GetExpressionPath(stream, qualify_cxx_base_classes, format); stream.PutCString(" ="); return true; diff --git a/source/Commands/CommandObjectHelp.h b/source/Commands/CommandObjectHelp.h index 721917a168524..cd9006619bc89 100644 --- a/source/Commands/CommandObjectHelp.h +++ b/source/Commands/CommandObjectHelp.h @@ -14,6 +14,7 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/Options.h" diff --git a/source/Commands/CommandObjectLog.cpp b/source/Commands/CommandObjectLog.cpp index 3fdd888d2ed0b..2099310d32c3f 100644 --- a/source/Commands/CommandObjectLog.cpp +++ b/source/Commands/CommandObjectLog.cpp @@ -13,15 +13,10 @@ // Project includes #include "CommandObjectLog.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegularExpression.h" -#include "lldb/Core/Stream.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/Timer.h" -#include "lldb/Host/FileSpec.h" -#include "lldb/Host/StringConvert.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -32,6 +27,10 @@ #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; @@ -41,13 +40,13 @@ static OptionDefinition g_log_options[] = { { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Set the destination file to log to." }, { LLDB_OPT_SET_1, false, "threadsafe", 't', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines." }, { LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose logging." }, - { LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable debug logging." }, { LLDB_OPT_SET_1, false, "sequence", 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id." }, { LLDB_OPT_SET_1, false, "timestamp", 'T', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with a timestamp." }, { LLDB_OPT_SET_1, false, "pid-tid", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with the process and thread ID that generates the log line." }, { LLDB_OPT_SET_1, false, "thread-name",'n', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with the thread name for the thread that generates the log line." }, { LLDB_OPT_SET_1, false, "stack", 'S', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append a stack backtrace to each log line." }, { LLDB_OPT_SET_1, false, "append", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append to the log file instead of overwriting." }, + { LLDB_OPT_SET_1, false, "file-function",'F',OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend the names of files and function that generate the logs." }, // clang-format on }; @@ -109,9 +108,6 @@ public: case 'v': log_options |= LLDB_LOG_OPTION_VERBOSE; break; - case 'g': - log_options |= LLDB_LOG_OPTION_DEBUG; - break; case 's': log_options |= LLDB_LOG_OPTION_PREPEND_SEQUENCE; break; @@ -130,6 +126,9 @@ public: case 'a': log_options |= LLDB_LOG_OPTION_APPEND; break; + case 'F': + log_options |= LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION; + break; default: error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); @@ -171,9 +170,14 @@ protected: m_options.log_file.GetPath(log_file, sizeof(log_file)); else log_file[0] = '\0'; + + std::string error; + llvm::raw_string_ostream error_stream(error); bool success = m_interpreter.GetDebugger().EnableLog( - channel.c_str(), args.GetConstArgumentVector(), log_file, - m_options.log_options, result.GetErrorStream()); + channel, args.GetArgumentArrayRef(), log_file, m_options.log_options, + error_stream); + result.GetErrorStream() << error_stream.str(); + if (success) result.SetStatus(eReturnStatusSuccessFinishNoResult); else @@ -227,25 +231,18 @@ protected: return false; } - Log::Callbacks log_callbacks; - const std::string channel = args[0].ref; args.Shift(); // Shift off the channel - if (Log::GetLogChannelCallbacks(ConstString(channel), log_callbacks)) { - log_callbacks.disable(args.GetConstArgumentVector(), - &result.GetErrorStream()); + if (channel == "all") { + Log::DisableAllLogChannels(); result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else if (channel == "all") { - Log::DisableAllLogChannels(&result.GetErrorStream()); } else { - LogChannelSP log_channel_sp(LogChannel::FindPlugin(channel.data())); - if (log_channel_sp) { - log_channel_sp->Disable(args.GetConstArgumentVector(), - &result.GetErrorStream()); + std::string error; + llvm::raw_string_ostream error_stream(error); + if (Log::DisableLogChannel(channel, args.GetArgumentArrayRef(), + error_stream)) result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else - result.AppendErrorWithFormat("Invalid log channel '%s'.\n", - channel.data()); + result.GetErrorStream() << error_stream.str(); } return result.Succeeded(); } @@ -280,31 +277,20 @@ public: protected: bool DoExecute(Args &args, CommandReturnObject &result) override { + std::string output; + llvm::raw_string_ostream output_stream(output); if (args.empty()) { - Log::ListAllLogChannels(&result.GetOutputStream()); + Log::ListAllLogChannels(output_stream); result.SetStatus(eReturnStatusSuccessFinishResult); } else { - for (auto &entry : args.entries()) { - Log::Callbacks log_callbacks; - - if (Log::GetLogChannelCallbacks(ConstString(entry.ref), - log_callbacks)) { - log_callbacks.list_categories(&result.GetOutputStream()); - result.SetStatus(eReturnStatusSuccessFinishResult); - } else if (entry.ref == "all") { - Log::ListAllLogChannels(&result.GetOutputStream()); - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - LogChannelSP log_channel_sp(LogChannel::FindPlugin(entry.c_str())); - if (log_channel_sp) { - log_channel_sp->ListCategories(&result.GetOutputStream()); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else - result.AppendErrorWithFormat("Invalid log channel '%s'.\n", - entry.c_str()); - } - } + bool success = true; + for (const auto &entry : args.entries()) + success = + success && Log::ListChannelCategories(entry.ref, output_stream); + if (success) + result.SetStatus(eReturnStatusSuccessFinishResult); } + result.GetOutputStream() << output_stream.str(); return result.Succeeded(); } }; diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp index 49ae923892772..1679614fe3f77 100644 --- a/source/Commands/CommandObjectMemory.cpp +++ b/source/Commands/CommandObjectMemory.cpp @@ -17,15 +17,13 @@ // Project includes #include "CommandObjectMemory.h" #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Core/Debugger.h" +#include "lldb/Core/DumpDataExtractor.h" #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" -#include "lldb/Core/StreamString.h" #include "lldb/Core/ValueObjectMemory.h" #include "lldb/DataFormatters/ValueObjectPrinter.h" -#include "lldb/Host/StringConvert.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -42,6 +40,9 @@ #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataBufferLLVM.h" +#include "lldb/Utility/StreamString.h" #include "lldb/lldb-private.h" @@ -861,10 +862,10 @@ protected: } assert(output_stream); - size_t bytes_dumped = - data.Dump(output_stream, 0, format, item_byte_size, item_count, - num_per_line / target->GetArchitecture().GetDataByteSize(), - addr, 0, 0, exe_scope); + size_t bytes_dumped = DumpDataExtractor( + data, output_stream, 0, format, item_byte_size, item_count, + num_per_line / target->GetArchitecture().GetDataByteSize(), addr, 0, 0, + exe_scope); m_next_addr = addr + bytes_dumped; output_stream->EOL(); return true; @@ -1131,10 +1132,10 @@ protected: DataExtractor data(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), process->GetByteOrder(), process->GetAddressByteSize()); - data.Dump(&result.GetOutputStream(), 0, lldb::eFormatBytesWithASCII, 1, - dumpbuffer.GetByteSize(), 16, - found_location + m_memory_options.m_offset.GetCurrentValue(), - 0, 0); + DumpDataExtractor( + data, &result.GetOutputStream(), 0, lldb::eFormatBytesWithASCII, 1, + dumpbuffer.GetByteSize(), 16, + found_location + m_memory_options.m_offset.GetCurrentValue(), 0, 0); result.GetOutputStream().EOL(); } @@ -1358,8 +1359,9 @@ protected: size_t length = SIZE_MAX; if (item_byte_size > 1) length = item_byte_size; - lldb::DataBufferSP data_sp(m_memory_options.m_infile.ReadFileContents( - m_memory_options.m_infile_offset, length)); + auto data_sp = DataBufferLLVM::CreateSliceFromPath( + m_memory_options.m_infile.GetPath(), length, + m_memory_options.m_infile_offset); if (data_sp) { length = data_sp->GetByteSize(); if (length > 0) { @@ -1441,8 +1443,16 @@ protected: case eFormatHex: case eFormatHexUppercase: case eFormatPointer: + { // Decode hex bytes - if (entry.ref.getAsInteger(16, uval64)) { + // Be careful, getAsInteger with a radix of 16 rejects "0xab" so we + // have to special case that: + bool success = false; + if (entry.ref.startswith("0x")) + success = !entry.ref.getAsInteger(0, uval64); + if (!success) + success = !entry.ref.getAsInteger(16, uval64); + if (!success) { result.AppendErrorWithFormat( "'%s' is not a valid hex string value.\n", entry.c_str()); result.SetStatus(eReturnStatusFailed); @@ -1457,7 +1467,7 @@ protected: } buffer.PutMaxHex64(uval64, item_byte_size); break; - + } case eFormatBoolean: uval64 = Args::StringToBoolean(entry.ref, false, &success); if (!success) { diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp index 562572b4c75e5..62ea683e6e0d8 100644 --- a/source/Commands/CommandObjectPlatform.cpp +++ b/source/Commands/CommandObjectPlatform.cpp @@ -13,10 +13,10 @@ // Other libraries and framework includes // Project includes #include "CommandObjectPlatform.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #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" @@ -27,9 +27,10 @@ #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" -#include "lldb/Utility/Utils.h" +#include "lldb/Utility/DataExtractor.h" #include "llvm/ADT/SmallString.h" +#include "llvm/Support/Threading.h" using namespace lldb; using namespace lldb_private; @@ -1182,21 +1183,21 @@ protected: m_options.match_info.GetProcessInfo().GetName(); if (match_name && match_name[0]) { switch (m_options.match_info.GetNameMatchType()) { - case eNameMatchIgnore: + case NameMatch::Ignore: break; - case eNameMatchEquals: + case NameMatch::Equals: match_desc = "matched"; break; - case eNameMatchContains: + case NameMatch::Contains: match_desc = "contained"; break; - case eNameMatchStartsWith: + case NameMatch::StartsWith: match_desc = "started with"; break; - case eNameMatchEndsWith: + case NameMatch::EndsWith: match_desc = "ended with"; break; - case eNameMatchRegularExpression: + case NameMatch::RegularExpression: match_desc = "matched the regular expression"; break; } @@ -1249,8 +1250,8 @@ protected: public: CommandOptions() : Options(), match_info(), show_args(false), verbose(false) { - static std::once_flag g_once_flag; - std::call_once(g_once_flag, []() { + static llvm::once_flag g_once_flag; + llvm::call_once(g_once_flag, []() { PosixPlatformCommandOptionValidator *posix_validator = new PosixPlatformCommandOptionValidator(); for (auto &Option : g_platform_process_list_options) { @@ -1342,31 +1343,31 @@ protected: case 'n': match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg, false); - match_info.SetNameMatchType(eNameMatchEquals); + match_info.SetNameMatchType(NameMatch::Equals); break; case 'e': match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg, false); - match_info.SetNameMatchType(eNameMatchEndsWith); + match_info.SetNameMatchType(NameMatch::EndsWith); break; case 's': match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg, false); - match_info.SetNameMatchType(eNameMatchStartsWith); + match_info.SetNameMatchType(NameMatch::StartsWith); break; case 'c': match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg, false); - match_info.SetNameMatchType(eNameMatchContains); + match_info.SetNameMatchType(NameMatch::Contains); break; case 'r': match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg, false); - match_info.SetNameMatchType(eNameMatchRegularExpression); + match_info.SetNameMatchType(NameMatch::RegularExpression); break; case 'A': @@ -1585,7 +1586,7 @@ public: if (partial_name) { match_info.GetProcessInfo().GetExecutableFile().SetFile( partial_name, false); - match_info.SetNameMatchType(eNameMatchStartsWith); + match_info.SetNameMatchType(NameMatch::StartsWith); } platform_sp->FindProcesses(match_info, process_infos); const uint32_t num_matches = process_infos.GetSize(); diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp index 5b7f1342328b3..557bdeecc22c0 100644 --- a/source/Commands/CommandObjectProcess.cpp +++ b/source/Commands/CommandObjectProcess.cpp @@ -19,6 +19,7 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/State.h" #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" @@ -416,7 +417,7 @@ public: if (partial_name) { match_info.GetProcessInfo().GetExecutableFile().SetFile( partial_name, false); - match_info.SetNameMatchType(eNameMatchStartsWith); + match_info.SetNameMatchType(NameMatch::StartsWith); } platform_sp->FindProcesses(match_info, process_infos); const size_t num_matches = process_infos.GetSize(); diff --git a/source/Commands/CommandObjectRegister.cpp b/source/Commands/CommandObjectRegister.cpp index 0ba6526d347d3..4d856d6bd1e03 100644 --- a/source/Commands/CommandObjectRegister.cpp +++ b/source/Commands/CommandObjectRegister.cpp @@ -14,10 +14,10 @@ // Project includes #include "CommandObjectRegister.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Core/Debugger.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" @@ -31,6 +31,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataExtractor.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Commands/CommandObjectSettings.cpp b/source/Commands/CommandObjectSettings.cpp index 23fdcb9e895ce..4a9f69f9c192f 100644 --- a/source/Commands/CommandObjectSettings.cpp +++ b/source/Commands/CommandObjectSettings.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/StringRef.h" // Project includes +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" diff --git a/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp index 6ff32080905ea..1b9ee1bf8c739 100644 --- a/source/Commands/CommandObjectSource.cpp +++ b/source/Commands/CommandObjectSource.cpp @@ -18,8 +18,7 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/SourceManager.h" -#include "lldb/Host/FileSpec.h" -#include "lldb/Host/StringConvert.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -31,6 +30,7 @@ #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/TargetList.h" +#include "lldb/Utility/FileSpec.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp index d2e53aa4a14fe..a2df4909dc02e 100644 --- a/source/Commands/CommandObjectTarget.cpp +++ b/source/Commands/CommandObjectTarget.cpp @@ -19,6 +19,7 @@ #include "lldb/Core/Timer.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/ValueObjectPrinter.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Host/StringConvert.h" #include "lldb/Host/Symbols.h" #include "lldb/Interpreter/Args.h" @@ -50,6 +51,8 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadSpec.h" +#include "llvm/Support/FileSystem.h" + // C Includes // C++ Includes #include <cerrno> @@ -2567,6 +2570,12 @@ public: m_option_group(), m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName, "Fullpath or basename for module to load.", ""), + m_load_option(LLDB_OPT_SET_1, false, "load", 'l', + "Write file contents to the memory.", false, true), + m_pc_option(LLDB_OPT_SET_1, false, "--set-pc-to-entry", 'p', + "Set PC to the entry point." + " Only applicable with '--load' option.", + false, true), m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset, "Set the load address for all sections to be the " "virtual address in the file plus the offset.", @@ -2574,6 +2583,8 @@ public: m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Finalize(); } @@ -2585,6 +2596,8 @@ public: protected: bool DoExecute(Args &args, CommandReturnObject &result) override { Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + const bool load = m_load_option.GetOptionValue().GetCurrentValue(); + const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue(); if (target == nullptr) { result.AppendError("invalid target, create a debug target using the " "'target create' command"); @@ -2594,6 +2607,21 @@ protected: const size_t argc = args.GetArgumentCount(); ModuleSpec module_spec; bool search_using_module_spec = false; + + // Allow "load" option to work without --file or --uuid + // option. + if (load) { + if (!m_file_option.GetOptionValue().OptionWasSet() && + !m_uuid_option_group.GetOptionValue().OptionWasSet()) { + ModuleList &module_list = target->GetImages(); + if (module_list.GetSize() == 1) { + search_using_module_spec = true; + module_spec.GetFileSpec() = + module_list.GetModuleAtIndex(0)->GetFileSpec(); + } + } + } + if (m_file_option.GetOptionValue().OptionWasSet()) { search_using_module_spec = true; const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue(); @@ -2721,6 +2749,13 @@ protected: if (process) process->Flush(); } + if (load) { + Error error = module->LoadInMemory(*target, set_pc); + if (error.Fail()) { + result.AppendError(error.AsCString()); + return false; + } + } } else { module->GetFileSpec().GetPath(path, sizeof(path)); result.AppendErrorWithFormat( @@ -2783,6 +2818,8 @@ protected: OptionGroupOptions m_option_group; OptionGroupUUID m_uuid_option_group; OptionGroupString m_file_option; + OptionGroupBoolean m_load_option; + OptionGroupBoolean m_pc_option; OptionGroupUInt64 m_slide_option; }; @@ -4102,20 +4139,21 @@ protected: module_sp->SetSymbolFileFileSpec(FileSpec()); } + namespace fs = llvm::sys::fs; if (module_spec.GetUUID().IsValid()) { StreamString ss_symfile_uuid; module_spec.GetUUID().Dump(&ss_symfile_uuid); result.AppendErrorWithFormat( "symbol file '%s' (%s) does not match any existing module%s\n", symfile_path, ss_symfile_uuid.GetData(), - (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular) + !fs::is_regular_file(symbol_fspec.GetPath()) ? "\n please specify the full path to the symbol file" : ""); } else { result.AppendErrorWithFormat( "symbol file '%s' does not match any existing module%s\n", symfile_path, - (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular) + !fs::is_regular_file(symbol_fspec.GetPath()) ? "\n please specify the full path to the symbol file" : ""); } diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp index 0c4072b19b841..7ba6f2c19a8db 100644 --- a/source/Commands/CommandObjectThread.cpp +++ b/source/Commands/CommandObjectThread.cpp @@ -17,6 +17,7 @@ #include "lldb/Core/State.h" #include "lldb/Core/ValueObject.h" #include "lldb/Host/Host.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" diff --git a/source/Commands/CommandObjectType.cpp b/source/Commands/CommandObjectType.cpp index 621ef581a9785..b34a42738d4fd 100644 --- a/source/Commands/CommandObjectType.cpp +++ b/source/Commands/CommandObjectType.cpp @@ -16,13 +16,11 @@ #include <functional> // Project includes -#include "lldb/Core/ConstString.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/IOHandler.h" -#include "lldb/Core/RegularExpression.h" #include "lldb/Core/State.h" -#include "lldb/Core/StringList.h" #include "lldb/DataFormatters/DataVisualization.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -38,6 +36,9 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadList.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/StringList.h" // Other libraries and framework includes #include "llvm/ADT/STLExtras.h" @@ -82,9 +83,9 @@ static bool WarnOnPotentialUnquotedUnsignedType(Args &command, return false; for (auto entry : llvm::enumerate(command.entries().drop_back())) { - if (entry.Value.ref != "unsigned") + if (entry.value().ref != "unsigned") continue; - auto next = command.entries()[entry.Index + 1].ref; + auto next = command.entries()[entry.index() + 1].ref; if (next == "int" || next == "short" || next == "char" || next == "long") { result.AppendWarningWithFormat( "unsigned %s being treated as two types. if you meant the combined " @@ -1188,8 +1189,7 @@ protected: category_closure(category_sp); } else { DataVisualization::Categories::ForEach( - [this, &command, &result, &category_regex, &formatter_regex, - &category_closure]( + [&category_regex, &category_closure]( const lldb::TypeCategoryImplSP &category) -> bool { if (category_regex) { bool escape = true; diff --git a/source/Commands/CommandObjectWatchpoint.cpp b/source/Commands/CommandObjectWatchpoint.cpp index baa9f4163a637..1ad53cdb88ada 100644 --- a/source/Commands/CommandObjectWatchpoint.cpp +++ b/source/Commands/CommandObjectWatchpoint.cpp @@ -20,10 +20,9 @@ // Project includes #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Breakpoint/WatchpointList.h" -#include "lldb/Core/StreamString.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectVariable.h" -#include "lldb/Host/StringConvert.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -31,6 +30,7 @@ #include "lldb/Symbol/VariableList.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/StreamString.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Commands/CommandObjectWatchpointCommand.cpp b/source/Commands/CommandObjectWatchpointCommand.cpp index 1860d4cca9fec..1509c487a8a7a 100644 --- a/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/source/Commands/CommandObjectWatchpointCommand.cpp @@ -19,6 +19,7 @@ #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/IOHandler.h" #include "lldb/Core/State.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Target/Target.h" |