Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / source / API / SBCommandInterpreter.cpp
blobc3cbb00145ed3ebbf1a53c65a5141ef9e58cb6db
1 //===-- SBCommandInterpreter.cpp ------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "lldb/lldb-types.h"
11 #include "lldb/Interpreter/CommandInterpreter.h"
12 #include "lldb/Interpreter/CommandObjectMultiword.h"
13 #include "lldb/Interpreter/CommandReturnObject.h"
14 #include "lldb/Target/Target.h"
15 #include "lldb/Utility/Instrumentation.h"
16 #include "lldb/Utility/Listener.h"
18 #include "lldb/API/SBBroadcaster.h"
19 #include "lldb/API/SBCommandInterpreter.h"
20 #include "lldb/API/SBCommandInterpreterRunOptions.h"
21 #include "lldb/API/SBCommandReturnObject.h"
22 #include "lldb/API/SBEvent.h"
23 #include "lldb/API/SBExecutionContext.h"
24 #include "lldb/API/SBListener.h"
25 #include "lldb/API/SBProcess.h"
26 #include "lldb/API/SBStream.h"
27 #include "lldb/API/SBStringList.h"
28 #include "lldb/API/SBTarget.h"
30 #include <memory>
31 #include <optional>
33 using namespace lldb;
34 using namespace lldb_private;
36 namespace lldb_private {
37 class CommandPluginInterfaceImplementation : public CommandObjectParsed {
38 public:
39 CommandPluginInterfaceImplementation(CommandInterpreter &interpreter,
40 const char *name,
41 lldb::SBCommandPluginInterface *backend,
42 const char *help = nullptr,
43 const char *syntax = nullptr,
44 uint32_t flags = 0,
45 const char *auto_repeat_command = "")
46 : CommandObjectParsed(interpreter, name, help, syntax, flags),
47 m_backend(backend) {
48 m_auto_repeat_command =
49 auto_repeat_command == nullptr
50 ? std::nullopt
51 : std::optional<std::string>(auto_repeat_command);
52 // We don't know whether any given command coming from this interface takes
53 // arguments or not so here we're just disabling the basic args check.
54 CommandArgumentData none_arg{eArgTypeNone, eArgRepeatStar};
55 m_arguments.push_back({none_arg});
58 bool IsRemovable() const override { return true; }
60 /// More documentation is available in lldb::CommandObject::GetRepeatCommand,
61 /// but in short, if std::nullopt is returned, the previous command will be
62 /// repeated, and if an empty string is returned, no commands will be
63 /// executed.
64 std::optional<std::string> GetRepeatCommand(Args &current_command_args,
65 uint32_t index) override {
66 if (!m_auto_repeat_command)
67 return std::nullopt;
68 else
69 return m_auto_repeat_command;
72 protected:
73 void DoExecute(Args &command, CommandReturnObject &result) override {
74 SBCommandReturnObject sb_return(result);
75 SBCommandInterpreter sb_interpreter(&m_interpreter);
76 SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this());
77 m_backend->DoExecute(debugger_sb, command.GetArgumentVector(), sb_return);
79 std::shared_ptr<lldb::SBCommandPluginInterface> m_backend;
80 std::optional<std::string> m_auto_repeat_command;
82 } // namespace lldb_private
84 SBCommandInterpreter::SBCommandInterpreter() : m_opaque_ptr() {
85 LLDB_INSTRUMENT_VA(this);
88 SBCommandInterpreter::SBCommandInterpreter(CommandInterpreter *interpreter)
89 : m_opaque_ptr(interpreter) {
90 LLDB_INSTRUMENT_VA(this, interpreter);
93 SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs)
94 : m_opaque_ptr(rhs.m_opaque_ptr) {
95 LLDB_INSTRUMENT_VA(this, rhs);
98 SBCommandInterpreter::~SBCommandInterpreter() = default;
100 const SBCommandInterpreter &SBCommandInterpreter::
101 operator=(const SBCommandInterpreter &rhs) {
102 LLDB_INSTRUMENT_VA(this, rhs);
104 m_opaque_ptr = rhs.m_opaque_ptr;
105 return *this;
108 bool SBCommandInterpreter::IsValid() const {
109 LLDB_INSTRUMENT_VA(this);
110 return this->operator bool();
112 SBCommandInterpreter::operator bool() const {
113 LLDB_INSTRUMENT_VA(this);
115 return m_opaque_ptr != nullptr;
118 bool SBCommandInterpreter::CommandExists(const char *cmd) {
119 LLDB_INSTRUMENT_VA(this, cmd);
121 return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->CommandExists(cmd)
122 : false);
125 bool SBCommandInterpreter::UserCommandExists(const char *cmd) {
126 LLDB_INSTRUMENT_VA(this, cmd);
128 return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->UserCommandExists(cmd)
129 : false);
132 bool SBCommandInterpreter::AliasExists(const char *cmd) {
133 LLDB_INSTRUMENT_VA(this, cmd);
135 return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->AliasExists(cmd)
136 : false);
139 bool SBCommandInterpreter::IsActive() {
140 LLDB_INSTRUMENT_VA(this);
142 return (IsValid() ? m_opaque_ptr->IsActive() : false);
145 bool SBCommandInterpreter::WasInterrupted() const {
146 LLDB_INSTRUMENT_VA(this);
148 return (IsValid() ? m_opaque_ptr->GetDebugger().InterruptRequested() : false);
151 bool SBCommandInterpreter::InterruptCommand() {
152 LLDB_INSTRUMENT_VA(this);
154 return (IsValid() ? m_opaque_ptr->InterruptCommand() : false);
157 const char *SBCommandInterpreter::GetIOHandlerControlSequence(char ch) {
158 LLDB_INSTRUMENT_VA(this, ch);
160 if (!IsValid())
161 return nullptr;
163 return ConstString(
164 m_opaque_ptr->GetDebugger().GetTopIOHandlerControlSequence(ch))
165 .GetCString();
168 lldb::ReturnStatus
169 SBCommandInterpreter::HandleCommand(const char *command_line,
170 SBCommandReturnObject &result,
171 bool add_to_history) {
172 LLDB_INSTRUMENT_VA(this, command_line, result, add_to_history);
174 SBExecutionContext sb_exe_ctx;
175 return HandleCommand(command_line, sb_exe_ctx, result, add_to_history);
178 lldb::ReturnStatus SBCommandInterpreter::HandleCommand(
179 const char *command_line, SBExecutionContext &override_context,
180 SBCommandReturnObject &result, bool add_to_history) {
181 LLDB_INSTRUMENT_VA(this, command_line, override_context, result,
182 add_to_history);
184 result.Clear();
185 if (command_line && IsValid()) {
186 result.ref().SetInteractive(false);
187 auto do_add_to_history = add_to_history ? eLazyBoolYes : eLazyBoolNo;
188 if (override_context.get())
189 m_opaque_ptr->HandleCommand(command_line, do_add_to_history,
190 override_context.get()->Lock(true),
191 result.ref());
192 else
193 m_opaque_ptr->HandleCommand(command_line, do_add_to_history,
194 result.ref());
195 } else {
196 result->AppendError(
197 "SBCommandInterpreter or the command line is not valid");
200 return result.GetStatus();
203 void SBCommandInterpreter::HandleCommandsFromFile(
204 lldb::SBFileSpec &file, lldb::SBExecutionContext &override_context,
205 lldb::SBCommandInterpreterRunOptions &options,
206 lldb::SBCommandReturnObject result) {
207 LLDB_INSTRUMENT_VA(this, file, override_context, options, result);
209 if (!IsValid()) {
210 result->AppendError("SBCommandInterpreter is not valid.");
211 return;
214 if (!file.IsValid()) {
215 SBStream s;
216 file.GetDescription(s);
217 result->AppendErrorWithFormat("File is not valid: %s.", s.GetData());
220 FileSpec tmp_spec = file.ref();
221 if (override_context.get())
222 m_opaque_ptr->HandleCommandsFromFile(tmp_spec,
223 override_context.get()->Lock(true),
224 options.ref(),
225 result.ref());
227 else
228 m_opaque_ptr->HandleCommandsFromFile(tmp_spec, options.ref(), result.ref());
231 int SBCommandInterpreter::HandleCompletion(
232 const char *current_line, const char *cursor, const char *last_char,
233 int match_start_point, int max_return_elements, SBStringList &matches) {
234 LLDB_INSTRUMENT_VA(this, current_line, cursor, last_char, match_start_point,
235 max_return_elements, matches);
237 SBStringList dummy_descriptions;
238 return HandleCompletionWithDescriptions(
239 current_line, cursor, last_char, match_start_point, max_return_elements,
240 matches, dummy_descriptions);
243 int SBCommandInterpreter::HandleCompletionWithDescriptions(
244 const char *current_line, const char *cursor, const char *last_char,
245 int match_start_point, int max_return_elements, SBStringList &matches,
246 SBStringList &descriptions) {
247 LLDB_INSTRUMENT_VA(this, current_line, cursor, last_char, match_start_point,
248 max_return_elements, matches, descriptions);
250 // Sanity check the arguments that are passed in: cursor & last_char have to
251 // be within the current_line.
252 if (current_line == nullptr || cursor == nullptr || last_char == nullptr)
253 return 0;
255 if (cursor < current_line || last_char < current_line)
256 return 0;
258 size_t current_line_size = strlen(current_line);
259 if (cursor - current_line > static_cast<ptrdiff_t>(current_line_size) ||
260 last_char - current_line > static_cast<ptrdiff_t>(current_line_size))
261 return 0;
263 if (!IsValid())
264 return 0;
266 lldb_private::StringList lldb_matches, lldb_descriptions;
267 CompletionResult result;
268 CompletionRequest request(current_line, cursor - current_line, result);
269 m_opaque_ptr->HandleCompletion(request);
270 result.GetMatches(lldb_matches);
271 result.GetDescriptions(lldb_descriptions);
273 // Make the result array indexed from 1 again by adding the 'common prefix'
274 // of all completions as element 0. This is done to emulate the old API.
275 if (request.GetParsedLine().GetArgumentCount() == 0) {
276 // If we got an empty string, insert nothing.
277 lldb_matches.InsertStringAtIndex(0, "");
278 lldb_descriptions.InsertStringAtIndex(0, "");
279 } else {
280 // Now figure out if there is a common substring, and if so put that in
281 // element 0, otherwise put an empty string in element 0.
282 std::string command_partial_str = request.GetCursorArgumentPrefix().str();
284 std::string common_prefix = lldb_matches.LongestCommonPrefix();
285 const size_t partial_name_len = command_partial_str.size();
286 common_prefix.erase(0, partial_name_len);
288 // If we matched a unique single command, add a space... Only do this if
289 // the completer told us this was a complete word, however...
290 if (lldb_matches.GetSize() == 1) {
291 char quote_char = request.GetParsedArg().GetQuoteChar();
292 common_prefix =
293 Args::EscapeLLDBCommandArgument(common_prefix, quote_char);
294 if (request.GetParsedArg().IsQuoted())
295 common_prefix.push_back(quote_char);
296 common_prefix.push_back(' ');
298 lldb_matches.InsertStringAtIndex(0, common_prefix.c_str());
299 lldb_descriptions.InsertStringAtIndex(0, "");
302 SBStringList temp_matches_list(&lldb_matches);
303 matches.AppendList(temp_matches_list);
304 SBStringList temp_descriptions_list(&lldb_descriptions);
305 descriptions.AppendList(temp_descriptions_list);
306 return result.GetNumberOfResults();
309 int SBCommandInterpreter::HandleCompletionWithDescriptions(
310 const char *current_line, uint32_t cursor_pos, int match_start_point,
311 int max_return_elements, SBStringList &matches,
312 SBStringList &descriptions) {
313 LLDB_INSTRUMENT_VA(this, current_line, cursor_pos, match_start_point,
314 max_return_elements, matches, descriptions);
316 const char *cursor = current_line + cursor_pos;
317 const char *last_char = current_line + strlen(current_line);
318 return HandleCompletionWithDescriptions(
319 current_line, cursor, last_char, match_start_point, max_return_elements,
320 matches, descriptions);
323 int SBCommandInterpreter::HandleCompletion(const char *current_line,
324 uint32_t cursor_pos,
325 int match_start_point,
326 int max_return_elements,
327 lldb::SBStringList &matches) {
328 LLDB_INSTRUMENT_VA(this, current_line, cursor_pos, match_start_point,
329 max_return_elements, matches);
331 const char *cursor = current_line + cursor_pos;
332 const char *last_char = current_line + strlen(current_line);
333 return HandleCompletion(current_line, cursor, last_char, match_start_point,
334 max_return_elements, matches);
337 bool SBCommandInterpreter::HasCommands() {
338 LLDB_INSTRUMENT_VA(this);
340 return (IsValid() ? m_opaque_ptr->HasCommands() : false);
343 bool SBCommandInterpreter::HasAliases() {
344 LLDB_INSTRUMENT_VA(this);
346 return (IsValid() ? m_opaque_ptr->HasAliases() : false);
349 bool SBCommandInterpreter::HasAliasOptions() {
350 LLDB_INSTRUMENT_VA(this);
352 return (IsValid() ? m_opaque_ptr->HasAliasOptions() : false);
355 bool SBCommandInterpreter::IsInteractive() {
356 LLDB_INSTRUMENT_VA(this);
358 return (IsValid() ? m_opaque_ptr->IsInteractive() : false);
361 SBProcess SBCommandInterpreter::GetProcess() {
362 LLDB_INSTRUMENT_VA(this);
364 SBProcess sb_process;
365 ProcessSP process_sp;
366 if (IsValid()) {
367 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
368 if (target_sp) {
369 std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
370 process_sp = target_sp->GetProcessSP();
371 sb_process.SetSP(process_sp);
375 return sb_process;
378 SBDebugger SBCommandInterpreter::GetDebugger() {
379 LLDB_INSTRUMENT_VA(this);
381 SBDebugger sb_debugger;
382 if (IsValid())
383 sb_debugger.reset(m_opaque_ptr->GetDebugger().shared_from_this());
385 return sb_debugger;
388 bool SBCommandInterpreter::GetPromptOnQuit() {
389 LLDB_INSTRUMENT_VA(this);
391 return (IsValid() ? m_opaque_ptr->GetPromptOnQuit() : false);
394 void SBCommandInterpreter::SetPromptOnQuit(bool b) {
395 LLDB_INSTRUMENT_VA(this, b);
397 if (IsValid())
398 m_opaque_ptr->SetPromptOnQuit(b);
401 void SBCommandInterpreter::AllowExitCodeOnQuit(bool allow) {
402 LLDB_INSTRUMENT_VA(this, allow);
404 if (m_opaque_ptr)
405 m_opaque_ptr->AllowExitCodeOnQuit(allow);
408 bool SBCommandInterpreter::HasCustomQuitExitCode() {
409 LLDB_INSTRUMENT_VA(this);
411 bool exited = false;
412 if (m_opaque_ptr)
413 m_opaque_ptr->GetQuitExitCode(exited);
414 return exited;
417 int SBCommandInterpreter::GetQuitStatus() {
418 LLDB_INSTRUMENT_VA(this);
420 bool exited = false;
421 return (m_opaque_ptr ? m_opaque_ptr->GetQuitExitCode(exited) : 0);
424 void SBCommandInterpreter::ResolveCommand(const char *command_line,
425 SBCommandReturnObject &result) {
426 LLDB_INSTRUMENT_VA(this, command_line, result);
428 result.Clear();
429 if (command_line && IsValid()) {
430 m_opaque_ptr->ResolveCommand(command_line, result.ref());
431 } else {
432 result->AppendError(
433 "SBCommandInterpreter or the command line is not valid");
437 CommandInterpreter *SBCommandInterpreter::get() { return m_opaque_ptr; }
439 CommandInterpreter &SBCommandInterpreter::ref() {
440 assert(m_opaque_ptr);
441 return *m_opaque_ptr;
444 void SBCommandInterpreter::reset(
445 lldb_private::CommandInterpreter *interpreter) {
446 m_opaque_ptr = interpreter;
449 void SBCommandInterpreter::SourceInitFileInGlobalDirectory(
450 SBCommandReturnObject &result) {
451 LLDB_INSTRUMENT_VA(this, result);
453 result.Clear();
454 if (IsValid()) {
455 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
456 std::unique_lock<std::recursive_mutex> lock;
457 if (target_sp)
458 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
459 m_opaque_ptr->SourceInitFileGlobal(result.ref());
460 } else {
461 result->AppendError("SBCommandInterpreter is not valid");
465 void SBCommandInterpreter::SourceInitFileInHomeDirectory(
466 SBCommandReturnObject &result) {
467 LLDB_INSTRUMENT_VA(this, result);
469 SourceInitFileInHomeDirectory(result, /*is_repl=*/false);
472 void SBCommandInterpreter::SourceInitFileInHomeDirectory(
473 SBCommandReturnObject &result, bool is_repl) {
474 LLDB_INSTRUMENT_VA(this, result, is_repl);
476 result.Clear();
477 if (IsValid()) {
478 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
479 std::unique_lock<std::recursive_mutex> lock;
480 if (target_sp)
481 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
482 m_opaque_ptr->SourceInitFileHome(result.ref(), is_repl);
483 } else {
484 result->AppendError("SBCommandInterpreter is not valid");
488 void SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory(
489 SBCommandReturnObject &result) {
490 LLDB_INSTRUMENT_VA(this, result);
492 result.Clear();
493 if (IsValid()) {
494 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
495 std::unique_lock<std::recursive_mutex> lock;
496 if (target_sp)
497 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
498 m_opaque_ptr->SourceInitFileCwd(result.ref());
499 } else {
500 result->AppendError("SBCommandInterpreter is not valid");
504 SBBroadcaster SBCommandInterpreter::GetBroadcaster() {
505 LLDB_INSTRUMENT_VA(this);
507 SBBroadcaster broadcaster(m_opaque_ptr, false);
509 return broadcaster;
512 const char *SBCommandInterpreter::GetBroadcasterClass() {
513 LLDB_INSTRUMENT();
515 return CommandInterpreter::GetStaticBroadcasterClass().AsCString();
518 const char *SBCommandInterpreter::GetArgumentTypeAsCString(
519 const lldb::CommandArgumentType arg_type) {
520 LLDB_INSTRUMENT_VA(arg_type);
522 return ConstString(CommandObject::GetArgumentTypeAsCString(arg_type))
523 .GetCString();
526 const char *SBCommandInterpreter::GetArgumentDescriptionAsCString(
527 const lldb::CommandArgumentType arg_type) {
528 LLDB_INSTRUMENT_VA(arg_type);
530 return ConstString(CommandObject::GetArgumentDescriptionAsCString(arg_type))
531 .GetCString();
534 bool SBCommandInterpreter::EventIsCommandInterpreterEvent(
535 const lldb::SBEvent &event) {
536 LLDB_INSTRUMENT_VA(event);
538 return event.GetBroadcasterClass() ==
539 SBCommandInterpreter::GetBroadcasterClass();
542 bool SBCommandInterpreter::SetCommandOverrideCallback(
543 const char *command_name, lldb::CommandOverrideCallback callback,
544 void *baton) {
545 LLDB_INSTRUMENT_VA(this, command_name, callback, baton);
547 if (command_name && command_name[0] && IsValid()) {
548 llvm::StringRef command_name_str = command_name;
549 CommandObject *cmd_obj =
550 m_opaque_ptr->GetCommandObjectForCommand(command_name_str);
551 if (cmd_obj) {
552 assert(command_name_str.empty());
553 cmd_obj->SetOverrideCallback(callback, baton);
554 return true;
557 return false;
560 lldb::SBCommand SBCommandInterpreter::AddMultiwordCommand(const char *name,
561 const char *help) {
562 LLDB_INSTRUMENT_VA(this, name, help);
564 lldb::CommandObjectSP new_command_sp(
565 new CommandObjectMultiword(*m_opaque_ptr, name, help));
566 new_command_sp->GetAsMultiwordCommand()->SetRemovable(true);
567 Status add_error = m_opaque_ptr->AddUserCommand(name, new_command_sp, true);
568 if (add_error.Success())
569 return lldb::SBCommand(new_command_sp);
570 return lldb::SBCommand();
573 lldb::SBCommand SBCommandInterpreter::AddCommand(
574 const char *name, lldb::SBCommandPluginInterface *impl, const char *help) {
575 LLDB_INSTRUMENT_VA(this, name, impl, help);
577 return AddCommand(name, impl, help, /*syntax=*/nullptr,
578 /*auto_repeat_command=*/"");
581 lldb::SBCommand
582 SBCommandInterpreter::AddCommand(const char *name,
583 lldb::SBCommandPluginInterface *impl,
584 const char *help, const char *syntax) {
585 LLDB_INSTRUMENT_VA(this, name, impl, help, syntax);
586 return AddCommand(name, impl, help, syntax, /*auto_repeat_command=*/"");
589 lldb::SBCommand SBCommandInterpreter::AddCommand(
590 const char *name, lldb::SBCommandPluginInterface *impl, const char *help,
591 const char *syntax, const char *auto_repeat_command) {
592 LLDB_INSTRUMENT_VA(this, name, impl, help, syntax, auto_repeat_command);
594 lldb::CommandObjectSP new_command_sp;
595 new_command_sp = std::make_shared<CommandPluginInterfaceImplementation>(
596 *m_opaque_ptr, name, impl, help, syntax, /*flags=*/0,
597 auto_repeat_command);
599 Status add_error = m_opaque_ptr->AddUserCommand(name, new_command_sp, true);
600 if (add_error.Success())
601 return lldb::SBCommand(new_command_sp);
602 return lldb::SBCommand();
605 SBCommand::SBCommand() { LLDB_INSTRUMENT_VA(this); }
607 SBCommand::SBCommand(lldb::CommandObjectSP cmd_sp) : m_opaque_sp(cmd_sp) {}
609 bool SBCommand::IsValid() {
610 LLDB_INSTRUMENT_VA(this);
611 return this->operator bool();
613 SBCommand::operator bool() const {
614 LLDB_INSTRUMENT_VA(this);
616 return m_opaque_sp.get() != nullptr;
619 const char *SBCommand::GetName() {
620 LLDB_INSTRUMENT_VA(this);
622 return (IsValid() ? ConstString(m_opaque_sp->GetCommandName()).AsCString() : nullptr);
625 const char *SBCommand::GetHelp() {
626 LLDB_INSTRUMENT_VA(this);
628 return (IsValid() ? ConstString(m_opaque_sp->GetHelp()).AsCString()
629 : nullptr);
632 const char *SBCommand::GetHelpLong() {
633 LLDB_INSTRUMENT_VA(this);
635 return (IsValid() ? ConstString(m_opaque_sp->GetHelpLong()).AsCString()
636 : nullptr);
639 void SBCommand::SetHelp(const char *help) {
640 LLDB_INSTRUMENT_VA(this, help);
642 if (IsValid())
643 m_opaque_sp->SetHelp(help);
646 void SBCommand::SetHelpLong(const char *help) {
647 LLDB_INSTRUMENT_VA(this, help);
649 if (IsValid())
650 m_opaque_sp->SetHelpLong(help);
653 lldb::SBCommand SBCommand::AddMultiwordCommand(const char *name,
654 const char *help) {
655 LLDB_INSTRUMENT_VA(this, name, help);
657 if (!IsValid())
658 return lldb::SBCommand();
659 if (!m_opaque_sp->IsMultiwordObject())
660 return lldb::SBCommand();
661 CommandObjectMultiword *new_command = new CommandObjectMultiword(
662 m_opaque_sp->GetCommandInterpreter(), name, help);
663 new_command->SetRemovable(true);
664 lldb::CommandObjectSP new_command_sp(new_command);
665 if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp))
666 return lldb::SBCommand(new_command_sp);
667 return lldb::SBCommand();
670 lldb::SBCommand SBCommand::AddCommand(const char *name,
671 lldb::SBCommandPluginInterface *impl,
672 const char *help) {
673 LLDB_INSTRUMENT_VA(this, name, impl, help);
674 return AddCommand(name, impl, help, /*syntax=*/nullptr,
675 /*auto_repeat_command=*/"");
678 lldb::SBCommand SBCommand::AddCommand(const char *name,
679 lldb::SBCommandPluginInterface *impl,
680 const char *help, const char *syntax) {
681 LLDB_INSTRUMENT_VA(this, name, impl, help, syntax);
682 return AddCommand(name, impl, help, syntax, /*auto_repeat_command=*/"");
685 lldb::SBCommand SBCommand::AddCommand(const char *name,
686 lldb::SBCommandPluginInterface *impl,
687 const char *help, const char *syntax,
688 const char *auto_repeat_command) {
689 LLDB_INSTRUMENT_VA(this, name, impl, help, syntax, auto_repeat_command);
691 if (!IsValid())
692 return lldb::SBCommand();
693 if (!m_opaque_sp->IsMultiwordObject())
694 return lldb::SBCommand();
695 lldb::CommandObjectSP new_command_sp;
696 new_command_sp = std::make_shared<CommandPluginInterfaceImplementation>(
697 m_opaque_sp->GetCommandInterpreter(), name, impl, help, syntax,
698 /*flags=*/0, auto_repeat_command);
699 if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp))
700 return lldb::SBCommand(new_command_sp);
701 return lldb::SBCommand();
704 uint32_t SBCommand::GetFlags() {
705 LLDB_INSTRUMENT_VA(this);
707 return (IsValid() ? m_opaque_sp->GetFlags().Get() : 0);
710 void SBCommand::SetFlags(uint32_t flags) {
711 LLDB_INSTRUMENT_VA(this, flags);
713 if (IsValid())
714 m_opaque_sp->GetFlags().Set(flags);