130fdc8d8SChris Lattner //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner 
99e85e5a8SEugene Zelenko #include "CommandObjectBreakpoint.h"
109e85e5a8SEugene Zelenko #include "CommandObjectBreakpointCommand.h"
1130fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h"
1230fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointIDList.h"
1330fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h"
143eb2b44dSZachary Turner #include "lldb/Host/OptionParser.h"
15b9c1b51eSKate Stone #include "lldb/Interpreter/CommandCompletions.h"
16b9c1b51eSKate Stone #include "lldb/Interpreter/CommandInterpreter.h"
17b9c1b51eSKate Stone #include "lldb/Interpreter/CommandReturnObject.h"
1847cbf4a0SPavel Labath #include "lldb/Interpreter/OptionArgParser.h"
19943a2481SJim Ingham #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
2032abc6edSZachary Turner #include "lldb/Interpreter/OptionValueBoolean.h"
215e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueString.h"
225e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueUInt64.h"
23b9c1b51eSKate Stone #include "lldb/Interpreter/Options.h"
240e0984eeSJim Ingham #include "lldb/Target/Language.h"
25b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h"
26b9c1b51eSKate Stone #include "lldb/Target/Target.h"
271b54c88cSJim Ingham #include "lldb/Target/Thread.h"
281b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h"
29bf9a7730SZachary Turner #include "lldb/Utility/RegularExpression.h"
30bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
3130fdc8d8SChris Lattner 
32796ac80bSJonas Devlieghere #include <memory>
33796ac80bSJonas Devlieghere #include <vector>
34796ac80bSJonas Devlieghere 
3530fdc8d8SChris Lattner using namespace lldb;
3630fdc8d8SChris Lattner using namespace lldb_private;
3730fdc8d8SChris Lattner 
38b9c1b51eSKate Stone static void AddBreakpointDescription(Stream *s, Breakpoint *bp,
39b9c1b51eSKate Stone                                      lldb::DescriptionLevel level) {
4030fdc8d8SChris Lattner   s->IndentMore();
4130fdc8d8SChris Lattner   bp->GetDescription(s, level, true);
4230fdc8d8SChris Lattner   s->IndentLess();
4330fdc8d8SChris Lattner   s->EOL();
4430fdc8d8SChris Lattner }
4530fdc8d8SChris Lattner 
46b842f2ecSJim Ingham // Modifiable Breakpoint Options
47b842f2ecSJim Ingham #pragma mark Modify::CommandOptions
48f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_modify
49f94668e3SRaphael Isemann #include "CommandOptions.inc"
50bd68a052SRaphael Isemann 
51*a925974bSAdrian Prantl class lldb_private::BreakpointOptionGroup : public OptionGroup {
52b842f2ecSJim Ingham public:
53*a925974bSAdrian Prantl   BreakpointOptionGroup() : OptionGroup(), m_bp_opts(false) {}
54b842f2ecSJim Ingham 
55b842f2ecSJim Ingham   ~BreakpointOptionGroup() override = default;
56b842f2ecSJim Ingham 
57b842f2ecSJim Ingham   llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
58b842f2ecSJim Ingham     return llvm::makeArrayRef(g_breakpoint_modify_options);
59b842f2ecSJim Ingham   }
60b842f2ecSJim Ingham 
61b842f2ecSJim Ingham   Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
62b842f2ecSJim Ingham                         ExecutionContext *execution_context) override {
63b842f2ecSJim Ingham     Status error;
64*a925974bSAdrian Prantl     const int short_option =
65*a925974bSAdrian Prantl         g_breakpoint_modify_options[option_idx].short_option;
66b842f2ecSJim Ingham 
67b842f2ecSJim Ingham     switch (short_option) {
68b842f2ecSJim Ingham     case 'c':
6905097246SAdrian Prantl       // Normally an empty breakpoint condition marks is as unset. But we need
7005097246SAdrian Prantl       // to say it was passed in.
71b842f2ecSJim Ingham       m_bp_opts.SetCondition(option_arg.str().c_str());
72b842f2ecSJim Ingham       m_bp_opts.m_set_flags.Set(BreakpointOptions::eCondition);
73b842f2ecSJim Ingham       break;
74b842f2ecSJim Ingham     case 'C':
75b842f2ecSJim Ingham       m_commands.push_back(option_arg);
76b842f2ecSJim Ingham       break;
77b842f2ecSJim Ingham     case 'd':
78b842f2ecSJim Ingham       m_bp_opts.SetEnabled(false);
79b842f2ecSJim Ingham       break;
80b842f2ecSJim Ingham     case 'e':
81b842f2ecSJim Ingham       m_bp_opts.SetEnabled(true);
82b842f2ecSJim Ingham       break;
83b842f2ecSJim Ingham     case 'G': {
84b842f2ecSJim Ingham       bool value, success;
8547cbf4a0SPavel Labath       value = OptionArgParser::ToBoolean(option_arg, false, &success);
86b842f2ecSJim Ingham       if (success) {
87b842f2ecSJim Ingham         m_bp_opts.SetAutoContinue(value);
88b842f2ecSJim Ingham       } else
89b842f2ecSJim Ingham         error.SetErrorStringWithFormat(
90b842f2ecSJim Ingham             "invalid boolean value '%s' passed for -G option",
91b842f2ecSJim Ingham             option_arg.str().c_str());
92*a925974bSAdrian Prantl     } break;
93*a925974bSAdrian Prantl     case 'i': {
94b842f2ecSJim Ingham       uint32_t ignore_count;
95b842f2ecSJim Ingham       if (option_arg.getAsInteger(0, ignore_count))
96b842f2ecSJim Ingham         error.SetErrorStringWithFormat("invalid ignore count '%s'",
97b842f2ecSJim Ingham                                        option_arg.str().c_str());
98b842f2ecSJim Ingham       else
99b842f2ecSJim Ingham         m_bp_opts.SetIgnoreCount(ignore_count);
100*a925974bSAdrian Prantl     } break;
101b842f2ecSJim Ingham     case 'o': {
102b842f2ecSJim Ingham       bool value, success;
10347cbf4a0SPavel Labath       value = OptionArgParser::ToBoolean(option_arg, false, &success);
104b842f2ecSJim Ingham       if (success) {
105b842f2ecSJim Ingham         m_bp_opts.SetOneShot(value);
106b842f2ecSJim Ingham       } else
107b842f2ecSJim Ingham         error.SetErrorStringWithFormat(
108b842f2ecSJim Ingham             "invalid boolean value '%s' passed for -o option",
109b842f2ecSJim Ingham             option_arg.str().c_str());
110b842f2ecSJim Ingham     } break;
111*a925974bSAdrian Prantl     case 't': {
112b842f2ecSJim Ingham       lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID;
113b842f2ecSJim Ingham       if (option_arg[0] != '\0') {
114b842f2ecSJim Ingham         if (option_arg.getAsInteger(0, thread_id))
115b842f2ecSJim Ingham           error.SetErrorStringWithFormat("invalid thread id string '%s'",
116b842f2ecSJim Ingham                                          option_arg.str().c_str());
117b842f2ecSJim Ingham       }
118b842f2ecSJim Ingham       m_bp_opts.SetThreadID(thread_id);
119*a925974bSAdrian Prantl     } break;
120b842f2ecSJim Ingham     case 'T':
121b842f2ecSJim Ingham       m_bp_opts.GetThreadSpec()->SetName(option_arg.str().c_str());
122b842f2ecSJim Ingham       break;
123b842f2ecSJim Ingham     case 'q':
124b842f2ecSJim Ingham       m_bp_opts.GetThreadSpec()->SetQueueName(option_arg.str().c_str());
125b842f2ecSJim Ingham       break;
126*a925974bSAdrian Prantl     case 'x': {
127b842f2ecSJim Ingham       uint32_t thread_index = UINT32_MAX;
128b842f2ecSJim Ingham       if (option_arg[0] != '\n') {
129b842f2ecSJim Ingham         if (option_arg.getAsInteger(0, thread_index))
130b842f2ecSJim Ingham           error.SetErrorStringWithFormat("invalid thread index string '%s'",
131b842f2ecSJim Ingham                                          option_arg.str().c_str());
132b842f2ecSJim Ingham       }
133b842f2ecSJim Ingham       m_bp_opts.GetThreadSpec()->SetIndex(thread_index);
134*a925974bSAdrian Prantl     } break;
135b842f2ecSJim Ingham     default:
13636162014SRaphael Isemann       llvm_unreachable("Unimplemented option");
137b842f2ecSJim Ingham     }
138b842f2ecSJim Ingham 
139b842f2ecSJim Ingham     return error;
140b842f2ecSJim Ingham   }
141b842f2ecSJim Ingham 
142b842f2ecSJim Ingham   void OptionParsingStarting(ExecutionContext *execution_context) override {
143b842f2ecSJim Ingham     m_bp_opts.Clear();
144b842f2ecSJim Ingham     m_commands.clear();
145b842f2ecSJim Ingham   }
146b842f2ecSJim Ingham 
147b842f2ecSJim Ingham   Status OptionParsingFinished(ExecutionContext *execution_context) override {
148*a925974bSAdrian Prantl     if (!m_commands.empty()) {
149*a925974bSAdrian Prantl       if (!m_commands.empty()) {
150a8f3ae7cSJonas Devlieghere         auto cmd_data = std::make_unique<BreakpointOptions::CommandData>();
151b842f2ecSJim Ingham 
152b842f2ecSJim Ingham         for (std::string &str : m_commands)
153b842f2ecSJim Ingham           cmd_data->user_source.AppendString(str);
154b842f2ecSJim Ingham 
155b842f2ecSJim Ingham         cmd_data->stop_on_error = true;
156b842f2ecSJim Ingham         m_bp_opts.SetCommandDataCallback(cmd_data);
157b842f2ecSJim Ingham       }
158b842f2ecSJim Ingham     }
159b842f2ecSJim Ingham     return Status();
160b842f2ecSJim Ingham   }
161b842f2ecSJim Ingham 
162*a925974bSAdrian Prantl   const BreakpointOptions &GetBreakpointOptions() { return m_bp_opts; }
163b842f2ecSJim Ingham 
164b842f2ecSJim Ingham   std::vector<std::string> m_commands;
165b842f2ecSJim Ingham   BreakpointOptions m_bp_opts;
166b842f2ecSJim Ingham };
167bd68a052SRaphael Isemann 
168f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_dummy
169f94668e3SRaphael Isemann #include "CommandOptions.inc"
170b842f2ecSJim Ingham 
171*a925974bSAdrian Prantl class BreakpointDummyOptionGroup : public OptionGroup {
172b842f2ecSJim Ingham public:
173*a925974bSAdrian Prantl   BreakpointDummyOptionGroup() : OptionGroup() {}
174b842f2ecSJim Ingham 
175b842f2ecSJim Ingham   ~BreakpointDummyOptionGroup() override = default;
176b842f2ecSJim Ingham 
177b842f2ecSJim Ingham   llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
178b842f2ecSJim Ingham     return llvm::makeArrayRef(g_breakpoint_dummy_options);
179b842f2ecSJim Ingham   }
180b842f2ecSJim Ingham 
181b842f2ecSJim Ingham   Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
182b842f2ecSJim Ingham                         ExecutionContext *execution_context) override {
183b842f2ecSJim Ingham     Status error;
184*a925974bSAdrian Prantl     const int short_option =
185*a925974bSAdrian Prantl         g_breakpoint_modify_options[option_idx].short_option;
186b842f2ecSJim Ingham 
187b842f2ecSJim Ingham     switch (short_option) {
188b842f2ecSJim Ingham     case 'D':
189b842f2ecSJim Ingham       m_use_dummy = true;
190b842f2ecSJim Ingham       break;
191b842f2ecSJim Ingham     default:
19236162014SRaphael Isemann       llvm_unreachable("Unimplemented option");
193b842f2ecSJim Ingham     }
194b842f2ecSJim Ingham 
195b842f2ecSJim Ingham     return error;
196b842f2ecSJim Ingham   }
197b842f2ecSJim Ingham 
198b842f2ecSJim Ingham   void OptionParsingStarting(ExecutionContext *execution_context) override {
199b842f2ecSJim Ingham     m_use_dummy = false;
200b842f2ecSJim Ingham   }
201b842f2ecSJim Ingham 
202b842f2ecSJim Ingham   bool m_use_dummy;
203b842f2ecSJim Ingham };
204b842f2ecSJim Ingham 
205f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_set
206f94668e3SRaphael Isemann #include "CommandOptions.inc"
2071f0f5b5bSZachary Turner 
2085a988416SJim Ingham // CommandObjectBreakpointSet
20930fdc8d8SChris Lattner 
210b9c1b51eSKate Stone class CommandObjectBreakpointSet : public CommandObjectParsed {
2115a988416SJim Ingham public:
212efe8e7e3SFangrui Song   enum BreakpointSetType {
2135a988416SJim Ingham     eSetTypeInvalid,
2145a988416SJim Ingham     eSetTypeFileAndLine,
2155a988416SJim Ingham     eSetTypeAddress,
2165a988416SJim Ingham     eSetTypeFunctionName,
2175a988416SJim Ingham     eSetTypeFunctionRegexp,
2185a988416SJim Ingham     eSetTypeSourceRegexp,
2193815e702SJim Ingham     eSetTypeException,
2203815e702SJim Ingham     eSetTypeScripted,
221efe8e7e3SFangrui Song   };
2225a988416SJim Ingham 
223b9c1b51eSKate Stone   CommandObjectBreakpointSet(CommandInterpreter &interpreter)
224b9c1b51eSKate Stone       : CommandObjectParsed(
225b9c1b51eSKate Stone             interpreter, "breakpoint set",
2265a988416SJim Ingham             "Sets a breakpoint or set of breakpoints in the executable.",
2275a988416SJim Ingham             "breakpoint set <cmd-options>"),
228738af7a6SJim Ingham         m_bp_opts(), m_python_class_options("scripted breakpoint", true, 'P'),
229f6a2086dSSam McCall         m_options() {
230b842f2ecSJim Ingham     // We're picking up all the normal options, commands and disable.
231*a925974bSAdrian Prantl     m_all_options.Append(&m_python_class_options,
232*a925974bSAdrian Prantl                          LLDB_OPT_SET_1 | LLDB_OPT_SET_2, LLDB_OPT_SET_11);
233b842f2ecSJim Ingham     m_all_options.Append(&m_bp_opts,
234b842f2ecSJim Ingham                          LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4,
235b842f2ecSJim Ingham                          LLDB_OPT_SET_ALL);
236f6a2086dSSam McCall     m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
237b842f2ecSJim Ingham     m_all_options.Append(&m_options);
238b842f2ecSJim Ingham     m_all_options.Finalize();
239b842f2ecSJim Ingham   }
2405a988416SJim Ingham 
2419e85e5a8SEugene Zelenko   ~CommandObjectBreakpointSet() override = default;
2425a988416SJim Ingham 
243b842f2ecSJim Ingham   Options *GetOptions() override { return &m_all_options; }
2445a988416SJim Ingham 
245b842f2ecSJim Ingham   class CommandOptions : public OptionGroup {
2465a988416SJim Ingham   public:
247b9c1b51eSKate Stone     CommandOptions()
248*a925974bSAdrian Prantl         : OptionGroup(), m_condition(), m_filenames(), m_line_num(0),
249*a925974bSAdrian Prantl           m_column(0), m_func_names(),
250*a925974bSAdrian Prantl           m_func_name_type_mask(eFunctionNameTypeNone), m_func_regexp(),
251*a925974bSAdrian Prantl           m_source_text_regexp(), m_modules(), m_load_addr(), m_catch_bp(false),
252*a925974bSAdrian Prantl           m_throw_bp(true), m_hardware(false),
253a72b31c7SJim Ingham           m_exception_language(eLanguageTypeUnknown),
25423b1decbSDawn Perchik           m_language(lldb::eLanguageTypeUnknown),
255*a925974bSAdrian Prantl           m_skip_prologue(eLazyBoolCalculate), m_all_files(false),
256*a925974bSAdrian Prantl           m_move_to_nearest_code(eLazyBoolCalculate) {}
25730fdc8d8SChris Lattner 
2589e85e5a8SEugene Zelenko     ~CommandOptions() override = default;
25987df91b8SJim Ingham 
26097206d57SZachary Turner     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
261b9c1b51eSKate Stone                           ExecutionContext *execution_context) override {
26297206d57SZachary Turner       Status error;
263*a925974bSAdrian Prantl       const int short_option =
264*a925974bSAdrian Prantl           g_breakpoint_set_options[option_idx].short_option;
26530fdc8d8SChris Lattner 
266b9c1b51eSKate Stone       switch (short_option) {
267b9c1b51eSKate Stone       case 'a': {
26847cbf4a0SPavel Labath         m_load_addr = OptionArgParser::ToAddress(execution_context, option_arg,
269e1cfbc79STodd Fiala                                                  LLDB_INVALID_ADDRESS, &error);
270b9c1b51eSKate Stone       } break;
27130fdc8d8SChris Lattner 
272e732052fSJim Ingham       case 'A':
273e732052fSJim Ingham         m_all_files = true;
274e732052fSJim Ingham         break;
275e732052fSJim Ingham 
276ca36cd16SJim Ingham       case 'b':
277ca36cd16SJim Ingham         m_func_names.push_back(option_arg);
278ca36cd16SJim Ingham         m_func_name_type_mask |= eFunctionNameTypeBase;
279ca36cd16SJim Ingham         break;
280ca36cd16SJim Ingham 
281fe11483bSZachary Turner       case 'C':
282fe11483bSZachary Turner         if (option_arg.getAsInteger(0, m_column))
283b9c1b51eSKate Stone           error.SetErrorStringWithFormat("invalid column number: %s",
284fe11483bSZachary Turner                                          option_arg.str().c_str());
28530fdc8d8SChris Lattner         break;
2869e85e5a8SEugene Zelenko 
287b9c1b51eSKate Stone       case 'E': {
288fe11483bSZachary Turner         LanguageType language = Language::GetLanguageTypeFromString(option_arg);
289fab10e89SJim Ingham 
290b9c1b51eSKate Stone         switch (language) {
291fab10e89SJim Ingham         case eLanguageTypeC89:
292fab10e89SJim Ingham         case eLanguageTypeC:
293fab10e89SJim Ingham         case eLanguageTypeC99:
2941d0089faSBruce Mitchener         case eLanguageTypeC11:
295a72b31c7SJim Ingham           m_exception_language = eLanguageTypeC;
296fab10e89SJim Ingham           break;
297fab10e89SJim Ingham         case eLanguageTypeC_plus_plus:
2981d0089faSBruce Mitchener         case eLanguageTypeC_plus_plus_03:
2991d0089faSBruce Mitchener         case eLanguageTypeC_plus_plus_11:
3002ba84a6aSBruce Mitchener         case eLanguageTypeC_plus_plus_14:
301a72b31c7SJim Ingham           m_exception_language = eLanguageTypeC_plus_plus;
302fab10e89SJim Ingham           break;
303fab10e89SJim Ingham         case eLanguageTypeObjC:
304a72b31c7SJim Ingham           m_exception_language = eLanguageTypeObjC;
305fab10e89SJim Ingham           break;
306fab10e89SJim Ingham         case eLanguageTypeObjC_plus_plus:
307b9c1b51eSKate Stone           error.SetErrorStringWithFormat(
308b9c1b51eSKate Stone               "Set exception breakpoints separately for c++ and objective-c");
309fab10e89SJim Ingham           break;
310fab10e89SJim Ingham         case eLanguageTypeUnknown:
311b9c1b51eSKate Stone           error.SetErrorStringWithFormat(
312b9c1b51eSKate Stone               "Unknown language type: '%s' for exception breakpoint",
313fe11483bSZachary Turner               option_arg.str().c_str());
314fab10e89SJim Ingham           break;
315fab10e89SJim Ingham         default:
316b9c1b51eSKate Stone           error.SetErrorStringWithFormat(
317b9c1b51eSKate Stone               "Unsupported language type: '%s' for exception breakpoint",
318fe11483bSZachary Turner               option_arg.str().c_str());
319fab10e89SJim Ingham         }
320b9c1b51eSKate Stone       } break;
321ca36cd16SJim Ingham 
322ca36cd16SJim Ingham       case 'f':
3238f3be7a3SJonas Devlieghere         m_filenames.AppendIfUnique(FileSpec(option_arg));
324fab10e89SJim Ingham         break;
325ca36cd16SJim Ingham 
326ca36cd16SJim Ingham       case 'F':
327ca36cd16SJim Ingham         m_func_names.push_back(option_arg);
328ca36cd16SJim Ingham         m_func_name_type_mask |= eFunctionNameTypeFull;
329ca36cd16SJim Ingham         break;
330ca36cd16SJim Ingham 
331b9c1b51eSKate Stone       case 'h': {
332fab10e89SJim Ingham         bool success;
33347cbf4a0SPavel Labath         m_catch_bp = OptionArgParser::ToBoolean(option_arg, true, &success);
334fab10e89SJim Ingham         if (!success)
335b9c1b51eSKate Stone           error.SetErrorStringWithFormat(
336fe11483bSZachary Turner               "Invalid boolean value for on-catch option: '%s'",
337fe11483bSZachary Turner               option_arg.str().c_str());
338b9c1b51eSKate Stone       } break;
339eb023e75SGreg Clayton 
340eb023e75SGreg Clayton       case 'H':
341eb023e75SGreg Clayton         m_hardware = true;
342eb023e75SGreg Clayton         break;
343eb023e75SGreg Clayton 
344b9c1b51eSKate Stone       case 'K': {
345a8558b62SJim Ingham         bool success;
346a8558b62SJim Ingham         bool value;
34747cbf4a0SPavel Labath         value = OptionArgParser::ToBoolean(option_arg, true, &success);
348a8558b62SJim Ingham         if (value)
349a8558b62SJim Ingham           m_skip_prologue = eLazyBoolYes;
350a8558b62SJim Ingham         else
351a8558b62SJim Ingham           m_skip_prologue = eLazyBoolNo;
352a8558b62SJim Ingham 
353a8558b62SJim Ingham         if (!success)
354b9c1b51eSKate Stone           error.SetErrorStringWithFormat(
355b9c1b51eSKate Stone               "Invalid boolean value for skip prologue option: '%s'",
356fe11483bSZachary Turner               option_arg.str().c_str());
357b9c1b51eSKate Stone       } break;
358ca36cd16SJim Ingham 
359fe11483bSZachary Turner       case 'l':
360fe11483bSZachary Turner         if (option_arg.getAsInteger(0, m_line_num))
361b9c1b51eSKate Stone           error.SetErrorStringWithFormat("invalid line number: %s.",
362fe11483bSZachary Turner                                          option_arg.str().c_str());
363ca36cd16SJim Ingham         break;
364055ad9beSIlia K 
36523b1decbSDawn Perchik       case 'L':
366fe11483bSZachary Turner         m_language = Language::GetLanguageTypeFromString(option_arg);
36723b1decbSDawn Perchik         if (m_language == eLanguageTypeUnknown)
368b9c1b51eSKate Stone           error.SetErrorStringWithFormat(
369fe11483bSZachary Turner               "Unknown language type: '%s' for breakpoint",
370fe11483bSZachary Turner               option_arg.str().c_str());
37123b1decbSDawn Perchik         break;
37223b1decbSDawn Perchik 
373b9c1b51eSKate Stone       case 'm': {
374055ad9beSIlia K         bool success;
375055ad9beSIlia K         bool value;
37647cbf4a0SPavel Labath         value = OptionArgParser::ToBoolean(option_arg, true, &success);
377055ad9beSIlia K         if (value)
378055ad9beSIlia K           m_move_to_nearest_code = eLazyBoolYes;
379055ad9beSIlia K         else
380055ad9beSIlia K           m_move_to_nearest_code = eLazyBoolNo;
381055ad9beSIlia K 
382055ad9beSIlia K         if (!success)
383b9c1b51eSKate Stone           error.SetErrorStringWithFormat(
384b9c1b51eSKate Stone               "Invalid boolean value for move-to-nearest-code option: '%s'",
385fe11483bSZachary Turner               option_arg.str().c_str());
386055ad9beSIlia K         break;
387055ad9beSIlia K       }
388055ad9beSIlia K 
389ca36cd16SJim Ingham       case 'M':
390ca36cd16SJim Ingham         m_func_names.push_back(option_arg);
391ca36cd16SJim Ingham         m_func_name_type_mask |= eFunctionNameTypeMethod;
392ca36cd16SJim Ingham         break;
393ca36cd16SJim Ingham 
394ca36cd16SJim Ingham       case 'n':
395ca36cd16SJim Ingham         m_func_names.push_back(option_arg);
396ca36cd16SJim Ingham         m_func_name_type_mask |= eFunctionNameTypeAuto;
397ca36cd16SJim Ingham         break;
398ca36cd16SJim Ingham 
3996fa7681bSZachary Turner       case 'N': {
400fe11483bSZachary Turner         if (BreakpointID::StringIsBreakpointName(option_arg, error))
4015e09c8c3SJim Ingham           m_breakpoint_names.push_back(option_arg);
402ff9a91eaSJim Ingham         else
403ff9a91eaSJim Ingham           error.SetErrorStringWithFormat("Invalid breakpoint name: %s",
404fe11483bSZachary Turner                                          option_arg.str().c_str());
4055e09c8c3SJim Ingham         break;
4066fa7681bSZachary Turner       }
4075e09c8c3SJim Ingham 
408b9c1b51eSKate Stone       case 'R': {
4092411167fSJim Ingham         lldb::addr_t tmp_offset_addr;
41047cbf4a0SPavel Labath         tmp_offset_addr = OptionArgParser::ToAddress(execution_context,
41147cbf4a0SPavel Labath                                                      option_arg, 0, &error);
4122411167fSJim Ingham         if (error.Success())
4132411167fSJim Ingham           m_offset_addr = tmp_offset_addr;
414b9c1b51eSKate Stone       } break;
4152411167fSJim Ingham 
416a72b31c7SJim Ingham       case 'O':
417fe11483bSZachary Turner         m_exception_extra_args.AppendArgument("-O");
418fe11483bSZachary Turner         m_exception_extra_args.AppendArgument(option_arg);
419a72b31c7SJim Ingham         break;
420a72b31c7SJim Ingham 
421ca36cd16SJim Ingham       case 'p':
422ca36cd16SJim Ingham         m_source_text_regexp.assign(option_arg);
423ca36cd16SJim Ingham         break;
424ca36cd16SJim Ingham 
425ca36cd16SJim Ingham       case 'r':
426ca36cd16SJim Ingham         m_func_regexp.assign(option_arg);
427ca36cd16SJim Ingham         break;
428ca36cd16SJim Ingham 
429ca36cd16SJim Ingham       case 's':
4308f3be7a3SJonas Devlieghere         m_modules.AppendIfUnique(FileSpec(option_arg));
431ca36cd16SJim Ingham         break;
432ca36cd16SJim Ingham 
433ca36cd16SJim Ingham       case 'S':
434ca36cd16SJim Ingham         m_func_names.push_back(option_arg);
435ca36cd16SJim Ingham         m_func_name_type_mask |= eFunctionNameTypeSelector;
436ca36cd16SJim Ingham         break;
437ca36cd16SJim Ingham 
438b9c1b51eSKate Stone       case 'w': {
439ca36cd16SJim Ingham         bool success;
44047cbf4a0SPavel Labath         m_throw_bp = OptionArgParser::ToBoolean(option_arg, true, &success);
441ca36cd16SJim Ingham         if (!success)
442b9c1b51eSKate Stone           error.SetErrorStringWithFormat(
443fe11483bSZachary Turner               "Invalid boolean value for on-throw option: '%s'",
444fe11483bSZachary Turner               option_arg.str().c_str());
445b9c1b51eSKate Stone       } break;
446ca36cd16SJim Ingham 
44776bb8d67SJim Ingham       case 'X':
44876bb8d67SJim Ingham         m_source_regex_func_names.insert(option_arg);
44976bb8d67SJim Ingham         break;
45076bb8d67SJim Ingham 
45130fdc8d8SChris Lattner       default:
45236162014SRaphael Isemann         llvm_unreachable("Unimplemented option");
45330fdc8d8SChris Lattner       }
45430fdc8d8SChris Lattner 
45530fdc8d8SChris Lattner       return error;
45630fdc8d8SChris Lattner     }
4579e85e5a8SEugene Zelenko 
458b9c1b51eSKate Stone     void OptionParsingStarting(ExecutionContext *execution_context) override {
45987df91b8SJim Ingham       m_filenames.Clear();
46030fdc8d8SChris Lattner       m_line_num = 0;
46130fdc8d8SChris Lattner       m_column = 0;
462fab10e89SJim Ingham       m_func_names.clear();
4631f746071SGreg Clayton       m_func_name_type_mask = eFunctionNameTypeNone;
46430fdc8d8SChris Lattner       m_func_regexp.clear();
4651f746071SGreg Clayton       m_source_text_regexp.clear();
46687df91b8SJim Ingham       m_modules.Clear();
4671f746071SGreg Clayton       m_load_addr = LLDB_INVALID_ADDRESS;
4682411167fSJim Ingham       m_offset_addr = 0;
469fab10e89SJim Ingham       m_catch_bp = false;
470fab10e89SJim Ingham       m_throw_bp = true;
471eb023e75SGreg Clayton       m_hardware = false;
472a72b31c7SJim Ingham       m_exception_language = eLanguageTypeUnknown;
47323b1decbSDawn Perchik       m_language = lldb::eLanguageTypeUnknown;
474a8558b62SJim Ingham       m_skip_prologue = eLazyBoolCalculate;
4755e09c8c3SJim Ingham       m_breakpoint_names.clear();
476e732052fSJim Ingham       m_all_files = false;
477a72b31c7SJim Ingham       m_exception_extra_args.Clear();
478055ad9beSIlia K       m_move_to_nearest_code = eLazyBoolCalculate;
47976bb8d67SJim Ingham       m_source_regex_func_names.clear();
4803815e702SJim Ingham       m_current_key.clear();
48130fdc8d8SChris Lattner     }
48230fdc8d8SChris Lattner 
4831f0f5b5bSZachary Turner     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
48470602439SZachary Turner       return llvm::makeArrayRef(g_breakpoint_set_options);
4851f0f5b5bSZachary Turner     }
48630fdc8d8SChris Lattner 
4875a988416SJim Ingham     // Instance variables to hold the values for command options.
488969795f1SJim Ingham 
4895a988416SJim Ingham     std::string m_condition;
4905a988416SJim Ingham     FileSpecList m_filenames;
4915a988416SJim Ingham     uint32_t m_line_num;
4925a988416SJim Ingham     uint32_t m_column;
4935a988416SJim Ingham     std::vector<std::string> m_func_names;
4945e09c8c3SJim Ingham     std::vector<std::string> m_breakpoint_names;
495117b1fa1SZachary Turner     lldb::FunctionNameType m_func_name_type_mask;
4965a988416SJim Ingham     std::string m_func_regexp;
4975a988416SJim Ingham     std::string m_source_text_regexp;
4985a988416SJim Ingham     FileSpecList m_modules;
4995a988416SJim Ingham     lldb::addr_t m_load_addr;
5002411167fSJim Ingham     lldb::addr_t m_offset_addr;
5015a988416SJim Ingham     bool m_catch_bp;
5025a988416SJim Ingham     bool m_throw_bp;
503eb023e75SGreg Clayton     bool m_hardware; // Request to use hardware breakpoints
504a72b31c7SJim Ingham     lldb::LanguageType m_exception_language;
50523b1decbSDawn Perchik     lldb::LanguageType m_language;
5065a988416SJim Ingham     LazyBool m_skip_prologue;
507e732052fSJim Ingham     bool m_all_files;
508a72b31c7SJim Ingham     Args m_exception_extra_args;
509055ad9beSIlia K     LazyBool m_move_to_nearest_code;
51076bb8d67SJim Ingham     std::unordered_set<std::string> m_source_regex_func_names;
5113815e702SJim Ingham     std::string m_current_key;
5125a988416SJim Ingham   };
5135a988416SJim Ingham 
5145a988416SJim Ingham protected:
515b9c1b51eSKate Stone   bool DoExecute(Args &command, CommandReturnObject &result) override {
516cb2380c9SRaphael Isemann     Target &target = GetSelectedOrDummyTarget(m_dummy_options.m_use_dummy);
51730fdc8d8SChris Lattner 
51830fdc8d8SChris Lattner     // The following are the various types of breakpoints that could be set:
51930fdc8d8SChris Lattner     //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
52030fdc8d8SChris Lattner     //   2).  -a  [-s -g]         (setting breakpoint by address)
52130fdc8d8SChris Lattner     //   3).  -n  [-s -g]         (setting breakpoint by function name)
522b9c1b51eSKate Stone     //   4).  -r  [-s -g]         (setting breakpoint by function name regular
523b9c1b51eSKate Stone     //   expression)
524b9c1b51eSKate Stone     //   5).  -p -f               (setting a breakpoint by comparing a reg-exp
525b9c1b51eSKate Stone     //   to source text)
526b9c1b51eSKate Stone     //   6).  -E [-w -h]          (setting a breakpoint for exceptions for a
527b9c1b51eSKate Stone     //   given language.)
52830fdc8d8SChris Lattner 
52930fdc8d8SChris Lattner     BreakpointSetType break_type = eSetTypeInvalid;
53030fdc8d8SChris Lattner 
531738af7a6SJim Ingham     if (!m_python_class_options.GetName().empty())
5323815e702SJim Ingham       break_type = eSetTypeScripted;
5333815e702SJim Ingham     else if (m_options.m_line_num != 0)
53430fdc8d8SChris Lattner       break_type = eSetTypeFileAndLine;
53530fdc8d8SChris Lattner     else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
53630fdc8d8SChris Lattner       break_type = eSetTypeAddress;
537fab10e89SJim Ingham     else if (!m_options.m_func_names.empty())
53830fdc8d8SChris Lattner       break_type = eSetTypeFunctionName;
53930fdc8d8SChris Lattner     else if (!m_options.m_func_regexp.empty())
54030fdc8d8SChris Lattner       break_type = eSetTypeFunctionRegexp;
541969795f1SJim Ingham     else if (!m_options.m_source_text_regexp.empty())
542969795f1SJim Ingham       break_type = eSetTypeSourceRegexp;
543a72b31c7SJim Ingham     else if (m_options.m_exception_language != eLanguageTypeUnknown)
544fab10e89SJim Ingham       break_type = eSetTypeException;
54530fdc8d8SChris Lattner 
546b842f2ecSJim Ingham     BreakpointSP bp_sp = nullptr;
547274060b6SGreg Clayton     FileSpec module_spec;
548a8558b62SJim Ingham     const bool internal = false;
549a8558b62SJim Ingham 
550b9c1b51eSKate Stone     // If the user didn't specify skip-prologue, having an offset should turn
551b9c1b51eSKate Stone     // that off.
552b9c1b51eSKate Stone     if (m_options.m_offset_addr != 0 &&
553b9c1b51eSKate Stone         m_options.m_skip_prologue == eLazyBoolCalculate)
5542411167fSJim Ingham       m_options.m_skip_prologue = eLazyBoolNo;
5552411167fSJim Ingham 
556b9c1b51eSKate Stone     switch (break_type) {
55730fdc8d8SChris Lattner     case eSetTypeFileAndLine: // Breakpoint by source position
55830fdc8d8SChris Lattner     {
55930fdc8d8SChris Lattner       FileSpec file;
560c7bece56SGreg Clayton       const size_t num_files = m_options.m_filenames.GetSize();
561b9c1b51eSKate Stone       if (num_files == 0) {
562b9c1b51eSKate Stone         if (!GetDefaultFile(target, file, result)) {
56387df91b8SJim Ingham           result.AppendError("No file supplied and no default file available.");
56487df91b8SJim Ingham           result.SetStatus(eReturnStatusFailed);
56587df91b8SJim Ingham           return false;
56687df91b8SJim Ingham         }
567b9c1b51eSKate Stone       } else if (num_files > 1) {
568b9c1b51eSKate Stone         result.AppendError("Only one file at a time is allowed for file and "
569b9c1b51eSKate Stone                            "line breakpoints.");
57087df91b8SJim Ingham         result.SetStatus(eReturnStatusFailed);
57187df91b8SJim Ingham         return false;
572b9c1b51eSKate Stone       } else
57387df91b8SJim Ingham         file = m_options.m_filenames.GetFileSpecAtIndex(0);
57430fdc8d8SChris Lattner 
5751f746071SGreg Clayton       // Only check for inline functions if
5761f746071SGreg Clayton       LazyBool check_inlines = eLazyBoolCalculate;
5771f746071SGreg Clayton 
578cb2380c9SRaphael Isemann       bp_sp = target.CreateBreakpoint(
579cb2380c9SRaphael Isemann           &(m_options.m_modules), file, m_options.m_line_num,
580cb2380c9SRaphael Isemann           m_options.m_column, m_options.m_offset_addr, check_inlines,
581cb2380c9SRaphael Isemann           m_options.m_skip_prologue, internal, m_options.m_hardware,
582b842f2ecSJim Ingham           m_options.m_move_to_nearest_code);
583b9c1b51eSKate Stone     } break;
5846eee5aa0SGreg Clayton 
58530fdc8d8SChris Lattner     case eSetTypeAddress: // Breakpoint by address
586055a08a4SJim Ingham     {
587b9c1b51eSKate Stone       // If a shared library has been specified, make an lldb_private::Address
588b842f2ecSJim Ingham       // with the library, and use that.  That way the address breakpoint
589b842f2ecSJim Ingham       //  will track the load location of the library.
590055a08a4SJim Ingham       size_t num_modules_specified = m_options.m_modules.GetSize();
591b9c1b51eSKate Stone       if (num_modules_specified == 1) {
592b9c1b51eSKate Stone         const FileSpec *file_spec =
593b9c1b51eSKate Stone             m_options.m_modules.GetFileSpecPointerAtIndex(0);
594cb2380c9SRaphael Isemann         bp_sp = target.CreateAddressInModuleBreakpoint(
595cb2380c9SRaphael Isemann             m_options.m_load_addr, internal, file_spec, m_options.m_hardware);
596b9c1b51eSKate Stone       } else if (num_modules_specified == 0) {
597cb2380c9SRaphael Isemann         bp_sp = target.CreateBreakpoint(m_options.m_load_addr, internal,
598b842f2ecSJim Ingham                                         m_options.m_hardware);
599b9c1b51eSKate Stone       } else {
600b9c1b51eSKate Stone         result.AppendError("Only one shared library can be specified for "
601b9c1b51eSKate Stone                            "address breakpoints.");
602055a08a4SJim Ingham         result.SetStatus(eReturnStatusFailed);
603055a08a4SJim Ingham         return false;
604055a08a4SJim Ingham       }
60530fdc8d8SChris Lattner       break;
606055a08a4SJim Ingham     }
60730fdc8d8SChris Lattner     case eSetTypeFunctionName: // Breakpoint by function name
6080c5cd90dSGreg Clayton     {
609117b1fa1SZachary Turner       FunctionNameType name_type_mask = m_options.m_func_name_type_mask;
6100c5cd90dSGreg Clayton 
6110c5cd90dSGreg Clayton       if (name_type_mask == 0)
612e02b8504SGreg Clayton         name_type_mask = eFunctionNameTypeAuto;
6130c5cd90dSGreg Clayton 
614cb2380c9SRaphael Isemann       bp_sp = target.CreateBreakpoint(
615cb2380c9SRaphael Isemann           &(m_options.m_modules), &(m_options.m_filenames),
616cb2380c9SRaphael Isemann           m_options.m_func_names, name_type_mask, m_options.m_language,
617cb2380c9SRaphael Isemann           m_options.m_offset_addr, m_options.m_skip_prologue, internal,
618b842f2ecSJim Ingham           m_options.m_hardware);
619b9c1b51eSKate Stone     } break;
6200c5cd90dSGreg Clayton 
621b9c1b51eSKate Stone     case eSetTypeFunctionRegexp: // Breakpoint by regular expression function
622b9c1b51eSKate Stone                                  // name
62330fdc8d8SChris Lattner     {
62495eae423SZachary Turner       RegularExpression regexp(m_options.m_func_regexp);
6253af3f1e8SJonas Devlieghere       if (llvm::Error err = regexp.GetError()) {
626b9c1b51eSKate Stone         result.AppendErrorWithFormat(
627b9c1b51eSKate Stone             "Function name regular expression could not be compiled: \"%s\"",
6283af3f1e8SJonas Devlieghere             llvm::toString(std::move(err)).c_str());
62930fdc8d8SChris Lattner         result.SetStatus(eReturnStatusFailed);
630969795f1SJim Ingham         return false;
63130fdc8d8SChris Lattner       }
63287df91b8SJim Ingham 
633cb2380c9SRaphael Isemann       bp_sp = target.CreateFuncRegexBreakpoint(
6345aa1d819SJan Kratochvil           &(m_options.m_modules), &(m_options.m_filenames), std::move(regexp),
635cb2380c9SRaphael Isemann           m_options.m_language, m_options.m_skip_prologue, internal,
636b842f2ecSJim Ingham           m_options.m_hardware);
637*a925974bSAdrian Prantl     } break;
638969795f1SJim Ingham     case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
639969795f1SJim Ingham     {
640c7bece56SGreg Clayton       const size_t num_files = m_options.m_filenames.GetSize();
64187df91b8SJim Ingham 
642b9c1b51eSKate Stone       if (num_files == 0 && !m_options.m_all_files) {
643969795f1SJim Ingham         FileSpec file;
644b9c1b51eSKate Stone         if (!GetDefaultFile(target, file, result)) {
645b9c1b51eSKate Stone           result.AppendError(
646b9c1b51eSKate Stone               "No files provided and could not find default file.");
64787df91b8SJim Ingham           result.SetStatus(eReturnStatusFailed);
64887df91b8SJim Ingham           return false;
649b9c1b51eSKate Stone         } else {
65087df91b8SJim Ingham           m_options.m_filenames.Append(file);
65187df91b8SJim Ingham         }
65287df91b8SJim Ingham       }
6530c5cd90dSGreg Clayton 
65495eae423SZachary Turner       RegularExpression regexp(m_options.m_source_text_regexp);
6553af3f1e8SJonas Devlieghere       if (llvm::Error err = regexp.GetError()) {
656b9c1b51eSKate Stone         result.AppendErrorWithFormat(
657b9c1b51eSKate Stone             "Source text regular expression could not be compiled: \"%s\"",
6583af3f1e8SJonas Devlieghere             llvm::toString(std::move(err)).c_str());
659969795f1SJim Ingham         result.SetStatus(eReturnStatusFailed);
660969795f1SJim Ingham         return false;
661969795f1SJim Ingham       }
662cb2380c9SRaphael Isemann       bp_sp = target.CreateSourceRegexBreakpoint(
663cb2380c9SRaphael Isemann           &(m_options.m_modules), &(m_options.m_filenames),
6645aa1d819SJan Kratochvil           m_options.m_source_regex_func_names, std::move(regexp), internal,
665cb2380c9SRaphael Isemann           m_options.m_hardware, m_options.m_move_to_nearest_code);
666b9c1b51eSKate Stone     } break;
667b9c1b51eSKate Stone     case eSetTypeException: {
66897206d57SZachary Turner       Status precond_error;
669cb2380c9SRaphael Isemann       bp_sp = target.CreateExceptionBreakpoint(
670cb2380c9SRaphael Isemann           m_options.m_exception_language, m_options.m_catch_bp,
671cb2380c9SRaphael Isemann           m_options.m_throw_bp, internal, &m_options.m_exception_extra_args,
672b842f2ecSJim Ingham           &precond_error);
673b9c1b51eSKate Stone       if (precond_error.Fail()) {
674b9c1b51eSKate Stone         result.AppendErrorWithFormat(
675b9c1b51eSKate Stone             "Error setting extra exception arguments: %s",
676a72b31c7SJim Ingham             precond_error.AsCString());
677cb2380c9SRaphael Isemann         target.RemoveBreakpointByID(bp_sp->GetID());
678a72b31c7SJim Ingham         result.SetStatus(eReturnStatusFailed);
679a72b31c7SJim Ingham         return false;
680a72b31c7SJim Ingham       }
681b9c1b51eSKate Stone     } break;
6823815e702SJim Ingham     case eSetTypeScripted: {
6833815e702SJim Ingham 
6843815e702SJim Ingham       Status error;
685cb2380c9SRaphael Isemann       bp_sp = target.CreateScriptedBreakpoint(
686738af7a6SJim Ingham           m_python_class_options.GetName().c_str(), &(m_options.m_modules),
687cb2380c9SRaphael Isemann           &(m_options.m_filenames), false, m_options.m_hardware,
688943a2481SJim Ingham           m_python_class_options.GetStructuredData(), &error);
6893815e702SJim Ingham       if (error.Fail()) {
6903815e702SJim Ingham         result.AppendErrorWithFormat(
691*a925974bSAdrian Prantl             "Error setting extra exception arguments: %s", error.AsCString());
692cb2380c9SRaphael Isemann         target.RemoveBreakpointByID(bp_sp->GetID());
6933815e702SJim Ingham         result.SetStatus(eReturnStatusFailed);
6943815e702SJim Ingham         return false;
6953815e702SJim Ingham       }
6963815e702SJim Ingham     } break;
69730fdc8d8SChris Lattner     default:
69830fdc8d8SChris Lattner       break;
69930fdc8d8SChris Lattner     }
70030fdc8d8SChris Lattner 
7011b54c88cSJim Ingham     // Now set the various options that were passed in:
702b842f2ecSJim Ingham     if (bp_sp) {
703b842f2ecSJim Ingham       bp_sp->GetOptions()->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
704ca36cd16SJim Ingham 
705b9c1b51eSKate Stone       if (!m_options.m_breakpoint_names.empty()) {
70697206d57SZachary Turner         Status name_error;
707ff9a91eaSJim Ingham         for (auto name : m_options.m_breakpoint_names) {
708cb2380c9SRaphael Isemann           target.AddNameToBreakpoint(bp_sp, name.c_str(), name_error);
709ff9a91eaSJim Ingham           if (name_error.Fail()) {
710ff9a91eaSJim Ingham             result.AppendErrorWithFormat("Invalid breakpoint name: %s",
711ff9a91eaSJim Ingham                                          name.c_str());
712cb2380c9SRaphael Isemann             target.RemoveBreakpointByID(bp_sp->GetID());
713ff9a91eaSJim Ingham             result.SetStatus(eReturnStatusFailed);
714ff9a91eaSJim Ingham             return false;
715ff9a91eaSJim Ingham           }
716ff9a91eaSJim Ingham         }
7175e09c8c3SJim Ingham       }
7181b54c88cSJim Ingham     }
7191b54c88cSJim Ingham 
720b842f2ecSJim Ingham     if (bp_sp) {
72185e8b814SJim Ingham       Stream &output_stream = result.GetOutputStream();
7221391cc7dSJim Ingham       const bool show_locations = false;
723b842f2ecSJim Ingham       bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
724b9c1b51eSKate Stone                             show_locations);
725cb2380c9SRaphael Isemann       if (&target == &GetDummyTarget())
726b9c1b51eSKate Stone         output_stream.Printf("Breakpoint set in dummy target, will get copied "
727b9c1b51eSKate Stone                              "into future targets.\n");
728b9c1b51eSKate Stone       else {
72905097246SAdrian Prantl         // Don't print out this warning for exception breakpoints.  They can
73005097246SAdrian Prantl         // get set before the target is set, but we won't know how to actually
73105097246SAdrian Prantl         // set the breakpoint till we run.
732b842f2ecSJim Ingham         if (bp_sp->GetNumLocations() == 0 && break_type != eSetTypeException) {
733b9c1b51eSKate Stone           output_stream.Printf("WARNING:  Unable to resolve breakpoint to any "
734b9c1b51eSKate Stone                                "actual locations.\n");
7354aeb1989SJim Ingham         }
7364aeb1989SJim Ingham       }
73730fdc8d8SChris Lattner       result.SetStatus(eReturnStatusSuccessFinishResult);
738b842f2ecSJim Ingham     } else if (!bp_sp) {
73930fdc8d8SChris Lattner       result.AppendError("Breakpoint creation failed: No breakpoint created.");
74030fdc8d8SChris Lattner       result.SetStatus(eReturnStatusFailed);
74130fdc8d8SChris Lattner     }
74230fdc8d8SChris Lattner 
74330fdc8d8SChris Lattner     return result.Succeeded();
74430fdc8d8SChris Lattner   }
74530fdc8d8SChris Lattner 
7465a988416SJim Ingham private:
747cb2380c9SRaphael Isemann   bool GetDefaultFile(Target &target, FileSpec &file,
748b9c1b51eSKate Stone                       CommandReturnObject &result) {
7495a988416SJim Ingham     uint32_t default_line;
75005097246SAdrian Prantl     // First use the Source Manager's default file. Then use the current stack
75105097246SAdrian Prantl     // frame's file.
752cb2380c9SRaphael Isemann     if (!target.GetSourceManager().GetDefaultFileAndLine(file, default_line)) {
753b57e4a1bSJason Molenda       StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
754b9c1b51eSKate Stone       if (cur_frame == nullptr) {
755b9c1b51eSKate Stone         result.AppendError(
756b9c1b51eSKate Stone             "No selected frame to use to find the default file.");
7575a988416SJim Ingham         result.SetStatus(eReturnStatusFailed);
7585a988416SJim Ingham         return false;
759b9c1b51eSKate Stone       } else if (!cur_frame->HasDebugInformation()) {
760b9c1b51eSKate Stone         result.AppendError("Cannot use the selected frame to find the default "
761b9c1b51eSKate Stone                            "file, it has no debug info.");
7625a988416SJim Ingham         result.SetStatus(eReturnStatusFailed);
7635a988416SJim Ingham         return false;
764b9c1b51eSKate Stone       } else {
765b9c1b51eSKate Stone         const SymbolContext &sc =
766b9c1b51eSKate Stone             cur_frame->GetSymbolContext(eSymbolContextLineEntry);
767b9c1b51eSKate Stone         if (sc.line_entry.file) {
7685a988416SJim Ingham           file = sc.line_entry.file;
769b9c1b51eSKate Stone         } else {
770b9c1b51eSKate Stone           result.AppendError("Can't find the file for the selected frame to "
771b9c1b51eSKate Stone                              "use as the default file.");
7725a988416SJim Ingham           result.SetStatus(eReturnStatusFailed);
7735a988416SJim Ingham           return false;
7745a988416SJim Ingham         }
7755a988416SJim Ingham       }
7765a988416SJim Ingham     }
7775a988416SJim Ingham     return true;
7785a988416SJim Ingham   }
7795a988416SJim Ingham 
780b842f2ecSJim Ingham   BreakpointOptionGroup m_bp_opts;
781b842f2ecSJim Ingham   BreakpointDummyOptionGroup m_dummy_options;
782943a2481SJim Ingham   OptionGroupPythonClassWithDict m_python_class_options;
7835a988416SJim Ingham   CommandOptions m_options;
784b842f2ecSJim Ingham   OptionGroupOptions m_all_options;
7855a988416SJim Ingham };
7869e85e5a8SEugene Zelenko 
7875a988416SJim Ingham // CommandObjectBreakpointModify
7885a988416SJim Ingham #pragma mark Modify
7895a988416SJim Ingham 
790b9c1b51eSKate Stone class CommandObjectBreakpointModify : public CommandObjectParsed {
7915a988416SJim Ingham public:
792b9c1b51eSKate Stone   CommandObjectBreakpointModify(CommandInterpreter &interpreter)
793b9c1b51eSKate Stone       : CommandObjectParsed(interpreter, "breakpoint modify",
794b9c1b51eSKate Stone                             "Modify the options on a breakpoint or set of "
795b9c1b51eSKate Stone                             "breakpoints in the executable.  "
796b9c1b51eSKate Stone                             "If no breakpoint is specified, acts on the last "
797b9c1b51eSKate Stone                             "created breakpoint.  "
798b9c1b51eSKate Stone                             "With the exception of -e, -d and -i, passing an "
799b9c1b51eSKate Stone                             "empty argument clears the modification.",
8009e85e5a8SEugene Zelenko                             nullptr),
801b9c1b51eSKate Stone         m_options() {
8025a988416SJim Ingham     CommandArgumentEntry arg;
803b9c1b51eSKate Stone     CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
804b9c1b51eSKate Stone                                       eArgTypeBreakpointIDRange);
805b9c1b51eSKate Stone     // Add the entry for the first argument for this command to the object's
806b9c1b51eSKate Stone     // arguments vector.
8075a988416SJim Ingham     m_arguments.push_back(arg);
808b842f2ecSJim Ingham 
809b842f2ecSJim Ingham     m_options.Append(&m_bp_opts,
810b842f2ecSJim Ingham                      LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3,
811b842f2ecSJim Ingham                      LLDB_OPT_SET_ALL);
812b842f2ecSJim Ingham     m_options.Append(&m_dummy_opts, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
813b842f2ecSJim Ingham     m_options.Finalize();
8145a988416SJim Ingham   }
8155a988416SJim Ingham 
8169e85e5a8SEugene Zelenko   ~CommandObjectBreakpointModify() override = default;
8175a988416SJim Ingham 
818b9c1b51eSKate Stone   Options *GetOptions() override { return &m_options; }
8195a988416SJim Ingham 
8205a988416SJim Ingham protected:
821b9c1b51eSKate Stone   bool DoExecute(Args &command, CommandReturnObject &result) override {
822cb2380c9SRaphael Isemann     Target &target = GetSelectedOrDummyTarget(m_dummy_opts.m_use_dummy);
8235a988416SJim Ingham 
824bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
825cb2380c9SRaphael Isemann     target.GetBreakpointList().GetListMutex(lock);
8265a988416SJim Ingham 
8275a988416SJim Ingham     BreakpointIDList valid_bp_ids;
8285a988416SJim Ingham 
829b9c1b51eSKate Stone     CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
830cb2380c9SRaphael Isemann         command, &target, result, &valid_bp_ids,
831b842f2ecSJim Ingham         BreakpointName::Permissions::PermissionKinds::disablePerm);
8325a988416SJim Ingham 
833b9c1b51eSKate Stone     if (result.Succeeded()) {
8345a988416SJim Ingham       const size_t count = valid_bp_ids.GetSize();
835b9c1b51eSKate Stone       for (size_t i = 0; i < count; ++i) {
8365a988416SJim Ingham         BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
8375a988416SJim Ingham 
838b9c1b51eSKate Stone         if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
839b9c1b51eSKate Stone           Breakpoint *bp =
840cb2380c9SRaphael Isemann               target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
841b9c1b51eSKate Stone           if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
842b9c1b51eSKate Stone             BreakpointLocation *location =
843b9c1b51eSKate Stone                 bp->FindLocationByID(cur_bp_id.GetLocationID()).get();
844b842f2ecSJim Ingham             if (location)
845*a925974bSAdrian Prantl               location->GetLocationOptions()->CopyOverSetOptions(
846*a925974bSAdrian Prantl                   m_bp_opts.GetBreakpointOptions());
847b9c1b51eSKate Stone           } else {
848*a925974bSAdrian Prantl             bp->GetOptions()->CopyOverSetOptions(
849*a925974bSAdrian Prantl                 m_bp_opts.GetBreakpointOptions());
8505a988416SJim Ingham           }
8515a988416SJim Ingham         }
8525a988416SJim Ingham       }
8535a988416SJim Ingham     }
8545a988416SJim Ingham 
8555a988416SJim Ingham     return result.Succeeded();
8565a988416SJim Ingham   }
8575a988416SJim Ingham 
8585a988416SJim Ingham private:
859b842f2ecSJim Ingham   BreakpointOptionGroup m_bp_opts;
860b842f2ecSJim Ingham   BreakpointDummyOptionGroup m_dummy_opts;
861b842f2ecSJim Ingham   OptionGroupOptions m_options;
8625a988416SJim Ingham };
8635a988416SJim Ingham 
8645a988416SJim Ingham // CommandObjectBreakpointEnable
8655a988416SJim Ingham #pragma mark Enable
8665a988416SJim Ingham 
867b9c1b51eSKate Stone class CommandObjectBreakpointEnable : public CommandObjectParsed {
8685a988416SJim Ingham public:
869b9c1b51eSKate Stone   CommandObjectBreakpointEnable(CommandInterpreter &interpreter)
870b9c1b51eSKate Stone       : CommandObjectParsed(interpreter, "enable",
871b9c1b51eSKate Stone                             "Enable the specified disabled breakpoint(s). If "
872b9c1b51eSKate Stone                             "no breakpoints are specified, enable all of them.",
873b9c1b51eSKate Stone                             nullptr) {
8745a988416SJim Ingham     CommandArgumentEntry arg;
875b9c1b51eSKate Stone     CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
876b9c1b51eSKate Stone                                       eArgTypeBreakpointIDRange);
877b9c1b51eSKate Stone     // Add the entry for the first argument for this command to the object's
878b9c1b51eSKate Stone     // arguments vector.
8795a988416SJim Ingham     m_arguments.push_back(arg);
8805a988416SJim Ingham   }
8815a988416SJim Ingham 
8829e85e5a8SEugene Zelenko   ~CommandObjectBreakpointEnable() override = default;
8835a988416SJim Ingham 
8845a988416SJim Ingham protected:
885b9c1b51eSKate Stone   bool DoExecute(Args &command, CommandReturnObject &result) override {
886cb2380c9SRaphael Isemann     Target &target = GetSelectedOrDummyTarget();
8875a988416SJim Ingham 
888bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
889cb2380c9SRaphael Isemann     target.GetBreakpointList().GetListMutex(lock);
8905a988416SJim Ingham 
891cb2380c9SRaphael Isemann     const BreakpointList &breakpoints = target.GetBreakpointList();
8925a988416SJim Ingham 
8935a988416SJim Ingham     size_t num_breakpoints = breakpoints.GetSize();
8945a988416SJim Ingham 
895b9c1b51eSKate Stone     if (num_breakpoints == 0) {
8965a988416SJim Ingham       result.AppendError("No breakpoints exist to be enabled.");
8975a988416SJim Ingham       result.SetStatus(eReturnStatusFailed);
8985a988416SJim Ingham       return false;
8995a988416SJim Ingham     }
9005a988416SJim Ingham 
90111eb9c64SZachary Turner     if (command.empty()) {
9025a988416SJim Ingham       // No breakpoint selected; enable all currently set breakpoints.
903cb2380c9SRaphael Isemann       target.EnableAllowedBreakpoints();
904b9c1b51eSKate Stone       result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64
905b9c1b51eSKate Stone                                      " breakpoints)\n",
906b9c1b51eSKate Stone                                      (uint64_t)num_breakpoints);
9075a988416SJim Ingham       result.SetStatus(eReturnStatusSuccessFinishNoResult);
908b9c1b51eSKate Stone     } else {
9095a988416SJim Ingham       // Particular breakpoint selected; enable that breakpoint.
9105a988416SJim Ingham       BreakpointIDList valid_bp_ids;
911b9c1b51eSKate Stone       CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
912cb2380c9SRaphael Isemann           command, &target, result, &valid_bp_ids,
913b842f2ecSJim Ingham           BreakpointName::Permissions::PermissionKinds::disablePerm);
9145a988416SJim Ingham 
915b9c1b51eSKate Stone       if (result.Succeeded()) {
9165a988416SJim Ingham         int enable_count = 0;
9175a988416SJim Ingham         int loc_count = 0;
9185a988416SJim Ingham         const size_t count = valid_bp_ids.GetSize();
919b9c1b51eSKate Stone         for (size_t i = 0; i < count; ++i) {
9205a988416SJim Ingham           BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
9215a988416SJim Ingham 
922b9c1b51eSKate Stone           if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
923b9c1b51eSKate Stone             Breakpoint *breakpoint =
924cb2380c9SRaphael Isemann                 target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
925b9c1b51eSKate Stone             if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
926b9c1b51eSKate Stone               BreakpointLocation *location =
927b9c1b51eSKate Stone                   breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
928b9c1b51eSKate Stone               if (location) {
9295a988416SJim Ingham                 location->SetEnabled(true);
9305a988416SJim Ingham                 ++loc_count;
9315a988416SJim Ingham               }
932b9c1b51eSKate Stone             } else {
9335a988416SJim Ingham               breakpoint->SetEnabled(true);
9345a988416SJim Ingham               ++enable_count;
9355a988416SJim Ingham             }
9365a988416SJim Ingham           }
9375a988416SJim Ingham         }
938b9c1b51eSKate Stone         result.AppendMessageWithFormat("%d breakpoints enabled.\n",
939b9c1b51eSKate Stone                                        enable_count + loc_count);
9405a988416SJim Ingham         result.SetStatus(eReturnStatusSuccessFinishNoResult);
9415a988416SJim Ingham       }
9425a988416SJim Ingham     }
9435a988416SJim Ingham 
9445a988416SJim Ingham     return result.Succeeded();
9455a988416SJim Ingham   }
9465a988416SJim Ingham };
9475a988416SJim Ingham 
9485a988416SJim Ingham // CommandObjectBreakpointDisable
9495a988416SJim Ingham #pragma mark Disable
9505a988416SJim Ingham 
951b9c1b51eSKate Stone class CommandObjectBreakpointDisable : public CommandObjectParsed {
9525a988416SJim Ingham public:
9537428a18cSKate Stone   CommandObjectBreakpointDisable(CommandInterpreter &interpreter)
954b9c1b51eSKate Stone       : CommandObjectParsed(
955b9c1b51eSKate Stone             interpreter, "breakpoint disable",
956b9c1b51eSKate Stone             "Disable the specified breakpoint(s) without deleting "
9577428a18cSKate Stone             "them.  If none are specified, disable all "
9587428a18cSKate Stone             "breakpoints.",
959b9c1b51eSKate Stone             nullptr) {
960b9c1b51eSKate Stone     SetHelpLong(
961b9c1b51eSKate Stone         "Disable the specified breakpoint(s) without deleting them.  \
9627428a18cSKate Stone If none are specified, disable all breakpoints."
9637428a18cSKate Stone         R"(
964ea671fbdSKate Stone 
9657428a18cSKate Stone )"
9667428a18cSKate Stone         "Note: disabling a breakpoint will cause none of its locations to be hit \
9677428a18cSKate Stone regardless of whether individual locations are enabled or disabled.  After the sequence:"
9687428a18cSKate Stone         R"(
969ea671fbdSKate Stone 
970ea671fbdSKate Stone     (lldb) break disable 1
971ea671fbdSKate Stone     (lldb) break enable 1.1
972ea671fbdSKate Stone 
973ea671fbdSKate Stone execution will NOT stop at location 1.1.  To achieve that, type:
974ea671fbdSKate Stone 
975ea671fbdSKate Stone     (lldb) break disable 1.*
976ea671fbdSKate Stone     (lldb) break enable 1.1
977ea671fbdSKate Stone 
9787428a18cSKate Stone )"
9797428a18cSKate Stone         "The first command disables all locations for breakpoint 1, \
9807428a18cSKate Stone the second re-enables the first location.");
981b0fac509SJim Ingham 
9825a988416SJim Ingham     CommandArgumentEntry arg;
983b9c1b51eSKate Stone     CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
984b9c1b51eSKate Stone                                       eArgTypeBreakpointIDRange);
985b9c1b51eSKate Stone     // Add the entry for the first argument for this command to the object's
986b9c1b51eSKate Stone     // arguments vector.
9875a988416SJim Ingham     m_arguments.push_back(arg);
9885a988416SJim Ingham   }
9895a988416SJim Ingham 
9909e85e5a8SEugene Zelenko   ~CommandObjectBreakpointDisable() override = default;
9915a988416SJim Ingham 
9925a988416SJim Ingham protected:
993b9c1b51eSKate Stone   bool DoExecute(Args &command, CommandReturnObject &result) override {
994cb2380c9SRaphael Isemann     Target &target = GetSelectedOrDummyTarget();
995bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
996cb2380c9SRaphael Isemann     target.GetBreakpointList().GetListMutex(lock);
9975a988416SJim Ingham 
998cb2380c9SRaphael Isemann     const BreakpointList &breakpoints = target.GetBreakpointList();
9995a988416SJim Ingham     size_t num_breakpoints = breakpoints.GetSize();
10005a988416SJim Ingham 
1001b9c1b51eSKate Stone     if (num_breakpoints == 0) {
10025a988416SJim Ingham       result.AppendError("No breakpoints exist to be disabled.");
10035a988416SJim Ingham       result.SetStatus(eReturnStatusFailed);
10045a988416SJim Ingham       return false;
10055a988416SJim Ingham     }
10065a988416SJim Ingham 
100711eb9c64SZachary Turner     if (command.empty()) {
10085a988416SJim Ingham       // No breakpoint selected; disable all currently set breakpoints.
1009cb2380c9SRaphael Isemann       target.DisableAllowedBreakpoints();
1010b9c1b51eSKate Stone       result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64
1011b9c1b51eSKate Stone                                      " breakpoints)\n",
1012b9c1b51eSKate Stone                                      (uint64_t)num_breakpoints);
10135a988416SJim Ingham       result.SetStatus(eReturnStatusSuccessFinishNoResult);
1014b9c1b51eSKate Stone     } else {
10155a988416SJim Ingham       // Particular breakpoint selected; disable that breakpoint.
10165a988416SJim Ingham       BreakpointIDList valid_bp_ids;
10175a988416SJim Ingham 
1018b9c1b51eSKate Stone       CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1019cb2380c9SRaphael Isemann           command, &target, result, &valid_bp_ids,
1020b842f2ecSJim Ingham           BreakpointName::Permissions::PermissionKinds::disablePerm);
10215a988416SJim Ingham 
1022b9c1b51eSKate Stone       if (result.Succeeded()) {
10235a988416SJim Ingham         int disable_count = 0;
10245a988416SJim Ingham         int loc_count = 0;
10255a988416SJim Ingham         const size_t count = valid_bp_ids.GetSize();
1026b9c1b51eSKate Stone         for (size_t i = 0; i < count; ++i) {
10275a988416SJim Ingham           BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
10285a988416SJim Ingham 
1029b9c1b51eSKate Stone           if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
1030b9c1b51eSKate Stone             Breakpoint *breakpoint =
1031cb2380c9SRaphael Isemann                 target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1032b9c1b51eSKate Stone             if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
1033b9c1b51eSKate Stone               BreakpointLocation *location =
1034b9c1b51eSKate Stone                   breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
1035b9c1b51eSKate Stone               if (location) {
10365a988416SJim Ingham                 location->SetEnabled(false);
10375a988416SJim Ingham                 ++loc_count;
10385a988416SJim Ingham               }
1039b9c1b51eSKate Stone             } else {
10405a988416SJim Ingham               breakpoint->SetEnabled(false);
10415a988416SJim Ingham               ++disable_count;
10425a988416SJim Ingham             }
10435a988416SJim Ingham           }
10445a988416SJim Ingham         }
1045b9c1b51eSKate Stone         result.AppendMessageWithFormat("%d breakpoints disabled.\n",
1046b9c1b51eSKate Stone                                        disable_count + loc_count);
10475a988416SJim Ingham         result.SetStatus(eReturnStatusSuccessFinishNoResult);
10485a988416SJim Ingham       }
10495a988416SJim Ingham     }
10505a988416SJim Ingham 
10515a988416SJim Ingham     return result.Succeeded();
10525a988416SJim Ingham   }
10535a988416SJim Ingham };
10545a988416SJim Ingham 
10555a988416SJim Ingham // CommandObjectBreakpointList
10561f0f5b5bSZachary Turner 
10571f0f5b5bSZachary Turner #pragma mark List::CommandOptions
10586f4fb4e7SRaphael Isemann #define LLDB_OPTIONS_breakpoint_list
1059c5a2d747SRaphael Isemann #include "CommandOptions.inc"
10601f0f5b5bSZachary Turner 
10615a988416SJim Ingham #pragma mark List
10625a988416SJim Ingham 
1063b9c1b51eSKate Stone class CommandObjectBreakpointList : public CommandObjectParsed {
10645a988416SJim Ingham public:
1065b9c1b51eSKate Stone   CommandObjectBreakpointList(CommandInterpreter &interpreter)
1066b9c1b51eSKate Stone       : CommandObjectParsed(
1067b9c1b51eSKate Stone             interpreter, "breakpoint list",
10685a988416SJim Ingham             "List some or all breakpoints at configurable levels of detail.",
10699e85e5a8SEugene Zelenko             nullptr),
1070b9c1b51eSKate Stone         m_options() {
10715a988416SJim Ingham     CommandArgumentEntry arg;
10725a988416SJim Ingham     CommandArgumentData bp_id_arg;
10735a988416SJim Ingham 
10745a988416SJim Ingham     // Define the first (and only) variant of this arg.
10755a988416SJim Ingham     bp_id_arg.arg_type = eArgTypeBreakpointID;
10765a988416SJim Ingham     bp_id_arg.arg_repetition = eArgRepeatOptional;
10775a988416SJim Ingham 
1078b9c1b51eSKate Stone     // There is only one variant this argument could be; put it into the
1079b9c1b51eSKate Stone     // argument entry.
10805a988416SJim Ingham     arg.push_back(bp_id_arg);
10815a988416SJim Ingham 
10825a988416SJim Ingham     // Push the data for the first argument into the m_arguments vector.
10835a988416SJim Ingham     m_arguments.push_back(arg);
10845a988416SJim Ingham   }
10855a988416SJim Ingham 
10869e85e5a8SEugene Zelenko   ~CommandObjectBreakpointList() override = default;
10875a988416SJim Ingham 
1088b9c1b51eSKate Stone   Options *GetOptions() override { return &m_options; }
10895a988416SJim Ingham 
1090b9c1b51eSKate Stone   class CommandOptions : public Options {
10915a988416SJim Ingham   public:
1092b9c1b51eSKate Stone     CommandOptions()
1093b9c1b51eSKate Stone         : Options(), m_level(lldb::eDescriptionLevelBrief), m_use_dummy(false) {
10945a988416SJim Ingham     }
10955a988416SJim Ingham 
10969e85e5a8SEugene Zelenko     ~CommandOptions() override = default;
10975a988416SJim Ingham 
109897206d57SZachary Turner     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1099b9c1b51eSKate Stone                           ExecutionContext *execution_context) override {
110097206d57SZachary Turner       Status error;
11013bcdfc0eSGreg Clayton       const int short_option = m_getopt_table[option_idx].val;
11025a988416SJim Ingham 
1103b9c1b51eSKate Stone       switch (short_option) {
11045a988416SJim Ingham       case 'b':
11055a988416SJim Ingham         m_level = lldb::eDescriptionLevelBrief;
11065a988416SJim Ingham         break;
110733df7cd3SJim Ingham       case 'D':
110833df7cd3SJim Ingham         m_use_dummy = true;
110933df7cd3SJim Ingham         break;
11105a988416SJim Ingham       case 'f':
11115a988416SJim Ingham         m_level = lldb::eDescriptionLevelFull;
11125a988416SJim Ingham         break;
11135a988416SJim Ingham       case 'v':
11145a988416SJim Ingham         m_level = lldb::eDescriptionLevelVerbose;
11155a988416SJim Ingham         break;
11165a988416SJim Ingham       case 'i':
11175a988416SJim Ingham         m_internal = true;
11185a988416SJim Ingham         break;
11195a988416SJim Ingham       default:
112036162014SRaphael Isemann         llvm_unreachable("Unimplemented option");
11215a988416SJim Ingham       }
11225a988416SJim Ingham 
11235a988416SJim Ingham       return error;
11245a988416SJim Ingham     }
11255a988416SJim Ingham 
1126b9c1b51eSKate Stone     void OptionParsingStarting(ExecutionContext *execution_context) override {
11275a988416SJim Ingham       m_level = lldb::eDescriptionLevelFull;
11285a988416SJim Ingham       m_internal = false;
112933df7cd3SJim Ingham       m_use_dummy = false;
11305a988416SJim Ingham     }
11315a988416SJim Ingham 
11321f0f5b5bSZachary Turner     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
113370602439SZachary Turner       return llvm::makeArrayRef(g_breakpoint_list_options);
11341f0f5b5bSZachary Turner     }
11355a988416SJim Ingham 
11365a988416SJim Ingham     // Instance variables to hold the values for command options.
11375a988416SJim Ingham 
11385a988416SJim Ingham     lldb::DescriptionLevel m_level;
11395a988416SJim Ingham 
11405a988416SJim Ingham     bool m_internal;
114133df7cd3SJim Ingham     bool m_use_dummy;
11425a988416SJim Ingham   };
11435a988416SJim Ingham 
11445a988416SJim Ingham protected:
1145b9c1b51eSKate Stone   bool DoExecute(Args &command, CommandReturnObject &result) override {
1146cb2380c9SRaphael Isemann     Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
11475a988416SJim Ingham 
1148b9c1b51eSKate Stone     const BreakpointList &breakpoints =
1149cb2380c9SRaphael Isemann         target.GetBreakpointList(m_options.m_internal);
1150bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
1151cb2380c9SRaphael Isemann     target.GetBreakpointList(m_options.m_internal).GetListMutex(lock);
11525a988416SJim Ingham 
11535a988416SJim Ingham     size_t num_breakpoints = breakpoints.GetSize();
11545a988416SJim Ingham 
1155b9c1b51eSKate Stone     if (num_breakpoints == 0) {
11565a988416SJim Ingham       result.AppendMessage("No breakpoints currently set.");
11575a988416SJim Ingham       result.SetStatus(eReturnStatusSuccessFinishNoResult);
11585a988416SJim Ingham       return true;
11595a988416SJim Ingham     }
11605a988416SJim Ingham 
11615a988416SJim Ingham     Stream &output_stream = result.GetOutputStream();
11625a988416SJim Ingham 
116311eb9c64SZachary Turner     if (command.empty()) {
11645a988416SJim Ingham       // No breakpoint selected; show info about all currently set breakpoints.
11655a988416SJim Ingham       result.AppendMessage("Current breakpoints:");
1166b9c1b51eSKate Stone       for (size_t i = 0; i < num_breakpoints; ++i) {
11675a988416SJim Ingham         Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex(i).get();
1168b842f2ecSJim Ingham         if (breakpoint->AllowList())
1169b842f2ecSJim Ingham           AddBreakpointDescription(&output_stream, breakpoint,
1170b842f2ecSJim Ingham                                    m_options.m_level);
11715a988416SJim Ingham       }
11725a988416SJim Ingham       result.SetStatus(eReturnStatusSuccessFinishNoResult);
1173b9c1b51eSKate Stone     } else {
11745a988416SJim Ingham       // Particular breakpoints selected; show info about that breakpoint.
11755a988416SJim Ingham       BreakpointIDList valid_bp_ids;
1176b9c1b51eSKate Stone       CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1177cb2380c9SRaphael Isemann           command, &target, result, &valid_bp_ids,
1178b842f2ecSJim Ingham           BreakpointName::Permissions::PermissionKinds::listPerm);
11795a988416SJim Ingham 
1180b9c1b51eSKate Stone       if (result.Succeeded()) {
1181b9c1b51eSKate Stone         for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) {
11825a988416SJim Ingham           BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
1183b9c1b51eSKate Stone           Breakpoint *breakpoint =
1184cb2380c9SRaphael Isemann               target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1185b9c1b51eSKate Stone           AddBreakpointDescription(&output_stream, breakpoint,
1186b9c1b51eSKate Stone                                    m_options.m_level);
11875a988416SJim Ingham         }
11885a988416SJim Ingham         result.SetStatus(eReturnStatusSuccessFinishNoResult);
1189b9c1b51eSKate Stone       } else {
11907428a18cSKate Stone         result.AppendError("Invalid breakpoint ID.");
11915a988416SJim Ingham         result.SetStatus(eReturnStatusFailed);
11925a988416SJim Ingham       }
11935a988416SJim Ingham     }
11945a988416SJim Ingham 
11955a988416SJim Ingham     return result.Succeeded();
11965a988416SJim Ingham   }
11975a988416SJim Ingham 
11985a988416SJim Ingham private:
11995a988416SJim Ingham   CommandOptions m_options;
12005a988416SJim Ingham };
12015a988416SJim Ingham 
12025a988416SJim Ingham // CommandObjectBreakpointClear
12031f0f5b5bSZachary Turner #pragma mark Clear::CommandOptions
12041f0f5b5bSZachary Turner 
1205f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_clear
1206f94668e3SRaphael Isemann #include "CommandOptions.inc"
12071f0f5b5bSZachary Turner 
12085a988416SJim Ingham #pragma mark Clear
12095a988416SJim Ingham 
1210b9c1b51eSKate Stone class CommandObjectBreakpointClear : public CommandObjectParsed {
12115a988416SJim Ingham public:
1212efe8e7e3SFangrui Song   enum BreakpointClearType { eClearTypeInvalid, eClearTypeFileAndLine };
12135a988416SJim Ingham 
12147428a18cSKate Stone   CommandObjectBreakpointClear(CommandInterpreter &interpreter)
12157428a18cSKate Stone       : CommandObjectParsed(interpreter, "breakpoint clear",
1216b9c1b51eSKate Stone                             "Delete or disable breakpoints matching the "
1217b9c1b51eSKate Stone                             "specified source file and line.",
12185a988416SJim Ingham                             "breakpoint clear <cmd-options>"),
1219b9c1b51eSKate Stone         m_options() {}
12205a988416SJim Ingham 
12219e85e5a8SEugene Zelenko   ~CommandObjectBreakpointClear() override = default;
12225a988416SJim Ingham 
1223b9c1b51eSKate Stone   Options *GetOptions() override { return &m_options; }
12245a988416SJim Ingham 
1225b9c1b51eSKate Stone   class CommandOptions : public Options {
12265a988416SJim Ingham   public:
1227b9c1b51eSKate Stone     CommandOptions() : Options(), m_filename(), m_line_num(0) {}
12285a988416SJim Ingham 
12299e85e5a8SEugene Zelenko     ~CommandOptions() override = default;
12305a988416SJim Ingham 
123197206d57SZachary Turner     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1232b9c1b51eSKate Stone                           ExecutionContext *execution_context) override {
123397206d57SZachary Turner       Status error;
12343bcdfc0eSGreg Clayton       const int short_option = m_getopt_table[option_idx].val;
12355a988416SJim Ingham 
1236b9c1b51eSKate Stone       switch (short_option) {
12375a988416SJim Ingham       case 'f':
12385a988416SJim Ingham         m_filename.assign(option_arg);
12395a988416SJim Ingham         break;
12405a988416SJim Ingham 
12415a988416SJim Ingham       case 'l':
1242fe11483bSZachary Turner         option_arg.getAsInteger(0, m_line_num);
12435a988416SJim Ingham         break;
12445a988416SJim Ingham 
12455a988416SJim Ingham       default:
124636162014SRaphael Isemann         llvm_unreachable("Unimplemented option");
12475a988416SJim Ingham       }
12485a988416SJim Ingham 
12495a988416SJim Ingham       return error;
12505a988416SJim Ingham     }
12515a988416SJim Ingham 
1252b9c1b51eSKate Stone     void OptionParsingStarting(ExecutionContext *execution_context) override {
12535a988416SJim Ingham       m_filename.clear();
12545a988416SJim Ingham       m_line_num = 0;
12555a988416SJim Ingham     }
12565a988416SJim Ingham 
12571f0f5b5bSZachary Turner     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
125870602439SZachary Turner       return llvm::makeArrayRef(g_breakpoint_clear_options);
12591f0f5b5bSZachary Turner     }
12605a988416SJim Ingham 
12615a988416SJim Ingham     // Instance variables to hold the values for command options.
12625a988416SJim Ingham 
12635a988416SJim Ingham     std::string m_filename;
12645a988416SJim Ingham     uint32_t m_line_num;
12655a988416SJim Ingham   };
12665a988416SJim Ingham 
12675a988416SJim Ingham protected:
1268b9c1b51eSKate Stone   bool DoExecute(Args &command, CommandReturnObject &result) override {
1269cb2380c9SRaphael Isemann     Target &target = GetSelectedOrDummyTarget();
12705a988416SJim Ingham 
127105097246SAdrian Prantl     // The following are the various types of breakpoints that could be
127205097246SAdrian Prantl     // cleared:
12735a988416SJim Ingham     //   1). -f -l (clearing breakpoint by source location)
12745a988416SJim Ingham 
12755a988416SJim Ingham     BreakpointClearType break_type = eClearTypeInvalid;
12765a988416SJim Ingham 
12775a988416SJim Ingham     if (m_options.m_line_num != 0)
12785a988416SJim Ingham       break_type = eClearTypeFileAndLine;
12795a988416SJim Ingham 
1280bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
1281cb2380c9SRaphael Isemann     target.GetBreakpointList().GetListMutex(lock);
12825a988416SJim Ingham 
1283cb2380c9SRaphael Isemann     BreakpointList &breakpoints = target.GetBreakpointList();
12845a988416SJim Ingham     size_t num_breakpoints = breakpoints.GetSize();
12855a988416SJim Ingham 
12865a988416SJim Ingham     // Early return if there's no breakpoint at all.
1287b9c1b51eSKate Stone     if (num_breakpoints == 0) {
12885a988416SJim Ingham       result.AppendError("Breakpoint clear: No breakpoint cleared.");
12895a988416SJim Ingham       result.SetStatus(eReturnStatusFailed);
12905a988416SJim Ingham       return result.Succeeded();
12915a988416SJim Ingham     }
12925a988416SJim Ingham 
12935a988416SJim Ingham     // Find matching breakpoints and delete them.
12945a988416SJim Ingham 
12955a988416SJim Ingham     // First create a copy of all the IDs.
12965a988416SJim Ingham     std::vector<break_id_t> BreakIDs;
12975a988416SJim Ingham     for (size_t i = 0; i < num_breakpoints; ++i)
12989e85e5a8SEugene Zelenko       BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID());
12995a988416SJim Ingham 
13005a988416SJim Ingham     int num_cleared = 0;
13015a988416SJim Ingham     StreamString ss;
1302b9c1b51eSKate Stone     switch (break_type) {
13035a988416SJim Ingham     case eClearTypeFileAndLine: // Breakpoint by source position
13045a988416SJim Ingham     {
13055a988416SJim Ingham       const ConstString filename(m_options.m_filename.c_str());
13065a988416SJim Ingham       BreakpointLocationCollection loc_coll;
13075a988416SJim Ingham 
1308b9c1b51eSKate Stone       for (size_t i = 0; i < num_breakpoints; ++i) {
13095a988416SJim Ingham         Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
13105a988416SJim Ingham 
1311b9c1b51eSKate Stone         if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) {
1312b9c1b51eSKate Stone           // If the collection size is 0, it's a full match and we can just
1313b9c1b51eSKate Stone           // remove the breakpoint.
1314b9c1b51eSKate Stone           if (loc_coll.GetSize() == 0) {
13155a988416SJim Ingham             bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
13165a988416SJim Ingham             ss.EOL();
1317cb2380c9SRaphael Isemann             target.RemoveBreakpointByID(bp->GetID());
13185a988416SJim Ingham             ++num_cleared;
13195a988416SJim Ingham           }
13205a988416SJim Ingham         }
13215a988416SJim Ingham       }
1322b9c1b51eSKate Stone     } break;
13235a988416SJim Ingham 
13245a988416SJim Ingham     default:
13255a988416SJim Ingham       break;
13265a988416SJim Ingham     }
13275a988416SJim Ingham 
1328b9c1b51eSKate Stone     if (num_cleared > 0) {
13295a988416SJim Ingham       Stream &output_stream = result.GetOutputStream();
13305a988416SJim Ingham       output_stream.Printf("%d breakpoints cleared:\n", num_cleared);
1331c156427dSZachary Turner       output_stream << ss.GetString();
13325a988416SJim Ingham       output_stream.EOL();
13335a988416SJim Ingham       result.SetStatus(eReturnStatusSuccessFinishNoResult);
1334b9c1b51eSKate Stone     } else {
13355a988416SJim Ingham       result.AppendError("Breakpoint clear: No breakpoint cleared.");
13365a988416SJim Ingham       result.SetStatus(eReturnStatusFailed);
13375a988416SJim Ingham     }
13385a988416SJim Ingham 
13395a988416SJim Ingham     return result.Succeeded();
13405a988416SJim Ingham   }
13415a988416SJim Ingham 
13425a988416SJim Ingham private:
13435a988416SJim Ingham   CommandOptions m_options;
13445a988416SJim Ingham };
13455a988416SJim Ingham 
13465a988416SJim Ingham // CommandObjectBreakpointDelete
1347f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_delete
1348f94668e3SRaphael Isemann #include "CommandOptions.inc"
13491f0f5b5bSZachary Turner 
13505a988416SJim Ingham #pragma mark Delete
13515a988416SJim Ingham 
1352b9c1b51eSKate Stone class CommandObjectBreakpointDelete : public CommandObjectParsed {
13535a988416SJim Ingham public:
1354b9c1b51eSKate Stone   CommandObjectBreakpointDelete(CommandInterpreter &interpreter)
1355b9c1b51eSKate Stone       : CommandObjectParsed(interpreter, "breakpoint delete",
1356b9c1b51eSKate Stone                             "Delete the specified breakpoint(s).  If no "
1357b9c1b51eSKate Stone                             "breakpoints are specified, delete them all.",
13589e85e5a8SEugene Zelenko                             nullptr),
1359b9c1b51eSKate Stone         m_options() {
13605a988416SJim Ingham     CommandArgumentEntry arg;
1361b9c1b51eSKate Stone     CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
1362b9c1b51eSKate Stone                                       eArgTypeBreakpointIDRange);
1363b9c1b51eSKate Stone     // Add the entry for the first argument for this command to the object's
1364b9c1b51eSKate Stone     // arguments vector.
13655a988416SJim Ingham     m_arguments.push_back(arg);
13665a988416SJim Ingham   }
13675a988416SJim Ingham 
13689e85e5a8SEugene Zelenko   ~CommandObjectBreakpointDelete() override = default;
13695a988416SJim Ingham 
1370b9c1b51eSKate Stone   Options *GetOptions() override { return &m_options; }
137133df7cd3SJim Ingham 
1372b9c1b51eSKate Stone   class CommandOptions : public Options {
137333df7cd3SJim Ingham   public:
1374b9c1b51eSKate Stone     CommandOptions() : Options(), m_use_dummy(false), m_force(false) {}
137533df7cd3SJim Ingham 
13769e85e5a8SEugene Zelenko     ~CommandOptions() override = default;
137733df7cd3SJim Ingham 
137897206d57SZachary Turner     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1379b9c1b51eSKate Stone                           ExecutionContext *execution_context) override {
138097206d57SZachary Turner       Status error;
138133df7cd3SJim Ingham       const int short_option = m_getopt_table[option_idx].val;
138233df7cd3SJim Ingham 
1383b9c1b51eSKate Stone       switch (short_option) {
138433df7cd3SJim Ingham       case 'f':
138533df7cd3SJim Ingham         m_force = true;
138633df7cd3SJim Ingham         break;
138733df7cd3SJim Ingham 
138833df7cd3SJim Ingham       case 'D':
138933df7cd3SJim Ingham         m_use_dummy = true;
139033df7cd3SJim Ingham         break;
139133df7cd3SJim Ingham 
139233df7cd3SJim Ingham       default:
139336162014SRaphael Isemann         llvm_unreachable("Unimplemented option");
139433df7cd3SJim Ingham       }
139533df7cd3SJim Ingham 
139633df7cd3SJim Ingham       return error;
139733df7cd3SJim Ingham     }
139833df7cd3SJim Ingham 
1399b9c1b51eSKate Stone     void OptionParsingStarting(ExecutionContext *execution_context) override {
140033df7cd3SJim Ingham       m_use_dummy = false;
140133df7cd3SJim Ingham       m_force = false;
140233df7cd3SJim Ingham     }
140333df7cd3SJim Ingham 
14041f0f5b5bSZachary Turner     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
140570602439SZachary Turner       return llvm::makeArrayRef(g_breakpoint_delete_options);
14061f0f5b5bSZachary Turner     }
140733df7cd3SJim Ingham 
140833df7cd3SJim Ingham     // Instance variables to hold the values for command options.
140933df7cd3SJim Ingham     bool m_use_dummy;
141033df7cd3SJim Ingham     bool m_force;
141133df7cd3SJim Ingham   };
141233df7cd3SJim Ingham 
14135a988416SJim Ingham protected:
1414b9c1b51eSKate Stone   bool DoExecute(Args &command, CommandReturnObject &result) override {
1415cb2380c9SRaphael Isemann     Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
14165a988416SJim Ingham 
1417bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
1418cb2380c9SRaphael Isemann     target.GetBreakpointList().GetListMutex(lock);
14195a988416SJim Ingham 
1420cb2380c9SRaphael Isemann     const BreakpointList &breakpoints = target.GetBreakpointList();
14215a988416SJim Ingham 
14225a988416SJim Ingham     size_t num_breakpoints = breakpoints.GetSize();
14235a988416SJim Ingham 
1424b9c1b51eSKate Stone     if (num_breakpoints == 0) {
14255a988416SJim Ingham       result.AppendError("No breakpoints exist to be deleted.");
14265a988416SJim Ingham       result.SetStatus(eReturnStatusFailed);
14275a988416SJim Ingham       return false;
14285a988416SJim Ingham     }
14295a988416SJim Ingham 
143011eb9c64SZachary Turner     if (command.empty()) {
1431b9c1b51eSKate Stone       if (!m_options.m_force &&
1432b9c1b51eSKate Stone           !m_interpreter.Confirm(
1433b9c1b51eSKate Stone               "About to delete all breakpoints, do you want to do that?",
1434b9c1b51eSKate Stone               true)) {
14355a988416SJim Ingham         result.AppendMessage("Operation cancelled...");
1436b9c1b51eSKate Stone       } else {
1437cb2380c9SRaphael Isemann         target.RemoveAllowedBreakpoints();
1438b9c1b51eSKate Stone         result.AppendMessageWithFormat(
1439b9c1b51eSKate Stone             "All breakpoints removed. (%" PRIu64 " breakpoint%s)\n",
1440b9c1b51eSKate Stone             (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
14415a988416SJim Ingham       }
14425a988416SJim Ingham       result.SetStatus(eReturnStatusSuccessFinishNoResult);
1443b9c1b51eSKate Stone     } else {
14445a988416SJim Ingham       // Particular breakpoint selected; disable that breakpoint.
14455a988416SJim Ingham       BreakpointIDList valid_bp_ids;
1446b9c1b51eSKate Stone       CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
1447cb2380c9SRaphael Isemann           command, &target, result, &valid_bp_ids,
1448b842f2ecSJim Ingham           BreakpointName::Permissions::PermissionKinds::deletePerm);
14495a988416SJim Ingham 
1450b9c1b51eSKate Stone       if (result.Succeeded()) {
14515a988416SJim Ingham         int delete_count = 0;
14525a988416SJim Ingham         int disable_count = 0;
14535a988416SJim Ingham         const size_t count = valid_bp_ids.GetSize();
1454b9c1b51eSKate Stone         for (size_t i = 0; i < count; ++i) {
14555a988416SJim Ingham           BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
14565a988416SJim Ingham 
1457b9c1b51eSKate Stone           if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
1458b9c1b51eSKate Stone             if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
1459b9c1b51eSKate Stone               Breakpoint *breakpoint =
1460cb2380c9SRaphael Isemann                   target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
1461b9c1b51eSKate Stone               BreakpointLocation *location =
1462b9c1b51eSKate Stone                   breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
1463b9c1b51eSKate Stone               // It makes no sense to try to delete individual locations, so we
1464b9c1b51eSKate Stone               // disable them instead.
1465b9c1b51eSKate Stone               if (location) {
14665a988416SJim Ingham                 location->SetEnabled(false);
14675a988416SJim Ingham                 ++disable_count;
14685a988416SJim Ingham               }
1469b9c1b51eSKate Stone             } else {
1470cb2380c9SRaphael Isemann               target.RemoveBreakpointByID(cur_bp_id.GetBreakpointID());
14715a988416SJim Ingham               ++delete_count;
14725a988416SJim Ingham             }
14735a988416SJim Ingham           }
14745a988416SJim Ingham         }
1475b9c1b51eSKate Stone         result.AppendMessageWithFormat(
1476b9c1b51eSKate Stone             "%d breakpoints deleted; %d breakpoint locations disabled.\n",
14775a988416SJim Ingham             delete_count, disable_count);
14785a988416SJim Ingham         result.SetStatus(eReturnStatusSuccessFinishNoResult);
14795a988416SJim Ingham       }
14805a988416SJim Ingham     }
14815a988416SJim Ingham     return result.Succeeded();
14825a988416SJim Ingham   }
14839e85e5a8SEugene Zelenko 
148433df7cd3SJim Ingham private:
148533df7cd3SJim Ingham   CommandOptions m_options;
148633df7cd3SJim Ingham };
148733df7cd3SJim Ingham 
14885e09c8c3SJim Ingham // CommandObjectBreakpointName
1489f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_name
1490f94668e3SRaphael Isemann #include "CommandOptions.inc"
1491bd68a052SRaphael Isemann 
1492b9c1b51eSKate Stone class BreakpointNameOptionGroup : public OptionGroup {
14935e09c8c3SJim Ingham public:
1494b9c1b51eSKate Stone   BreakpointNameOptionGroup()
1495b9c1b51eSKate Stone       : OptionGroup(), m_breakpoint(LLDB_INVALID_BREAK_ID), m_use_dummy(false) {
14965e09c8c3SJim Ingham   }
14975e09c8c3SJim Ingham 
14989e85e5a8SEugene Zelenko   ~BreakpointNameOptionGroup() override = default;
14995e09c8c3SJim Ingham 
15001f0f5b5bSZachary Turner   llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
150170602439SZachary Turner     return llvm::makeArrayRef(g_breakpoint_name_options);
15025e09c8c3SJim Ingham   }
15035e09c8c3SJim Ingham 
150497206d57SZachary Turner   Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1505b9c1b51eSKate Stone                         ExecutionContext *execution_context) override {
150697206d57SZachary Turner     Status error;
15075e09c8c3SJim Ingham     const int short_option = g_breakpoint_name_options[option_idx].short_option;
15085e09c8c3SJim Ingham 
1509b9c1b51eSKate Stone     switch (short_option) {
15105e09c8c3SJim Ingham     case 'N':
1511fe11483bSZachary Turner       if (BreakpointID::StringIsBreakpointName(option_arg, error) &&
1512b9c1b51eSKate Stone           error.Success())
1513fe11483bSZachary Turner         m_name.SetValueFromString(option_arg);
15145e09c8c3SJim Ingham       break;
15155e09c8c3SJim Ingham     case 'B':
1516fe11483bSZachary Turner       if (m_breakpoint.SetValueFromString(option_arg).Fail())
1517b9c1b51eSKate Stone         error.SetErrorStringWithFormat(
15188cef4b0bSZachary Turner             "unrecognized value \"%s\" for breakpoint",
1519fe11483bSZachary Turner             option_arg.str().c_str());
15205e09c8c3SJim Ingham       break;
15215e09c8c3SJim Ingham     case 'D':
1522fe11483bSZachary Turner       if (m_use_dummy.SetValueFromString(option_arg).Fail())
1523b9c1b51eSKate Stone         error.SetErrorStringWithFormat(
15248cef4b0bSZachary Turner             "unrecognized value \"%s\" for use-dummy",
1525fe11483bSZachary Turner             option_arg.str().c_str());
15265e09c8c3SJim Ingham       break;
1527e9632ebaSJim Ingham     case 'H':
1528e9632ebaSJim Ingham       m_help_string.SetValueFromString(option_arg);
1529e9632ebaSJim Ingham       break;
15305e09c8c3SJim Ingham 
15315e09c8c3SJim Ingham     default:
153236162014SRaphael Isemann       llvm_unreachable("Unimplemented option");
15335e09c8c3SJim Ingham     }
15345e09c8c3SJim Ingham     return error;
15355e09c8c3SJim Ingham   }
15365e09c8c3SJim Ingham 
1537b9c1b51eSKate Stone   void OptionParsingStarting(ExecutionContext *execution_context) override {
15385e09c8c3SJim Ingham     m_name.Clear();
15395e09c8c3SJim Ingham     m_breakpoint.Clear();
15405e09c8c3SJim Ingham     m_use_dummy.Clear();
15415e09c8c3SJim Ingham     m_use_dummy.SetDefaultValue(false);
1542e9632ebaSJim Ingham     m_help_string.Clear();
15435e09c8c3SJim Ingham   }
15445e09c8c3SJim Ingham 
15455e09c8c3SJim Ingham   OptionValueString m_name;
15465e09c8c3SJim Ingham   OptionValueUInt64 m_breakpoint;
15475e09c8c3SJim Ingham   OptionValueBoolean m_use_dummy;
1548e9632ebaSJim Ingham   OptionValueString m_help_string;
15495e09c8c3SJim Ingham };
15505e09c8c3SJim Ingham 
1551f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_access
1552f94668e3SRaphael Isemann #include "CommandOptions.inc"
1553b842f2ecSJim Ingham 
15548fe53c49STatyana Krasnukha class BreakpointAccessOptionGroup : public OptionGroup {
1555b842f2ecSJim Ingham public:
15568fe53c49STatyana Krasnukha   BreakpointAccessOptionGroup() : OptionGroup() {}
1557b842f2ecSJim Ingham 
1558b842f2ecSJim Ingham   ~BreakpointAccessOptionGroup() override = default;
1559b842f2ecSJim Ingham 
1560b842f2ecSJim Ingham   llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1561b842f2ecSJim Ingham     return llvm::makeArrayRef(g_breakpoint_access_options);
1562b842f2ecSJim Ingham   }
1563b842f2ecSJim Ingham   Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1564b842f2ecSJim Ingham                         ExecutionContext *execution_context) override {
1565b842f2ecSJim Ingham     Status error;
1566*a925974bSAdrian Prantl     const int short_option =
1567*a925974bSAdrian Prantl         g_breakpoint_access_options[option_idx].short_option;
1568b842f2ecSJim Ingham 
1569b842f2ecSJim Ingham     switch (short_option) {
1570b842f2ecSJim Ingham     case 'L': {
1571b842f2ecSJim Ingham       bool value, success;
157247cbf4a0SPavel Labath       value = OptionArgParser::ToBoolean(option_arg, false, &success);
1573b842f2ecSJim Ingham       if (success) {
1574b842f2ecSJim Ingham         m_permissions.SetAllowList(value);
1575b842f2ecSJim Ingham       } else
1576b842f2ecSJim Ingham         error.SetErrorStringWithFormat(
1577b842f2ecSJim Ingham             "invalid boolean value '%s' passed for -L option",
1578b842f2ecSJim Ingham             option_arg.str().c_str());
1579b842f2ecSJim Ingham     } break;
1580b842f2ecSJim Ingham     case 'A': {
1581b842f2ecSJim Ingham       bool value, success;
158247cbf4a0SPavel Labath       value = OptionArgParser::ToBoolean(option_arg, false, &success);
1583b842f2ecSJim Ingham       if (success) {
1584b842f2ecSJim Ingham         m_permissions.SetAllowDisable(value);
1585b842f2ecSJim Ingham       } else
1586b842f2ecSJim Ingham         error.SetErrorStringWithFormat(
1587b842f2ecSJim Ingham             "invalid boolean value '%s' passed for -L option",
1588b842f2ecSJim Ingham             option_arg.str().c_str());
1589b842f2ecSJim Ingham     } break;
1590b842f2ecSJim Ingham     case 'D': {
1591b842f2ecSJim Ingham       bool value, success;
159247cbf4a0SPavel Labath       value = OptionArgParser::ToBoolean(option_arg, false, &success);
1593b842f2ecSJim Ingham       if (success) {
1594b842f2ecSJim Ingham         m_permissions.SetAllowDelete(value);
1595b842f2ecSJim Ingham       } else
1596b842f2ecSJim Ingham         error.SetErrorStringWithFormat(
1597b842f2ecSJim Ingham             "invalid boolean value '%s' passed for -L option",
1598b842f2ecSJim Ingham             option_arg.str().c_str());
1599b842f2ecSJim Ingham     } break;
160036162014SRaphael Isemann     default:
160136162014SRaphael Isemann       llvm_unreachable("Unimplemented option");
1602b842f2ecSJim Ingham     }
1603b842f2ecSJim Ingham 
1604b842f2ecSJim Ingham     return error;
1605b842f2ecSJim Ingham   }
1606b842f2ecSJim Ingham 
1607*a925974bSAdrian Prantl   void OptionParsingStarting(ExecutionContext *execution_context) override {}
1608b842f2ecSJim Ingham 
1609*a925974bSAdrian Prantl   const BreakpointName::Permissions &GetPermissions() const {
1610b842f2ecSJim Ingham     return m_permissions;
1611b842f2ecSJim Ingham   }
1612b842f2ecSJim Ingham   BreakpointName::Permissions m_permissions;
1613b842f2ecSJim Ingham };
1614b842f2ecSJim Ingham 
1615b842f2ecSJim Ingham class CommandObjectBreakpointNameConfigure : public CommandObjectParsed {
1616b842f2ecSJim Ingham public:
1617b842f2ecSJim Ingham   CommandObjectBreakpointNameConfigure(CommandInterpreter &interpreter)
1618b842f2ecSJim Ingham       : CommandObjectParsed(
1619*a925974bSAdrian Prantl             interpreter, "configure",
1620*a925974bSAdrian Prantl             "Configure the options for the breakpoint"
1621b842f2ecSJim Ingham             " name provided.  "
1622b842f2ecSJim Ingham             "If you provide a breakpoint id, the options will be copied from "
1623b842f2ecSJim Ingham             "the breakpoint, otherwise only the options specified will be set "
1624b842f2ecSJim Ingham             "on the name.",
1625b842f2ecSJim Ingham             "breakpoint name configure <command-options> "
1626b842f2ecSJim Ingham             "<breakpoint-name-list>"),
1627b842f2ecSJim Ingham         m_bp_opts(), m_option_group() {
1628b842f2ecSJim Ingham     // Create the first variant for the first (and only) argument for this
1629b842f2ecSJim Ingham     // command.
1630b842f2ecSJim Ingham     CommandArgumentEntry arg1;
1631b842f2ecSJim Ingham     CommandArgumentData id_arg;
1632b842f2ecSJim Ingham     id_arg.arg_type = eArgTypeBreakpointName;
1633b842f2ecSJim Ingham     id_arg.arg_repetition = eArgRepeatOptional;
1634b842f2ecSJim Ingham     arg1.push_back(id_arg);
1635b842f2ecSJim Ingham     m_arguments.push_back(arg1);
1636b842f2ecSJim Ingham 
1637*a925974bSAdrian Prantl     m_option_group.Append(&m_bp_opts, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
1638*a925974bSAdrian Prantl     m_option_group.Append(&m_access_options, LLDB_OPT_SET_ALL,
1639b842f2ecSJim Ingham                           LLDB_OPT_SET_ALL);
1640*a925974bSAdrian Prantl     m_option_group.Append(&m_bp_id, LLDB_OPT_SET_2 | LLDB_OPT_SET_4,
1641e9632ebaSJim Ingham                           LLDB_OPT_SET_ALL);
1642b842f2ecSJim Ingham     m_option_group.Finalize();
1643b842f2ecSJim Ingham   }
1644b842f2ecSJim Ingham 
1645b842f2ecSJim Ingham   ~CommandObjectBreakpointNameConfigure() override = default;
1646b842f2ecSJim Ingham 
1647b842f2ecSJim Ingham   Options *GetOptions() override { return &m_option_group; }
1648b842f2ecSJim Ingham 
1649b842f2ecSJim Ingham protected:
1650b842f2ecSJim Ingham   bool DoExecute(Args &command, CommandReturnObject &result) override {
1651b842f2ecSJim Ingham 
1652b842f2ecSJim Ingham     const size_t argc = command.GetArgumentCount();
1653b842f2ecSJim Ingham     if (argc == 0) {
1654b842f2ecSJim Ingham       result.AppendError("No names provided.");
1655b842f2ecSJim Ingham       result.SetStatus(eReturnStatusFailed);
1656b842f2ecSJim Ingham       return false;
1657b842f2ecSJim Ingham     }
1658b842f2ecSJim Ingham 
1659cb2380c9SRaphael Isemann     Target &target = GetSelectedOrDummyTarget(false);
1660b842f2ecSJim Ingham 
1661b842f2ecSJim Ingham     std::unique_lock<std::recursive_mutex> lock;
1662cb2380c9SRaphael Isemann     target.GetBreakpointList().GetListMutex(lock);
1663b842f2ecSJim Ingham 
1664b842f2ecSJim Ingham     // Make a pass through first to see that all the names are legal.
1665b842f2ecSJim Ingham     for (auto &entry : command.entries()) {
1666b842f2ecSJim Ingham       Status error;
1667*a925974bSAdrian Prantl       if (!BreakpointID::StringIsBreakpointName(entry.ref(), error)) {
1668b842f2ecSJim Ingham         result.AppendErrorWithFormat("Invalid breakpoint name: %s - %s",
1669b842f2ecSJim Ingham                                      entry.c_str(), error.AsCString());
1670b842f2ecSJim Ingham         result.SetStatus(eReturnStatusFailed);
1671b842f2ecSJim Ingham         return false;
1672b842f2ecSJim Ingham       }
1673b842f2ecSJim Ingham     }
167405097246SAdrian Prantl     // Now configure them, we already pre-checked the names so we don't need to
167505097246SAdrian Prantl     // check the error:
1676b842f2ecSJim Ingham     BreakpointSP bp_sp;
1677*a925974bSAdrian Prantl     if (m_bp_id.m_breakpoint.OptionWasSet()) {
1678b842f2ecSJim Ingham       lldb::break_id_t bp_id = m_bp_id.m_breakpoint.GetUInt64Value();
1679cb2380c9SRaphael Isemann       bp_sp = target.GetBreakpointByID(bp_id);
1680*a925974bSAdrian Prantl       if (!bp_sp) {
1681b842f2ecSJim Ingham         result.AppendErrorWithFormatv("Could not find specified breakpoint {0}",
1682b842f2ecSJim Ingham                                       bp_id);
1683b842f2ecSJim Ingham         result.SetStatus(eReturnStatusFailed);
1684b842f2ecSJim Ingham         return false;
1685b842f2ecSJim Ingham       }
1686b842f2ecSJim Ingham     }
1687b842f2ecSJim Ingham 
1688b842f2ecSJim Ingham     Status error;
1689b842f2ecSJim Ingham     for (auto &entry : command.entries()) {
1690b842f2ecSJim Ingham       ConstString name(entry.c_str());
1691cb2380c9SRaphael Isemann       BreakpointName *bp_name = target.FindBreakpointName(name, true, error);
1692b842f2ecSJim Ingham       if (!bp_name)
1693b842f2ecSJim Ingham         continue;
1694e9632ebaSJim Ingham       if (m_bp_id.m_help_string.OptionWasSet())
1695e9632ebaSJim Ingham         bp_name->SetHelp(m_bp_id.m_help_string.GetStringValue().str().c_str());
1696e9632ebaSJim Ingham 
1697b842f2ecSJim Ingham       if (bp_sp)
1698cb2380c9SRaphael Isemann         target.ConfigureBreakpointName(*bp_name, *bp_sp->GetOptions(),
1699b842f2ecSJim Ingham                                        m_access_options.GetPermissions());
1700b842f2ecSJim Ingham       else
1701cb2380c9SRaphael Isemann         target.ConfigureBreakpointName(*bp_name,
1702b842f2ecSJim Ingham                                        m_bp_opts.GetBreakpointOptions(),
1703b842f2ecSJim Ingham                                        m_access_options.GetPermissions());
1704b842f2ecSJim Ingham     }
1705b842f2ecSJim Ingham     return true;
1706b842f2ecSJim Ingham   }
1707b842f2ecSJim Ingham 
1708b842f2ecSJim Ingham private:
1709b842f2ecSJim Ingham   BreakpointNameOptionGroup m_bp_id; // Only using the id part of this.
1710b842f2ecSJim Ingham   BreakpointOptionGroup m_bp_opts;
1711b842f2ecSJim Ingham   BreakpointAccessOptionGroup m_access_options;
1712b842f2ecSJim Ingham   OptionGroupOptions m_option_group;
1713b842f2ecSJim Ingham };
1714b842f2ecSJim Ingham 
1715b9c1b51eSKate Stone class CommandObjectBreakpointNameAdd : public CommandObjectParsed {
17165e09c8c3SJim Ingham public:
1717b9c1b51eSKate Stone   CommandObjectBreakpointNameAdd(CommandInterpreter &interpreter)
1718b9c1b51eSKate Stone       : CommandObjectParsed(
1719b9c1b51eSKate Stone             interpreter, "add", "Add a name to the breakpoints provided.",
17205e09c8c3SJim Ingham             "breakpoint name add <command-options> <breakpoint-id-list>"),
1721b9c1b51eSKate Stone         m_name_options(), m_option_group() {
1722b9c1b51eSKate Stone     // Create the first variant for the first (and only) argument for this
1723b9c1b51eSKate Stone     // command.
17245e09c8c3SJim Ingham     CommandArgumentEntry arg1;
17255e09c8c3SJim Ingham     CommandArgumentData id_arg;
17265e09c8c3SJim Ingham     id_arg.arg_type = eArgTypeBreakpointID;
17275e09c8c3SJim Ingham     id_arg.arg_repetition = eArgRepeatOptional;
17285e09c8c3SJim Ingham     arg1.push_back(id_arg);
17295e09c8c3SJim Ingham     m_arguments.push_back(arg1);
17305e09c8c3SJim Ingham 
17315e09c8c3SJim Ingham     m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
17325e09c8c3SJim Ingham     m_option_group.Finalize();
17335e09c8c3SJim Ingham   }
17345e09c8c3SJim Ingham 
17359e85e5a8SEugene Zelenko   ~CommandObjectBreakpointNameAdd() override = default;
17365e09c8c3SJim Ingham 
1737b9c1b51eSKate Stone   Options *GetOptions() override { return &m_option_group; }
17385e09c8c3SJim Ingham 
17395e09c8c3SJim Ingham protected:
1740b9c1b51eSKate Stone   bool DoExecute(Args &command, CommandReturnObject &result) override {
1741b9c1b51eSKate Stone     if (!m_name_options.m_name.OptionWasSet()) {
17425e09c8c3SJim Ingham       result.SetError("No name option provided.");
17435e09c8c3SJim Ingham       return false;
17445e09c8c3SJim Ingham     }
17455e09c8c3SJim Ingham 
1746cb2380c9SRaphael Isemann     Target &target =
1747b9c1b51eSKate Stone         GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
17485e09c8c3SJim Ingham 
1749bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
1750cb2380c9SRaphael Isemann     target.GetBreakpointList().GetListMutex(lock);
17515e09c8c3SJim Ingham 
1752cb2380c9SRaphael Isemann     const BreakpointList &breakpoints = target.GetBreakpointList();
17535e09c8c3SJim Ingham 
17545e09c8c3SJim Ingham     size_t num_breakpoints = breakpoints.GetSize();
1755b9c1b51eSKate Stone     if (num_breakpoints == 0) {
17565e09c8c3SJim Ingham       result.SetError("No breakpoints, cannot add names.");
17575e09c8c3SJim Ingham       result.SetStatus(eReturnStatusFailed);
17585e09c8c3SJim Ingham       return false;
17595e09c8c3SJim Ingham     }
17605e09c8c3SJim Ingham 
17615e09c8c3SJim Ingham     // Particular breakpoint selected; disable that breakpoint.
17625e09c8c3SJim Ingham     BreakpointIDList valid_bp_ids;
1763b9c1b51eSKate Stone     CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
1764cb2380c9SRaphael Isemann         command, &target, result, &valid_bp_ids,
1765b842f2ecSJim Ingham         BreakpointName::Permissions::PermissionKinds::listPerm);
17665e09c8c3SJim Ingham 
1767b9c1b51eSKate Stone     if (result.Succeeded()) {
1768b9c1b51eSKate Stone       if (valid_bp_ids.GetSize() == 0) {
17695e09c8c3SJim Ingham         result.SetError("No breakpoints specified, cannot add names.");
17705e09c8c3SJim Ingham         result.SetStatus(eReturnStatusFailed);
17715e09c8c3SJim Ingham         return false;
17725e09c8c3SJim Ingham       }
17735e09c8c3SJim Ingham       size_t num_valid_ids = valid_bp_ids.GetSize();
1774b842f2ecSJim Ingham       const char *bp_name = m_name_options.m_name.GetCurrentValue();
1775b842f2ecSJim Ingham       Status error; // This error reports illegal names, but we've already
1776b842f2ecSJim Ingham                     // checked that, so we don't need to check it again here.
1777b9c1b51eSKate Stone       for (size_t index = 0; index < num_valid_ids; index++) {
1778b9c1b51eSKate Stone         lldb::break_id_t bp_id =
1779b9c1b51eSKate Stone             valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
17805e09c8c3SJim Ingham         BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
1781cb2380c9SRaphael Isemann         target.AddNameToBreakpoint(bp_sp, bp_name, error);
17825e09c8c3SJim Ingham       }
17835e09c8c3SJim Ingham     }
17845e09c8c3SJim Ingham 
17855e09c8c3SJim Ingham     return true;
17865e09c8c3SJim Ingham   }
17875e09c8c3SJim Ingham 
17885e09c8c3SJim Ingham private:
17895e09c8c3SJim Ingham   BreakpointNameOptionGroup m_name_options;
17905e09c8c3SJim Ingham   OptionGroupOptions m_option_group;
17915e09c8c3SJim Ingham };
17925e09c8c3SJim Ingham 
1793b9c1b51eSKate Stone class CommandObjectBreakpointNameDelete : public CommandObjectParsed {
17945e09c8c3SJim Ingham public:
1795b9c1b51eSKate Stone   CommandObjectBreakpointNameDelete(CommandInterpreter &interpreter)
1796b9c1b51eSKate Stone       : CommandObjectParsed(
1797b9c1b51eSKate Stone             interpreter, "delete",
17985e09c8c3SJim Ingham             "Delete a name from the breakpoints provided.",
17995e09c8c3SJim Ingham             "breakpoint name delete <command-options> <breakpoint-id-list>"),
1800b9c1b51eSKate Stone         m_name_options(), m_option_group() {
1801b9c1b51eSKate Stone     // Create the first variant for the first (and only) argument for this
1802b9c1b51eSKate Stone     // command.
18035e09c8c3SJim Ingham     CommandArgumentEntry arg1;
18045e09c8c3SJim Ingham     CommandArgumentData id_arg;
18055e09c8c3SJim Ingham     id_arg.arg_type = eArgTypeBreakpointID;
18065e09c8c3SJim Ingham     id_arg.arg_repetition = eArgRepeatOptional;
18075e09c8c3SJim Ingham     arg1.push_back(id_arg);
18085e09c8c3SJim Ingham     m_arguments.push_back(arg1);
18095e09c8c3SJim Ingham 
18105e09c8c3SJim Ingham     m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
18115e09c8c3SJim Ingham     m_option_group.Finalize();
18125e09c8c3SJim Ingham   }
18135e09c8c3SJim Ingham 
18149e85e5a8SEugene Zelenko   ~CommandObjectBreakpointNameDelete() override = default;
18155e09c8c3SJim Ingham 
1816b9c1b51eSKate Stone   Options *GetOptions() override { return &m_option_group; }
18175e09c8c3SJim Ingham 
18185e09c8c3SJim Ingham protected:
1819b9c1b51eSKate Stone   bool DoExecute(Args &command, CommandReturnObject &result) override {
1820b9c1b51eSKate Stone     if (!m_name_options.m_name.OptionWasSet()) {
18215e09c8c3SJim Ingham       result.SetError("No name option provided.");
18225e09c8c3SJim Ingham       return false;
18235e09c8c3SJim Ingham     }
18245e09c8c3SJim Ingham 
1825cb2380c9SRaphael Isemann     Target &target =
1826b9c1b51eSKate Stone         GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
18275e09c8c3SJim Ingham 
1828bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
1829cb2380c9SRaphael Isemann     target.GetBreakpointList().GetListMutex(lock);
18305e09c8c3SJim Ingham 
1831cb2380c9SRaphael Isemann     const BreakpointList &breakpoints = target.GetBreakpointList();
18325e09c8c3SJim Ingham 
18335e09c8c3SJim Ingham     size_t num_breakpoints = breakpoints.GetSize();
1834b9c1b51eSKate Stone     if (num_breakpoints == 0) {
18355e09c8c3SJim Ingham       result.SetError("No breakpoints, cannot delete names.");
18365e09c8c3SJim Ingham       result.SetStatus(eReturnStatusFailed);
18375e09c8c3SJim Ingham       return false;
18385e09c8c3SJim Ingham     }
18395e09c8c3SJim Ingham 
18405e09c8c3SJim Ingham     // Particular breakpoint selected; disable that breakpoint.
18415e09c8c3SJim Ingham     BreakpointIDList valid_bp_ids;
1842b9c1b51eSKate Stone     CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
1843cb2380c9SRaphael Isemann         command, &target, result, &valid_bp_ids,
1844b842f2ecSJim Ingham         BreakpointName::Permissions::PermissionKinds::deletePerm);
18455e09c8c3SJim Ingham 
1846b9c1b51eSKate Stone     if (result.Succeeded()) {
1847b9c1b51eSKate Stone       if (valid_bp_ids.GetSize() == 0) {
18485e09c8c3SJim Ingham         result.SetError("No breakpoints specified, cannot delete names.");
18495e09c8c3SJim Ingham         result.SetStatus(eReturnStatusFailed);
18505e09c8c3SJim Ingham         return false;
18515e09c8c3SJim Ingham       }
1852b842f2ecSJim Ingham       ConstString bp_name(m_name_options.m_name.GetCurrentValue());
18535e09c8c3SJim Ingham       size_t num_valid_ids = valid_bp_ids.GetSize();
1854b9c1b51eSKate Stone       for (size_t index = 0; index < num_valid_ids; index++) {
1855b9c1b51eSKate Stone         lldb::break_id_t bp_id =
1856b9c1b51eSKate Stone             valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
18575e09c8c3SJim Ingham         BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
1858cb2380c9SRaphael Isemann         target.RemoveNameFromBreakpoint(bp_sp, bp_name);
18595e09c8c3SJim Ingham       }
18605e09c8c3SJim Ingham     }
18615e09c8c3SJim Ingham 
18625e09c8c3SJim Ingham     return true;
18635e09c8c3SJim Ingham   }
18645e09c8c3SJim Ingham 
18655e09c8c3SJim Ingham private:
18665e09c8c3SJim Ingham   BreakpointNameOptionGroup m_name_options;
18675e09c8c3SJim Ingham   OptionGroupOptions m_option_group;
18685e09c8c3SJim Ingham };
18695e09c8c3SJim Ingham 
1870b9c1b51eSKate Stone class CommandObjectBreakpointNameList : public CommandObjectParsed {
18715e09c8c3SJim Ingham public:
1872b9c1b51eSKate Stone   CommandObjectBreakpointNameList(CommandInterpreter &interpreter)
1873b9c1b51eSKate Stone       : CommandObjectParsed(interpreter, "list",
1874b842f2ecSJim Ingham                             "List either the names for a breakpoint or info "
1875b842f2ecSJim Ingham                             "about a given name.  With no arguments, lists all "
1876b842f2ecSJim Ingham                             "names",
18775e09c8c3SJim Ingham                             "breakpoint name list <command-options>"),
1878b9c1b51eSKate Stone         m_name_options(), m_option_group() {
1879b842f2ecSJim Ingham     m_option_group.Append(&m_name_options, LLDB_OPT_SET_3, LLDB_OPT_SET_ALL);
18805e09c8c3SJim Ingham     m_option_group.Finalize();
18815e09c8c3SJim Ingham   }
18825e09c8c3SJim Ingham 
18839e85e5a8SEugene Zelenko   ~CommandObjectBreakpointNameList() override = default;
18845e09c8c3SJim Ingham 
1885b9c1b51eSKate Stone   Options *GetOptions() override { return &m_option_group; }
18865e09c8c3SJim Ingham 
18875e09c8c3SJim Ingham protected:
1888b9c1b51eSKate Stone   bool DoExecute(Args &command, CommandReturnObject &result) override {
1889cb2380c9SRaphael Isemann     Target &target =
1890b9c1b51eSKate Stone         GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
18915e09c8c3SJim Ingham 
1892b842f2ecSJim Ingham     std::vector<std::string> name_list;
1893b842f2ecSJim Ingham     if (command.empty()) {
1894cb2380c9SRaphael Isemann       target.GetBreakpointNames(name_list);
1895b842f2ecSJim Ingham     } else {
1896*a925974bSAdrian Prantl       for (const Args::ArgEntry &arg : command) {
1897b842f2ecSJim Ingham         name_list.push_back(arg.c_str());
1898b842f2ecSJim Ingham       }
1899b842f2ecSJim Ingham     }
1900b842f2ecSJim Ingham 
1901b842f2ecSJim Ingham     if (name_list.empty()) {
1902b842f2ecSJim Ingham       result.AppendMessage("No breakpoint names found.");
1903b842f2ecSJim Ingham     } else {
1904b842f2ecSJim Ingham       for (const std::string &name_str : name_list) {
1905b842f2ecSJim Ingham         const char *name = name_str.c_str();
1906b842f2ecSJim Ingham         // First print out the options for the name:
1907b842f2ecSJim Ingham         Status error;
1908cb2380c9SRaphael Isemann         BreakpointName *bp_name =
1909cb2380c9SRaphael Isemann             target.FindBreakpointName(ConstString(name), false, error);
1910*a925974bSAdrian Prantl         if (bp_name) {
1911b842f2ecSJim Ingham           StreamString s;
1912b842f2ecSJim Ingham           result.AppendMessageWithFormat("Name: %s\n", name);
1913*a925974bSAdrian Prantl           if (bp_name->GetDescription(&s, eDescriptionLevelFull)) {
1914b842f2ecSJim Ingham             result.AppendMessage(s.GetString());
1915b842f2ecSJim Ingham           }
1916b842f2ecSJim Ingham 
1917bb19a13cSSaleem Abdulrasool           std::unique_lock<std::recursive_mutex> lock;
1918cb2380c9SRaphael Isemann           target.GetBreakpointList().GetListMutex(lock);
19195e09c8c3SJim Ingham 
1920cb2380c9SRaphael Isemann           BreakpointList &breakpoints = target.GetBreakpointList();
1921b842f2ecSJim Ingham           bool any_set = false;
1922b9c1b51eSKate Stone           for (BreakpointSP bp_sp : breakpoints.Breakpoints()) {
1923b9c1b51eSKate Stone             if (bp_sp->MatchesName(name)) {
19245e09c8c3SJim Ingham               StreamString s;
1925b842f2ecSJim Ingham               any_set = true;
19265e09c8c3SJim Ingham               bp_sp->GetDescription(&s, eDescriptionLevelBrief);
19275e09c8c3SJim Ingham               s.EOL();
1928c156427dSZachary Turner               result.AppendMessage(s.GetString());
19295e09c8c3SJim Ingham             }
19305e09c8c3SJim Ingham           }
1931b842f2ecSJim Ingham           if (!any_set)
1932b842f2ecSJim Ingham             result.AppendMessage("No breakpoints using this name.");
1933b9c1b51eSKate Stone         } else {
1934b842f2ecSJim Ingham           result.AppendMessageWithFormat("Name: %s not found.\n", name);
19355e09c8c3SJim Ingham         }
1936b842f2ecSJim Ingham       }
19375e09c8c3SJim Ingham     }
19385e09c8c3SJim Ingham     return true;
19395e09c8c3SJim Ingham   }
19405e09c8c3SJim Ingham 
19415e09c8c3SJim Ingham private:
19425e09c8c3SJim Ingham   BreakpointNameOptionGroup m_name_options;
19435e09c8c3SJim Ingham   OptionGroupOptions m_option_group;
19445e09c8c3SJim Ingham };
19455e09c8c3SJim Ingham 
1946e14dc268SJim Ingham // CommandObjectBreakpointName
1947b9c1b51eSKate Stone class CommandObjectBreakpointName : public CommandObjectMultiword {
19485e09c8c3SJim Ingham public:
19497428a18cSKate Stone   CommandObjectBreakpointName(CommandInterpreter &interpreter)
1950b9c1b51eSKate Stone       : CommandObjectMultiword(
1951b9c1b51eSKate Stone             interpreter, "name", "Commands to manage name tags for breakpoints",
1952b9c1b51eSKate Stone             "breakpoint name <subcommand> [<command-options>]") {
1953b9c1b51eSKate Stone     CommandObjectSP add_command_object(
1954b9c1b51eSKate Stone         new CommandObjectBreakpointNameAdd(interpreter));
1955b9c1b51eSKate Stone     CommandObjectSP delete_command_object(
1956b9c1b51eSKate Stone         new CommandObjectBreakpointNameDelete(interpreter));
1957b9c1b51eSKate Stone     CommandObjectSP list_command_object(
1958b9c1b51eSKate Stone         new CommandObjectBreakpointNameList(interpreter));
1959b842f2ecSJim Ingham     CommandObjectSP configure_command_object(
1960b842f2ecSJim Ingham         new CommandObjectBreakpointNameConfigure(interpreter));
19615e09c8c3SJim Ingham 
19625e09c8c3SJim Ingham     LoadSubCommand("add", add_command_object);
19635e09c8c3SJim Ingham     LoadSubCommand("delete", delete_command_object);
19645e09c8c3SJim Ingham     LoadSubCommand("list", list_command_object);
1965b842f2ecSJim Ingham     LoadSubCommand("configure", configure_command_object);
19665e09c8c3SJim Ingham   }
19675e09c8c3SJim Ingham 
19689e85e5a8SEugene Zelenko   ~CommandObjectBreakpointName() override = default;
19695e09c8c3SJim Ingham };
19705e09c8c3SJim Ingham 
1971e14dc268SJim Ingham // CommandObjectBreakpointRead
19723acdf385SJim Ingham #pragma mark Read::CommandOptions
1973f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_read
1974f94668e3SRaphael Isemann #include "CommandOptions.inc"
19751f0f5b5bSZachary Turner 
19761f0f5b5bSZachary Turner #pragma mark Read
1977e14dc268SJim Ingham 
1978e14dc268SJim Ingham class CommandObjectBreakpointRead : public CommandObjectParsed {
1979e14dc268SJim Ingham public:
1980e14dc268SJim Ingham   CommandObjectBreakpointRead(CommandInterpreter &interpreter)
1981e14dc268SJim Ingham       : CommandObjectParsed(interpreter, "breakpoint read",
1982e14dc268SJim Ingham                             "Read and set the breakpoints previously saved to "
1983e14dc268SJim Ingham                             "a file with \"breakpoint write\".  ",
1984e14dc268SJim Ingham                             nullptr),
1985e14dc268SJim Ingham         m_options() {
1986e14dc268SJim Ingham     CommandArgumentEntry arg;
1987e14dc268SJim Ingham     CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
1988e14dc268SJim Ingham                                       eArgTypeBreakpointIDRange);
1989e14dc268SJim Ingham     // Add the entry for the first argument for this command to the object's
1990e14dc268SJim Ingham     // arguments vector.
1991e14dc268SJim Ingham     m_arguments.push_back(arg);
1992e14dc268SJim Ingham   }
1993e14dc268SJim Ingham 
1994e14dc268SJim Ingham   ~CommandObjectBreakpointRead() override = default;
1995e14dc268SJim Ingham 
1996e14dc268SJim Ingham   Options *GetOptions() override { return &m_options; }
1997e14dc268SJim Ingham 
1998e14dc268SJim Ingham   class CommandOptions : public Options {
1999e14dc268SJim Ingham   public:
2000e14dc268SJim Ingham     CommandOptions() : Options() {}
2001e14dc268SJim Ingham 
2002e14dc268SJim Ingham     ~CommandOptions() override = default;
2003e14dc268SJim Ingham 
200497206d57SZachary Turner     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2005e14dc268SJim Ingham                           ExecutionContext *execution_context) override {
200697206d57SZachary Turner       Status error;
2007e14dc268SJim Ingham       const int short_option = m_getopt_table[option_idx].val;
2008e14dc268SJim Ingham 
2009e14dc268SJim Ingham       switch (short_option) {
2010e14dc268SJim Ingham       case 'f':
2011e14dc268SJim Ingham         m_filename.assign(option_arg);
2012e14dc268SJim Ingham         break;
20133acdf385SJim Ingham       case 'N': {
201497206d57SZachary Turner         Status name_error;
20153acdf385SJim Ingham         if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(option_arg),
20163acdf385SJim Ingham                                                   name_error)) {
20173acdf385SJim Ingham           error.SetErrorStringWithFormat("Invalid breakpoint name: %s",
20183acdf385SJim Ingham                                          name_error.AsCString());
20193acdf385SJim Ingham         }
20203acdf385SJim Ingham         m_names.push_back(option_arg);
20213acdf385SJim Ingham         break;
20223acdf385SJim Ingham       }
2023e14dc268SJim Ingham       default:
202436162014SRaphael Isemann         llvm_unreachable("Unimplemented option");
2025e14dc268SJim Ingham       }
2026e14dc268SJim Ingham 
2027e14dc268SJim Ingham       return error;
2028e14dc268SJim Ingham     }
2029e14dc268SJim Ingham 
2030e14dc268SJim Ingham     void OptionParsingStarting(ExecutionContext *execution_context) override {
2031e14dc268SJim Ingham       m_filename.clear();
20323acdf385SJim Ingham       m_names.clear();
2033e14dc268SJim Ingham     }
2034e14dc268SJim Ingham 
20351f0f5b5bSZachary Turner     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
203670602439SZachary Turner       return llvm::makeArrayRef(g_breakpoint_read_options);
20371f0f5b5bSZachary Turner     }
2038e14dc268SJim Ingham 
2039e14dc268SJim Ingham     // Instance variables to hold the values for command options.
2040e14dc268SJim Ingham 
2041e14dc268SJim Ingham     std::string m_filename;
20423acdf385SJim Ingham     std::vector<std::string> m_names;
2043e14dc268SJim Ingham   };
2044e14dc268SJim Ingham 
2045e14dc268SJim Ingham protected:
2046e14dc268SJim Ingham   bool DoExecute(Args &command, CommandReturnObject &result) override {
2047cb2380c9SRaphael Isemann     Target &target = GetSelectedOrDummyTarget();
2048e14dc268SJim Ingham 
20493acdf385SJim Ingham     std::unique_lock<std::recursive_mutex> lock;
2050cb2380c9SRaphael Isemann     target.GetBreakpointList().GetListMutex(lock);
20513acdf385SJim Ingham 
20528f3be7a3SJonas Devlieghere     FileSpec input_spec(m_options.m_filename);
20538f3be7a3SJonas Devlieghere     FileSystem::Instance().Resolve(input_spec);
205401f16664SJim Ingham     BreakpointIDList new_bps;
2055cb2380c9SRaphael Isemann     Status error = target.CreateBreakpointsFromFile(input_spec,
2056cb2380c9SRaphael Isemann                                                     m_options.m_names, new_bps);
2057e14dc268SJim Ingham 
2058e14dc268SJim Ingham     if (!error.Success()) {
205901f16664SJim Ingham       result.AppendError(error.AsCString());
2060e14dc268SJim Ingham       result.SetStatus(eReturnStatusFailed);
206101f16664SJim Ingham       return false;
2062e14dc268SJim Ingham     }
20633acdf385SJim Ingham 
20643acdf385SJim Ingham     Stream &output_stream = result.GetOutputStream();
20653acdf385SJim Ingham 
20663acdf385SJim Ingham     size_t num_breakpoints = new_bps.GetSize();
20673acdf385SJim Ingham     if (num_breakpoints == 0) {
20683acdf385SJim Ingham       result.AppendMessage("No breakpoints added.");
20693acdf385SJim Ingham     } else {
20703acdf385SJim Ingham       // No breakpoint selected; show info about all currently set breakpoints.
20713acdf385SJim Ingham       result.AppendMessage("New breakpoints:");
20723acdf385SJim Ingham       for (size_t i = 0; i < num_breakpoints; ++i) {
20733acdf385SJim Ingham         BreakpointID bp_id = new_bps.GetBreakpointIDAtIndex(i);
2074cb2380c9SRaphael Isemann         Breakpoint *bp = target.GetBreakpointList()
20753acdf385SJim Ingham                              .FindBreakpointByID(bp_id.GetBreakpointID())
20763acdf385SJim Ingham                              .get();
20773acdf385SJim Ingham         if (bp)
20783acdf385SJim Ingham           bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
20793acdf385SJim Ingham                              false);
20803acdf385SJim Ingham       }
20813acdf385SJim Ingham     }
2082e14dc268SJim Ingham     return result.Succeeded();
2083e14dc268SJim Ingham   }
2084e14dc268SJim Ingham 
2085e14dc268SJim Ingham private:
2086e14dc268SJim Ingham   CommandOptions m_options;
2087e14dc268SJim Ingham };
2088e14dc268SJim Ingham 
2089e14dc268SJim Ingham // CommandObjectBreakpointWrite
20901f0f5b5bSZachary Turner #pragma mark Write::CommandOptions
2091f94668e3SRaphael Isemann #define LLDB_OPTIONS_breakpoint_write
2092f94668e3SRaphael Isemann #include "CommandOptions.inc"
20931f0f5b5bSZachary Turner 
20941f0f5b5bSZachary Turner #pragma mark Write
2095e14dc268SJim Ingham class CommandObjectBreakpointWrite : public CommandObjectParsed {
2096e14dc268SJim Ingham public:
2097e14dc268SJim Ingham   CommandObjectBreakpointWrite(CommandInterpreter &interpreter)
2098e14dc268SJim Ingham       : CommandObjectParsed(interpreter, "breakpoint write",
2099e14dc268SJim Ingham                             "Write the breakpoints listed to a file that can "
2100e14dc268SJim Ingham                             "be read in with \"breakpoint read\".  "
2101e14dc268SJim Ingham                             "If given no arguments, writes all breakpoints.",
2102e14dc268SJim Ingham                             nullptr),
2103e14dc268SJim Ingham         m_options() {
2104e14dc268SJim Ingham     CommandArgumentEntry arg;
2105e14dc268SJim Ingham     CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
2106e14dc268SJim Ingham                                       eArgTypeBreakpointIDRange);
2107e14dc268SJim Ingham     // Add the entry for the first argument for this command to the object's
2108e14dc268SJim Ingham     // arguments vector.
2109e14dc268SJim Ingham     m_arguments.push_back(arg);
2110e14dc268SJim Ingham   }
2111e14dc268SJim Ingham 
2112e14dc268SJim Ingham   ~CommandObjectBreakpointWrite() override = default;
2113e14dc268SJim Ingham 
2114e14dc268SJim Ingham   Options *GetOptions() override { return &m_options; }
2115e14dc268SJim Ingham 
2116e14dc268SJim Ingham   class CommandOptions : public Options {
2117e14dc268SJim Ingham   public:
2118e14dc268SJim Ingham     CommandOptions() : Options() {}
2119e14dc268SJim Ingham 
2120e14dc268SJim Ingham     ~CommandOptions() override = default;
2121e14dc268SJim Ingham 
212297206d57SZachary Turner     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2123e14dc268SJim Ingham                           ExecutionContext *execution_context) override {
212497206d57SZachary Turner       Status error;
2125e14dc268SJim Ingham       const int short_option = m_getopt_table[option_idx].val;
2126e14dc268SJim Ingham 
2127e14dc268SJim Ingham       switch (short_option) {
2128e14dc268SJim Ingham       case 'f':
2129e14dc268SJim Ingham         m_filename.assign(option_arg);
2130e14dc268SJim Ingham         break;
21312d3628e1SJim Ingham       case 'a':
21322d3628e1SJim Ingham         m_append = true;
21332d3628e1SJim Ingham         break;
2134e14dc268SJim Ingham       default:
213536162014SRaphael Isemann         llvm_unreachable("Unimplemented option");
2136e14dc268SJim Ingham       }
2137e14dc268SJim Ingham 
2138e14dc268SJim Ingham       return error;
2139e14dc268SJim Ingham     }
2140e14dc268SJim Ingham 
2141e14dc268SJim Ingham     void OptionParsingStarting(ExecutionContext *execution_context) override {
2142e14dc268SJim Ingham       m_filename.clear();
21432d3628e1SJim Ingham       m_append = false;
2144e14dc268SJim Ingham     }
2145e14dc268SJim Ingham 
21461f0f5b5bSZachary Turner     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
214770602439SZachary Turner       return llvm::makeArrayRef(g_breakpoint_write_options);
21481f0f5b5bSZachary Turner     }
2149e14dc268SJim Ingham 
2150e14dc268SJim Ingham     // Instance variables to hold the values for command options.
2151e14dc268SJim Ingham 
2152e14dc268SJim Ingham     std::string m_filename;
21532d3628e1SJim Ingham     bool m_append = false;
2154e14dc268SJim Ingham   };
2155e14dc268SJim Ingham 
2156e14dc268SJim Ingham protected:
2157e14dc268SJim Ingham   bool DoExecute(Args &command, CommandReturnObject &result) override {
2158cb2380c9SRaphael Isemann     Target &target = GetSelectedOrDummyTarget();
2159e14dc268SJim Ingham 
2160e14dc268SJim Ingham     std::unique_lock<std::recursive_mutex> lock;
2161cb2380c9SRaphael Isemann     target.GetBreakpointList().GetListMutex(lock);
2162e14dc268SJim Ingham 
2163e14dc268SJim Ingham     BreakpointIDList valid_bp_ids;
216411eb9c64SZachary Turner     if (!command.empty()) {
2165e14dc268SJim Ingham       CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
2166cb2380c9SRaphael Isemann           command, &target, result, &valid_bp_ids,
2167b842f2ecSJim Ingham           BreakpointName::Permissions::PermissionKinds::listPerm);
2168e14dc268SJim Ingham 
216901f16664SJim Ingham       if (!result.Succeeded()) {
2170e14dc268SJim Ingham         result.SetStatus(eReturnStatusFailed);
2171e14dc268SJim Ingham         return false;
2172e14dc268SJim Ingham       }
2173e14dc268SJim Ingham     }
21748f3be7a3SJonas Devlieghere     FileSpec file_spec(m_options.m_filename);
21758f3be7a3SJonas Devlieghere     FileSystem::Instance().Resolve(file_spec);
2176cb2380c9SRaphael Isemann     Status error = target.SerializeBreakpointsToFile(file_spec, valid_bp_ids,
21778f3be7a3SJonas Devlieghere                                                      m_options.m_append);
217801f16664SJim Ingham     if (!error.Success()) {
217901f16664SJim Ingham       result.AppendErrorWithFormat("error serializing breakpoints: %s.",
218001f16664SJim Ingham                                    error.AsCString());
218101f16664SJim Ingham       result.SetStatus(eReturnStatusFailed);
2182e14dc268SJim Ingham     }
2183e14dc268SJim Ingham     return result.Succeeded();
2184e14dc268SJim Ingham   }
2185e14dc268SJim Ingham 
2186e14dc268SJim Ingham private:
2187e14dc268SJim Ingham   CommandOptions m_options;
2188e14dc268SJim Ingham };
2189e14dc268SJim Ingham 
219030fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint
2191ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint
219230fdc8d8SChris Lattner 
2193b9c1b51eSKate Stone CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint(
2194b9c1b51eSKate Stone     CommandInterpreter &interpreter)
2195b9c1b51eSKate Stone     : CommandObjectMultiword(
2196b9c1b51eSKate Stone           interpreter, "breakpoint",
21977428a18cSKate Stone           "Commands for operating on breakpoints (see 'help b' for shorthand.)",
2198b9c1b51eSKate Stone           "breakpoint <subcommand> [<command-options>]") {
2199b9c1b51eSKate Stone   CommandObjectSP list_command_object(
2200b9c1b51eSKate Stone       new CommandObjectBreakpointList(interpreter));
2201b9c1b51eSKate Stone   CommandObjectSP enable_command_object(
2202b9c1b51eSKate Stone       new CommandObjectBreakpointEnable(interpreter));
2203b9c1b51eSKate Stone   CommandObjectSP disable_command_object(
2204b9c1b51eSKate Stone       new CommandObjectBreakpointDisable(interpreter));
2205b9c1b51eSKate Stone   CommandObjectSP clear_command_object(
2206b9c1b51eSKate Stone       new CommandObjectBreakpointClear(interpreter));
2207b9c1b51eSKate Stone   CommandObjectSP delete_command_object(
2208b9c1b51eSKate Stone       new CommandObjectBreakpointDelete(interpreter));
2209b9c1b51eSKate Stone   CommandObjectSP set_command_object(
2210b9c1b51eSKate Stone       new CommandObjectBreakpointSet(interpreter));
2211b9c1b51eSKate Stone   CommandObjectSP command_command_object(
2212b9c1b51eSKate Stone       new CommandObjectBreakpointCommand(interpreter));
2213b9c1b51eSKate Stone   CommandObjectSP modify_command_object(
2214b9c1b51eSKate Stone       new CommandObjectBreakpointModify(interpreter));
2215b9c1b51eSKate Stone   CommandObjectSP name_command_object(
2216b9c1b51eSKate Stone       new CommandObjectBreakpointName(interpreter));
2217e14dc268SJim Ingham   CommandObjectSP write_command_object(
2218e14dc268SJim Ingham       new CommandObjectBreakpointWrite(interpreter));
2219e14dc268SJim Ingham   CommandObjectSP read_command_object(
2220e14dc268SJim Ingham       new CommandObjectBreakpointRead(interpreter));
222130fdc8d8SChris Lattner 
2222b7234e40SJohnny Chen   list_command_object->SetCommandName("breakpoint list");
222330fdc8d8SChris Lattner   enable_command_object->SetCommandName("breakpoint enable");
222430fdc8d8SChris Lattner   disable_command_object->SetCommandName("breakpoint disable");
2225b7234e40SJohnny Chen   clear_command_object->SetCommandName("breakpoint clear");
2226b7234e40SJohnny Chen   delete_command_object->SetCommandName("breakpoint delete");
2227ae1c4cf5SJim Ingham   set_command_object->SetCommandName("breakpoint set");
2228b7234e40SJohnny Chen   command_command_object->SetCommandName("breakpoint command");
2229b7234e40SJohnny Chen   modify_command_object->SetCommandName("breakpoint modify");
22305e09c8c3SJim Ingham   name_command_object->SetCommandName("breakpoint name");
2231e14dc268SJim Ingham   write_command_object->SetCommandName("breakpoint write");
2232e14dc268SJim Ingham   read_command_object->SetCommandName("breakpoint read");
223330fdc8d8SChris Lattner 
223423f59509SGreg Clayton   LoadSubCommand("list", list_command_object);
223523f59509SGreg Clayton   LoadSubCommand("enable", enable_command_object);
223623f59509SGreg Clayton   LoadSubCommand("disable", disable_command_object);
223723f59509SGreg Clayton   LoadSubCommand("clear", clear_command_object);
223823f59509SGreg Clayton   LoadSubCommand("delete", delete_command_object);
223923f59509SGreg Clayton   LoadSubCommand("set", set_command_object);
224023f59509SGreg Clayton   LoadSubCommand("command", command_command_object);
224123f59509SGreg Clayton   LoadSubCommand("modify", modify_command_object);
22425e09c8c3SJim Ingham   LoadSubCommand("name", name_command_object);
2243e14dc268SJim Ingham   LoadSubCommand("write", write_command_object);
2244e14dc268SJim Ingham   LoadSubCommand("read", read_command_object);
224530fdc8d8SChris Lattner }
224630fdc8d8SChris Lattner 
22479e85e5a8SEugene Zelenko CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default;
224830fdc8d8SChris Lattner 
2249*a925974bSAdrian Prantl void CommandObjectMultiwordBreakpoint::VerifyIDs(
2250*a925974bSAdrian Prantl     Args &args, Target *target, bool allow_locations,
2251*a925974bSAdrian Prantl     CommandReturnObject &result, BreakpointIDList *valid_ids,
2252*a925974bSAdrian Prantl     BreakpointName::Permissions ::PermissionKinds purpose) {
225330fdc8d8SChris Lattner   // args can be strings representing 1). integers (for breakpoint ids)
2254b9c1b51eSKate Stone   //                                  2). the full breakpoint & location
2255b9c1b51eSKate Stone   //                                  canonical representation
2256b9c1b51eSKate Stone   //                                  3). the word "to" or a hyphen,
2257b9c1b51eSKate Stone   //                                  representing a range (in which case there
2258b9c1b51eSKate Stone   //                                      had *better* be an entry both before &
2259b9c1b51eSKate Stone   //                                      after of one of the first two types.
22605e09c8c3SJim Ingham   //                                  4). A breakpoint name
2261b9c1b51eSKate Stone   // If args is empty, we will use the last created breakpoint (if there is
2262b9c1b51eSKate Stone   // one.)
226330fdc8d8SChris Lattner 
226430fdc8d8SChris Lattner   Args temp_args;
226530fdc8d8SChris Lattner 
226611eb9c64SZachary Turner   if (args.empty()) {
2267b9c1b51eSKate Stone     if (target->GetLastCreatedBreakpoint()) {
2268b9c1b51eSKate Stone       valid_ids->AddBreakpointID(BreakpointID(
2269b9c1b51eSKate Stone           target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
227036f3b369SJim Ingham       result.SetStatus(eReturnStatusSuccessFinishNoResult);
2271b9c1b51eSKate Stone     } else {
2272b9c1b51eSKate Stone       result.AppendError(
2273b9c1b51eSKate Stone           "No breakpoint specified and no last created breakpoint.");
227436f3b369SJim Ingham       result.SetStatus(eReturnStatusFailed);
227536f3b369SJim Ingham     }
227636f3b369SJim Ingham     return;
227736f3b369SJim Ingham   }
227836f3b369SJim Ingham 
2279b9c1b51eSKate Stone   // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff
228005097246SAdrian Prantl   // directly from the old ARGS to the new TEMP_ARGS.  Do not copy breakpoint
228105097246SAdrian Prantl   // id range strings over; instead generate a list of strings for all the
228205097246SAdrian Prantl   // breakpoint ids in the range, and shove all of those breakpoint id strings
228305097246SAdrian Prantl   // into TEMP_ARGS.
228430fdc8d8SChris Lattner 
2285b9c1b51eSKate Stone   BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations,
2286b842f2ecSJim Ingham                                            purpose, result, temp_args);
228730fdc8d8SChris Lattner 
2288b9c1b51eSKate Stone   // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual
2289b9c1b51eSKate Stone   // BreakpointIDList:
229030fdc8d8SChris Lattner 
229116662f3cSPavel Labath   valid_ids->InsertStringArray(temp_args.GetArgumentArrayRef(), result);
229230fdc8d8SChris Lattner 
229305097246SAdrian Prantl   // At this point,  all of the breakpoint ids that the user passed in have
229405097246SAdrian Prantl   // been converted to breakpoint IDs and put into valid_ids.
229530fdc8d8SChris Lattner 
2296b9c1b51eSKate Stone   if (result.Succeeded()) {
2297b9c1b51eSKate Stone     // Now that we've converted everything from args into a list of breakpoint
229805097246SAdrian Prantl     // ids, go through our tentative list of breakpoint id's and verify that
229905097246SAdrian Prantl     // they correspond to valid/currently set breakpoints.
230030fdc8d8SChris Lattner 
2301c982c768SGreg Clayton     const size_t count = valid_ids->GetSize();
2302b9c1b51eSKate Stone     for (size_t i = 0; i < count; ++i) {
230330fdc8d8SChris Lattner       BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex(i);
2304b9c1b51eSKate Stone       Breakpoint *breakpoint =
2305b9c1b51eSKate Stone           target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
2306b9c1b51eSKate Stone       if (breakpoint != nullptr) {
2307c7bece56SGreg Clayton         const size_t num_locations = breakpoint->GetNumLocations();
2308b9c1b51eSKate Stone         if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations) {
230930fdc8d8SChris Lattner           StreamString id_str;
2310b9c1b51eSKate Stone           BreakpointID::GetCanonicalReference(
2311b9c1b51eSKate Stone               &id_str, cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID());
2312c982c768SGreg Clayton           i = valid_ids->GetSize() + 1;
2313b9c1b51eSKate Stone           result.AppendErrorWithFormat(
2314b9c1b51eSKate Stone               "'%s' is not a currently valid breakpoint/location id.\n",
231530fdc8d8SChris Lattner               id_str.GetData());
231630fdc8d8SChris Lattner           result.SetStatus(eReturnStatusFailed);
231730fdc8d8SChris Lattner         }
2318b9c1b51eSKate Stone       } else {
2319c982c768SGreg Clayton         i = valid_ids->GetSize() + 1;
2320b9c1b51eSKate Stone         result.AppendErrorWithFormat(
2321b9c1b51eSKate Stone             "'%d' is not a currently valid breakpoint ID.\n",
23227428a18cSKate Stone             cur_bp_id.GetBreakpointID());
232330fdc8d8SChris Lattner         result.SetStatus(eReturnStatusFailed);
232430fdc8d8SChris Lattner       }
232530fdc8d8SChris Lattner     }
232630fdc8d8SChris Lattner   }
232730fdc8d8SChris Lattner }
2328