diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpointCommand.cpp')
| -rw-r--r-- | contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpointCommand.cpp | 1204 | 
1 files changed, 540 insertions, 664 deletions
diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpointCommand.cpp index 57572c8ef144..5e4ee0ba0700 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpointCommand.cpp @@ -13,16 +13,18 @@  // Project includes  #include "CommandObjectBreakpointCommand.h"  #include "CommandObjectBreakpoint.h" +#include "lldb/Breakpoint/Breakpoint.h" +#include "lldb/Breakpoint/BreakpointIDList.h" +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Breakpoint/StoppointCallbackContext.h"  #include "lldb/Core/IOHandler.h" +#include "lldb/Core/State.h"  #include "lldb/Interpreter/CommandInterpreter.h"  #include "lldb/Interpreter/CommandReturnObject.h"  #include "lldb/Target/Target.h"  #include "lldb/Target/Thread.h" -#include "lldb/Breakpoint/BreakpointIDList.h" -#include "lldb/Breakpoint/Breakpoint.h" -#include "lldb/Breakpoint/BreakpointLocation.h" -#include "lldb/Breakpoint/StoppointCallbackContext.h" -#include "lldb/Core/State.h" + +#include "llvm/ADT/STLExtras.h"  using namespace lldb;  using namespace lldb_private; @@ -31,44 +33,75 @@ using namespace lldb_private;  // CommandObjectBreakpointCommandAdd  //------------------------------------------------------------------------- -class CommandObjectBreakpointCommandAdd : -    public CommandObjectParsed, -    public IOHandlerDelegateMultiline -{ +// FIXME: "script-type" needs to have its contents determined dynamically, so +// somebody can add a new scripting +// language to lldb and have it pickable here without having to change this +// enumeration by hand and rebuild lldb proper. + +static OptionEnumValueElement g_script_option_enumeration[4] = { +    {eScriptLanguageNone, "command", +     "Commands are in the lldb command interpreter language"}, +    {eScriptLanguagePython, "python", "Commands are in the Python language."}, +    {eSortOrderByName, "default-script", +     "Commands are in the default scripting language."}, +    {0, nullptr, nullptr}}; + +static OptionDefinition g_breakpoint_add_options[] = { +    // clang-format off +  { LLDB_OPT_SET_1,   false, "one-liner",         'o', OptionParser::eRequiredArgument, nullptr, 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, nullptr,                     0, eArgTypeBoolean,        "Specify whether breakpoint command execution should terminate on error." }, +  { LLDB_OPT_SET_ALL, false, "script-type",       's', OptionParser::eRequiredArgument, nullptr, g_script_option_enumeration, 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, 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, nullptr,                     0, eArgTypeNone,           "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, +    // clang-format on +}; + +class CommandObjectBreakpointCommandAdd : public CommandObjectParsed, +                                          public IOHandlerDelegateMultiline {  public: -    CommandObjectBreakpointCommandAdd(CommandInterpreter &interpreter) -        : CommandObjectParsed(interpreter, "add", -                              "Add LLDB commands to a breakpoint, to be executed whenever the breakpoint is hit." -                              "  If no breakpoint is specified, adds the commands to the last created breakpoint.", -                              nullptr), -          IOHandlerDelegateMultiline("DONE", IOHandlerDelegate::Completion::LLDBCommand), -          m_options(interpreter) -    { -        SetHelpLong ( -R"( +  CommandObjectBreakpointCommandAdd(CommandInterpreter &interpreter) +      : CommandObjectParsed(interpreter, "add", +                            "Add LLDB commands to a breakpoint, to be executed " +                            "whenever the breakpoint is hit." +                            "  If no breakpoint is specified, adds the " +                            "commands to the last created breakpoint.", +                            nullptr), +        IOHandlerDelegateMultiline("DONE", +                                   IOHandlerDelegate::Completion::LLDBCommand), +        m_options() { +    SetHelpLong( +        R"(  General information about entering breakpoint commands  ------------------------------------------------------ -)" "This command will prompt for commands to be executed when the specified \ +)" +        "This command will prompt for commands to be executed when the specified \  breakpoint is hit.  Each command is typed on its own line following the '> ' \ -prompt until 'DONE' is entered." R"( +prompt until 'DONE' is entered." +        R"( -)" "Syntactic errors may not be detected when initially entered, and many \ +)" +        "Syntactic errors may not be detected when initially entered, and many \  malformed commands can silently fail when executed.  If your breakpoint commands \ -do not appear to be executing, double-check the command syntax." R"( +do not appear to be executing, double-check the command syntax." +        R"( -)" "Note: You may enter any debugger command exactly as you would at the debugger \ +)" +        "Note: You may enter any debugger command exactly as you would at the debugger \  prompt.  There is no limit to the number of commands supplied, but do NOT enter \ -more than one command per line." R"( +more than one command per line." +        R"(  Special information about PYTHON breakpoint commands  ---------------------------------------------------- -)" "You may enter either one or more lines of Python, including function \ +)" +        "You may enter either one or more lines of Python, including function \  definitions or calls to functions that will have been imported by the time \  the code executes.  Single line breakpoint commands will be interpreted 'as is' \  when the breakpoint is hit.  Multiple lines of Python will be wrapped in a \ -generated function, and a call to the function will be attached to the breakpoint." R"( +generated function, and a call to the function will be attached to the breakpoint." +        R"(  This auto-generated function is passed in three arguments: @@ -78,8 +111,10 @@ This auto-generated function is passed in three arguments:      dict:   the python session dictionary hit. -)" "When specifying a python function with the --python-function option, you need \ -to supply the function name prepended by the module name:" R"( +)" +        "When specifying a python function with the --python-function option, you need \ +to supply the function name prepended by the module name:" +        R"(      --python-function myutils.breakpoint_callback @@ -88,16 +123,20 @@ The function itself must have the following prototype:  def breakpoint_callback(frame, bp_loc, dict):    # Your code goes here -)" "The arguments are the same as the arguments passed to generated functions as \ +)" +        "The arguments are the same as the arguments passed to generated functions as \  described above.  Note that the global variable 'lldb.frame' will NOT be updated when \  this function is called, so be sure to use the 'frame' argument. The 'frame' argument \  can get you to the thread via frame.GetThread(), the thread can get you to the \  process via thread.GetProcess(), and the process can get you back to the target \ -via process.GetTarget()." R"( +via process.GetTarget()." +        R"( -)" "Important Note: As Python code gets collected into functions, access to global \ +)" +        "Important Note: As Python code gets collected into functions, access to global \  variables requires explicit scoping using the 'global' keyword.  Be sure to use correct \ -Python syntax, including indentation, when entering Python breakpoint commands." R"( +Python syntax, including indentation, when entering Python breakpoint commands." +        R"(  Example Python one-line breakpoint command: @@ -142,735 +181,572 @@ Enter your Python command(s). Type 'DONE' to end.  > breakpoint_output (1)  > DONE -)" "In this case, since there is a reference to a global variable, \ +)" +        "In this case, since there is a reference to a global variable, \  'bp_count', you will also need to make sure 'bp_count' exists and is \ -initialized:" R"( +initialized:" +        R"(  (lldb) script  >>> bp_count = 0  >>> quit() -)" "Your Python code, however organized, can optionally return a value.  \ +)" +        "Your Python code, however organized, can optionally return a value.  \  If the returned value is False, that tells LLDB not to stop at the breakpoint \  to which the code is associated. Returning anything other than False, or even \  returning None, or even omitting a return statement entirely, will cause \ -LLDB to stop." R"( +LLDB to stop." +        R"( -)" "Final Note: A warning that no breakpoint command was generated when there \ -are no syntax errors may indicate that a function was declared but never called." -        ); +)" +        "Final Note: A warning that no breakpoint command was generated when there \ +are no syntax errors may indicate that a function was declared but never called."); -        CommandArgumentEntry arg; -        CommandArgumentData bp_id_arg; +    CommandArgumentEntry arg; +    CommandArgumentData bp_id_arg; -        // Define the first (and only) variant of this arg. -        bp_id_arg.arg_type = eArgTypeBreakpointID; -        bp_id_arg.arg_repetition = eArgRepeatOptional; +    // Define the first (and only) variant of this arg. +    bp_id_arg.arg_type = eArgTypeBreakpointID; +    bp_id_arg.arg_repetition = eArgRepeatOptional; -        // There is only one variant this argument could be; put it into the argument entry. -        arg.push_back (bp_id_arg); +    // There is only one variant this argument could be; put it into the +    // argument entry. +    arg.push_back(bp_id_arg); -        // Push the data for the first argument into the m_arguments vector. -        m_arguments.push_back (arg); -    } +    // Push the data for the first argument into the m_arguments vector. +    m_arguments.push_back(arg); +  } -    ~CommandObjectBreakpointCommandAdd() override = default; +  ~CommandObjectBreakpointCommandAdd() override = default; -    Options * -    GetOptions () override -    { -        return &m_options; -    } +  Options *GetOptions() override { return &m_options; } -    void -    IOHandlerActivated (IOHandler &io_handler) override -    { -        StreamFileSP output_sp(io_handler.GetOutputStreamFile()); -        if (output_sp) -        { -            output_sp->PutCString(g_reader_instructions); -            output_sp->Flush(); -        } +  void IOHandlerActivated(IOHandler &io_handler) override { +    StreamFileSP output_sp(io_handler.GetOutputStreamFile()); +    if (output_sp) { +      output_sp->PutCString(g_reader_instructions); +      output_sp->Flush();      } +  } -    void -    IOHandlerInputComplete (IOHandler &io_handler, std::string &line) override -    { -        io_handler.SetIsDone(true); -         -        std::vector<BreakpointOptions *> *bp_options_vec = (std::vector<BreakpointOptions *> *)io_handler.GetUserData(); -        for (BreakpointOptions *bp_options : *bp_options_vec) -        { -            if (!bp_options) -                continue; -                     -            std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData()); -            if (data_ap) -            { -                data_ap->user_source.SplitIntoLines (line.c_str(), line.size()); -                BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); -                bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp); -            } -        } +  void IOHandlerInputComplete(IOHandler &io_handler, +                              std::string &line) override { +    io_handler.SetIsDone(true); + +    std::vector<BreakpointOptions *> *bp_options_vec = +        (std::vector<BreakpointOptions *> *)io_handler.GetUserData(); +    for (BreakpointOptions *bp_options : *bp_options_vec) { +      if (!bp_options) +        continue; + +      auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>(); +      cmd_data->user_source.SplitIntoLines(line.c_str(), line.size()); +      bp_options->SetCommandDataCallback(cmd_data);      } -     -    void -    CollectDataForBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec, -                                             CommandReturnObject &result) -    { -        m_interpreter.GetLLDBCommandsFromIOHandler ("> ",           // Prompt -                                                    *this,          // IOHandlerDelegate -                                                    true,           // Run IOHandler in async mode -                                                    &bp_options_vec);    // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions +  } + +  void CollectDataForBreakpointCommandCallback( +      std::vector<BreakpointOptions *> &bp_options_vec, +      CommandReturnObject &result) { +    m_interpreter.GetLLDBCommandsFromIOHandler( +        "> ",             // Prompt +        *this,            // IOHandlerDelegate +        true,             // Run IOHandler in async mode +        &bp_options_vec); // Baton for the "io_handler" that will be passed back +                          // into our IOHandlerDelegate functions +  } + +  /// Set a one-liner as the callback for the breakpoint. +  void +  SetBreakpointCommandCallback(std::vector<BreakpointOptions *> &bp_options_vec, +                               const char *oneliner) { +    for (auto bp_options : bp_options_vec) { +      auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>(); + +      cmd_data->user_source.AppendString(oneliner); +      cmd_data->stop_on_error = m_options.m_stop_on_error; + +      bp_options->SetCommandDataCallback(cmd_data);      } -     -    /// Set a one-liner as the callback for the breakpoint. -    void  -    SetBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec, -                                  const char *oneliner) -    { -        for (auto bp_options : bp_options_vec) -        { -            std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData()); - -            // It's necessary to set both user_source and script_source to the oneliner. -            // The former is used to generate callback description (as in breakpoint command list) -            // while the latter is used for Python to interpret during the actual callback. -            data_ap->user_source.AppendString (oneliner); -            data_ap->script_source.assign (oneliner); -            data_ap->stop_on_error = m_options.m_stop_on_error; - -            BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); -            bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp); +  } + +  class CommandOptions : public Options { +  public: +    CommandOptions() +        : Options(), m_use_commands(false), m_use_script_language(false), +          m_script_language(eScriptLanguageNone), m_use_one_liner(false), +          m_one_liner(), m_function_name() {} + +    ~CommandOptions() override = default; + +    Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, +                         ExecutionContext *execution_context) override { +      Error error; +      const int short_option = m_getopt_table[option_idx].val; + +      switch (short_option) { +      case 'o': +        m_use_one_liner = true; +        m_one_liner = option_arg; +        break; + +      case 's': +        m_script_language = (lldb::ScriptLanguage)Args::StringToOptionEnum( +            option_arg, g_breakpoint_add_options[option_idx].enum_values, +            eScriptLanguageNone, error); + +        if (m_script_language == eScriptLanguagePython || +            m_script_language == eScriptLanguageDefault) { +          m_use_script_language = true; +        } else { +          m_use_script_language = false;          } +        break; + +      case 'e': { +        bool success = false; +        m_stop_on_error = Args::StringToBoolean(option_arg, false, &success); +        if (!success) +          error.SetErrorStringWithFormat( +              "invalid value for stop-on-error: \"%s\"", +              option_arg.str().c_str()); +      } break; + +      case 'F': +        m_use_one_liner = false; +        m_use_script_language = true; +        m_function_name.assign(option_arg); +        break; + +      case 'D': +        m_use_dummy = true; +        break; + +      default: +        break; +      } +      return error;      } -     -    static bool -    BreakpointOptionsCallbackFunction (void *baton, -                                       StoppointCallbackContext *context,  -                                       lldb::user_id_t break_id, -                                       lldb::user_id_t break_loc_id) -    { -        bool ret_value = true; -        if (baton == nullptr) -            return true; - -        BreakpointOptions::CommandData *data = (BreakpointOptions::CommandData *) baton; -        StringList &commands = data->user_source; -         -        if (commands.GetSize() > 0) -        { -            ExecutionContext exe_ctx (context->exe_ctx_ref); -            Target *target = exe_ctx.GetTargetPtr(); -            if (target) -            { -                CommandReturnObject result; -                Debugger &debugger = target->GetDebugger(); -                // Rig up the results secondary output stream to the debugger's, so the output will come out synchronously -                // if the debugger is set up that way. -                     -                StreamSP output_stream (debugger.GetAsyncOutputStream()); -                StreamSP error_stream (debugger.GetAsyncErrorStream()); -                result.SetImmediateOutputStream (output_stream); -                result.SetImmediateErrorStream (error_stream); -         -                CommandInterpreterRunOptions options; -                options.SetStopOnContinue(true); -                options.SetStopOnError (data->stop_on_error); -                options.SetEchoCommands (true); -                options.SetPrintResults (true); -                options.SetAddToHistory (false); - -                debugger.GetCommandInterpreter().HandleCommands (commands, -                                                                 &exe_ctx, -                                                                 options, -                                                                 result); -                result.GetImmediateOutputStream()->Flush(); -                result.GetImmediateErrorStream()->Flush(); -           } -        } -        return ret_value; -    }     - -    class CommandOptions : public Options -    { -    public: -        CommandOptions (CommandInterpreter &interpreter) : -            Options (interpreter), -            m_use_commands (false), -            m_use_script_language (false), -            m_script_language (eScriptLanguageNone), -            m_use_one_liner (false), -            m_one_liner(), -            m_function_name() -        { -        } -        ~CommandOptions() override = default; - -        Error -        SetOptionValue (uint32_t option_idx, const char *option_arg) override -        { -            Error error; -            const int short_option = m_getopt_table[option_idx].val; - -            switch (short_option) -            { -            case 'o': -                m_use_one_liner = true; -                m_one_liner = option_arg; -                break; - -            case 's': -                m_script_language = (lldb::ScriptLanguage) Args::StringToOptionEnum (option_arg,  -                                                                                     g_option_table[option_idx].enum_values,  -                                                                                     eScriptLanguageNone, -                                                                                     error); - -                if (m_script_language == eScriptLanguagePython || m_script_language == eScriptLanguageDefault) -                { -                    m_use_script_language = true; -                } -                else -                { -                    m_use_script_language = false; -                }           -                break; - -            case 'e': -                { -                    bool success = false; -                    m_stop_on_error = Args::StringToBoolean(option_arg, false, &success); -                    if (!success) -                        error.SetErrorStringWithFormat("invalid value for stop-on-error: \"%s\"", option_arg); -                } -                break; -                     -            case 'F': -                m_use_one_liner = false; -                m_use_script_language = true; -                m_function_name.assign(option_arg); -                break; - -            case 'D': -                m_use_dummy = true; -                break; - -            default: -                break; -            } -            return error; -        } - -        void -        OptionParsingStarting () override -        { -            m_use_commands = true; -            m_use_script_language = false; -            m_script_language = eScriptLanguageNone; - -            m_use_one_liner = false; -            m_stop_on_error = true; -            m_one_liner.clear(); -            m_function_name.clear(); -            m_use_dummy = false; -        } - -        const OptionDefinition* -        GetDefinitions () override -        { -            return g_option_table; -        } +    void OptionParsingStarting(ExecutionContext *execution_context) override { +      m_use_commands = true; +      m_use_script_language = false; +      m_script_language = eScriptLanguageNone; -        // Options table: Required for subclasses of Options. +      m_use_one_liner = false; +      m_stop_on_error = true; +      m_one_liner.clear(); +      m_function_name.clear(); +      m_use_dummy = false; +    } -        static OptionDefinition g_option_table[]; +    llvm::ArrayRef<OptionDefinition> GetDefinitions() override { +      return llvm::makeArrayRef(g_breakpoint_add_options); +    } -        // Instance variables to hold the values for command options. +    // Instance variables to hold the values for command options. -        bool m_use_commands; -        bool m_use_script_language; -        lldb::ScriptLanguage m_script_language; +    bool m_use_commands; +    bool m_use_script_language; +    lldb::ScriptLanguage m_script_language; -        // Instance variables to hold the values for one_liner options. -        bool m_use_one_liner; -        std::string m_one_liner; -        bool m_stop_on_error; -        std::string m_function_name; -        bool m_use_dummy; -    }; +    // Instance variables to hold the values for one_liner options. +    bool m_use_one_liner; +    std::string m_one_liner; +    bool m_stop_on_error; +    std::string m_function_name; +    bool m_use_dummy; +  };  protected: -    bool -    DoExecute (Args& command, CommandReturnObject &result) override -    { -        Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); - -        if (target == nullptr) -        { -            result.AppendError ("There is not a current executable; there are no breakpoints to which to add commands"); -            result.SetStatus (eReturnStatusFailed); -            return false; -        } +  bool DoExecute(Args &command, CommandReturnObject &result) override { +    Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); + +    if (target == nullptr) { +      result.AppendError("There is not a current executable; there are no " +                         "breakpoints to which to add commands"); +      result.SetStatus(eReturnStatusFailed); +      return false; +    } -        const BreakpointList &breakpoints = target->GetBreakpointList(); -        size_t num_breakpoints = breakpoints.GetSize(); +    const BreakpointList &breakpoints = target->GetBreakpointList(); +    size_t num_breakpoints = breakpoints.GetSize(); -        if (num_breakpoints == 0) -        { -            result.AppendError ("No breakpoints exist to have commands added"); -            result.SetStatus (eReturnStatusFailed); -            return false; -        } +    if (num_breakpoints == 0) { +      result.AppendError("No breakpoints exist to have commands added"); +      result.SetStatus(eReturnStatusFailed); +      return false; +    } -        if (!m_options.m_use_script_language && !m_options.m_function_name.empty()) -        { -            result.AppendError ("need to enable scripting to have a function run as a breakpoint command"); -            result.SetStatus (eReturnStatusFailed); -            return false; -        } -         -        BreakpointIDList valid_bp_ids; -        CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); - -        m_bp_options_vec.clear(); -         -        if (result.Succeeded()) -        { -            const size_t count = valid_bp_ids.GetSize(); -             -            for (size_t i = 0; i < count; ++i) -            { -                BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); -                if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) -                { -                    Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); -                    BreakpointOptions *bp_options = nullptr; -                    if (cur_bp_id.GetLocationID() == LLDB_INVALID_BREAK_ID) -                    { -                        // This breakpoint does not have an associated location. -                        bp_options = bp->GetOptions(); -                    } -                    else                     -                    { -                        BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID())); -                        // This breakpoint does have an associated location. -                        // Get its breakpoint options. -                        if (bp_loc_sp) -                            bp_options = bp_loc_sp->GetLocationOptions(); -                    } -                    if (bp_options) -                        m_bp_options_vec.push_back (bp_options); -                } -            } +    if (!m_options.m_use_script_language && +        !m_options.m_function_name.empty()) { +      result.AppendError("need to enable scripting to have a function run as a " +                         "breakpoint command"); +      result.SetStatus(eReturnStatusFailed); +      return false; +    } -            // If we are using script language, get the script interpreter -            // in order to set or collect command callback.  Otherwise, call -            // the methods associated with this object. -            if (m_options.m_use_script_language) -            { -                ScriptInterpreter *script_interp = m_interpreter.GetScriptInterpreter(); -                // Special handling for one-liner specified inline. -                if (m_options.m_use_one_liner) -                { -                    script_interp->SetBreakpointCommandCallback (m_bp_options_vec, -                                                                 m_options.m_one_liner.c_str()); -                } -                else if (!m_options.m_function_name.empty()) -                { -                    script_interp->SetBreakpointCommandCallbackFunction (m_bp_options_vec, -                                                                         m_options.m_function_name.c_str()); -                } -                else -                { -                    script_interp->CollectDataForBreakpointCommandCallback (m_bp_options_vec, -                                                                            result); -                } -            } -            else -            { -                // Special handling for one-liner specified inline. -                if (m_options.m_use_one_liner) -                    SetBreakpointCommandCallback (m_bp_options_vec, -                                                  m_options.m_one_liner.c_str()); -                else -                    CollectDataForBreakpointCommandCallback (m_bp_options_vec, -                                                             result); -            } +    BreakpointIDList valid_bp_ids; +    CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( +        command, target, result, &valid_bp_ids); + +    m_bp_options_vec.clear(); + +    if (result.Succeeded()) { +      const size_t count = valid_bp_ids.GetSize(); + +      for (size_t i = 0; i < count; ++i) { +        BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); +        if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { +          Breakpoint *bp = +              target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); +          BreakpointOptions *bp_options = nullptr; +          if (cur_bp_id.GetLocationID() == LLDB_INVALID_BREAK_ID) { +            // This breakpoint does not have an associated location. +            bp_options = bp->GetOptions(); +          } else { +            BreakpointLocationSP bp_loc_sp( +                bp->FindLocationByID(cur_bp_id.GetLocationID())); +            // This breakpoint does have an associated location. +            // Get its breakpoint options. +            if (bp_loc_sp) +              bp_options = bp_loc_sp->GetLocationOptions(); +          } +          if (bp_options) +            m_bp_options_vec.push_back(bp_options);          } - -        return result.Succeeded(); +      } + +      // If we are using script language, get the script interpreter +      // in order to set or collect command callback.  Otherwise, call +      // the methods associated with this object. +      if (m_options.m_use_script_language) { +        ScriptInterpreter *script_interp = m_interpreter.GetScriptInterpreter(); +        // Special handling for one-liner specified inline. +        if (m_options.m_use_one_liner) { +          script_interp->SetBreakpointCommandCallback( +              m_bp_options_vec, m_options.m_one_liner.c_str()); +        } else if (!m_options.m_function_name.empty()) { +          script_interp->SetBreakpointCommandCallbackFunction( +              m_bp_options_vec, m_options.m_function_name.c_str()); +        } else { +          script_interp->CollectDataForBreakpointCommandCallback( +              m_bp_options_vec, result); +        } +      } else { +        // Special handling for one-liner specified inline. +        if (m_options.m_use_one_liner) +          SetBreakpointCommandCallback(m_bp_options_vec, +                                       m_options.m_one_liner.c_str()); +        else +          CollectDataForBreakpointCommandCallback(m_bp_options_vec, result); +      }      } -private: -    CommandOptions m_options; -    std::vector<BreakpointOptions *> m_bp_options_vec;  // This stores the breakpoint options that we are currently -                                                        // collecting commands for.  In the CollectData... calls we need -                                                        // to hand this off to the IOHandler, which may run asynchronously. -                                                        // So we have to have some way to keep it alive, and not leak it. -                                                        // Making it an ivar of the command object, which never goes away -                                                        // achieves this.  Note that if we were able to run -                                                        // the same command concurrently in one interpreter we'd have to -                                                        // make this "per invocation".  But there are many more reasons -                                                        // why it is not in general safe to do that in lldb at present, -                                                        // so it isn't worthwhile to come up with a more complex mechanism -                                                        // to address this particular weakness right now. -    static const char *g_reader_instructions; -}; - -const char * -CommandObjectBreakpointCommandAdd::g_reader_instructions = "Enter your debugger command(s).  Type 'DONE' to end.\n"; +    return result.Succeeded(); +  } -// FIXME: "script-type" needs to have its contents determined dynamically, so somebody can add a new scripting -// language to lldb and have it pickable here without having to change this enumeration by hand and rebuild lldb proper. - -static OptionEnumValueElement -g_script_option_enumeration[4] = -{ -    { eScriptLanguageNone,    "command",         "Commands are in the lldb command interpreter language"}, -    { eScriptLanguagePython,  "python",          "Commands are in the Python language."}, -    { eSortOrderByName,       "default-script",  "Commands are in the default scripting language."}, -    { 0,                      nullptr,           nullptr } +private: +  CommandOptions m_options; +  std::vector<BreakpointOptions *> m_bp_options_vec; // This stores the +                                                     // breakpoint options that +                                                     // we are currently +  // collecting commands for.  In the CollectData... calls we need +  // to hand this off to the IOHandler, which may run asynchronously. +  // So we have to have some way to keep it alive, and not leak it. +  // Making it an ivar of the command object, which never goes away +  // achieves this.  Note that if we were able to run +  // the same command concurrently in one interpreter we'd have to +  // make this "per invocation".  But there are many more reasons +  // why it is not in general safe to do that in lldb at present, +  // so it isn't worthwhile to come up with a more complex mechanism +  // to address this particular weakness right now. +  static const char *g_reader_instructions;  }; -OptionDefinition -CommandObjectBreakpointCommandAdd::CommandOptions::g_option_table[] = -{ -    { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, 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, nullptr, 0, eArgTypeBoolean, -        "Specify whether breakpoint command execution should terminate on error." }, - -    { LLDB_OPT_SET_ALL,   false, "script-type",     's', OptionParser::eRequiredArgument, nullptr, g_script_option_enumeration, 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, 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, nullptr, 0, eArgTypeNone, -        "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, - -    { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } -}; +const char *CommandObjectBreakpointCommandAdd::g_reader_instructions = +    "Enter your debugger command(s).  Type 'DONE' to end.\n";  //-------------------------------------------------------------------------  // CommandObjectBreakpointCommandDelete  //------------------------------------------------------------------------- -class CommandObjectBreakpointCommandDelete : public CommandObjectParsed -{ +static OptionDefinition g_breakpoint_delete_options[] = { +    // clang-format off +  { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, +    // clang-format on +}; + +class CommandObjectBreakpointCommandDelete : public CommandObjectParsed {  public: -    CommandObjectBreakpointCommandDelete (CommandInterpreter &interpreter) : -        CommandObjectParsed(interpreter, -                            "delete", +  CommandObjectBreakpointCommandDelete(CommandInterpreter &interpreter) +      : CommandObjectParsed(interpreter, "delete",                              "Delete the set of commands from a breakpoint.",                              nullptr), -        m_options (interpreter) -    { -        CommandArgumentEntry arg; -        CommandArgumentData bp_id_arg; - -        // Define the first (and only) variant of this arg. -        bp_id_arg.arg_type = eArgTypeBreakpointID; -        bp_id_arg.arg_repetition = eArgRepeatPlain; - -        // There is only one variant this argument could be; put it into the argument entry. -        arg.push_back (bp_id_arg); +        m_options() { +    CommandArgumentEntry arg; +    CommandArgumentData bp_id_arg; -        // Push the data for the first argument into the m_arguments vector. -        m_arguments.push_back (arg); -    } +    // Define the first (and only) variant of this arg. +    bp_id_arg.arg_type = eArgTypeBreakpointID; +    bp_id_arg.arg_repetition = eArgRepeatPlain; -    ~CommandObjectBreakpointCommandDelete() override = default; +    // There is only one variant this argument could be; put it into the +    // argument entry. +    arg.push_back(bp_id_arg); -    Options * -    GetOptions () override -    { -        return &m_options; -    } +    // Push the data for the first argument into the m_arguments vector. +    m_arguments.push_back(arg); +  } -    class CommandOptions : public Options -    { -    public: -        CommandOptions (CommandInterpreter &interpreter) : -            Options (interpreter), -            m_use_dummy (false) -        { -        } +  ~CommandObjectBreakpointCommandDelete() override = default; -        ~CommandOptions() override = default; +  Options *GetOptions() override { return &m_options; } -        Error -        SetOptionValue (uint32_t option_idx, const char *option_arg) override -        { -            Error error; -            const int short_option = m_getopt_table[option_idx].val; +  class CommandOptions : public Options { +  public: +    CommandOptions() : Options(), m_use_dummy(false) {} -            switch (short_option) -            { -                case 'D': -                    m_use_dummy = true; -                    break; +    ~CommandOptions() override = default; -                default: -                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); -                    break; -            } +    Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, +                         ExecutionContext *execution_context) override { +      Error error; +      const int short_option = m_getopt_table[option_idx].val; -            return error; -        } +      switch (short_option) { +      case 'D': +        m_use_dummy = true; +        break; -        void -        OptionParsingStarting () override -        { -            m_use_dummy = false; -        } +      default: +        error.SetErrorStringWithFormat("unrecognized option '%c'", +                                       short_option); +        break; +      } -        const OptionDefinition* -        GetDefinitions () override -        { -            return g_option_table; -        } +      return error; +    } -        // Options table: Required for subclasses of Options. +    void OptionParsingStarting(ExecutionContext *execution_context) override { +      m_use_dummy = false; +    } -        static OptionDefinition g_option_table[]; +    llvm::ArrayRef<OptionDefinition> GetDefinitions() override { +      return llvm::makeArrayRef(g_breakpoint_delete_options); +    } -        // Instance variables to hold the values for command options. -        bool m_use_dummy; -    }; +    // Instance variables to hold the values for command options. +    bool m_use_dummy; +  };  protected: -    bool -    DoExecute (Args& command, CommandReturnObject &result) override -    { -        Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); - -        if (target == nullptr) -        { -            result.AppendError ("There is not a current executable; there are no breakpoints from which to delete commands"); -            result.SetStatus (eReturnStatusFailed); -            return false; -        } +  bool DoExecute(Args &command, CommandReturnObject &result) override { +    Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); + +    if (target == nullptr) { +      result.AppendError("There is not a current executable; there are no " +                         "breakpoints from which to delete commands"); +      result.SetStatus(eReturnStatusFailed); +      return false; +    } -        const BreakpointList &breakpoints = target->GetBreakpointList(); -        size_t num_breakpoints = breakpoints.GetSize(); +    const BreakpointList &breakpoints = target->GetBreakpointList(); +    size_t num_breakpoints = breakpoints.GetSize(); -        if (num_breakpoints == 0) -        { -            result.AppendError ("No breakpoints exist to have commands deleted"); -            result.SetStatus (eReturnStatusFailed); -            return false; -        } +    if (num_breakpoints == 0) { +      result.AppendError("No breakpoints exist to have commands deleted"); +      result.SetStatus(eReturnStatusFailed); +      return false; +    } -        if (command.GetArgumentCount() == 0) -        { -            result.AppendError ("No breakpoint specified from which to delete the commands"); -            result.SetStatus (eReturnStatusFailed); -            return false; -        } +    if (command.empty()) { +      result.AppendError( +          "No breakpoint specified from which to delete the commands"); +      result.SetStatus(eReturnStatusFailed); +      return false; +    } -        BreakpointIDList valid_bp_ids; -        CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); - -        if (result.Succeeded()) -        { -            const size_t count = valid_bp_ids.GetSize(); -            for (size_t i = 0; i < count; ++i) -            { -                BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); -                if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) -                { -                    Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); -                    if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) -                    { -                        BreakpointLocationSP bp_loc_sp (bp->FindLocationByID (cur_bp_id.GetLocationID())); -                        if (bp_loc_sp) -                            bp_loc_sp->ClearCallback(); -                        else -                        { -                            result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n",  -                                                         cur_bp_id.GetBreakpointID(), -                                                         cur_bp_id.GetLocationID()); -                            result.SetStatus (eReturnStatusFailed); -                            return false; -                        } -                    } -                    else -                    { -                        bp->ClearCallback(); -                    } -                } +    BreakpointIDList valid_bp_ids; +    CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( +        command, target, result, &valid_bp_ids); + +    if (result.Succeeded()) { +      const size_t count = valid_bp_ids.GetSize(); +      for (size_t i = 0; i < count; ++i) { +        BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); +        if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { +          Breakpoint *bp = +              target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); +          if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { +            BreakpointLocationSP bp_loc_sp( +                bp->FindLocationByID(cur_bp_id.GetLocationID())); +            if (bp_loc_sp) +              bp_loc_sp->ClearCallback(); +            else { +              result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n", +                                           cur_bp_id.GetBreakpointID(), +                                           cur_bp_id.GetLocationID()); +              result.SetStatus(eReturnStatusFailed); +              return false;              } +          } else { +            bp->ClearCallback(); +          }          } -        return result.Succeeded(); +      }      } +    return result.Succeeded(); +  }  private: -    CommandOptions m_options; -}; - -OptionDefinition -CommandObjectBreakpointCommandDelete::CommandOptions::g_option_table[] = -{ -    { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, -        "Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, - -    { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } +  CommandOptions m_options;  };  //-------------------------------------------------------------------------  // CommandObjectBreakpointCommandList  //------------------------------------------------------------------------- -class CommandObjectBreakpointCommandList : public CommandObjectParsed -{ +class CommandObjectBreakpointCommandList : public CommandObjectParsed {  public: -    CommandObjectBreakpointCommandList (CommandInterpreter &interpreter) : -        CommandObjectParsed(interpreter, -                            "list", -                            "List the script or set of commands to be executed when the breakpoint is hit.", -                            nullptr) -    { -        CommandArgumentEntry arg; -        CommandArgumentData bp_id_arg; - -        // Define the first (and only) variant of this arg. -        bp_id_arg.arg_type = eArgTypeBreakpointID; -        bp_id_arg.arg_repetition = eArgRepeatPlain; - -        // There is only one variant this argument could be; put it into the argument entry. -        arg.push_back (bp_id_arg); - -        // Push the data for the first argument into the m_arguments vector. -        m_arguments.push_back (arg); -    } +  CommandObjectBreakpointCommandList(CommandInterpreter &interpreter) +      : CommandObjectParsed(interpreter, "list", "List the script or set of " +                                                 "commands to be executed when " +                                                 "the breakpoint is hit.", +                            nullptr) { +    CommandArgumentEntry arg; +    CommandArgumentData bp_id_arg; + +    // Define the first (and only) variant of this arg. +    bp_id_arg.arg_type = eArgTypeBreakpointID; +    bp_id_arg.arg_repetition = eArgRepeatPlain; + +    // There is only one variant this argument could be; put it into the +    // argument entry. +    arg.push_back(bp_id_arg); -    ~CommandObjectBreakpointCommandList() override = default; +    // Push the data for the first argument into the m_arguments vector. +    m_arguments.push_back(arg); +  } + +  ~CommandObjectBreakpointCommandList() override = default;  protected: -    bool -    DoExecute (Args& command, -             CommandReturnObject &result) override -    { -        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - -        if (target == nullptr) -        { -            result.AppendError ("There is not a current executable; there are no breakpoints for which to list commands"); -            result.SetStatus (eReturnStatusFailed); -            return false; -        } +  bool DoExecute(Args &command, CommandReturnObject &result) override { +    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + +    if (target == nullptr) { +      result.AppendError("There is not a current executable; there are no " +                         "breakpoints for which to list commands"); +      result.SetStatus(eReturnStatusFailed); +      return false; +    } -        const BreakpointList &breakpoints = target->GetBreakpointList(); -        size_t num_breakpoints = breakpoints.GetSize(); +    const BreakpointList &breakpoints = target->GetBreakpointList(); +    size_t num_breakpoints = breakpoints.GetSize(); -        if (num_breakpoints == 0) -        { -            result.AppendError ("No breakpoints exist for which to list commands"); -            result.SetStatus (eReturnStatusFailed); -            return false; -        } +    if (num_breakpoints == 0) { +      result.AppendError("No breakpoints exist for which to list commands"); +      result.SetStatus(eReturnStatusFailed); +      return false; +    } -        if (command.GetArgumentCount() == 0) -        { -            result.AppendError ("No breakpoint specified for which to list the commands"); -            result.SetStatus (eReturnStatusFailed); -            return false; -        } +    if (command.empty()) { +      result.AppendError( +          "No breakpoint specified for which to list the commands"); +      result.SetStatus(eReturnStatusFailed); +      return false; +    } -        BreakpointIDList valid_bp_ids; -        CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids); - -        if (result.Succeeded()) -        { -            const size_t count = valid_bp_ids.GetSize(); -            for (size_t i = 0; i < count; ++i) -            { -                BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i); -                if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) -                { -                    Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get(); -                     -                    if (bp) -                    { -                        const BreakpointOptions *bp_options = nullptr; -                        if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) -                        { -                            BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID())); -                            if (bp_loc_sp) -                                bp_options = bp_loc_sp->GetOptionsNoCreate(); -                            else -                            { -                                result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n",  -                                                             cur_bp_id.GetBreakpointID(), -                                                             cur_bp_id.GetLocationID()); -                                result.SetStatus (eReturnStatusFailed); -                                return false; -                            } -                        } -                        else -                        { -                            bp_options = bp->GetOptions(); -                        } - -                        if (bp_options) -                        { -                            StreamString id_str; -                            BreakpointID::GetCanonicalReference (&id_str,  -                                                                 cur_bp_id.GetBreakpointID(),  -                                                                 cur_bp_id.GetLocationID()); -                            const Baton *baton = bp_options->GetBaton(); -                            if (baton) -                            { -                                result.GetOutputStream().Printf ("Breakpoint %s:\n", id_str.GetData()); -                                result.GetOutputStream().IndentMore (); -                                baton->GetDescription(&result.GetOutputStream(), eDescriptionLevelFull); -                                result.GetOutputStream().IndentLess (); -                            } -                            else -                            { -                                result.AppendMessageWithFormat ("Breakpoint %s does not have an associated command.\n",  -                                                                id_str.GetData()); -                            } -                        } -                        result.SetStatus (eReturnStatusSuccessFinishResult); -                    } -                    else -                    { -                        result.AppendErrorWithFormat("Invalid breakpoint ID: %u.\n", cur_bp_id.GetBreakpointID()); -                        result.SetStatus (eReturnStatusFailed); -                    } -                } +    BreakpointIDList valid_bp_ids; +    CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( +        command, target, result, &valid_bp_ids); + +    if (result.Succeeded()) { +      const size_t count = valid_bp_ids.GetSize(); +      for (size_t i = 0; i < count; ++i) { +        BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); +        if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { +          Breakpoint *bp = +              target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); + +          if (bp) { +            const BreakpointOptions *bp_options = nullptr; +            if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { +              BreakpointLocationSP bp_loc_sp( +                  bp->FindLocationByID(cur_bp_id.GetLocationID())); +              if (bp_loc_sp) +                bp_options = bp_loc_sp->GetOptionsNoCreate(); +              else { +                result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n", +                                             cur_bp_id.GetBreakpointID(), +                                             cur_bp_id.GetLocationID()); +                result.SetStatus(eReturnStatusFailed); +                return false; +              } +            } else { +              bp_options = bp->GetOptions();              } -        } -        return result.Succeeded(); +            if (bp_options) { +              StreamString id_str; +              BreakpointID::GetCanonicalReference(&id_str, +                                                  cur_bp_id.GetBreakpointID(), +                                                  cur_bp_id.GetLocationID()); +              const Baton *baton = bp_options->GetBaton(); +              if (baton) { +                result.GetOutputStream().Printf("Breakpoint %s:\n", +                                                id_str.GetData()); +                result.GetOutputStream().IndentMore(); +                baton->GetDescription(&result.GetOutputStream(), +                                      eDescriptionLevelFull); +                result.GetOutputStream().IndentLess(); +              } else { +                result.AppendMessageWithFormat( +                    "Breakpoint %s does not have an associated command.\n", +                    id_str.GetData()); +              } +            } +            result.SetStatus(eReturnStatusSuccessFinishResult); +          } else { +            result.AppendErrorWithFormat("Invalid breakpoint ID: %u.\n", +                                         cur_bp_id.GetBreakpointID()); +            result.SetStatus(eReturnStatusFailed); +          } +        } +      }      } + +    return result.Succeeded(); +  }  };  //-------------------------------------------------------------------------  // CommandObjectBreakpointCommand  //------------------------------------------------------------------------- -CommandObjectBreakpointCommand::CommandObjectBreakpointCommand(CommandInterpreter &interpreter) +CommandObjectBreakpointCommand::CommandObjectBreakpointCommand( +    CommandInterpreter &interpreter)      : CommandObjectMultiword( -          interpreter, "command", -          "Commands for adding, removing and listing LLDB commands executed when a breakpoint is hit.", -          "command <sub-command> [<sub-command-options>] <breakpoint-id>") -{ -    CommandObjectSP add_command_object (new CommandObjectBreakpointCommandAdd (interpreter)); -    CommandObjectSP delete_command_object (new CommandObjectBreakpointCommandDelete (interpreter)); -    CommandObjectSP list_command_object (new CommandObjectBreakpointCommandList (interpreter)); - -    add_command_object->SetCommandName ("breakpoint command add"); -    delete_command_object->SetCommandName ("breakpoint command delete"); -    list_command_object->SetCommandName ("breakpoint command list"); - -    LoadSubCommand ("add",    add_command_object); -    LoadSubCommand ("delete", delete_command_object); -    LoadSubCommand ("list",   list_command_object); +          interpreter, "command", "Commands for adding, removing and listing " +                                  "LLDB commands executed when a breakpoint is " +                                  "hit.", +          "command <sub-command> [<sub-command-options>] <breakpoint-id>") { +  CommandObjectSP add_command_object( +      new CommandObjectBreakpointCommandAdd(interpreter)); +  CommandObjectSP delete_command_object( +      new CommandObjectBreakpointCommandDelete(interpreter)); +  CommandObjectSP list_command_object( +      new CommandObjectBreakpointCommandList(interpreter)); + +  add_command_object->SetCommandName("breakpoint command add"); +  delete_command_object->SetCommandName("breakpoint command delete"); +  list_command_object->SetCommandName("breakpoint command list"); + +  LoadSubCommand("add", add_command_object); +  LoadSubCommand("delete", delete_command_object); +  LoadSubCommand("list", list_command_object);  }  CommandObjectBreakpointCommand::~CommandObjectBreakpointCommand() = default;  | 
