From d9516dd8859b3d552047072ca3030233bc4a299b Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Fri, 12 Jul 2019 15:30:55 +0000 Subject: [PATCH 01/13] [lldb] Let table gen create command option initializers. Summary: We currently have man large arrays containing initializers for our command options. These tables are tricky maintain as we don't have any good place to check them for consistency and it's also hard to read (`nullptr, {}, 0` is not very descriptive). This patch fixes this by letting table gen generate those tables. This way we can have a more readable syntax for this (especially for all the default arguments) and we can let TableCheck check them for consistency (e.g. an option with an optional argument can't have `eArgTypeNone`, naming of flags', etc.). Also refactoring the related data structures can now be done without changing the hundred of option initializers. For example, this line: ``` {LLDB_OPT_SET_ALL, false, "hide-aliases", 'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Hide aliases in the command list."}, ``` becomes this: ``` def hide_aliases : Option<"hide-aliases", "a">, Desc<"Hide aliases in the command list.">; ``` For now I just moved a few initializers to the new format to demonstrate the change. I'll slowly migrate the other option initializers tables in separate patches. Reviewers: JDevlieghere, davide, sgraenitz Reviewed By: JDevlieghere Subscribers: jingham, xiaobai, labath, mgorny, abidh, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D64365 llvm-svn: 365908 (cherry picked from commit 6f4fb4e7ad67499391dd5b63ad9f5a11b1c74171) --- lldb/CMakeLists.txt | 2 + lldb/cmake/modules/AddLLDB.cmake | 35 +++- lldb/source/Commands/CMakeLists.txt | 6 + .../Commands/CommandObjectBreakpoint.cpp | 13 +- lldb/source/Commands/CommandObjectHelp.cpp | 7 +- .../source/Commands/CommandObjectSettings.cpp | 17 +- lldb/source/Commands/CommandObjectTarget.cpp | 5 +- lldb/source/Commands/Options.td | 53 ++++++ lldb/source/Commands/OptionsBase.td | 62 +++++++ lldb/utils/TableGen/CMakeLists.txt | 8 + lldb/utils/TableGen/LLDBOptionDefEmitter.cpp | 152 ++++++++++++++++++ lldb/utils/TableGen/LLDBTableGen.cpp | 71 ++++++++ lldb/utils/TableGen/LLDBTableGenBackends.h | 34 ++++ 13 files changed, 436 insertions(+), 29 deletions(-) create mode 100644 lldb/source/Commands/Options.td create mode 100644 lldb/source/Commands/OptionsBase.td create mode 100644 lldb/utils/TableGen/CMakeLists.txt create mode 100644 lldb/utils/TableGen/LLDBOptionDefEmitter.cpp create mode 100644 lldb/utils/TableGen/LLDBTableGen.cpp create mode 100644 lldb/utils/TableGen/LLDBTableGenBackends.h diff --git a/lldb/CMakeLists.txt b/lldb/CMakeLists.txt index 20eb493f7e24c6..280c3a29984a30 100644 --- a/lldb/CMakeLists.txt +++ b/lldb/CMakeLists.txt @@ -33,6 +33,8 @@ endif() if (NOT LLDB_DISABLE_PYTHON) add_subdirectory(scripts) endif () + +add_subdirectory(utils/TableGen) add_subdirectory(source) add_subdirectory(tools) add_subdirectory(docs) diff --git a/lldb/cmake/modules/AddLLDB.cmake b/lldb/cmake/modules/AddLLDB.cmake index a40d8e9cae9d73..064b51f1a786a5 100644 --- a/lldb/cmake/modules/AddLLDB.cmake +++ b/lldb/cmake/modules/AddLLDB.cmake @@ -1,4 +1,37 @@ +function(lldb_tablegen) + # Syntax: + # lldb_tablegen output-file [tablegen-arg ...] SOURCE source-file + # [[TARGET cmake-target-name] [DEPENDS extra-dependency ...]] + # + # Generates a custom command for invoking tblgen as + # + # tblgen source-file -o=output-file tablegen-arg ... + # + # and, if cmake-target-name is provided, creates a custom target for + # executing the custom command depending on output-file. It is + # possible to list more files to depend after DEPENDS. + + cmake_parse_arguments(LTG "" "SOURCE;TARGET" "" ${ARGN}) + + if(NOT LTG_SOURCE) + message(FATAL_ERROR "SOURCE source-file required by lldb_tablegen") + endif() + + set(LLVM_TARGET_DEFINITIONS ${LTG_SOURCE}) + tablegen(LLDB ${LTG_UNPARSED_ARGUMENTS}) + + if(LTG_TARGET) + add_public_tablegen_target(${LTG_TARGET}) + set_target_properties( ${LTG_TARGET} PROPERTIES FOLDER "LLDB tablegenning") + set_property(GLOBAL APPEND PROPERTY LLDB_TABLEGEN_TARGETS ${LTG_TARGET}) + endif() +endfunction(lldb_tablegen) + function(add_lldb_library name) + include_directories(BEFORE + ${CMAKE_CURRENT_BINARY_DIR} +) + # only supported parameters to this macro are the optional # MODULE;SHARED;STATIC library type and source files cmake_parse_arguments(PARAM @@ -236,4 +269,4 @@ function(lldb_setup_rpaths name) BUILD_RPATH "${LIST_BUILD_RPATH}" INSTALL_RPATH "${LIST_INSTALL_RPATH}" ) -endfunction() \ No newline at end of file +endfunction() diff --git a/lldb/source/Commands/CMakeLists.txt b/lldb/source/Commands/CMakeLists.txt index d7fd47af026ad2..f3f96af7dab02d 100644 --- a/lldb/source/Commands/CMakeLists.txt +++ b/lldb/source/Commands/CMakeLists.txt @@ -1,3 +1,7 @@ +lldb_tablegen(Options.inc -gen-lldb-option-defs + SOURCE Options.td + TARGET LLDBOptionsGen) + add_lldb_library(lldbCommands CommandCompletions.cpp CommandObjectApropos.cpp @@ -45,3 +49,5 @@ add_lldb_library(lldbCommands LINK_COMPONENTS Support ) + +add_dependencies(lldbCommands LLDBOptionsGen) diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp index a4f558e7f81ba5..a661ffc62512cd 100644 --- a/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -1246,15 +1246,10 @@ the second re-enables the first location."); #pragma mark List::CommandOptions static constexpr OptionDefinition g_breakpoint_list_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show debugger internal breakpoints" }, - { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Give a brief description of the breakpoint (no location info)." }, - // FIXME: We need to add an "internal" command, and then add this sort of thing to it. - // But I need to see it for now, and don't want to wait. - { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Give a full description of the breakpoint and its locations." }, - { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Explain everything we know about the breakpoint (for debugging debugger bugs)." }, - { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, - // clang-format on + // FIXME: We need to add an "internal" command, and then add this sort of + // thing to it. But I need to see it for now, and don't want to wait. +#define LLDB_OPTIONS_breakpoint_list +#include "Options.inc" }; #pragma mark List diff --git a/lldb/source/Commands/CommandObjectHelp.cpp b/lldb/source/Commands/CommandObjectHelp.cpp index 4e663c797ebb8d..ad53e03121f0d3 100644 --- a/lldb/source/Commands/CommandObjectHelp.cpp +++ b/lldb/source/Commands/CommandObjectHelp.cpp @@ -66,11 +66,8 @@ CommandObjectHelp::CommandObjectHelp(CommandInterpreter &interpreter) CommandObjectHelp::~CommandObjectHelp() = default; static constexpr OptionDefinition g_help_options[] = { - // clang-format off - {LLDB_OPT_SET_ALL, false, "hide-aliases", 'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Hide aliases in the command list."}, - {LLDB_OPT_SET_ALL, false, "hide-user-commands", 'u', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Hide user-defined commands from the list."}, - {LLDB_OPT_SET_ALL, false, "show-hidden-commands", 'h', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Include commands prefixed with an underscore."}, - // clang-format on +#define LLDB_OPTIONS_help +#include "Options.inc" }; llvm::ArrayRef diff --git a/lldb/source/Commands/CommandObjectSettings.cpp b/lldb/source/Commands/CommandObjectSettings.cpp index e7e72de5a7eefb..057c5de619cfae 100644 --- a/lldb/source/Commands/CommandObjectSettings.cpp +++ b/lldb/source/Commands/CommandObjectSettings.cpp @@ -22,10 +22,8 @@ using namespace lldb_private; // CommandObjectSettingsSet static constexpr OptionDefinition g_settings_set_options[] = { - // clang-format off - { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Apply the new value to the global default value." }, - { LLDB_OPT_SET_2, false, "force", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Force an empty value to be accepted as the default." } - // clang-format on +#define LLDB_OPTIONS_settings_set +#include "Options.inc" }; class CommandObjectSettingsSet : public CommandObjectRaw { @@ -313,10 +311,8 @@ class CommandObjectSettingsShow : public CommandObjectParsed { // CommandObjectSettingsWrite -- Write settings to file static constexpr OptionDefinition g_settings_write_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the settings." }, - { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to saved settings file if it exists."}, - // clang-format on +#define LLDB_OPTIONS_settings_write +#include "Options.inc" }; class CommandObjectSettingsWrite : public CommandObjectParsed { @@ -438,9 +434,8 @@ class CommandObjectSettingsWrite : public CommandObjectParsed { // CommandObjectSettingsRead -- Read settings from file static constexpr OptionDefinition g_settings_read_options[] = { - // clang-format off - {LLDB_OPT_SET_ALL, true, "file",'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." }, - // clang-format on +#define LLDB_OPTIONS_settings_read +#include "Options.inc" }; class CommandObjectSettingsRead : public CommandObjectParsed { diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index 764461ee92b841..e8720157ab4cbc 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -1967,9 +1967,8 @@ static constexpr OptionEnumValueElement g_sort_option_enumeration[] = { {eSortOrderByName, "name", "Sort output by symbol name."} }; static constexpr OptionDefinition g_target_modules_dump_symtab_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, nullptr, OptionEnumValues(g_sort_option_enumeration), 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table." } - // clang-format on +#define LLDB_OPTIONS_target_modules_dump_symtab +#include "Options.inc" }; class CommandObjectTargetModulesDumpSymtab diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td new file mode 100644 index 00000000000000..1f4c09c3860967 --- /dev/null +++ b/lldb/source/Commands/Options.td @@ -0,0 +1,53 @@ +include "OptionsBase.td" + +let Command = "target modules dump symtab" in { + def tm_sort : Option<"sort", "s">, Group<1>, + Desc<"Supply a sort order when dumping the symbol table.">, + EnumArg<"SortOrder", "OptionEnumValues(g_sort_option_enumeration)">; +} + +let Command = "help" in { + def help_hide_aliases : Option<"hide-aliases", "a">, + Desc<"Hide aliases in the command list.">; + def help_hide_user : Option<"hide-user-commands", "u">, + Desc<"Hide user-defined commands from the list.">; + def help_show_hidden : Option<"show-hidden-commands", "h">, + Desc<"Include commands prefixed with an underscore.">; +} + +let Command = "settings set" in { + def setset_global : Option<"global", "g">, Arg<"Filename">, + Completion<"DiskFile">, + Desc<"Apply the new value to the global default value.">; + def setset_force : Option<"force", "f">, + Desc<"Force an empty value to be accepted as the default.">; +} + +let Command = "settings write" in { + def setwrite_file : Option<"file", "f">, Required, Arg<"Filename">, + Completion<"DiskFile">, + Desc<"The file into which to write the settings.">; + def setwrite_append : Option<"append", "a">, + Desc<"Append to saved settings file if it exists.">; +} + +let Command = "settings read" in { + def setread_file : Option<"file", "f">, Required, Arg<"Filename">, + Completion<"DiskFile">, + Desc<"The file from which to read the settings.">; +} + +let Command = "breakpoint list" in { + def blist_internal : Option<"internal", "i">, + Desc<"Show debugger internal breakpoints">; + def blist_brief : Option<"brief", "b">, Group<1>, + Desc<"Give a brief description of the breakpoint (no location info).">; + def blist_full : Option<"full", "f">, Group<2>, + Desc<"Give a full description of the breakpoint and its locations.">; + def blist_verbose : Option<"verbose", "v">, Group<3>, + Desc<"Explain everything we know about the breakpoint (for debugging " + "debugger bugs).">; + def blist_dummy_bp : Option<"dummy-breakpoints", "D">, + Desc<"List Dummy breakpoints - i.e. breakpoints set before a file is " + "provided, which prime new targets.">; +} diff --git a/lldb/source/Commands/OptionsBase.td b/lldb/source/Commands/OptionsBase.td new file mode 100644 index 00000000000000..c4a326fbaf5f7b --- /dev/null +++ b/lldb/source/Commands/OptionsBase.td @@ -0,0 +1,62 @@ +// Base class for all options. +class Option { + string FullName = fullname; + string ShortName = shortname; + // The full associated command/subcommand such as "settings set". + string Command; +} + +// Moves the option into a list of option groups. +class Groups groups> { + list Groups = groups; +} + +// Moves the option in all option groups in a range. +// Start and end values are inclusive. +class GroupRange { + int GroupStart = start; + int GroupEnd = end; +} +// Moves the option in a single option group. +class Group { + int GroupStart = group; + int GroupEnd = group; +} + +// Sets the description for the option that should be +// displayed to the user. +class Desc { + string Description = description; +} + +// Marks the option as required when calling the +// associated command. +class Required { + bit Required = 1; +} + +// Gives the option an optional argument. +class OptionalArg { + string ArgType = type; + bit OptionalArg = 1; +} + +// Gives the option an required argument. +class Arg { + string ArgType = type; +} + +// Gives the option an required argument. +class EnumArg { + string ArgType = type; + string ArgEnum = enum; +} + +// Sets the available completions for the given option. +class Completions completions> { + list Completions = completions; +} +// Sets a single completion for the given option. +class Completion { + list Completions = [completion]; +} diff --git a/lldb/utils/TableGen/CMakeLists.txt b/lldb/utils/TableGen/CMakeLists.txt new file mode 100644 index 00000000000000..76e819160ea6e4 --- /dev/null +++ b/lldb/utils/TableGen/CMakeLists.txt @@ -0,0 +1,8 @@ +set(LLVM_LINK_COMPONENTS Support) + +add_tablegen(lldb-tblgen LLDB + LLDBOptionDefEmitter.cpp + LLDBTableGen.cpp + ) +set_target_properties(lldb-tblgen PROPERTIES FOLDER "LLDB tablegenning") + diff --git a/lldb/utils/TableGen/LLDBOptionDefEmitter.cpp b/lldb/utils/TableGen/LLDBOptionDefEmitter.cpp new file mode 100644 index 00000000000000..00b44c020a2012 --- /dev/null +++ b/lldb/utils/TableGen/LLDBOptionDefEmitter.cpp @@ -0,0 +1,152 @@ +//===- TableGen.cpp - Top-Level TableGen implementation for Clang ---------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// These tablegen backends emits LLDB's OptionDefinition values for different +// LLDB commands. +// +//===----------------------------------------------------------------------===// + +#include "LLDBTableGenBackends.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/StringMatcher.h" +#include "llvm/TableGen/TableGenBackend.h" +#include +#include + +using namespace llvm; + +/// Map of command names to their associated records. Also makes sure our +/// commands are sorted in a deterministic way. +typedef std::map> RecordsByCommand; + +/// Groups all records by their command. +static RecordsByCommand getCommandList(std::vector Options) { + RecordsByCommand result; + for (Record *Option : Options) + result[Option->getValueAsString("Command").str()].push_back(Option); + return result; +} + +static void emitOption(Record *Option, raw_ostream &OS) { + OS << " {"; + + // List of option groups this option is in. + std::vector GroupsArg; + + if (Option->getValue("Groups")) { + // The user specified a list of groups. + auto Groups = Option->getValueAsListOfInts("Groups"); + for (int Group : Groups) + GroupsArg.push_back("LLDB_OPT_SET_" + std::to_string(Group)); + OS << llvm::join(GroupsArg.begin(), GroupsArg.end(), " | "); + } else if (Option->getValue("GroupStart")) { + // The user specified a range of groups (with potentially only one element). + int GroupStart = Option->getValueAsInt("GroupStart"); + int GroupEnd = Option->getValueAsInt("GroupEnd"); + for (int i = GroupStart; i <= GroupEnd; ++i) + GroupsArg.push_back("LLDB_OPT_SET_" + std::to_string(i)); + } + + // If we have any groups, we merge them. Otherwise we move this option into + // the all group. + if (GroupsArg.empty()) + OS << "LLDB_OPT_SET_ALL"; + else + OS << llvm::join(GroupsArg.begin(), GroupsArg.end(), " | "); + + OS << ", "; + + // Check if this option is required. + OS << (Option->getValue("Required") ? "true" : "false"); + + // Add the full and short name for this option. + OS << ", \"" << Option->getValueAsString("FullName") << "\", "; + OS << '\'' << Option->getValueAsString("ShortName") << "'"; + + auto ArgType = Option->getValue("ArgType"); + bool IsOptionalArg = Option->getValue("OptionalArg") != nullptr; + + // Decide if we have either an option, required or no argument for this + // option. + OS << ", OptionParser::"; + if (ArgType) { + if (IsOptionalArg) + OS << "eOptionalArgument"; + else + OS << "eRequiredArgument"; + } else + OS << "eNoArgument"; + OS << ", nullptr, "; + + if (Option->getValue("ArgEnum")) + OS << Option->getValueAsString("ArgEnum"); + else + OS << "{}"; + OS << ", "; + + // Read the tab completions we offer for this option (if there are any) + if (Option->getValue("Completions")) { + auto Completions = Option->getValueAsListOfStrings("Completions"); + std::vector CompletionArgs; + for (llvm::StringRef Completion : Completions) + CompletionArgs.push_back("CommandCompletions::e" + Completion.str() + + "Completion"); + + OS << llvm::join(CompletionArgs.begin(), CompletionArgs.end(), " | "); + } else { + OS << "CommandCompletions::eNoCompletion"; + } + + // Add the argument type. + OS << ", eArgType"; + if (ArgType) { + OS << ArgType->getValue()->getAsUnquotedString(); + } else + OS << "None"; + OS << ", "; + + // Add the description if there is any. + if (auto D = Option->getValue("Description")) + OS << D->getValue()->getAsString(); + else + OS << "\"\""; + OS << "},\n"; +} + +/// Emits all option initializers to the raw_ostream. +static void emitOptions(std::string Command, std::vector Option, + raw_ostream &OS) { + // Generate the macro that the user needs to define before including the + // *.inc file. + std::string NeededMacro = "LLDB_OPTIONS_" + Command; + std::replace(NeededMacro.begin(), NeededMacro.end(), ' ', '_'); + + // All options are in one file, so we need put them behind macros and ask the + // user to define the macro for the options that are needed. + OS << "// Options for " << Command << "\n"; + OS << "#ifdef " << NeededMacro << "\n"; + for (Record *R : Option) + emitOption(R, OS); + // We undefine the macro for the user like Clang's include files are doing it. + OS << "#undef " << NeededMacro << "\n"; + OS << "#endif // " << Command << " command\n\n"; +} + +void lldb_private::EmitOptionDefs(RecordKeeper &Records, raw_ostream &OS) { + + std::vector Options = Records.getAllDerivedDefinitions("Option"); + + emitSourceFileHeader("Options for LLDB command line commands.", OS); + + RecordsByCommand ByCommand = getCommandList(Options); + + for (auto &CommandRecordPair : ByCommand) { + emitOptions(CommandRecordPair.first, CommandRecordPair.second, OS); + } +} diff --git a/lldb/utils/TableGen/LLDBTableGen.cpp b/lldb/utils/TableGen/LLDBTableGen.cpp new file mode 100644 index 00000000000000..9325fe03856153 --- /dev/null +++ b/lldb/utils/TableGen/LLDBTableGen.cpp @@ -0,0 +1,71 @@ +//===- TableGen.cpp - Top-Level TableGen implementation for Clang ---------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the main function for Clang's TableGen. +// +//===----------------------------------------------------------------------===// + +#include "LLDBTableGenBackends.h" // Declares all backends. +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Signals.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Main.h" +#include "llvm/TableGen/Record.h" + +using namespace llvm; +using namespace lldb_private; + +enum ActionType { + PrintRecords, + DumpJSON, + GenOptionDefs, +}; + +static cl::opt + Action(cl::desc("Action to perform:"), + cl::values(clEnumValN(PrintRecords, "print-records", + "Print all records to stdout (default)"), + clEnumValN(DumpJSON, "dump-json", + "Dump all records as machine-readable JSON"), + clEnumValN(GenOptionDefs, "gen-lldb-option-defs", + "Generate clang attribute clases"))); + +static bool LLDBTableGenMain(raw_ostream &OS, RecordKeeper &Records) { + switch (Action) { + case PrintRecords: + OS << Records; // No argument, dump all contents + break; + case DumpJSON: + EmitJSON(Records, OS); + break; + case GenOptionDefs: + EmitOptionDefs(Records, OS); + break; + } + return false; +} + +int main(int argc, char **argv) { + sys::PrintStackTraceOnErrorSignal(argv[0]); + PrettyStackTraceProgram X(argc, argv); + cl::ParseCommandLineOptions(argc, argv); + + llvm_shutdown_obj Y; + + return TableGenMain(argv[0], &LLDBTableGenMain); +} + +#ifdef __has_feature +#if __has_feature(address_sanitizer) +#include +// Disable LeakSanitizer for this binary as it has too many leaks that are not +// very interesting to fix. See compiler-rt/include/sanitizer/lsan_interface.h . +int __lsan_is_turned_off() { return 1; } +#endif // __has_feature(address_sanitizer) +#endif // defined(__has_feature) diff --git a/lldb/utils/TableGen/LLDBTableGenBackends.h b/lldb/utils/TableGen/LLDBTableGenBackends.h new file mode 100644 index 00000000000000..eb14d80c5627ef --- /dev/null +++ b/lldb/utils/TableGen/LLDBTableGenBackends.h @@ -0,0 +1,34 @@ +//===- TableGen.cpp - Top-Level TableGen implementation for Clang ---------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the declarations for all of the LLDB TableGen +// backends. A "TableGen backend" is just a function. See +// "$LLVM_ROOT/utils/TableGen/TableGenBackends.h" for more info. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LLDB_UTILS_TABLEGEN_TABLEGENBACKENDS_H +#define LLVM_LLDB_UTILS_TABLEGEN_TABLEGENBACKENDS_H + +#include + +namespace llvm { +class raw_ostream; +class RecordKeeper; +} // namespace llvm + +using llvm::raw_ostream; +using llvm::RecordKeeper; + +namespace lldb_private { + +void EmitOptionDefs(RecordKeeper &RK, raw_ostream &OS); + +} // namespace lldb_private + +#endif From 4ecae5fd39f04a8f49ad0084e7b5f03911cd8ba7 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 17 Jul 2019 11:48:29 +0000 Subject: [PATCH 02/13] [lldb][NFC] Tablegenify watchpoint commands Part of the project that migrates these struct initializers to our new lldb-tablegen. llvm-svn: 366316 (cherry picked from commit 60bd7a9c13bdb6da854c4a7b595407c0ce18b55d) --- .../Commands/CommandObjectWatchpoint.cpp | 17 +++------ .../CommandObjectWatchpointCommand.cpp | 8 +--- lldb/source/Commands/Options.td | 38 +++++++++++++++++++ 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/lldb/source/Commands/CommandObjectWatchpoint.cpp b/lldb/source/Commands/CommandObjectWatchpoint.cpp index 3c3bd2d12095ad..98e758b7ef6a76 100644 --- a/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -148,11 +148,8 @@ bool CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs( #pragma mark List::CommandOptions static constexpr OptionDefinition g_watchpoint_list_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Give a brief description of the watchpoint (no location info)." }, - { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Give a full description of the watchpoint and its locations." }, - { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Explain everything we know about the watchpoint (for debugging debugger bugs)." } - // clang-format on +#define LLDB_OPTIONS_watchpoint_list +#include "CommandOptions.inc" }; #pragma mark List @@ -511,9 +508,8 @@ class CommandObjectWatchpointDelete : public CommandObjectParsed { #pragma mark Ignore::CommandOptions static constexpr OptionDefinition g_watchpoint_ignore_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, true, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "Set the number of times this watchpoint is skipped before stopping." } - // clang-format on +#define LLDB_OPTIONS_watchpoint_ignore +#include "CommandOptions.inc" }; class CommandObjectWatchpointIgnore : public CommandObjectParsed { @@ -631,9 +627,8 @@ class CommandObjectWatchpointIgnore : public CommandObjectParsed { #pragma mark Modify::CommandOptions static constexpr OptionDefinition g_watchpoint_modify_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeExpression, "The watchpoint stops only if this condition expression evaluates to true." } - // clang-format on +#define LLDB_OPTIONS_watchpoint_modify +#include "CommandOptions.inc" }; #pragma mark Modify diff --git a/lldb/source/Commands/CommandObjectWatchpointCommand.cpp b/lldb/source/Commands/CommandObjectWatchpointCommand.cpp index 8be6688fc3a69b..2be0b5b154e0f5 100644 --- a/lldb/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/lldb/source/Commands/CommandObjectWatchpointCommand.cpp @@ -43,12 +43,8 @@ static constexpr OptionEnumValues ScriptOptionEnum() { } static constexpr OptionDefinition g_watchpoint_command_add_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner, "Specify a one-line watchpoint command inline. Be sure to surround it with quotes." }, - { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Specify whether watchpoint command execution should terminate on error." }, - { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, ScriptOptionEnum(), 0, eArgTypeNone, "Specify the language for the commands - if none is specified, the lldb command interpreter will be used." }, - { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonFunction, "Give the name of a Python function to run as command for this watchpoint. Be sure to give a module name if appropriate." } - // clang-format on +#define LLDB_OPTIONS_watchpoint_command_add +#include "CommandOptions.inc" }; class CommandObjectWatchpointCommandAdd : public CommandObjectParsed, diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 1f4c09c3860967..1d1bbbf7b7041f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -51,3 +51,41 @@ let Command = "breakpoint list" in { Desc<"List Dummy breakpoints - i.e. breakpoints set before a file is " "provided, which prime new targets.">; } + +let Command = "watchpoint list" in { + def watchpoint_list_brief : Option<"brief", "b">, Group<1>, Desc<"Give a " + "brief description of the watchpoint (no location info).">; + def watchpoint_list_full : Option<"full", "f">, Group<2>, Desc<"Give a full " + "description of the watchpoint and its locations.">; + def watchpoint_list_verbose : Option<"verbose", "v">, Group<3>, Desc<"Explain" + "everything we know about the watchpoint (for debugging debugger bugs).">; +} + +let Command = "watchpoint ignore" in { + def watchpoint_ignore_ignore_count : Option<"ignore-count", "i">, + Arg<"Count">, Required, Desc<"Set the number of times this watchpoint is" + " skipped before stopping.">; +} + +let Command = "watchpoint modify" in { + def watchpoint_modify_condition : Option<"condition", "c">, Arg<"Expression">, + Desc<"The watchpoint stops only if this condition expression evaluates " + "to true.">; +} + +let Command = "watchpoint command add" in { + def watchpoint_command_add_one_liner : Option<"one-liner", "o">, Group<1>, + Arg<"OneLiner">, Desc<"Specify a one-line watchpoint command inline. Be " + "sure to surround it with quotes.">; + def watchpoint_command_add_stop_on_error : Option<"stop-on-error", "e">, + Arg<"Boolean">, Desc<"Specify whether watchpoint command execution should " + "terminate on error.">; + def watchpoint_command_add_script_type : Option<"script-type", "s">, + EnumArg<"None", "ScriptOptionEnum()">, Desc<"Specify the language for the" + " commands - if none is specified, the lldb command interpreter will be " + "used.">; + def watchpoint_command_add_python_function : Option<"python-function", "F">, + Group<2>, Arg<"PythonFunction">, Desc<"Give the name of a Python function " + "to run as command for this watchpoint. Be sure to give a module name if " + "appropriate.">; +} From b2995342877bebe911bcc41a98c21aa451206ee1 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 18 Jul 2019 08:22:19 +0000 Subject: [PATCH 03/13] [lldb][NFC] Tablegenify type commands llvm-svn: 366415 (cherry picked from commit beadf7d0ae10ede0689f43d8d3e5617e62f58faf) --- lldb/source/Commands/CommandObjectType.cpp | 90 ++++++---------------- lldb/source/Commands/Options.td | 79 +++++++++++++++++++ 2 files changed, 101 insertions(+), 68 deletions(-) diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp index 650a8dd216ff6c..98a43f50b1b1f6 100644 --- a/lldb/source/Commands/CommandObjectType.cpp +++ b/lldb/source/Commands/CommandObjectType.cpp @@ -96,23 +96,8 @@ static bool WarnOnPotentialUnquotedUnsignedType(Args &command, } static constexpr OptionDefinition g_type_summary_add_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Add this to the given category instead of the default one." }, - { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, cascade through typedef chains." }, - { LLDB_OPT_SET_ALL, false, "no-value", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't show the value, just show the summary, for this type." }, - { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for references-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Type names are actually regular expressions." }, - { LLDB_OPT_SET_1, true, "inline-children", 'c', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "If true, inline all child values into summary string." }, - { LLDB_OPT_SET_1, false, "omit-names", 'O', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "If true, omit value names in the summary display." }, - { LLDB_OPT_SET_2, true, "summary-string", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeSummaryString, "Summary string used to display text and object contents." }, - { LLDB_OPT_SET_3, false, "python-script", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command." }, - { LLDB_OPT_SET_3, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type." }, - { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Input Python code to use for this type manually." }, - { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Expand aggregate data types to show children on separate lines." }, - { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "hide-empty", 'h', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Do not expand aggregate data types with no children." }, - { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "A name for this summary string." } - // clang-format on +#define LLDB_OPTIONS_type_summary_add +#include "CommandOptions.inc" }; class CommandObjectTypeSummaryAdd : public CommandObjectParsed, @@ -298,15 +283,8 @@ static const char *g_synth_addreader_instructions = "class synthProvider:\n"; static constexpr OptionDefinition g_type_synth_add_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, cascade through typedef chains." }, - { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for references-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Add this to the given category instead of the default one." }, - { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children." }, - { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children." }, - { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Type names are actually regular expressions." } - // clang-format on +#define LLDB_OPTIONS_type_synth_add +#include "CommandOptions.inc" }; class CommandObjectTypeSynthAdd : public CommandObjectParsed, @@ -526,14 +504,8 @@ class CommandObjectTypeSynthAdd : public CommandObjectParsed, // CommandObjectTypeFormatAdd static constexpr OptionDefinition g_type_format_add_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Add this to the given category instead of the default one." }, - { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, cascade through typedef chains." }, - { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for references-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Type names are actually regular expressions." }, - { LLDB_OPT_SET_2, false, "type", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Format variables as if they were of this type." } - // clang-format on +#define LLDB_OPTIONS_type_format_add +#include "CommandOptions.inc" }; class CommandObjectTypeFormatAdd : public CommandObjectParsed { @@ -749,11 +721,8 @@ pointers to floats. Nor will it change the default display for Afloat and Bfloa }; static constexpr OptionDefinition g_type_formatter_delete_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete from every category." }, - { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Delete from given category." }, - { LLDB_OPT_SET_3, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Delete from given language's category." } - // clang-format on +#define LLDB_OPTIONS_type_formatter_delete +#include "CommandOptions.inc" }; class CommandObjectTypeFormatterDelete : public CommandObjectParsed { @@ -891,9 +860,8 @@ class CommandObjectTypeFormatterDelete : public CommandObjectParsed { }; static constexpr OptionDefinition g_type_formatter_clear_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Clear every category." } - // clang-format on +#define LLDB_OPTIONS_type_formatter_clear +#include "CommandOptions.inc" }; class CommandObjectTypeFormatterClear : public CommandObjectParsed { @@ -1005,10 +973,8 @@ class CommandObjectTypeFormatClear : public CommandObjectTypeFormatterClear { static constexpr OptionDefinition g_type_formatter_list_options[] = { - // clang-format off - {LLDB_OPT_SET_1, false, "category-regex", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Only show categories matching this filter."}, - {LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Only show the category for a specific language."} - // clang-format on +#define LLDB_OPTIONS_type_formatter_list +#include "CommandOptions.inc" }; template @@ -1767,10 +1733,8 @@ class CommandObjectTypeSummaryList // CommandObjectTypeCategoryDefine static constexpr OptionDefinition g_type_category_define_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "enabled", 'e', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "If specified, this category will be created enabled." }, - { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Specify the language that this category is supported for." } - // clang-format on +#define LLDB_OPTIONS_type_category_define +#include "CommandOptions.inc" }; class CommandObjectTypeCategoryDefine : public CommandObjectParsed { @@ -1872,9 +1836,8 @@ class CommandObjectTypeCategoryDefine : public CommandObjectParsed { // CommandObjectTypeCategoryEnable static constexpr OptionDefinition g_type_category_enable_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Enable the category for this language." }, - // clang-format on +#define LLDB_OPTIONS_type_category_enable +#include "CommandOptions.inc" }; class CommandObjectTypeCategoryEnable : public CommandObjectParsed { @@ -2045,9 +2008,8 @@ class CommandObjectTypeCategoryDelete : public CommandObjectParsed { // CommandObjectTypeCategoryDisable OptionDefinition constexpr g_type_category_disable_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Enable the category for this language." } - // clang-format on +#define LLDB_OPTIONS_type_category_disable +#include "CommandOptions.inc" }; class CommandObjectTypeCategoryDisable : public CommandObjectParsed { @@ -2455,14 +2417,8 @@ bool CommandObjectTypeSynthAdd::AddSynth(ConstString type_name, #endif // LLDB_DISABLE_PYTHON static constexpr OptionDefinition g_type_filter_add_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, cascade through typedef chains." }, - { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for references-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Add this to the given category instead of the default one." }, - { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view." }, - { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Type names are actually regular expressions." } - // clang-format on +#define LLDB_OPTIONS_type_filter_add +#include "CommandOptions.inc" }; class CommandObjectTypeFilterAdd : public CommandObjectParsed { @@ -2708,10 +2664,8 @@ all children of my_foo as if no filter was defined:" // "type lookup" static constexpr OptionDefinition g_type_lookup_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "show-help", 'h', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display available help for types" }, - { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Which language's types should the search scope be" } - // clang-format on +#define LLDB_OPTIONS_type_lookup +#include "CommandOptions.inc" }; class CommandObjectTypeLookup : public CommandObjectRaw { diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 1d1bbbf7b7041f..da0c5ba9789bb7 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -52,6 +52,85 @@ let Command = "breakpoint list" in { "provided, which prime new targets.">; } +let Command = "type summary add" in { + def type_summary_add_category : Option<"category", "w">, Arg<"Name">, Desc<"Add this to the given category instead of the default one.">; + def type_summary_add_cascade : Option<"cascade", "C">, Arg<"Boolean">, Desc<"If true, cascade through typedef chains.">; + def type_summary_add_no_value : Option<"no-value", "v">, Desc<"Don't show the value, just show the summary, for this type.">; + def type_summary_add_skip_pointers : Option<"skip-pointers", "p">, Desc<"Don't use this format for pointers-to-type objects.">; + def type_summary_add_skip_references : Option<"skip-references", "r">, Desc<"Don't use this format for references-to-type objects.">; + def type_summary_add_regex : Option<"regex", "x">, Desc<"Type names are actually regular expressions.">; + def type_summary_add_inline_children : Option<"inline-children", "c">, Group<1>, Required, Desc<"If true, inline all child values into summary string.">; + def type_summary_add_omit_names : Option<"omit-names", "O">, Group<1>, Desc<"If true, omit value names in the summary display.">; + def type_summary_add_summary_string : Option<"summary-string", "s">, Group<2>, Arg<"SummaryString">, Required, Desc<"Summary string used to display text and object contents.">; + def type_summary_add_python_script : Option<"python-script", "o">, Group<3>, Arg<"PythonScript">, Desc<"Give a one-liner Python script as part of the command.">; + def type_summary_add_python_function : Option<"python-function", "F">, Group<3>, Arg<"PythonFunction">, Desc<"Give the name of a Python function to use for this type.">; + def type_summary_add_input_python : Option<"input-python", "P">, Group<3>, Desc<"Input Python code to use for this type manually.">; + def type_summary_add_expand : Option<"expand", "e">, Groups<[2,3]>, Desc<"Expand aggregate data types to show children on separate lines.">; + def type_summary_add_hide_empty : Option<"hide-empty", "h">, Groups<[2,3]>, Desc<"Do not expand aggregate data types with no children.">; + def type_summary_add_name : Option<"name", "n">, Groups<[2,3]>, Arg<"Name">, Desc<"A name for this summary string.">; +} + +let Command = "type synth add" in { + def type_synth_add_cascade : Option<"cascade", "C">, Arg<"Boolean">, Desc<"If true, cascade through typedef chains.">; + def type_synth_add_skip_pointers : Option<"skip-pointers", "p">, Desc<"Don't use this format for pointers-to-type objects.">; + def type_synth_add_skip_references : Option<"skip-references", "r">, Desc<"Don't use this format for references-to-type objects.">; + def type_synth_add_category : Option<"category", "w">, Arg<"Name">, Desc<"Add this to the given category instead of the default one.">; + def type_synth_add_python_class : Option<"python-class", "l">, Group<2>, Arg<"PythonClass">, Desc<"Use this Python class to produce synthetic children.">; + def type_synth_add_input_python : Option<"input-python", "P">, Group<3>, Desc<"Type Python code to generate a class that provides synthetic children.">; + def type_synth_add_regex : Option<"regex", "x">, Desc<"Type names are actually regular expressions.">; +} + +let Command = "type format add" in { + def type_format_add_category : Option<"category", "w">, Arg<"Name">, Desc<"Add this to the given category instead of the default one.">; + def type_format_add_cascade : Option<"cascade", "C">, Arg<"Boolean">, Desc<"If true, cascade through typedef chains.">; + def type_format_add_skip_pointers : Option<"skip-pointers", "p">, Desc<"Don't use this format for pointers-to-type objects.">; + def type_format_add_skip_references : Option<"skip-references", "r">, Desc<"Don't use this format for references-to-type objects.">; + def type_format_add_regex : Option<"regex", "x">, Desc<"Type names are actually regular expressions.">; + def type_format_add_type : Option<"type", "t">, Group<2>, Arg<"Name">, Desc<"Format variables as if they were of this type.">; +} + +let Command = "type formatter delete" in { + def type_formatter_delete_all : Option<"all", "a">, Group<1>, Desc<"Delete from every category.">; + def type_formatter_delete_category : Option<"category", "w">, Group<2>, Arg<"Name">, Desc<"Delete from given category.">; + def type_formatter_delete_language : Option<"language", "l">, Group<3>, Arg<"Language">, Desc<"Delete from given language's category.">; +} + +let Command = "type formatter clear" in { + def type_formatter_clear_all : Option<"all", "a">, Desc<"Clear every category.">; +} + +let Command = "type formatter list" in { + def type_formatter_list_category_regex : Option<"category-regex", "w">, Group<1>, Arg<"Name">, Desc<"Only show categories matching this filter.">; + def type_formatter_list_language : Option<"language", "l">, Group<2>, Arg<"Language">, Desc<"Only show the category for a specific language.">; +} + +let Command = "type category define" in { + def type_category_define_enabled : Option<"enabled", "e">, Desc<"If specified, this category will be created enabled.">; + def type_category_define_language : Option<"language", "l">, Arg<"Language">, Desc<"Specify the language that this category is supported for.">; +} + +let Command = "type category enable" in { + def type_category_enable_language : Option<"language", "l">, Arg<"Language">, Desc<"Enable the category for this language.">; +} + +let Command = "type category disable" in { + def type_category_disable_language : Option<"language", "l">, Arg<"Language">, Desc<"Enable the category for this language.">; +} + +let Command = "type filter add" in { + def type_filter_add_cascade : Option<"cascade", "C">, Arg<"Boolean">, Desc<"If true, cascade through typedef chains.">; + def type_filter_add_skip_pointers : Option<"skip-pointers", "p">, Desc<"Don't use this format for pointers-to-type objects.">; + def type_filter_add_skip_references : Option<"skip-references", "r">, Desc<"Don't use this format for references-to-type objects.">; + def type_filter_add_category : Option<"category", "w">, Arg<"Name">, Desc<"Add this to the given category instead of the default one.">; + def type_filter_add_child : Option<"child", "c">, Arg<"ExpressionPath">, Desc<"Include this expression path in the synthetic view.">; + def type_filter_add_regex : Option<"regex", "x">, Desc<"Type names are actually regular expressions.">; +} + +let Command = "type lookup" in { + def type_lookup_show_help : Option<"show-help", "h">, Desc<"Display available help for types">; + def type_lookup_language : Option<"language", "l">, Arg<"Language">, Desc<"Which language's types should the search scope be">; +} + let Command = "watchpoint list" in { def watchpoint_list_brief : Option<"brief", "b">, Group<1>, Desc<"Give a " "brief description of the watchpoint (no location info).">; From bf9524d9f4286e929b5db95fd969613c1b48e163 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 18 Jul 2019 11:12:00 +0000 Subject: [PATCH 04/13] [lldb] Tablegenify thread commands and fix completion bug for thread step-* Beside turning the options into the new tablegen format, this patch also fixes that a few commands had source file completions for the "count" and "end-linenumber" arguments (which both accepted only integers). Reason for that are that somehow we added a '1' instead of our usual '0' value to the initial value for completion. llvm-svn: 366425 (cherry picked from commit 0cadf7bb2e78b9276421a44c0e1ad3cb4520050b) --- lldb/source/Commands/CommandObjectThread.cpp | 53 ++++-------- lldb/source/Commands/Options.td | 86 ++++++++++++++++++++ 2 files changed, 100 insertions(+), 39 deletions(-) diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index 3c6088d6e192ef..ed7cf0a1a48d78 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -239,11 +239,8 @@ class CommandObjectIterateOverThreads : public CommandObjectParsed { // CommandObjectThreadBacktrace static constexpr OptionDefinition g_thread_backtrace_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "How many frames to display (-1 for all)" }, - { LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace" }, - { LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Show the extended backtrace, if available" } - // clang-format on +#define LLDB_OPTIONS_thread_backtrace +#include "CommandOptions.inc" }; class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads { @@ -407,16 +404,8 @@ static constexpr OptionEnumValues TriRunningModes() { } static constexpr OptionDefinition g_thread_step_scope_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information." }, - { LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information." }, - { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst." }, - { LLDB_OPT_SET_1, false, "end-linenumber", 'e', OptionParser::eRequiredArgument, nullptr, {}, 1, eArgTypeLineNum, "The line at which to stop stepping - defaults to the next line and only supported for step-in and step-over. You can also pass the string 'block' to step to the end of the current block. This is particularly useful in conjunction with --step-target to step through a complex calling sequence." }, - { LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, nullptr, TriRunningModes(), 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread." }, - { LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in." }, - { LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into." }, - { LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step." } - // clang-format on +#define LLDB_OPTIONS_thread_step_scope +#include "CommandOptions.inc" }; class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed { @@ -995,12 +984,8 @@ static constexpr OptionEnumValues DuoRunningModes() { } static constexpr OptionDefinition g_thread_until_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0" }, - { LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation" }, - { LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, nullptr, DuoRunningModes(), 0, eArgTypeRunMode, "Determine how to run other threads while stepping this one" }, - { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times." } - // clang-format on +#define LLDB_OPTIONS_thread_until +#include "CommandOptions.inc" }; class CommandObjectThreadUntil : public CommandObjectParsed { @@ -1419,10 +1404,8 @@ class CommandObjectThreadList : public CommandObjectParsed { // CommandObjectThreadInfo static constexpr OptionDefinition g_thread_info_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "json", 'j', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the thread info in JSON format." }, - { LLDB_OPT_SET_ALL, false, "stop-info", 's', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the extended stop info in JSON format." } - // clang-format on +#define LLDB_OPTIONS_thread_info +#include "CommandOptions.inc" }; class CommandObjectThreadInfo : public CommandObjectIterateOverThreads { @@ -1555,9 +1538,8 @@ class CommandObjectThreadException : public CommandObjectIterateOverThreads { // CommandObjectThreadReturn static constexpr OptionDefinition g_thread_return_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Return from the innermost expression evaluation." } - // clang-format on +#define LLDB_OPTIONS_thread_return +#include "CommandOptions.inc" }; class CommandObjectThreadReturn : public CommandObjectRaw { @@ -1731,13 +1713,8 @@ class CommandObjectThreadReturn : public CommandObjectRaw { // CommandObjectThreadJump static constexpr OptionDefinition g_thread_jump_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file to jump to." }, - { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Specifies the line number to jump to." }, - { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "Jumps by a relative line offset from the current line." }, - { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Jumps to a specific address." }, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "force", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allows the PC to leave the current function." } - // clang-format on +#define LLDB_OPTIONS_thread_jump +#include "CommandOptions.inc" }; class CommandObjectThreadJump : public CommandObjectParsed { @@ -1879,10 +1856,8 @@ class CommandObjectThreadJump : public CommandObjectParsed { // CommandObjectThreadPlanList static constexpr OptionDefinition g_thread_plan_list_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display more information about the thread plans" }, - { LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display internal as well as user thread plans" } - // clang-format on +#define LLDB_OPTIONS_thread_plan_list +#include "CommandOptions.inc" }; class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads { diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index da0c5ba9789bb7..29f8a3d99aa8a7 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -52,6 +52,92 @@ let Command = "breakpoint list" in { "provided, which prime new targets.">; } +let Command = "thread backtrace" in { + def thread_backtrace_count : Option<"count", "c">, Group<1>, Arg<"Count">, + Desc<"How many frames to display (-1 for all)">; + def thread_backtrace_start : Option<"start", "s">, Group<1>, + Arg<"FrameIndex">, Desc<"Frame in which to start the backtrace">; + def thread_backtrace_extended : Option<"extended", "e">, Group<1>, + Arg<"Boolean">, Desc<"Show the extended backtrace, if available">; +} + +let Command = "thread step scope" in { + def thread_step_scope_step_in_avoids_no_debug : + Option<"step-in-avoids-no-debug", "a">, Group<1>, Arg<"Boolean">, + Desc<"A boolean value that sets whether stepping into functions will step " + "over functions with no debug information.">; + def thread_step_scope_step_out_avoids_no_debug : + Option<"step-out-avoids-no-debug", "A">, Group<1>, Arg<"Boolean">, + Desc<"A boolean value, if true stepping out of functions will continue to" + " step out till it hits a function with debug information.">; + def thread_step_scope_count : Option<"count", "c">, Group<1>, Arg<"Count">, + Desc<"How many times to perform the stepping operation - currently only " + "supported for step-inst and next-inst.">; + def thread_step_scope_end_linenumber : Option<"end-linenumber", "e">, + Group<1>, Arg<"LineNum">, Desc<"The line at which to stop stepping - " + "defaults to the next line and only supported for step-in and step-over." + " You can also pass the string 'block' to step to the end of the current" + " block. This is particularly use in conjunction with --step-target to" + " step through a complex calling sequence.">; + def thread_step_scope_run_mode : Option<"run-mode", "m">, Group<1>, + EnumArg<"RunMode", "TriRunningModes()">, Desc<"Determine how to run other " + "threads while stepping the current thread.">; + def thread_step_scope_step_over_regexp : Option<"step-over-regexp", "r">, + Group<1>, Arg<"RegularExpression">, Desc<"A regular expression that defines" + "function names to not to stop at when stepping in.">; + def thread_step_scope_step_in_target : Option<"step-in-target", "t">, + Group<1>, Arg<"FunctionName">, Desc<"The name of the directly called " + "function step in should stop at when stepping into.">; + def thread_step_scope_python_class : Option<"python-class", "C">, Group<2>, + Arg<"PythonClass">, Desc<"The name of the class that will manage this step " + "- only supported for Scripted Step.">; +} + +let Command = "thread until" in { + def thread_until_frame : Option<"frame", "f">, Group<1>, Arg<"FrameIndex">, + Desc<"Frame index for until operation - defaults to 0">; + def thread_until_thread : Option<"thread", "t">, Group<1>, Arg<"ThreadIndex">, + Desc<"Thread index for the thread for until operation">; + def thread_until_run_mode : Option<"run-mode", "m">, Group<1>, + EnumArg<"RunMode", "DuoRunningModes()">, Desc<"Determine how to run other" + "threads while stepping this one">; + def thread_until_address : Option<"address", "a">, Group<1>, + Arg<"AddressOrExpression">, Desc<"Run until we reach the specified address," + "or leave the function - can be specified multiple times.">; +} + +let Command = "thread info" in { + def thread_info_json : Option<"json", "j">, Desc<"Display the thread info in" + " JSON format.">; + def thread_info_stop_info : Option<"stop-info", "s">, Desc<"Display the " + "extended stop info in JSON format.">; +} + +let Command = "thread return" in { + def thread_return_from_expression : Option<"from-expression", "x">, + Desc<"Return from the innermost expression evaluation.">; +} + +let Command = "thread jump" in { + def thread_jump_file : Option<"file", "f">, Group<1>, Arg<"Filename">, + Completion<"SourceFile">, Desc<"Specifies the source file to jump to.">; + def thread_jump_line : Option<"line", "l">, Group<1>, Arg<"LineNum">, + Required, Desc<"Specifies the line number to jump to.">; + def thread_jump_by : Option<"by", "b">, Group<2>, Arg<"Offset">, Required, + Desc<"Jumps by a relative line offset from the current line.">; + def thread_jump_address : Option<"address", "a">, Group<3>, + Arg<"AddressOrExpression">, Required, Desc<"Jumps to a specific address.">; + def thread_jump_force : Option<"force", "r">, Groups<[1,2,3]>, + Desc<"Allows the PC to leave the current function.">; +} + +let Command = "thread plan list" in { + def thread_plan_list_verbose : Option<"verbose", "v">, Group<1>, + Desc<"Display more information about the thread plans">; + def thread_plan_list_internal : Option<"internal", "i">, Group<1>, + Desc<"Display internal as well as user thread plans">; +} + let Command = "type summary add" in { def type_summary_add_category : Option<"category", "w">, Arg<"Name">, Desc<"Add this to the given category instead of the default one.">; def type_summary_add_cascade : Option<"cascade", "C">, Arg<"Boolean">, Desc<"If true, cascade through typedef chains.">; From 16965153d9f2de68b1717920a1391029b7bf297c Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 18 Jul 2019 11:43:45 +0000 Subject: [PATCH 05/13] [lldb][NFC] Format 'type' commands in Options.td llvm-svn: 366426 (cherry picked from commit c89a3d78f43d81b9cff7b9248772ddf14d21b749) --- lldb/source/Commands/Options.td | 144 ++++++++++++++++++++++---------- 1 file changed, 98 insertions(+), 46 deletions(-) diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 29f8a3d99aa8a7..9cfbcd2d4ebfe0 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -139,82 +139,134 @@ let Command = "thread plan list" in { } let Command = "type summary add" in { - def type_summary_add_category : Option<"category", "w">, Arg<"Name">, Desc<"Add this to the given category instead of the default one.">; - def type_summary_add_cascade : Option<"cascade", "C">, Arg<"Boolean">, Desc<"If true, cascade through typedef chains.">; - def type_summary_add_no_value : Option<"no-value", "v">, Desc<"Don't show the value, just show the summary, for this type.">; - def type_summary_add_skip_pointers : Option<"skip-pointers", "p">, Desc<"Don't use this format for pointers-to-type objects.">; - def type_summary_add_skip_references : Option<"skip-references", "r">, Desc<"Don't use this format for references-to-type objects.">; - def type_summary_add_regex : Option<"regex", "x">, Desc<"Type names are actually regular expressions.">; - def type_summary_add_inline_children : Option<"inline-children", "c">, Group<1>, Required, Desc<"If true, inline all child values into summary string.">; - def type_summary_add_omit_names : Option<"omit-names", "O">, Group<1>, Desc<"If true, omit value names in the summary display.">; - def type_summary_add_summary_string : Option<"summary-string", "s">, Group<2>, Arg<"SummaryString">, Required, Desc<"Summary string used to display text and object contents.">; - def type_summary_add_python_script : Option<"python-script", "o">, Group<3>, Arg<"PythonScript">, Desc<"Give a one-liner Python script as part of the command.">; - def type_summary_add_python_function : Option<"python-function", "F">, Group<3>, Arg<"PythonFunction">, Desc<"Give the name of a Python function to use for this type.">; - def type_summary_add_input_python : Option<"input-python", "P">, Group<3>, Desc<"Input Python code to use for this type manually.">; - def type_summary_add_expand : Option<"expand", "e">, Groups<[2,3]>, Desc<"Expand aggregate data types to show children on separate lines.">; - def type_summary_add_hide_empty : Option<"hide-empty", "h">, Groups<[2,3]>, Desc<"Do not expand aggregate data types with no children.">; - def type_summary_add_name : Option<"name", "n">, Groups<[2,3]>, Arg<"Name">, Desc<"A name for this summary string.">; + def type_summary_add_category : Option<"category", "w">, Arg<"Name">, + Desc<"Add this to the given category instead of the default one.">; + def type_summary_add_cascade : Option<"cascade", "C">, Arg<"Boolean">, + Desc<"If true, cascade through typedef chains.">; + def type_summary_add_no_value : Option<"no-value", "v">, + Desc<"Don't show the value, just show the summary, for this type.">; + def type_summary_add_skip_pointers : Option<"skip-pointers", "p">, + Desc<"Don't use this format for pointers-to-type objects.">; + def type_summary_add_skip_references : Option<"skip-references", "r">, + Desc<"Don't use this format for references-to-type objects.">; + def type_summary_add_regex : Option<"regex", "x">, + Desc<"Type names are actually regular expressions.">; + def type_summary_add_inline_children : Option<"inline-children", "c">, + Group<1>, Required, + Desc<"If true, inline all child values into summary string.">; + def type_summary_add_omit_names : Option<"omit-names", "O">, Group<1>, + Desc<"If true, omit value names in the summary display.">; + def type_summary_add_summary_string : Option<"summary-string", "s">, Group<2>, + Arg<"SummaryString">, Required, + Desc<"Summary string used to display text and object contents.">; + def type_summary_add_python_script : Option<"python-script", "o">, Group<3>, + Arg<"PythonScript">, + Desc<"Give a one-liner Python script as part of the command.">; + def type_summary_add_python_function : Option<"python-function", "F">, + Group<3>, Arg<"PythonFunction">, + Desc<"Give the name of a Python function to use for this type.">; + def type_summary_add_input_python : Option<"input-python", "P">, Group<3>, + Desc<"Input Python code to use for this type manually.">; + def type_summary_add_expand : Option<"expand", "e">, Groups<[2,3]>, + Desc<"Expand aggregate data types to show children on separate lines.">; + def type_summary_add_hide_empty : Option<"hide-empty", "h">, Groups<[2,3]>, + Desc<"Do not expand aggregate data types with no children.">; + def type_summary_add_name : Option<"name", "n">, Groups<[2,3]>, Arg<"Name">, + Desc<"A name for this summary string.">; } let Command = "type synth add" in { - def type_synth_add_cascade : Option<"cascade", "C">, Arg<"Boolean">, Desc<"If true, cascade through typedef chains.">; - def type_synth_add_skip_pointers : Option<"skip-pointers", "p">, Desc<"Don't use this format for pointers-to-type objects.">; - def type_synth_add_skip_references : Option<"skip-references", "r">, Desc<"Don't use this format for references-to-type objects.">; - def type_synth_add_category : Option<"category", "w">, Arg<"Name">, Desc<"Add this to the given category instead of the default one.">; - def type_synth_add_python_class : Option<"python-class", "l">, Group<2>, Arg<"PythonClass">, Desc<"Use this Python class to produce synthetic children.">; - def type_synth_add_input_python : Option<"input-python", "P">, Group<3>, Desc<"Type Python code to generate a class that provides synthetic children.">; - def type_synth_add_regex : Option<"regex", "x">, Desc<"Type names are actually regular expressions.">; + def type_synth_add_cascade : Option<"cascade", "C">, Arg<"Boolean">, + Desc<"If true, cascade through typedef chains.">; + def type_synth_add_skip_pointers : Option<"skip-pointers", "p">, + Desc<"Don't use this format for pointers-to-type objects.">; + def type_synth_add_skip_references : Option<"skip-references", "r">, + Desc<"Don't use this format for references-to-type objects.">; + def type_synth_add_category : Option<"category", "w">, Arg<"Name">, + Desc<"Add this to the given category instead of the default one.">; + def type_synth_add_python_class : Option<"python-class", "l">, Group<2>, + Arg<"PythonClass">, + Desc<"Use this Python class to produce synthetic children.">; + def type_synth_add_input_python : Option<"input-python", "P">, Group<3>, + Desc<"Type Python code to generate a class that provides synthetic " + "children.">; + def type_synth_add_regex : Option<"regex", "x">, + Desc<"Type names are actually regular expressions.">; } let Command = "type format add" in { - def type_format_add_category : Option<"category", "w">, Arg<"Name">, Desc<"Add this to the given category instead of the default one.">; - def type_format_add_cascade : Option<"cascade", "C">, Arg<"Boolean">, Desc<"If true, cascade through typedef chains.">; - def type_format_add_skip_pointers : Option<"skip-pointers", "p">, Desc<"Don't use this format for pointers-to-type objects.">; - def type_format_add_skip_references : Option<"skip-references", "r">, Desc<"Don't use this format for references-to-type objects.">; - def type_format_add_regex : Option<"regex", "x">, Desc<"Type names are actually regular expressions.">; - def type_format_add_type : Option<"type", "t">, Group<2>, Arg<"Name">, Desc<"Format variables as if they were of this type.">; + def type_format_add_category : Option<"category", "w">, Arg<"Name">, + Desc<"Add this to the given category instead of the default one.">; + def type_format_add_cascade : Option<"cascade", "C">, Arg<"Boolean">, + Desc<"If true, cascade through typedef chains.">; + def type_format_add_skip_pointers : Option<"skip-pointers", "p">, + Desc<"Don't use this format for pointers-to-type objects.">; + def type_format_add_skip_references : Option<"skip-references", "r">, + Desc<"Don't use this format for references-to-type objects.">; + def type_format_add_regex : Option<"regex", "x">, + Desc<"Type names are actually regular expressions.">; + def type_format_add_type : Option<"type", "t">, Group<2>, Arg<"Name">, + Desc<"Format variables as if they were of this type.">; } let Command = "type formatter delete" in { - def type_formatter_delete_all : Option<"all", "a">, Group<1>, Desc<"Delete from every category.">; - def type_formatter_delete_category : Option<"category", "w">, Group<2>, Arg<"Name">, Desc<"Delete from given category.">; - def type_formatter_delete_language : Option<"language", "l">, Group<3>, Arg<"Language">, Desc<"Delete from given language's category.">; + def type_formatter_delete_all : Option<"all", "a">, Group<1>, + Desc<"Delete from every category.">; + def type_formatter_delete_category : Option<"category", "w">, Group<2>, + Arg<"Name">, Desc<"Delete from given category.">; + def type_formatter_delete_language : Option<"language", "l">, Group<3>, + Arg<"Language">, Desc<"Delete from given language's category.">; } let Command = "type formatter clear" in { - def type_formatter_clear_all : Option<"all", "a">, Desc<"Clear every category.">; + def type_formatter_clear_all : Option<"all", "a">, + Desc<"Clear every category.">; } let Command = "type formatter list" in { - def type_formatter_list_category_regex : Option<"category-regex", "w">, Group<1>, Arg<"Name">, Desc<"Only show categories matching this filter.">; - def type_formatter_list_language : Option<"language", "l">, Group<2>, Arg<"Language">, Desc<"Only show the category for a specific language.">; + def type_formatter_list_category_regex : Option<"category-regex", "w">, + Group<1>, Arg<"Name">, Desc<"Only show categories matching this filter.">; + def type_formatter_list_language : Option<"language", "l">, Group<2>, + Arg<"Language">, Desc<"Only show the category for a specific language.">; } let Command = "type category define" in { - def type_category_define_enabled : Option<"enabled", "e">, Desc<"If specified, this category will be created enabled.">; - def type_category_define_language : Option<"language", "l">, Arg<"Language">, Desc<"Specify the language that this category is supported for.">; + def type_category_define_enabled : Option<"enabled", "e">, + Desc<"If specified, this category will be created enabled.">; + def type_category_define_language : Option<"language", "l">, Arg<"Language">, + Desc<"Specify the language that this category is supported for.">; } let Command = "type category enable" in { - def type_category_enable_language : Option<"language", "l">, Arg<"Language">, Desc<"Enable the category for this language.">; + def type_category_enable_language : Option<"language", "l">, Arg<"Language">, + Desc<"Enable the category for this language.">; } let Command = "type category disable" in { - def type_category_disable_language : Option<"language", "l">, Arg<"Language">, Desc<"Enable the category for this language.">; + def type_category_disable_language : Option<"language", "l">, Arg<"Language">, + Desc<"Enable the category for this language.">; } let Command = "type filter add" in { - def type_filter_add_cascade : Option<"cascade", "C">, Arg<"Boolean">, Desc<"If true, cascade through typedef chains.">; - def type_filter_add_skip_pointers : Option<"skip-pointers", "p">, Desc<"Don't use this format for pointers-to-type objects.">; - def type_filter_add_skip_references : Option<"skip-references", "r">, Desc<"Don't use this format for references-to-type objects.">; - def type_filter_add_category : Option<"category", "w">, Arg<"Name">, Desc<"Add this to the given category instead of the default one.">; - def type_filter_add_child : Option<"child", "c">, Arg<"ExpressionPath">, Desc<"Include this expression path in the synthetic view.">; - def type_filter_add_regex : Option<"regex", "x">, Desc<"Type names are actually regular expressions.">; + def type_filter_add_cascade : Option<"cascade", "C">, Arg<"Boolean">, + Desc<"If true, cascade through typedef chains.">; + def type_filter_add_skip_pointers : Option<"skip-pointers", "p">, + Desc<"Don't use this format for pointers-to-type objects.">; + def type_filter_add_skip_references : Option<"skip-references", "r">, + Desc<"Don't use this format for references-to-type objects.">; + def type_filter_add_category : Option<"category", "w">, Arg<"Name">, + Desc<"Add this to the given category instead of the default one.">; + def type_filter_add_child : Option<"child", "c">, Arg<"ExpressionPath">, + Desc<"Include this expression path in the synthetic view.">; + def type_filter_add_regex : Option<"regex", "x">, + Desc<"Type names are actually regular expressions.">; } let Command = "type lookup" in { - def type_lookup_show_help : Option<"show-help", "h">, Desc<"Display available help for types">; - def type_lookup_language : Option<"language", "l">, Arg<"Language">, Desc<"Which language's types should the search scope be">; + def type_lookup_show_help : Option<"show-help", "h">, + Desc<"Display available help for types">; + def type_lookup_language : Option<"language", "l">, Arg<"Language">, + Desc<"Which language's types should the search scope be">; } let Command = "watchpoint list" in { From 375ee97f9afd0d62937f7b0e13225990d598fafa Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 18 Jul 2019 14:10:49 +0000 Subject: [PATCH 06/13] [lldb][NFC] Tablegenify alias/regex/history/source/script (Converting these commands together as they are all simple commands that share the same file). llvm-svn: 366440 (cherry picked from commit 64becc11a87a6bf2328550009f3c09a807d36931) --- .../source/Commands/CommandObjectCommands.cpp | 40 ++++--------- lldb/source/Commands/Options.td | 57 +++++++++++++++++++ 2 files changed, 69 insertions(+), 28 deletions(-) diff --git a/lldb/source/Commands/CommandObjectCommands.cpp b/lldb/source/Commands/CommandObjectCommands.cpp index 4092e76be6ac8b..943f508e7ad117 100644 --- a/lldb/source/Commands/CommandObjectCommands.cpp +++ b/lldb/source/Commands/CommandObjectCommands.cpp @@ -32,12 +32,8 @@ using namespace lldb_private; // CommandObjectCommandsSource static constexpr OptionDefinition g_history_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "How many history commands to print." }, - { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)." }, - { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands." }, - { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeBoolean, "Clears the current command history." }, - // clang-format on +#define LLDB_OPTIONS_history +#include "CommandOptions.inc" }; class CommandObjectCommandsHistory : public CommandObjectParsed { @@ -189,11 +185,8 @@ class CommandObjectCommandsHistory : public CommandObjectParsed { // CommandObjectCommandsSource static constexpr OptionDefinition g_source_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, stop executing commands on error." }, - { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, stop executing commands on continue." }, - { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true don't echo commands while executing." }, - // clang-format on +#define LLDB_OPTIONS_source +#include "CommandOptions.inc" }; class CommandObjectCommandsSource : public CommandObjectParsed { @@ -344,10 +337,8 @@ class CommandObjectCommandsSource : public CommandObjectParsed { // CommandObjectCommandsAlias static constexpr OptionDefinition g_alias_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "help", 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeHelpText, "Help text for this command" }, - { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeHelpText, "Long help text for this command" }, - // clang-format on +#define LLDB_OPTIONS_alias +#include "CommandOptions.inc" }; static const char *g_python_command_instructions = @@ -912,10 +903,8 @@ class CommandObjectCommandsDelete : public CommandObjectParsed { // CommandObjectCommandsAddRegex static constexpr OptionDefinition g_regex_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The help text to display for this command." }, - { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "A syntax string showing the typical usage syntax." }, - // clang-format on +#define LLDB_OPTIONS_regex +#include "CommandOptions.inc" }; #pragma mark CommandObjectCommandsAddRegex @@ -1387,9 +1376,8 @@ class CommandObjectScriptingObject : public CommandObjectRaw { // CommandObjectCommandsScriptImport static constexpr OptionDefinition g_script_import_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not." }, - // clang-format on +#define LLDB_OPTIONS_script_import +#include "CommandOptions.inc" }; class CommandObjectCommandsScriptImport : public CommandObjectParsed { @@ -1521,12 +1509,8 @@ static constexpr OptionEnumValues ScriptSynchroType() { } static constexpr OptionDefinition g_script_add_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name." }, - { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name." }, - { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeHelpText, "The help text to display for this command." }, - { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, nullptr, ScriptSynchroType(), 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system." }, - // clang-format on +#define LLDB_OPTIONS_script_add +#include "CommandOptions.inc" }; class CommandObjectCommandsScriptAdd : public CommandObjectParsed, diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9cfbcd2d4ebfe0..59180e1cff60c9 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -52,6 +52,63 @@ let Command = "breakpoint list" in { "provided, which prime new targets.">; } +let Command = "history" in { + def history_count : Option<"count", "c">, Group<1>, Arg<"UnsignedInteger">, + Desc<"How many history commands to print.">; + def history_start_index : Option<"start-index", "s">, Group<1>, + Arg<"UnsignedInteger">, Desc<"Index at which to start printing history " + "commands (or end to mean tail mode).">; + def history_end_index : Option<"end-index", "e">, Group<1>, + Arg<"UnsignedInteger">, + Desc<"Index at which to stop printing history commands.">; + def history_clear : Option<"clear", "C">, Group<2>, + Desc<"Clears the current command history.">; +} + +let Command = "source" in { + def source_stop_on_error : Option<"stop-on-error", "e">, Arg<"Boolean">, + Desc<"If true, stop executing commands on error.">; + def source_stop_on_continue : Option<"stop-on-continue", "c">, Arg<"Boolean">, + Desc<"If true, stop executing commands on continue.">; + def source_silent_run : Option<"silent-run", "s">, Arg<"Boolean">, + Desc<"If true don't echo commands while executing.">; +} + +let Command = "alias" in { + def alias_help : Option<"help", "h">, Arg<"HelpText">, + Desc<"Help text for this command">; + def alias_long_help : Option<"long-help", "H">, Arg<"HelpText">, + Desc<"Long help text for this command">; +} + +let Command = "regex" in { + def regex_help : Option<"help", "h">, Group<1>, Arg<"None">, + Desc<"The help text to display for this command.">; + def regex_syntax : Option<"syntax", "s">, Group<1>, Arg<"None">, + Desc<"A syntax string showing the typical usage syntax.">; +} + +let Command = "script import" in { + def script_import_allow_reload : Option<"allow-reload", "r">, Group<1>, + Desc<"Allow the script to be loaded even if it was already loaded before. " + "This argument exists for backwards compatibility, but reloading is always " + "allowed, whether you specify it or not.">; +} + +let Command = "script add" in { + def script_add_function : Option<"function", "f">, Group<1>, + Arg<"PythonFunction">, + Desc<"Name of the Python function to bind to this command name.">; + def script_add_class : Option<"class", "c">, Group<2>, Arg<"PythonClass">, + Desc<"Name of the Python class to bind to this command name.">; + def script_add_help : Option<"help", "h">, Group<1>, Arg<"HelpText">, + Desc<"The help text to display for this command.">; + def script_add_synchronicity : Option<"synchronicity", "s">, + EnumArg<"ScriptedCommandSynchronicity", "ScriptSynchroType()">, + Desc<"Set the synchronicity of this command's executions with regard to " + "LLDB event system.">; +} + let Command = "thread backtrace" in { def thread_backtrace_count : Option<"count", "c">, Group<1>, Arg<"Count">, Desc<"How many frames to display (-1 for all)">; From a9df875665abb72b52f494826ca7062dd6eaafc9 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Mon, 22 Jul 2019 10:02:09 +0000 Subject: [PATCH 07/13] [lldb][NFC] Tablegenify breakpoint llvm-svn: 366673 (cherry picked from commit f94668e3360e5c32997bfd9be188750b3eb85769) --- .../Commands/CommandObjectBreakpoint.cpp | 144 ++--------- .../CommandObjectBreakpointCommand.cpp | 14 +- lldb/source/Commands/Options.td | 243 ++++++++++++++++++ lldb/utils/TableGen/LLDBOptionDefEmitter.cpp | 8 +- 4 files changed, 270 insertions(+), 139 deletions(-) diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp index a661ffc62512cd..117639add0159c 100644 --- a/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -45,19 +45,8 @@ static void AddBreakpointDescription(Stream *s, Breakpoint *bp, // Modifiable Breakpoint Options #pragma mark Modify::CommandOptions static constexpr OptionDefinition g_breakpoint_modify_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." }, - { LLDB_OPT_SET_1, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." }, - { LLDB_OPT_SET_1, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." }, - { LLDB_OPT_SET_1, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." }, - { LLDB_OPT_SET_1, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument." }, - { LLDB_OPT_SET_1, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument." }, - { LLDB_OPT_SET_1, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." }, - { LLDB_OPT_SET_1, false, "auto-continue",'G', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "The breakpoint will auto-continue after running its commands." }, - { LLDB_OPT_SET_2, false, "enable", 'e', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable the breakpoint." }, - { LLDB_OPT_SET_3, false, "disable", 'd', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disable the breakpoint." }, - { LLDB_OPT_SET_4, false, "command", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCommand, "A command to run when the breakpoint is hit, can be provided more than once, the commands will get run in order left to right." }, - // clang-format on +#define LLDB_OPTIONS_breakpoint_modify +#include "CommandOptions.inc" }; class lldb_private::BreakpointOptionGroup : public OptionGroup { @@ -193,10 +182,8 @@ class lldb_private::BreakpointOptionGroup : public OptionGroup }; static constexpr OptionDefinition g_breakpoint_dummy_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Act on Dummy breakpoints - i.e. breakpoints set before a file is provided, " - "which prime new targets." }, - // clang-format on +#define LLDB_OPTIONS_breakpoint_dummy +#include "CommandOptions.inc" }; class BreakpointDummyOptionGroup : public OptionGroup @@ -237,87 +224,9 @@ class BreakpointDummyOptionGroup : public OptionGroup }; -// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to -// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately. -#define LLDB_OPT_NOT_10 (LLDB_OPT_SET_FROM_TO(1, 11) & ~LLDB_OPT_SET_10) -#define LLDB_OPT_SKIP_PROLOGUE (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3, 8)) -#define LLDB_OPT_FILE (LLDB_OPT_SET_FROM_TO(1, 11) & ~LLDB_OPT_SET_2 & ~LLDB_OPT_SET_10) -#define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_FROM_TO(1, 8) & ~LLDB_OPT_SET_2) -#define LLDB_OPT_MOVE_TO_NEAREST_CODE (LLDB_OPT_SET_1 | LLDB_OPT_SET_9) -#define LLDB_OPT_EXPR_LANGUAGE (LLDB_OPT_SET_FROM_TO(3, 8)) - static constexpr OptionDefinition g_breakpoint_set_options[] = { - // clang-format off - { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the breakpoint only in this shared library. Can repeat this option " - "multiple times to specify multiple shared libraries." }, - { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Require the breakpoint to use hardware breakpoints." }, - { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file in which to set this breakpoint. Note, by default " - "lldb only looks for files that are #included if they use the standard include " - "file extensions. To set breakpoints on .c/.cpp/.m/.mm files that are " - "#included, set target.inline-breakpoint-strategy to \"always\"." }, - { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, 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. - // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "", - // "Set the breakpoint by source location at this particular column."}, - - { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Set the breakpoint at the specified address. If the address maps uniquely to " - "a particular binary, then the address will be converted to a \"file\" " - "address, so that the breakpoint will track that binary+offset no matter where " - "the binary eventually loads. Alternately, if you also specify the module - " - "with the -s option - then the address will be treated as a file address in " - "that module, and resolved accordingly. Again, this will allow lldb to track " - "that offset on subsequent reloads. The module need not have been loaded at " - "the time you specify this breakpoint, and will get resolved when the module " - "is loaded." }, - { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function name. Can be repeated multiple times to make " - "one breakpoint for multiple names" }, - { LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, 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, {}, 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 " - "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, {}, 0, eArgTypeSelector, "Set the breakpoint by ObjC selector name. Can be repeated multiple times to " - "make one breakpoint for multiple Selectors." }, - { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeMethod, "Set the breakpoint by C++ method names. Can be repeated multiple times to " - "make one breakpoint for multiple methods." }, - { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "Set the breakpoint by function name, evaluating a regular-expression to find " - "the function name(s)." }, - { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function basename (C++ namespaces and arguments will be " - "ignored). Can be repeated multiple times to make one breakpoint for multiple " - "symbols." }, - { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "Set the breakpoint by specifying a regular expression which is matched " - "against the source text in a source file or files specified with the -f " - "option. The -f option can be specified more than once. If no source files " - "are specified, uses the current \"default source file\". If you want to " - "match against all source files, pass the \"--all-files\" option." }, - { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "All files are searched for source pattern matches." }, - { LLDB_OPT_SET_11, true, "python-class", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "The name of the class that implement a scripted breakpoint." }, - { LLDB_OPT_SET_11, false, "python-class-key", 'k', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The key for a key/value pair passed to the class that implements a scripted breakpoint. Can be specified more than once." }, - { LLDB_OPT_SET_11, false, "python-class-value", 'v', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The value for the previous key in the pair passed to the class that implements a scripted breakpoint. Can be specified more than once." }, - { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Set the breakpoint on exceptions thrown by the specified language (without " - "options, on throw but not catch.)" }, - { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Set the breakpoint on exception throW." }, - { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Set the breakpoint on exception catcH." }, - - // Don't add this option till it actually does something useful... - // { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName, - // "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" }, - - { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Specifies the Language to use when interpreting the breakpoint's expression " - "(note: currently only implemented for setting breakpoints on identifiers). " - "If not set the target.language setting is used." }, - { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "sKip the prologue if the breakpoint is at the beginning of a function. " - "If not set the target.skip-prologue setting is used." }, - { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Adds this to the list of names for this breakpoint." }, - { LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddress, "Add the specified offset to whatever address(es) the breakpoint resolves to. " - "At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries." }, - { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Move breakpoints to nearest code. If not set the target.move-to-nearest-code " - "setting is used." }, - // clang-format on +#define LLDB_OPTIONS_breakpoint_set +#include "CommandOptions.inc" }; // CommandObjectBreakpointSet @@ -1246,8 +1155,6 @@ the second re-enables the first location."); #pragma mark List::CommandOptions static constexpr OptionDefinition g_breakpoint_list_options[] = { - // FIXME: We need to add an "internal" command, and then add this sort of - // thing to it. But I need to see it for now, and don't want to wait. #define LLDB_OPTIONS_breakpoint_list #include "Options.inc" }; @@ -1405,10 +1312,8 @@ class CommandObjectBreakpointList : public CommandObjectParsed { #pragma mark Clear::CommandOptions static constexpr OptionDefinition g_breakpoint_clear_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the breakpoint by source location in this particular file." }, - { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Specify the breakpoint by source location at this particular line." } - // clang-format on +#define LLDB_OPTIONS_breakpoint_clear +#include "CommandOptions.inc" }; #pragma mark Clear @@ -1558,10 +1463,8 @@ class CommandObjectBreakpointClear : public CommandObjectParsed { // CommandObjectBreakpointDelete static constexpr OptionDefinition g_breakpoint_delete_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete all breakpoints without querying for confirmation." }, - { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, - // clang-format on +#define LLDB_OPTIONS_breakpoint_delete +#include "CommandOptions.inc" }; #pragma mark Delete @@ -1713,12 +1616,8 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed { // CommandObjectBreakpointName static constexpr OptionDefinition g_breakpoint_name_options[] = { - // clang-format off - {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."}, - {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."}, - {LLDB_OPT_SET_3, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, - {LLDB_OPT_SET_4, false, "help-string", 'H', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "A help string describing the purpose of this name."}, - // clang-format on +#define LLDB_OPTIONS_breakpoint_name +#include "CommandOptions.inc" }; class BreakpointNameOptionGroup : public OptionGroup { public: @@ -1782,11 +1681,8 @@ class BreakpointNameOptionGroup : public OptionGroup { }; static constexpr OptionDefinition g_breakpoint_access_options[] = { - // clang-format off - {LLDB_OPT_SET_1, false, "allow-list", 'L', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint will show up in break list if not referred to explicitly."}, - {LLDB_OPT_SET_2, false, "allow-disable", 'A', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint can be disabled by name or when all breakpoints are disabled."}, - {LLDB_OPT_SET_3, false, "allow-delete", 'D', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint can be deleted by name or when all breakpoints are deleted."}, - // clang-format on +#define LLDB_OPTIONS_breakpoint_access +#include "CommandOptions.inc" }; class BreakpointAccessOptionGroup : public OptionGroup { @@ -2247,10 +2143,8 @@ class CommandObjectBreakpointName : public CommandObjectMultiword { // CommandObjectBreakpointRead #pragma mark Read::CommandOptions static constexpr OptionDefinition g_breakpoint_read_options[] = { - // clang-format off - {LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." }, - {LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Only read in breakpoints with this name."}, - // clang-format on +#define LLDB_OPTIONS_breakpoint_read +#include "CommandOptions.inc" }; #pragma mark Read @@ -2376,10 +2270,8 @@ class CommandObjectBreakpointRead : public CommandObjectParsed { // CommandObjectBreakpointWrite #pragma mark Write::CommandOptions static constexpr OptionDefinition g_breakpoint_write_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the breakpoints." }, - { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to saved breakpoints file if it exists."}, - // clang-format on +#define LLDB_OPTIONS_breakpoint_write +#include "CommandOptions.inc" }; #pragma mark Write diff --git a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp index 3f9d83cd86a8d7..ec72a04333e480 100644 --- a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp @@ -45,13 +45,8 @@ static constexpr OptionEnumValues ScriptOptionEnum() { } static constexpr OptionDefinition g_breakpoint_add_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner, "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, - { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Specify whether breakpoint command execution should terminate on error." }, - { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, ScriptOptionEnum(), 0, eArgTypeNone, "Specify the language for the commands - if none is specified, the lldb command interpreter will be used." }, - { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonFunction, "Give the name of a Python function to run as command for this breakpoint. Be sure to give a module name if appropriate." }, - { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, - // clang-format on +#define LLDB_OPTIONS_breakpoint_command_add +#include "CommandOptions.inc" }; class CommandObjectBreakpointCommandAdd : public CommandObjectParsed, @@ -470,9 +465,8 @@ const char *CommandObjectBreakpointCommandAdd::g_reader_instructions = // CommandObjectBreakpointCommandDelete static constexpr OptionDefinition g_breakpoint_delete_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, - // clang-format on +#define LLDB_OPTIONS_breakpoint_command_delete +#include "CommandOptions.inc" }; class CommandObjectBreakpointCommandDelete : public CommandObjectParsed { diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 59180e1cff60c9..0c236116b744fe 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -38,6 +38,8 @@ let Command = "settings read" in { } let Command = "breakpoint list" in { + // FIXME: We need to add an "internal" command, and then add this sort of + // thing to it. But I need to see it for now, and don't want to wait. def blist_internal : Option<"internal", "i">, Desc<"Show debugger internal breakpoints">; def blist_brief : Option<"brief", "b">, Group<1>, @@ -52,6 +54,247 @@ let Command = "breakpoint list" in { "provided, which prime new targets.">; } +let Command = "breakpoint modify" in { + def breakpoint_modify_ignore_count : Option<"ignore-count", "i">, Group<1>, + Arg<"Count">, + Desc<"Set the number of times this breakpoint is skipped before stopping.">; + def breakpoint_modify_one_shot : Option<"one-shot", "o">, Group<1>, + Arg<"Boolean">, + Desc<"The breakpoint is deleted the first time it stop causes a stop.">; + def breakpoint_modify_thread_index : Option<"thread-index", "x">, Group<1>, + Arg<"ThreadIndex">, Desc<"The breakpoint stops only for the thread whose " + "index matches this argument.">; + def breakpoint_modify_thread_id : Option<"thread-id", "t">, Group<1>, + Arg<"ThreadID">, Desc<"The breakpoint stops only for the thread whose TID " + "matches this argument.">; + def breakpoint_modify_thread_name : Option<"thread-name", "T">, Group<1>, + Arg<"ThreadName">, Desc<"The breakpoint stops only for the thread whose " + "thread name matches this argument.">; + def breakpoint_modify_queue_name : Option<"queue-name", "q">, Group<1>, + Arg<"QueueName">, Desc<"The breakpoint stops only for threads in the queue " + "whose name is given by this argument.">; + def breakpoint_modify_condition : Option<"condition", "c">, Group<1>, + Arg<"Expression">, Desc<"The breakpoint stops only if this condition " + "expression evaluates to true.">; + def breakpoint_modify_auto_continue : Option<"auto-continue", "G">, Group<1>, + Arg<"Boolean">, + Desc<"The breakpoint will auto-continue after running its commands.">; + def breakpoint_modify_enable : Option<"enable", "e">, Group<2>, + Desc<"Enable the breakpoint.">; + def breakpoint_modify_disable : Option<"disable", "d">, Group<3>, + Desc<"Disable the breakpoint.">; + def breakpoint_modify_command : Option<"command", "C">, Group<4>, + Arg<"Command">, + Desc<"A command to run when the breakpoint is hit, can be provided more " + "than once, the commands will get run in order left to right.">; +} + +let Command = "breakpoint dummy" in { + def breakpoint_dummy_options_dummy_breakpoints : + Option<"dummy-breakpoints", "D">, Group<1>, + Desc<"Act on Dummy breakpoints - i.e. breakpoints set before a file is " + "provided, which prime new targets.">; +} + +let Command = "breakpoint set" in { + def breakpoint_set_shlib : Option<"shlib", "s">, Arg<"ShlibName">, + Completion<"Module">, Groups<[1,2,3,4,5,6,7,8,9,11]>, // *not* in group 10 + Desc<"Set the breakpoint only in this shared library. Can repeat this " + "option multiple times to specify multiple shared libraries.">; + def breakpoint_set_hardware : Option<"hardware", "H">, + Desc<"Require the breakpoint to use hardware breakpoints.">; + def breakpoint_set_file : Option<"file", "f">, Arg<"Filename">, + Completion<"SourceFile">, Groups<[1,3,4,5,6,7,8,9,11]>, + Desc<"Specifies the source file in which to set this breakpoint. Note, by " + "default lldb only looks for files that are #included if they use the " + "standard include file extensions. To set breakpoints on .c/.cpp/.m/.mm " + "files that are #included, set target.inline-breakpoint-strategy to " + "\"always\".">; + def breakpoint_set_line : Option<"line", "l">, Group<1>, Arg<"LineNum">, + Required, + Desc<"Specifies the line number on which to set this breakpoint.">; + def breakpoint_set_address : Option<"address", "a">, Group<2>, + Arg<"AddressOrExpression">, Required, + Desc<"Set the breakpoint at the specified address. If the address maps " + "uniquely toa particular binary, then the address will be converted to " + "a \"file\"address, so that the breakpoint will track that binary+offset " + "no matter where the binary eventually loads. Alternately, if you also " + "specify the module - with the -s option - then the address will be " + "treated as a file address in that module, and resolved accordingly. " + "Again, this will allow lldb to track that offset on subsequent reloads. " + " The module need not have been loaded at the time you specify this " + "breakpoint, and will get resolved when the module is loaded.">; + def breakpoint_set_name : Option<"name", "n">, Group<3>, Arg<"FunctionName">, + Completion<"Symbol">, Required, + Desc<"Set the breakpoint by function name. Can be repeated multiple times " + "to makeone breakpoint for multiple names">; + def breakpoint_set_source_regexp_function : + Option<"source-regexp-function", "X">, Group<9>, Arg<"FunctionName">, + Completion<"Symbol">, + Desc<"When used with '-p' limits the source regex to source contained in " + "the namedfunctions. Can be repeated multiple times.">; + def breakpoint_set_fullname : Option<"fullname", "F">, Group<4>, + Arg<"FullName">, Required, Completion<"Symbol">, + Desc<"Set the breakpoint by fully qualified function names. For C++ this " + "means namespaces and all arguments, and for Objective-C this means a full " + "functionprototype with class and selector. Can be repeated multiple times" + " to make one breakpoint for multiple names.">; + def breakpoint_set_selector : Option<"selector", "S">, Group<5>, + Arg<"Selector">, Required, + Desc<"Set the breakpoint by ObjC selector name. Can be repeated multiple " + "times tomake one breakpoint for multiple Selectors.">; + def breakpoint_set_method : Option<"method", "M">, Group<6>, Arg<"Method">, + Required, Desc<"Set the breakpoint by C++ method names. Can be repeated " + "multiple times tomake one breakpoint for multiple methods.">; + def breakpoint_set_func_regex : Option<"func-regex", "r">, Group<7>, + Arg<"RegularExpression">, Required, Desc<"Set the breakpoint by function " + "name, evaluating a regular-expression to findthe function name(s).">; + def breakpoint_set_basename : Option<"basename", "b">, Group<8>, + Arg<"FunctionName">, Required, Completion<"Symbol">, + Desc<"Set the breakpoint by function basename (C++ namespaces and arguments" + " will beignored). Can be repeated multiple times to make one breakpoint " + "for multiplesymbols.">; + def breakpoint_set_source_pattern_regexp : + Option<"source-pattern-regexp", "p">, Group<9>, Arg<"RegularExpression">, + Required, Desc<"Set the breakpoint by specifying a regular expression which" + " is matched against the source text in a source file or files specified " + "with the -f can be specified more than once. If no source files " + "are specified, uses the current \"default source file\". If you want to " + "match against all source files, pass the \"--all-files\" option.">; + def breakpoint_set_all_files : Option<"all-files", "A">, Group<9>, + Desc<"All files are searched for source pattern matches.">; + def breakpoint_set_python_class : Option<"python-class", "P">, Group<11>, + Arg<"PythonClass">, Required, Desc<"The name of the class that implement " + "a scripted breakpoint.">; + def breakpoint_set_python_class_key : Option<"python-class-key", "k">, + Group<11>, Arg<"None">, + Desc<"The key for a key/value pair passed to the class that implements a " + "scripted breakpoint. Can be specified more than once.">; + def breakpoint_set_python_class_value : Option<"python-class-value", "v">, + Group<11>, Arg<"None">, Desc<"The value for the previous key in the pair " + "passed to the class that implements a scripted breakpoint. " + "Can be specified more than once.">; + def breakpoint_set_language_exception : Option<"language-exception", "E">, + Group<10>, Arg<"Language">, Required, + Desc<"Set the breakpoint on exceptions thrown by the specified language " + "(without options, on throw but not catch.)">; + def breakpoint_set_on_throw : Option<"on-throw", "w">, Group<10>, + Arg<"Boolean">, Desc<"Set the breakpoint on exception throW.">; + def breakpoint_set_on_catch : Option<"on-catch", "h">, Group<10>, + Arg<"Boolean">, Desc<"Set the breakpoint on exception catcH.">; + def breakpoint_set_language : Option<"language", "L">, GroupRange<3, 8>, + Arg<"Language">, + Desc<"Specifies the Language to use when interpreting the breakpoint's " + "expression (note: currently only implemented for setting breakpoints on " + "identifiers). If not set the target.language setting is used.">; + def breakpoint_set_skip_prologue : Option<"skip-prologue", "K">, + Arg<"Boolean">, Groups<[1,3,4,5,6,7,8]>, + Desc<"sKip the prologue if the breakpoint is at the beginning of a " + "function. If not set the target.skip-prologue setting is used.">; + def breakpoint_set_breakpoint_name : Option<"breakpoint-name", "N">, + Arg<"BreakpointName">, + Desc<"Adds this to the list of names for this breakpoint.">; + def breakpoint_set_address_slide : Option<"address-slide", "R">, + Arg<"Address">, Groups<[1,3,4,5,6,7,8]>, + Desc<"Add the specified offset to whatever address(es) the breakpoint " + "resolves to. At present this applies the offset directly as given, and " + "doesn't try to align it to instruction boundaries.">; + def breakpoint_set_move_to_nearest_code : Option<"move-to-nearest-code", "m">, + Groups<[1, 9]>, Arg<"Boolean">, + Desc<"Move breakpoints to nearest code. If not set the " + "target.move-to-nearest-codesetting is used.">; + /* Don't add this option till it actually does something useful... + def breakpoint_set_exception_typename : Option<"exception-typename", "O">, + Arg<"TypeName">, Desc<"The breakpoint will only stop if an " + "exception Object of this type is thrown. Can be repeated multiple times " + "to stop for multiple object types">; + */ +} + +let Command = "breakpoint clear" in { + def breakpoint_clear_file : Option<"file", "f">, Group<1>, Arg<"Filename">, + Completion<"SourceFile">, + Desc<"Specify the breakpoint by source location in this particular file.">; + def breakpoint_clear_line : Option<"line", "l">, Group<1>, Arg<"LineNum">, + Required, + Desc<"Specify the breakpoint by source location at this particular line.">; +} + +let Command = "breakpoint delete" in { + def breakpoint_delete_force : Option<"force", "f">, Group<1>, + Desc<"Delete all breakpoints without querying for confirmation.">; + def breakpoint_delete_dummy_breakpoints : Option<"dummy-breakpoints", "D">, + Group<1>, Desc<"Delete Dummy breakpoints - i.e. breakpoints set before a " + "file is provided, which prime new targets.">; +} + +let Command = "breakpoint name" in { + def breakpoint_name_name : Option<"name", "N">, Group<1>, + Arg<"BreakpointName">, Desc<"Specifies a breakpoint name to use.">; + def breakpoint_name_breakpoint_id : Option<"breakpoint-id", "B">, Group<2>, + Arg<"BreakpointID">, Desc<"Specify a breakpoint ID to use.">; + def breakpoint_name_dummy_breakpoints : Option<"dummy-breakpoints", "D">, + Group<3>, Desc<"Operate on Dummy breakpoints - i.e. breakpoints set before " + "a file is provided, which prime new targets.">; + def breakpoint_name_help_string : Option<"help-string", "H">, Group<4>, + Arg<"None">, Desc<"A help string describing the purpose of this name.">; +} + +let Command = "breakpoint access" in { + def breakpoint_access_allow_list : Option<"allow-list", "L">, Group<1>, + Arg<"Boolean">, Desc<"Determines whether the breakpoint will show up in " + "break list if not referred to explicitly.">; + def breakpoint_access_allow_disable : Option<"allow-disable", "A">, Group<2>, + Arg<"Boolean">, Desc<"Determines whether the breakpoint can be disabled by " + "name or when all breakpoints are disabled.">; + def breakpoint_access_allow_delete : Option<"allow-delete", "D">, Group<3>, + Arg<"Boolean">, Desc<"Determines whether the breakpoint can be deleted by " + "name or when all breakpoints are deleted.">; +} + +let Command = "breakpoint read" in { + def breakpoint_read_file : Option<"file", "f">, Arg<"Filename">, Required, + Completion<"DiskFile">, + Desc<"The file from which to read the breakpoints.">; + def breakpoint_read_breakpoint_name : Option<"breakpoint-name", "N">, + Arg<"BreakpointName">, Desc<"Only read in breakpoints with this name.">; +} + +let Command = "breakpoint write" in { + def breakpoint_write_file : Option<"file", "f">, Arg<"Filename">, Required, + Completion<"DiskFile">, + Desc<"The file into which to write the breakpoints.">; + def breakpoint_write_append : Option<"append", "a">, + Desc<"Append to saved breakpoints file if it exists.">; +} + +let Command = "breakpoint command add" in { + def breakpoint_add_one_liner : Option<"one-liner", "o">, Group<1>, + Arg<"OneLiner">, Desc<"Specify a one-line breakpoint command inline. Be " + "sure to surround it with quotes.">; + def breakpoint_add_stop_on_error : Option<"stop-on-error", "e">, + Arg<"Boolean">, Desc<"Specify whether breakpoint command execution should " + "terminate on error.">; + def breakpoint_add_script_type : Option<"script-type", "s">, + EnumArg<"None", "ScriptOptionEnum()">, + Desc<"Specify the language for the commands - if none is specified, the " + "lldb command interpreter will be used.">; + def breakpoint_add_python_function : Option<"python-function", "F">, + Group<2>, Arg<"PythonFunction">, + Desc<"Give the name of a Python function to run as command for this " + "breakpoint. Be sure to give a module name if appropriate.">; + def breakpoint_add_dummy_breakpoints : Option<"dummy-breakpoints", "D">, + Desc<"Sets Dummy breakpoints - i.e. breakpoints set before a file is " + "provided, which prime new targets.">; +} + +let Command = "breakpoint command delete" in { + def breakpoint_command_delete_dummy_breakpoints : + Option<"dummy-breakpoints", "D">, Group<1>, + Desc<"Delete commands from Dummy breakpoints - i.e. breakpoints set before " + "a file is provided, which prime new targets.">; +} + let Command = "history" in { def history_count : Option<"count", "c">, Group<1>, Arg<"UnsignedInteger">, Desc<"How many history commands to print.">; diff --git a/lldb/utils/TableGen/LLDBOptionDefEmitter.cpp b/lldb/utils/TableGen/LLDBOptionDefEmitter.cpp index 00b44c020a2012..f977bffba3e6e3 100644 --- a/lldb/utils/TableGen/LLDBOptionDefEmitter.cpp +++ b/lldb/utils/TableGen/LLDBOptionDefEmitter.cpp @@ -112,9 +112,11 @@ static void emitOption(Record *Option, raw_ostream &OS) { OS << ", "; // Add the description if there is any. - if (auto D = Option->getValue("Description")) - OS << D->getValue()->getAsString(); - else + if (auto D = Option->getValue("Description")) { + OS << "\""; + llvm::printEscapedString(D->getValue()->getAsUnquotedString(), OS); + OS << "\""; + } else OS << "\"\""; OS << "},\n"; } From 15ef0fa78925fb556804d79b062d3a3476ee5b61 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Tue, 23 Jul 2019 07:15:54 +0000 Subject: [PATCH 08/13] [lldb][NFC] Tablegenify disassemble llvm-svn: 366783 (cherry picked from commit f1883637f2dc70643d735013f54ecc414109c0fb) --- .../Commands/CommandObjectDisassemble.cpp | 26 +------------ lldb/source/Commands/Options.td | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/lldb/source/Commands/CommandObjectDisassemble.cpp b/lldb/source/Commands/CommandObjectDisassemble.cpp index 5972555b2499de..34d3f63156aae1 100644 --- a/lldb/source/Commands/CommandObjectDisassemble.cpp +++ b/lldb/source/Commands/CommandObjectDisassemble.cpp @@ -31,30 +31,8 @@ using namespace lldb; using namespace lldb_private; static constexpr OptionDefinition g_disassemble_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "bytes", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show opcode bytes when disassembling." }, - { LLDB_OPT_SET_ALL, false, "context", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNumLines, "Number of context lines of source to show." }, - { LLDB_OPT_SET_ALL, false, "mixed", 'm', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable mixed source and assembly display." }, - { LLDB_OPT_SET_ALL, false, "raw", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Print raw disassembly with no symbol information." }, - { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use." }, - { LLDB_OPT_SET_ALL, false, "flavor", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeDisassemblyFlavor, "Name of the disassembly flavor you want to use. " - "Currently the only valid options are default, and for Intel " - "architectures, att and intel." }, - { LLDB_OPT_SET_ALL, false, "arch", 'A', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeArchitecture, "Specify the architecture to use from cross disassembly." }, - { LLDB_OPT_SET_1 | - LLDB_OPT_SET_2, true, "start-address", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Address at which to start disassembling." }, - { LLDB_OPT_SET_1, false, "end-address", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Address at which to end disassembling." }, - { LLDB_OPT_SET_2 | - LLDB_OPT_SET_3 | - LLDB_OPT_SET_4 | - LLDB_OPT_SET_5, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNumLines, "Number of instructions to display." }, - { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Disassemble entire contents of the given function name." }, - { LLDB_OPT_SET_4, false, "frame", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disassemble from the start of the current frame's function." }, - { LLDB_OPT_SET_5, false, "pc", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disassemble around the current pc." }, - { LLDB_OPT_SET_6, false, "line", 'l', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disassemble the current frame's current source line instructions if there is debug line " - "table information, else disassemble around the pc." }, - { LLDB_OPT_SET_7, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Disassemble function containing this address." }, - // clang-format on +#define LLDB_OPTIONS_disassemble +#include "CommandOptions.inc" }; CommandObjectDisassemble::CommandOptions::CommandOptions() diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 0c236116b744fe..0771ff188ff916 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -295,6 +295,45 @@ let Command = "breakpoint command delete" in { "a file is provided, which prime new targets.">; } +let Command = "disassemble" in { + def disassemble_options_bytes : Option<"bytes", "b">, + Desc<"Show opcode bytes when disassembling.">; + def disassemble_options_context : Option<"context", "C">, Arg<"NumLines">, + Desc<"Number of context lines of source to show.">; + def disassemble_options_mixed : Option<"mixed", "m">, + Desc<"Enable mixed source and assembly display.">; + def disassemble_options_raw : Option<"raw", "r">, + Desc<"Print raw disassembly with no symbol information.">; + def disassemble_options_plugin : Option<"plugin", "P">, Arg<"Plugin">, + Desc<"Name of the disassembler plugin you want to use.">; + def disassemble_options_flavor : Option<"flavor", "F">, + Arg<"DisassemblyFlavor">, Desc<"Name of the disassembly flavor you want to " + "use. Currently the only valid options are default, and for Intel " + "architectures, att and intel.">; + def disassemble_options_arch : Option<"arch", "A">, Arg<"Architecture">, + Desc<"Specify the architecture to use from cross disassembly.">; + def disassemble_options_start_address : Option<"start-address", "s">, + Groups<[1,2]>, Arg<"AddressOrExpression">, Required, + Desc<"Address at which to start disassembling.">; + def disassemble_options_end_address : Option<"end-address", "e">, Group<1>, + Arg<"AddressOrExpression">, Desc<"Address at which to end disassembling.">; + def disassemble_options_count : Option<"count", "c">, Groups<[2,3,4,5]>, + Arg<"NumLines">, Desc<"Number of instructions to display.">; + def disassemble_options_name : Option<"name", "n">, Group<3>, + Arg<"FunctionName">, Completion<"Symbol">, + Desc<"Disassemble entire contents of the given function name.">; + def disassemble_options_frame : Option<"frame", "f">, Group<4>, + Desc<"Disassemble from the start of the current frame's function.">; + def disassemble_options_pc : Option<"pc", "p">, Group<5>, + Desc<"Disassemble around the current pc.">; + def disassemble_options_line : Option<"line", "l">, Group<6>, + Desc<"Disassemble the current frame's current source line instructions if" + "there is debug line table information, else disassemble around the pc.">; + def disassemble_options_address : Option<"address", "a">, Group<7>, + Arg<"AddressOrExpression">, + Desc<"Disassemble function containing this address.">; +} + let Command = "history" in { def history_count : Option<"count", "c">, Group<1>, Arg<"UnsignedInteger">, Desc<"How many history commands to print.">; From ca0bdcbba16b98754e2a771790d1bf07d3a958b8 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Tue, 23 Jul 2019 11:08:12 +0000 Subject: [PATCH 09/13] [lldb][NFC] Tablegenify source llvm-svn: 366795 (cherry picked from commit aaa682752685b1f3ed7ef90c18480dced27b1c6c) --- lldb/source/Commands/CommandObjectSource.cpp | 23 ++--------- lldb/source/Commands/Options.td | 42 ++++++++++++++++++++ 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp index 1b515d0f1099cf..7aab5130941425 100644 --- a/lldb/source/Commands/CommandObjectSource.cpp +++ b/lldb/source/Commands/CommandObjectSource.cpp @@ -35,15 +35,8 @@ using namespace lldb_private; // CommandObjectSourceInfo - debug line entries dumping command static constexpr OptionDefinition g_source_info_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "The number of line entries to display." }, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source in the given module or shared library (can be specified more than once)." }, - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source." }, - { LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "The line number at which to start the displaying lines." }, - { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "The line number at which to stop displaying lines." }, - { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display." }, - { LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." }, - // clang-format on +#define LLDB_OPTIONS_source_info +#include "CommandOptions.inc" }; class CommandObjectSourceInfo : public CommandObjectParsed { @@ -645,16 +638,8 @@ class CommandObjectSourceInfo : public CommandObjectParsed { // CommandObjectSourceList static constexpr OptionDefinition g_source_list_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "The number of source lines to display." }, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library." }, - { LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints." }, - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source." }, - { LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "The line number at which to start the display source." }, - { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display." }, - { LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." }, - { LLDB_OPT_SET_4, false, "reverse", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Reverse the listing to look backwards from the last displayed block of source." }, - // clang-format on +#define LLDB_OPTIONS_source_list +#include "CommandOptions.inc" }; class CommandObjectSourceList : public CommandObjectParsed { diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 0771ff188ff916..9df298616a11cd 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -390,6 +390,48 @@ let Command = "script add" in { Desc<"Set the synchronicity of this command's executions with regard to " "LLDB event system.">; } +let Command = "source info" in { + def source_info_count : Option<"count", "c">, Arg<"Count">, + Desc<"The number of line entries to display.">; + def source_info_shlib : Option<"shlib", "s">, Groups<[1,2]>, Arg<"ShlibName">, + Completion<"Module">, Desc<"Look up the source in the given module or " + "shared library (can be specified more than once).">; + def source_info_file : Option<"file", "f">, Group<1>, Arg<"Filename">, + Completion<"SourceFile">, Desc<"The file from which to display source.">; + def source_info_line : Option<"line", "l">, Group<1>, Arg<"LineNum">, + Desc<"The line number at which to start the displaying lines.">; + def source_info_end_line : Option<"end-line", "e">, Group<1>, Arg<"LineNum">, + Desc<"The line number at which to stop displaying lines.">; + def source_info_name : Option<"name", "n">, Group<2>, Arg<"Symbol">, + Completion<"Symbol">, + Desc<"The name of a function whose source to display.">; + def source_info_address : Option<"address", "a">, Group<3>, + Arg<"AddressOrExpression">, Desc<"Lookup the address and display the source" + " information for the corresponding file and line.">; +} + +let Command = "source list" in { + def source_list_count : Option<"count", "c">, Arg<"Count">, + Desc<"The number of source lines to display.">; + def source_list_shlib : Option<"shlib", "s">, Groups<[1,2]>, Arg<"ShlibName">, + Completion<"Module">, + Desc<"Look up the source file in the given shared library.">; + def source_list_show_breakpoints : Option<"show-breakpoints", "b">, + Desc<"Show the line table locations from the debug information that " + "indicate valid places to set source level breakpoints.">; + def source_list_file : Option<"file", "f">, Group<1>, Arg<"Filename">, + Completion<"SourceFile">, Desc<"The file from which to display source.">; + def source_list_line : Option<"line", "l">, Group<1>, Arg<"LineNum">, + Desc<"The line number at which to start the display source.">; + def source_list_name : Option<"name", "n">, Group<2>, Arg<"Symbol">, + Completion<"Symbol">, + Desc<"The name of a function whose source to display.">; + def source_list_address : Option<"address", "a">, Group<3>, + Arg<"AddressOrExpression">, Desc<"Lookup the address and display the source" + " information for the corresponding file and line.">; + def source_list_reverse : Option<"reverse", "r">, Group<4>, Desc<"Reverse the" + " listing to look backwards from the last displayed block of source.">; +} let Command = "thread backtrace" in { def thread_backtrace_count : Option<"count", "c">, Group<1>, Arg<"Count">, From eef9a24cc4617515ed7c0da4e1454926d9c652c6 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Tue, 23 Jul 2019 12:54:33 +0000 Subject: [PATCH 10/13] [lldb][NFC] Tablegenify process llvm-svn: 366804 (cherry picked from commit 438dfcffe96f6a2bbc8c34331dd6bd3850903165) --- lldb/source/Commands/CommandObjectProcess.cpp | 37 +++++--------- lldb/source/Commands/Options.td | 50 +++++++++++++++++++ 2 files changed, 62 insertions(+), 25 deletions(-) diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index b20a2d5333327b..72286028a04b99 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -256,14 +256,8 @@ class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach { }; static constexpr OptionDefinition g_process_attach_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "continue", 'c', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Immediately continue the process once attached." }, - { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the process plugin you want to use." }, - { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "The process ID of an existing process to attach to." }, - { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "The name of the process to attach to." }, - { LLDB_OPT_SET_2, false, "include-existing", 'i', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Include existing processes when doing attach -w." }, - { LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Wait for the process with to launch." }, - // clang-format on +#define LLDB_OPTIONS_process_attach +#include "CommandOptions.inc" }; #pragma mark CommandObjectProcessAttach @@ -506,9 +500,8 @@ class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach { // CommandObjectProcessContinue static constexpr OptionDefinition g_process_continue_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Ignore crossings of the breakpoint (if it exists) for the currently selected thread." } - // clang-format on +#define LLDB_OPTIONS_process_continue +#include "CommandOptions.inc" }; #pragma mark CommandObjectProcessContinue @@ -667,9 +660,8 @@ class CommandObjectProcessContinue : public CommandObjectParsed { // CommandObjectProcessDetach static constexpr OptionDefinition g_process_detach_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "keep-stopped", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." }, - // clang-format on +#define LLDB_OPTIONS_process_detach +#include "CommandOptions.inc" }; #pragma mark CommandObjectProcessDetach @@ -764,9 +756,8 @@ class CommandObjectProcessDetach : public CommandObjectParsed { // CommandObjectProcessConnect static constexpr OptionDefinition g_process_connect_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the process plugin you want to use." }, - // clang-format on +#define LLDB_OPTIONS_process_connect +#include "CommandOptions.inc" }; #pragma mark CommandObjectProcessConnect @@ -889,9 +880,8 @@ class CommandObjectProcessPlugin : public CommandObjectProxy { // CommandObjectProcessLoad static constexpr OptionDefinition g_process_load_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "install", 'i', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypePath, "Install the shared library to the target. If specified without an argument then the library will installed in the current working directory." }, - // clang-format on +#define LLDB_OPTIONS_process_load +#include "CommandOptions.inc" }; #pragma mark CommandObjectProcessLoad @@ -1273,11 +1263,8 @@ class CommandObjectProcessStatus : public CommandObjectParsed { // CommandObjectProcessHandle static constexpr OptionDefinition g_process_handle_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "stop", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." }, - { LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." }, - { LLDB_OPT_SET_1, false, "pass", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." } - // clang-format on +#define LLDB_OPTIONS_process_handle +#include "CommandOptions.inc" }; #pragma mark CommandObjectProcessHandle diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 9df298616a11cd..8abefba88b1df5 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -370,6 +370,56 @@ let Command = "regex" in { Desc<"A syntax string showing the typical usage syntax.">; } +let Command = "process attach" in { + def process_attach_continue : Option<"continue", "c">, + Desc<"Immediately continue the process once attached.">; + def process_attach_plugin : Option<"plugin", "P">, Arg<"Plugin">, + Desc<"Name of the process plugin you want to use.">; + def process_attach_pid : Option<"pid", "p">, Group<1>, Arg<"Pid">, + Desc<"The process ID of an existing process to attach to.">; + def process_attach_name : Option<"name", "n">, Group<2>, Arg<"ProcessName">, + Desc<"The name of the process to attach to.">; + def process_attach_include_existing : Option<"include-existing", "i">, + Group<2>, Desc<"Include existing processes when doing attach -w.">; + def process_attach_waitfor : Option<"waitfor", "w">, Group<2>, + Desc<"Wait for the process with to launch.">; +} + +let Command = "process continue" in { + def process_continue_ignore_count : Option<"ignore-count", "i">, + Arg<"UnsignedInteger">, Desc<"Ignore crossings of the breakpoint (if it" + " exists) for the currently selected thread.">; +} + +let Command = "process detach" in { + def process_detach_keep_stopped : Option<"keep-stopped", "s">, Group<1>, + Arg<"Boolean">, Desc<"Whether or not the process should be kept stopped on" + " detach (if possible).">; +} + +let Command = "process connect" in { + def process_connect_plugin : Option<"plugin", "p">, Arg<"Plugin">, + Desc<"Name of the process plugin you want to use.">; +} + +let Command = "process load" in { + def process_load_install : Option<"install", "i">, OptionalArg<"Path">, + Desc<"Install the shared library to the target. If specified without an " + "argument then the library will installed in the current working " + "directory.">; +} + +let Command = "process handle" in { + def process_handle_stop : Option<"stop", "s">, Group<1>, Arg<"Boolean">, + Desc<"Whether or not the process should be stopped if the signal is " + "received.">; + def process_handle_notify : Option<"notify", "n">, Group<1>, Arg<"Boolean">, + Desc<"Whether or not the debugger should notify the user if the signal is " + "received.">; + def process_handle_pass : Option<"pass", "p">, Group<1>, Arg<"Boolean">, + Desc<"Whether or not the signal should be passed to the process.">; +} + let Command = "script import" in { def script_import_allow_reload : Option<"allow-reload", "r">, Group<1>, Desc<"Allow the script to be loaded even if it was already loaded before. " From e91442da4cb38fc2a42b1b0d5bf6382524177259 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 24 Jul 2019 12:05:42 +0000 Subject: [PATCH 11/13] [lldb][NFC] Tablegenify platform llvm-svn: 366891 (cherry picked from commit 2359fecf82dbf85d6e05d09d7b3be683f613c236) --- .../source/Commands/CommandObjectPlatform.cpp | 58 +++------- lldb/source/Commands/Options.td | 100 ++++++++++++++++++ 2 files changed, 112 insertions(+), 46 deletions(-) diff --git a/lldb/source/Commands/CommandObjectPlatform.cpp b/lldb/source/Commands/CommandObjectPlatform.cpp index 53549cdeee326a..7a4c4fad40ac69 100644 --- a/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/lldb/source/Commands/CommandObjectPlatform.cpp @@ -59,19 +59,8 @@ static mode_t ParsePermissionString(llvm::StringRef permissions) { } static constexpr OptionDefinition g_permissions_options[] = { - // clang-format off - {LLDB_OPT_SET_ALL, false, "permissions-value", 'v', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePermissionsNumber, "Give out the numeric value for permissions (e.g. 757)"}, - {LLDB_OPT_SET_ALL, false, "permissions-string", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePermissionsString, "Give out the string value for permissions (e.g. rwxr-xr--)."}, - {LLDB_OPT_SET_ALL, false, "user-read", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow user to read."}, - {LLDB_OPT_SET_ALL, false, "user-write", 'w', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow user to write."}, - {LLDB_OPT_SET_ALL, false, "user-exec", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow user to execute."}, - {LLDB_OPT_SET_ALL, false, "group-read", 'R', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow group to read."}, - {LLDB_OPT_SET_ALL, false, "group-write", 'W', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow group to write."}, - {LLDB_OPT_SET_ALL, false, "group-exec", 'X', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow group to execute."}, - {LLDB_OPT_SET_ALL, false, "world-read", 'd', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow world to read."}, - {LLDB_OPT_SET_ALL, false, "world-write", 't', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow world to write."}, - {LLDB_OPT_SET_ALL, false, "world-exec", 'e', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow world to execute."}, - // clang-format on +#define LLDB_OPTIONS_permissions +#include "CommandObject.inc" }; class OptionPermissions : public OptionGroup { @@ -586,10 +575,8 @@ class CommandObjectPlatformFClose : public CommandObjectParsed { // "platform fread" static constexpr OptionDefinition g_platform_fread_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeIndex, "Offset into the file at which to start reading." }, - { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "Number of bytes to read from the file." }, - // clang-format on +#define LLDB_OPTIONS_platform_fread +#include "CommandOptions.inc" }; class CommandObjectPlatformFRead : public CommandObjectParsed { @@ -679,10 +666,8 @@ class CommandObjectPlatformFRead : public CommandObjectParsed { // "platform fwrite" static constexpr OptionDefinition g_platform_fwrite_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeIndex, "Offset into the file at which to start reading." }, - { LLDB_OPT_SET_1, false, "data", 'd', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeValue, "Text to write to the file." }, - // clang-format on +#define LLDB_OPTIONS_platform_fwrite +#include "CommandOptions.inc" }; class CommandObjectPlatformFWrite : public CommandObjectParsed { @@ -1057,22 +1042,8 @@ class CommandObjectPlatformProcessLaunch : public CommandObjectParsed { // "platform process list" static OptionDefinition g_platform_process_list_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "List the process info for a specific process ID." }, - { LLDB_OPT_SET_2, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that match a string." }, - { LLDB_OPT_SET_3, true, "ends-with", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that end with a string." }, - { LLDB_OPT_SET_4, true, "starts-with", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that start with a string." }, - { LLDB_OPT_SET_5, true, "contains", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that contain a string." }, - { LLDB_OPT_SET_6, true, "regex", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "parent", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "Find processes that have a matching parent process ID." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "uid", 'u', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching user ID." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "euid", 'U', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching effective user ID." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "gid", 'g', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching group ID." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "egid", 'G', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching effective group ID." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "arch", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeArchitecture, "Find processes that have a matching architecture." }, - { LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show process arguments instead of the process executable basename." }, - { LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable verbose output." }, - // clang-format on +#define LLDB_OPTIONS_platform_process_list +#include "CommandOptions.inc" }; class CommandObjectPlatformProcessList : public CommandObjectParsed { @@ -1437,12 +1408,8 @@ class CommandObjectPlatformProcessInfo : public CommandObjectParsed { }; static constexpr OptionDefinition g_platform_process_attach_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the process plugin you want to use." }, - { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "The process ID of an existing process to attach to." }, - { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "The name of the process to attach to." }, - { LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Wait for the process with to launch." }, - // clang-format on +#define LLDB_OPTIONS_platform_process_attach +#include "CommandOptions.inc" }; class CommandObjectPlatformProcessAttach : public CommandObjectParsed { @@ -1616,9 +1583,8 @@ class CommandObjectPlatformProcess : public CommandObjectMultiword { // "platform shell" static constexpr OptionDefinition g_platform_shell_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeValue, "Seconds to wait for the remote host to finish running the command." }, - // clang-format on +#define LLDB_OPTIONS_platform_shell +#include "CommandOptions.inc" }; class CommandObjectPlatformShell : public CommandObjectRaw { diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 8abefba88b1df5..7e8eacd06c5cf2 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -370,6 +370,106 @@ let Command = "regex" in { Desc<"A syntax string showing the typical usage syntax.">; } +let Command = "permissions" in { + def permissions_permissions_value : Option<"permissions-value", "v">, + Arg<"PermissionsNumber">, + Desc<"Give out the numeric value for permissions (e.g. 757)">; + def permissions_permissions_string : Option<"permissions-string", "s">, + Arg<"PermissionsString">, + Desc<"Give out the string value for permissions (e.g. rwxr-xr--).">; + def permissions_user_read : Option<"user-read", "r">, + Desc<"Allow user to read.">; + def permissions_user_write : Option<"user-write", "w">, + Desc<"Allow user to write.">; + def permissions_user_exec : Option<"user-exec", "x">, + Desc<"Allow user to execute.">; + def permissions_group_read : Option<"group-read", "R">, + Desc<"Allow group to read.">; + def permissions_group_write : Option<"group-write", "W">, + Desc<"Allow group to write.">; + def permissions_group_exec : Option<"group-exec", "X">, + Desc<"Allow group to execute.">; + def permissions_world_read : Option<"world-read", "d">, + Desc<"Allow world to read.">; + def permissions_world_write : Option<"world-write", "t">, + Desc<"Allow world to write.">; + def permissions_world_exec : Option<"world-exec", "e">, + Desc<"Allow world to execute.">; +} + +let Command = "platform fread" in { + def platform_fread_offset : Option<"offset", "o">, Group<1>, Arg<"Index">, + Desc<"Offset into the file at which to start reading.">; + def platform_fread_count : Option<"count", "c">, Group<1>, Arg<"Count">, + Desc<"Number of bytes to read from the file.">; +} + +let Command = "platform fwrite" in { + def platform_fwrite_offset : Option<"offset", "o">, Group<1>, Arg<"Index">, + Desc<"Offset into the file at which to start reading.">; + def platform_fwrite_data : Option<"data", "d">, Group<1>, Arg<"Value">, + Desc<"Text to write to the file.">; +} + +let Command = "platform process list" in { + def platform_process_list_pid : Option<"pid", "p">, Group<1>, Arg<"Pid">, + Desc<"List the process info for a specific process ID.">; + def platform_process_list_name : Option<"name", "n">, Group<2>, + Arg<"ProcessName">, Required, + Desc<"Find processes with executable basenames that match a string.">; + def platform_process_list_ends_with : Option<"ends-with", "e">, Group<3>, + Arg<"ProcessName">, Required, + Desc<"Find processes with executable basenames that end with a string.">; + def platform_process_list_starts_with : Option<"starts-with", "s">, Group<4>, + Arg<"ProcessName">, Required, + Desc<"Find processes with executable basenames that start with a string.">; + def platform_process_list_contains : Option<"contains", "c">, Group<5>, + Arg<"ProcessName">, Required, + Desc<"Find processes with executable basenames that contain a string.">; + def platform_process_list_regex : Option<"regex", "r">, Group<6>, + Arg<"RegularExpression">, Required, + Desc<"Find processes with executable basenames that match a regular " + "expression.">; + def platform_process_list_parent : Option<"parent", "P">, OptionRange<2, 6>, + Arg<"Pid">, Desc<"Find processes that have a matching parent process ID.">; + def platform_process_list_uid : Option<"uid", "u">, OptionRange<2, 6>, + Arg<"UnsignedInteger">, + Desc<"Find processes that have a matching user ID.">; + def platform_process_list_euid : Option<"euid", "U">, OptionRange<2, 6>, + Arg<"UnsignedInteger">, + Desc<"Find processes that have a matching effective user ID.">; + def platform_process_list_gid : Option<"gid", "g">, OptionRange<2, 6>, + Arg<"UnsignedInteger">, + Desc<"Find processes that have a matching group ID.">; + def platform_process_list_egid : Option<"egid", "G">, OptionRange<2, 6>, + Arg<"UnsignedInteger">, + Desc<"Find processes that have a matching effective group ID.">; + def platform_process_list_arch : Option<"arch", "a">, OptionRange<2, 6>, + Arg<"Architecture">, + Desc<"Find processes that have a matching architecture.">; + def platform_process_list_show_args : Option<"show-args", "A">, + OptionRange<1, 6>, + Desc<"Show process arguments instead of the process executable basename.">; + def platform_process_list_verbose : Option<"verbose", "v">, OptionRange<1, 6>, + Desc<"Enable verbose output.">; +} + +let Command = "platform process attach" in { + def platform_process_attach_plugin : Option<"plugin", "P">, Arg<"Plugin">, + Desc<"Name of the process plugin you want to use.">; + def platform_process_attach_pid : Option<"pid", "p">, Group<1>, Arg<"Pid">, + Desc<"The process ID of an existing process to attach to.">; + def platform_process_attach_name : Option<"name", "n">, Group<2>, + Arg<"ProcessName">, Desc<"The name of the process to attach to.">; + def platform_process_attach_waitfor : Option<"waitfor", "w">, Group<2>, + Desc<"Wait for the process with to launch.">; +} + +let Command = "platform shell" in { + def platform_shell_timeout : Option<"timeout", "t">, Arg<"Value">, + Desc<"Seconds to wait for the remote host to finish running the command.">; +} + let Command = "process attach" in { def process_attach_continue : Option<"continue", "c">, Desc<"Immediately continue the process once attached.">; From 4ca4b5d58f29fd316d483732e80d11e32d549c26 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 24 Jul 2019 12:08:08 +0000 Subject: [PATCH 12/13] [lldb] Fix build errors from tablegenify platform commit Forgot to stage some changes... llvm-svn: 366892 (cherry picked from commit aaad1a8959d05718fa44c10122ba0ce4d7d3935c) --- lldb/source/Commands/CommandObjectPlatform.cpp | 2 +- lldb/source/Commands/Options.td | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lldb/source/Commands/CommandObjectPlatform.cpp b/lldb/source/Commands/CommandObjectPlatform.cpp index 7a4c4fad40ac69..d1054020c8197d 100644 --- a/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/lldb/source/Commands/CommandObjectPlatform.cpp @@ -60,7 +60,7 @@ static mode_t ParsePermissionString(llvm::StringRef permissions) { static constexpr OptionDefinition g_permissions_options[] = { #define LLDB_OPTIONS_permissions -#include "CommandObject.inc" +#include "CommandOptions.inc" }; class OptionPermissions : public OptionGroup { diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 7e8eacd06c5cf2..ff89a35e728f7a 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -430,27 +430,27 @@ let Command = "platform process list" in { Arg<"RegularExpression">, Required, Desc<"Find processes with executable basenames that match a regular " "expression.">; - def platform_process_list_parent : Option<"parent", "P">, OptionRange<2, 6>, + def platform_process_list_parent : Option<"parent", "P">, GroupRange<2, 6>, Arg<"Pid">, Desc<"Find processes that have a matching parent process ID.">; - def platform_process_list_uid : Option<"uid", "u">, OptionRange<2, 6>, + def platform_process_list_uid : Option<"uid", "u">, GroupRange<2, 6>, Arg<"UnsignedInteger">, Desc<"Find processes that have a matching user ID.">; - def platform_process_list_euid : Option<"euid", "U">, OptionRange<2, 6>, + def platform_process_list_euid : Option<"euid", "U">, GroupRange<2, 6>, Arg<"UnsignedInteger">, Desc<"Find processes that have a matching effective user ID.">; - def platform_process_list_gid : Option<"gid", "g">, OptionRange<2, 6>, + def platform_process_list_gid : Option<"gid", "g">, GroupRange<2, 6>, Arg<"UnsignedInteger">, Desc<"Find processes that have a matching group ID.">; - def platform_process_list_egid : Option<"egid", "G">, OptionRange<2, 6>, + def platform_process_list_egid : Option<"egid", "G">, GroupRange<2, 6>, Arg<"UnsignedInteger">, Desc<"Find processes that have a matching effective group ID.">; - def platform_process_list_arch : Option<"arch", "a">, OptionRange<2, 6>, + def platform_process_list_arch : Option<"arch", "a">, GroupRange<2, 6>, Arg<"Architecture">, Desc<"Find processes that have a matching architecture.">; def platform_process_list_show_args : Option<"show-args", "A">, - OptionRange<1, 6>, + GroupRange<1, 6>, Desc<"Show process arguments instead of the process executable basename.">; - def platform_process_list_verbose : Option<"verbose", "v">, OptionRange<1, 6>, + def platform_process_list_verbose : Option<"verbose", "v">, GroupRange<1, 6>, Desc<"Enable verbose output.">; } From bd555c120afa5e7cece4f060c4307086edaa8442 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 25 Jul 2019 11:22:46 +0000 Subject: [PATCH 13/13] [lldb] Tablegenify expr/frame/log/register/memory llvm-svn: 367009 (cherry picked from commit ec67e73430889882861fb21a193f57cdf2c3a1d2) --- .../Commands/CommandObjectExpression.cpp | 19 +-- lldb/source/Commands/CommandObjectFrame.cpp | 20 +-- lldb/source/Commands/CommandObjectLog.cpp | 14 +- lldb/source/Commands/CommandObjectMemory.cpp | 28 +--- .../source/Commands/CommandObjectRegister.cpp | 7 +- lldb/source/Commands/Options.td | 143 ++++++++++++++++++ 6 files changed, 161 insertions(+), 70 deletions(-) diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index 29e4ab69552257..a10f42d977331a 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -48,23 +48,8 @@ static constexpr OptionEnumValues DescriptionVerbosityTypes() { } static constexpr OptionDefinition g_expression_options[] = { - // clang-format off - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, or raises a signal. " - "Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "When specified, debug the JIT code by setting a breakpoint on the first instruction " - "and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Specifies the Language to use when parsing the expression. If not set the target.language " - "setting is used." }, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "apply-fixits", 'X', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "If true, simple fix-it hints will be automatically applied to the expression." }, - {LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, nullptr, DescriptionVerbosityTypes(), 0, eArgTypeDescriptionVerbosity, "How verbose should the output of this expression be, if the object description is asked for."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "top-level", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Interpret the expression as a complete translation unit, without injecting it into the local " - "context. Allows declaration of persistent, top-level entities without a $ prefix."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "allow-jit", 'j', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Controls whether the expression can fall back to being JITted if it's not supported by " - "the interpreter (defaults to true)."} - // clang-format on +#define LLDB_OPTIONS_expression +#include "CommandOptions.inc" }; Status CommandObjectExpression::CommandOptions::SetOptionValue( diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp index ab6a07952f194b..a6f4354d97471a 100644 --- a/lldb/source/Commands/CommandObjectFrame.cpp +++ b/lldb/source/Commands/CommandObjectFrame.cpp @@ -55,11 +55,8 @@ using namespace lldb_private; // CommandObjectFrameDiagnose static constexpr OptionDefinition g_frame_diag_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "register", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegisterName, "A register to diagnose." }, - { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddress, "An address to diagnose." }, - { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "An optional offset. Requires --register." } - // clang-format on +#define LLDB_OPTIONS_frame_diag +#include "CommandOptions.inc" }; class CommandObjectFrameDiagnose : public CommandObjectParsed { @@ -239,9 +236,8 @@ class CommandObjectFrameInfo : public CommandObjectParsed { // CommandObjectFrameSelect static OptionDefinition g_frame_select_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "relative", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "A relative frame index offset from the current frame index." }, - // clang-format on +#define LLDB_OPTIONS_frame_select +#include "CommandOptions.inc" }; class CommandObjectFrameSelect : public CommandObjectParsed { @@ -745,12 +741,8 @@ class CommandObjectFrameVariable : public CommandObjectParsed { #pragma mark CommandObjectFrameRecognizer static OptionDefinition g_frame_recognizer_add_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Name of the module or shared library that this recognizer applies to." }, - { LLDB_OPT_SET_ALL, false, "function", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeName, "Name of the function that this recognizer applies to." }, - { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "Give the name of a Python class to use for this frame recognizer." }, - { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Function name and module name are actually regular expressions." } - // clang-format on +#define LLDB_OPTIONS_frame_recognizer_add +#include "CommandOptions.inc" }; class CommandObjectFrameRecognizerAdd : public CommandObjectParsed { diff --git a/lldb/source/Commands/CommandObjectLog.cpp b/lldb/source/Commands/CommandObjectLog.cpp index 2ad61de1a3e9f6..e096836cbaf508 100644 --- a/lldb/source/Commands/CommandObjectLog.cpp +++ b/lldb/source/Commands/CommandObjectLog.cpp @@ -32,18 +32,8 @@ using namespace lldb; using namespace lldb_private; static constexpr OptionDefinition g_log_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename, "Set the destination file to log to." }, - { LLDB_OPT_SET_1, false, "threadsafe", 't', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines." }, - { LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable verbose logging." }, - { LLDB_OPT_SET_1, false, "sequence", 's', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id." }, - { LLDB_OPT_SET_1, false, "timestamp", 'T', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend all log lines with a timestamp." }, - { LLDB_OPT_SET_1, false, "pid-tid", 'p', OptionParser::eNoArgument, 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, {}, 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, {}, 0, eArgTypeNone, "Append a stack backtrace to each log line." }, - { LLDB_OPT_SET_1, false, "append", 'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to the log file instead of overwriting." }, - { LLDB_OPT_SET_1, false, "file-function",'F',OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend the names of files and function that generate the logs." }, - // clang-format on +#define LLDB_OPTIONS_log +#include "CommandOptions.inc" }; class CommandObjectLogEnable : public CommandObjectParsed { diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp index 1afcac71318dfb..7409915665f257 100644 --- a/lldb/source/Commands/CommandObjectMemory.cpp +++ b/lldb/source/Commands/CommandObjectMemory.cpp @@ -47,18 +47,8 @@ using namespace lldb; using namespace lldb_private; static constexpr OptionDefinition g_read_memory_options[] = { - // clang-format off - {LLDB_OPT_SET_1, false, "num-per-line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNumberPerLine, "The number of items per line to display." }, - {LLDB_OPT_SET_2, false, "binary", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that " - "uses the format, size, count and number per line settings." }, - {LLDB_OPT_SET_3 | - LLDB_OPT_SET_4, true , "type", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "The name of a type to view memory as." }, - {LLDB_OPT_SET_4, false, "language", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "The language of the type to view memory as."}, - {LLDB_OPT_SET_3, false, "offset", 'E', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "How many elements of the specified type to skip before starting to display data." }, - {LLDB_OPT_SET_1 | - LLDB_OPT_SET_2 | - LLDB_OPT_SET_3, false, "force", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Necessary if reading over target.max-memory-read-size bytes." }, - // clang-format on +#define LLDB_OPTIONS_memory_read +#include "CommandOptions.inc" }; class OptionGroupReadMemory : public OptionGroup { @@ -907,12 +897,8 @@ class CommandObjectMemoryRead : public CommandObjectParsed { }; static constexpr OptionDefinition g_memory_find_option_table[] = { - // clang-format off - {LLDB_OPT_SET_1, true, "expression", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeExpression, "Evaluate an expression to obtain a byte pattern."}, - {LLDB_OPT_SET_2, true, "string", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Use text to find a byte pattern."}, - {LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "How many times to perform the search."}, - {LLDB_OPT_SET_ALL, false, "dump-offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "When dumping memory for a match, an offset from the match location to start dumping from."}, - // clang-format on +#define LLDB_OPTIONS_memory_find +#include "CommandOptions.inc" }; // Find the specified data in memory @@ -1204,10 +1190,8 @@ class CommandObjectMemoryFind : public CommandObjectParsed { }; static constexpr OptionDefinition g_memory_write_option_table[] = { - // clang-format off - {LLDB_OPT_SET_1, true, "infile", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename, "Write memory using the contents of a file."}, - {LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "Start writing bytes from an offset within the input file."}, - // clang-format on +#define LLDB_OPTIONS_memory_write +#include "CommandOptions.inc" }; // Write memory to the inferior process diff --git a/lldb/source/Commands/CommandObjectRegister.cpp b/lldb/source/Commands/CommandObjectRegister.cpp index 34482a8b1e4f95..62b173141d8ed3 100644 --- a/lldb/source/Commands/CommandObjectRegister.cpp +++ b/lldb/source/Commands/CommandObjectRegister.cpp @@ -34,11 +34,8 @@ using namespace lldb_private; // "register read" static constexpr OptionDefinition g_register_read_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "alternate", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display register names using the alternate register name if there is one." }, - { LLDB_OPT_SET_1, false, "set", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeIndex, "Specify which register sets to dump by index." }, - { LLDB_OPT_SET_2, false, "all", 'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show all register sets." }, - // clang-format on +#define LLDB_OPTIONS_register_read +#include "CommandOptions.inc" }; class CommandObjectRegisterRead : public CommandObjectParsed { diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index ff89a35e728f7a..892bfb87252b70 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -334,6 +334,75 @@ let Command = "disassemble" in { Desc<"Disassemble function containing this address.">; } +let Command = "expression" in { + def expression_options_all_threads : Option<"all-threads", "a">, + Groups<[1,2]>, Arg<"Boolean">, Desc<"Should we run all threads if the " + "execution doesn't complete on one thread.">; + def expression_options_ignore_breakpoints : Option<"ignore-breakpoints", "i">, + Groups<[1,2]>, Arg<"Boolean">, + Desc<"Ignore breakpoint hits while running expressions">; + def expression_options_timeout : Option<"timeout", "t">, Groups<[1,2]>, + Arg<"UnsignedInteger">, + Desc<"Timeout value (in microseconds) for running the expression.">; + def expression_options_unwind_on_error : Option<"unwind-on-error", "u">, + Groups<[1,2]>, Arg<"Boolean">, + Desc<"Clean up program state if the expression causes a crash, or raises a " + "signal. Note, unlike gdb hitting a breakpoint is controlled by another " + "option (-i).">; + def expression_options_debug : Option<"debug", "g">, Groups<[1,2]>, + Desc<"When specified, debug the JIT code by setting a breakpoint on the " + "first instruction and forcing breakpoints to not be ignored (-i0) and no " + "unwinding to happen on error (-u0).">; + def expression_options_language : Option<"language", "l">, Groups<[1,2]>, + Arg<"Language">, Desc<"Specifies the Language to use when parsing the " + "expression. If not set the target.language setting is used.">; + def expression_options_apply_fixits : Option<"apply-fixits", "X">, + Groups<[1,2]>, Arg<"Language">, Desc<"If true, simple fix-it hints will be " + "automatically applied to the expression.">; + def expression_options_description_verbosity : + Option<"description-verbosity", "v">, Group<1>, + OptionalEnumArg<"DescriptionVerbosity", "DescriptionVerbosityTypes()">, + Desc<"How verbose should the output of this expression be, if the object " + "description is asked for.">; + def expression_options_top_level : Option<"top-level", "p">, Groups<[1,2]>, + Desc<"Interpret the expression as a complete translation unit, without " + "injecting it into the local context. Allows declaration of persistent, " + "top-level entities without a $ prefix.">; + def expression_options_allow_jit : Option<"allow-jit", "j">, Groups<[1,2]>, + Arg<"Boolean">, + Desc<"Controls whether the expression can fall back to being JITted if it's" + "not supported by the interpreter (defaults to true).">; +} + +let Command = "frame diag" in { + def frame_diag_register : Option<"register", "r">, Group<1>, + Arg<"RegisterName">, Desc<"A register to diagnose.">; + def frame_diag_address : Option<"address", "a">, Group<1>, Arg<"Address">, + Desc<"An address to diagnose.">; + def frame_diag_offset : Option<"offset", "o">, Group<1>, Arg<"Offset">, + Desc<"An optional offset. Requires --register.">; +} + +let Command = "frame select" in { + def frame_select_relative : Option<"relative", "r">, Group<1>, Arg<"Offset">, + Desc<"A relative frame index offset from the current frame index.">; +} + +let Command = "frame recognizer add" in { + def frame_recognizer_shlib : Option<"shlib", "s">, Arg<"ShlibName">, + Completion<"Module">, + Desc<"Name of the module or shared library that this recognizer applies " + "to.">; + def frame_recognizer_function : Option<"function", "n">, Arg<"Name">, + Completion<"Symbol">, + Desc<"Name of the function that this recognizer applies to.">; + def frame_recognizer_python_class : Option<"python-class", "l">, Group<2>, + Arg<"PythonClass">, + Desc<"Give the name of a Python class to use for this frame recognizer.">; + def frame_recognizer_regex : Option<"regex", "x">, + Desc<"Function name and module name are actually regular expressions.">; +} + let Command = "history" in { def history_count : Option<"count", "c">, Group<1>, Arg<"UnsignedInteger">, Desc<"How many history commands to print.">; @@ -347,6 +416,80 @@ let Command = "history" in { Desc<"Clears the current command history.">; } +let Command = "log" in { + def log_file : Option<"file", "f">, Group<1>, Arg<"Filename">, + Desc<"Set the destination file to log to.">; + def log_threadsafe : Option<"threadsafe", "t">, Group<1>, + Desc<"Enable thread safe logging to avoid interweaved log lines.">; + def log_verbose : Option<"verbose", "v">, Group<1>, + Desc<"Enable verbose logging.">; + def log_sequence : Option<"sequence", "s">, Group<1>, + Desc<"Prepend all log lines with an increasing integer sequence id.">; + def log_timestamp : Option<"timestamp", "T">, Group<1>, + Desc<"Prepend all log lines with a timestamp.">; + def log_pid_tid : Option<"pid-tid", "p">, Group<1>, + Desc<"Prepend all log lines with the process and thread ID that generates " + "the log line.">; + def log_thread_name : Option<"thread-name", "n">, Group<1>, + Desc<"Prepend all log lines with the thread name for the thread that " + "generates the log line.">; + + def log_stack : Option<"stack", "S">, Group<1>, + Desc<"Append a stack backtrace to each log line.">; + def log_append : Option<"append", "a">, Group<1>, + Desc<"Append to the log file instead of overwriting.">; + def log_file_function : Option<"file-function", "F">, Group<1>, + Desc<"Prepend the names of files and function that generate the logs.">; +} + +let Command = "memory read" in { + def memory_read_num_per_line : Option<"num-per-line", "l">, Group<1>, + Arg<"NumberPerLine">, Desc<"The number of items per line to display.">; + def memory_read_binary : Option<"binary", "b">, Group<2>, + Desc<"If true, memory will be saved as binary. If false, the memory is " + "saved save as an ASCII dump that uses the format, size, count and number " + "per line settings.">; + def memory_read_type : Option<"type", "t">, Groups<[3,4]>, Arg<"Name">, + Required, Desc<"The name of a type to view memory as.">; + def memory_read_language : Option<"language", "x">, Group<4>, Arg<"Language">, + Desc<"The language of the type to view memory as.">; + def memory_read_offset : Option<"offset", "E">, Group<3>, Arg<"Count">, + Desc<"How many elements of the specified type to skip before starting to " + "display data.">; + def memory_read_force : Option<"force", "r">, Groups<[1,2,3]>, + Desc<"Necessary if reading over target.max-memory-read-size bytes.">; +} + +let Command = "memory find" in { + def memory_find_expression : Option<"expression", "e">, Group<1>, + Arg<"Expression">, Required, + Desc<"Evaluate an expression to obtain a byte pattern.">; + def memory_find_string : Option<"string", "s">, Group<2>, Arg<"Name">, + Required, Desc<"Use text to find a byte pattern.">; + def memory_find_count : Option<"count", "c">, Arg<"Count">, + Desc<"How many times to perform the search.">; + def memory_find_dump_offset : Option<"dump-offset", "o">, Arg<"Offset">, + Desc<"When dumping memory for a match, an offset from the match location to" + " start dumping from.">; +} + +let Command = "memory write" in { + def memory_write_infile : Option<"infile", "i">, Group<1>, Arg<"Filename">, + Required, Desc<"Write memory using the contents of a file.">; + def memory_write_offset : Option<"offset", "o">, Group<1>, Arg<"Offset">, + Desc<"Start writing bytes from an offset within the input file.">; +} + +let Command = "register read" in { + def register_read_alternate : Option<"alternate", "A">, + Desc<"Display register names using the alternate register name if there " + "is one.">; + def register_read_set : Option<"set", "s">, Group<1>, Arg<"Index">, + Desc<"Specify which register sets to dump by index.">; + def register_read_all : Option<"all", "a">, Group<2>, + Desc<"Show all register sets.">; +} + let Command = "source" in { def source_stop_on_error : Option<"stop-on-error", "e">, Arg<"Boolean">, Desc<"If true, stop executing commands on error.">;