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 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/lldb-types.h"
10 
11 #include "SBReproducerPrivate.h"
12 #include "lldb/Interpreter/CommandInterpreter.h"
13 #include "lldb/Interpreter/CommandObjectMultiword.h"
14 #include "lldb/Interpreter/CommandReturnObject.h"
15 #include "lldb/Target/Target.h"
16 #include "lldb/Utility/Listener.h"
17 
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"
29 
30 #include <memory>
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
35 class CommandPluginInterfaceImplementation : public CommandObjectParsed {
36 public:
37   CommandPluginInterfaceImplementation(CommandInterpreter &interpreter,
38                                        const char *name,
39                                        lldb::SBCommandPluginInterface *backend,
40                                        const char *help = nullptr,
41                                        const char *syntax = nullptr,
42                                        uint32_t flags = 0,
43                                        const char *auto_repeat_command = "")
44       : CommandObjectParsed(interpreter, name, help, syntax, flags),
45         m_backend(backend) {
46     m_auto_repeat_command =
47         auto_repeat_command == nullptr
48             ? llvm::None
49             : llvm::Optional<std::string>(auto_repeat_command);
50   }
51 
52   bool IsRemovable() const override { return true; }
53 
54   /// More documentation is available in lldb::CommandObject::GetRepeatCommand,
55   /// but in short, if nullptr is returned, the previous command will be
56   /// repeated, and if an empty string is returned, no commands will be
57   /// executed.
58   const char *GetRepeatCommand(Args &current_command_args,
59                                uint32_t index) override {
60     if (!m_auto_repeat_command)
61       return nullptr;
62     else
63       return m_auto_repeat_command->c_str();
64   }
65 
66 protected:
67   bool DoExecute(Args &command, CommandReturnObject &result) override {
68     SBCommandReturnObject sb_return(result);
69     SBCommandInterpreter sb_interpreter(&m_interpreter);
70     SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this());
71     bool ret = m_backend->DoExecute(
72         debugger_sb, command.GetArgumentVector(), sb_return);
73     return ret;
74   }
75   std::shared_ptr<lldb::SBCommandPluginInterface> m_backend;
76   llvm::Optional<std::string> m_auto_repeat_command;
77 };
78 
79 SBCommandInterpreter::SBCommandInterpreter(CommandInterpreter *interpreter)
80     : m_opaque_ptr(interpreter) {
81   LLDB_RECORD_CONSTRUCTOR(SBCommandInterpreter,
82                           (lldb_private::CommandInterpreter *), interpreter);
83 
84 }
85 
86 SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs)
87     : m_opaque_ptr(rhs.m_opaque_ptr) {
88   LLDB_RECORD_CONSTRUCTOR(SBCommandInterpreter,
89                           (const lldb::SBCommandInterpreter &), rhs);
90 }
91 
92 SBCommandInterpreter::~SBCommandInterpreter() = default;
93 
94 const SBCommandInterpreter &SBCommandInterpreter::
95 operator=(const SBCommandInterpreter &rhs) {
96   LLDB_RECORD_METHOD(
97       const lldb::SBCommandInterpreter &,
98       SBCommandInterpreter, operator=,(const lldb::SBCommandInterpreter &),
99       rhs);
100 
101   m_opaque_ptr = rhs.m_opaque_ptr;
102   return LLDB_RECORD_RESULT(*this);
103 }
104 
105 bool SBCommandInterpreter::IsValid() const {
106   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreter, IsValid);
107   return this->operator bool();
108 }
109 SBCommandInterpreter::operator bool() const {
110   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreter, operator bool);
111 
112   return m_opaque_ptr != nullptr;
113 }
114 
115 bool SBCommandInterpreter::CommandExists(const char *cmd) {
116   LLDB_RECORD_METHOD(bool, SBCommandInterpreter, CommandExists, (const char *),
117                      cmd);
118 
119   return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->CommandExists(cmd)
120                                           : false);
121 }
122 
123 bool SBCommandInterpreter::AliasExists(const char *cmd) {
124   LLDB_RECORD_METHOD(bool, SBCommandInterpreter, AliasExists, (const char *),
125                      cmd);
126 
127   return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->AliasExists(cmd)
128                                           : false);
129 }
130 
131 bool SBCommandInterpreter::IsActive() {
132   LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandInterpreter, IsActive);
133 
134   return (IsValid() ? m_opaque_ptr->IsActive() : false);
135 }
136 
137 bool SBCommandInterpreter::WasInterrupted() const {
138   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandInterpreter, WasInterrupted);
139 
140   return (IsValid() ? m_opaque_ptr->WasInterrupted() : false);
141 }
142 
143 const char *SBCommandInterpreter::GetIOHandlerControlSequence(char ch) {
144   LLDB_RECORD_METHOD(const char *, SBCommandInterpreter,
145                      GetIOHandlerControlSequence, (char), ch);
146 
147   return (IsValid()
148               ? m_opaque_ptr->GetDebugger()
149                     .GetTopIOHandlerControlSequence(ch)
150                     .GetCString()
151               : nullptr);
152 }
153 
154 lldb::ReturnStatus
155 SBCommandInterpreter::HandleCommand(const char *command_line,
156                                     SBCommandReturnObject &result,
157                                     bool add_to_history) {
158   LLDB_RECORD_METHOD(lldb::ReturnStatus, SBCommandInterpreter, HandleCommand,
159                      (const char *, lldb::SBCommandReturnObject &, bool),
160                      command_line, result, add_to_history);
161 
162   SBExecutionContext sb_exe_ctx;
163   return HandleCommand(command_line, sb_exe_ctx, result, add_to_history);
164 }
165 
166 lldb::ReturnStatus SBCommandInterpreter::HandleCommand(
167     const char *command_line, SBExecutionContext &override_context,
168     SBCommandReturnObject &result, bool add_to_history) {
169   LLDB_RECORD_METHOD(lldb::ReturnStatus, SBCommandInterpreter, HandleCommand,
170                      (const char *, lldb::SBExecutionContext &,
171                       lldb::SBCommandReturnObject &, bool),
172                      command_line, override_context, result, add_to_history);
173 
174   result.Clear();
175   if (command_line && IsValid()) {
176     result.ref().SetInteractive(false);
177     auto do_add_to_history = add_to_history ? eLazyBoolYes : eLazyBoolNo;
178     if (override_context.get())
179       m_opaque_ptr->HandleCommand(command_line, do_add_to_history,
180                                   override_context.get()->Lock(true),
181                                   result.ref());
182     else
183       m_opaque_ptr->HandleCommand(command_line, do_add_to_history,
184                                   result.ref());
185   } else {
186     result->AppendError(
187         "SBCommandInterpreter or the command line is not valid");
188     result->SetStatus(eReturnStatusFailed);
189   }
190 
191   return result.GetStatus();
192 }
193 
194 void SBCommandInterpreter::HandleCommandsFromFile(
195     lldb::SBFileSpec &file, lldb::SBExecutionContext &override_context,
196     lldb::SBCommandInterpreterRunOptions &options,
197     lldb::SBCommandReturnObject result) {
198   LLDB_RECORD_METHOD(void, SBCommandInterpreter, HandleCommandsFromFile,
199                      (lldb::SBFileSpec &, lldb::SBExecutionContext &,
200                       lldb::SBCommandInterpreterRunOptions &,
201                       lldb::SBCommandReturnObject),
202                      file, override_context, options, result);
203 
204   if (!IsValid()) {
205     result->AppendError("SBCommandInterpreter is not valid.");
206     result->SetStatus(eReturnStatusFailed);
207     return;
208   }
209 
210   if (!file.IsValid()) {
211     SBStream s;
212     file.GetDescription(s);
213     result->AppendErrorWithFormat("File is not valid: %s.", s.GetData());
214     result->SetStatus(eReturnStatusFailed);
215   }
216 
217   FileSpec tmp_spec = file.ref();
218   if (override_context.get())
219     m_opaque_ptr->HandleCommandsFromFile(tmp_spec,
220                                          override_context.get()->Lock(true),
221                                          options.ref(),
222                                          result.ref());
223 
224   else
225     m_opaque_ptr->HandleCommandsFromFile(tmp_spec, options.ref(), result.ref());
226 }
227 
228 int SBCommandInterpreter::HandleCompletion(
229     const char *current_line, const char *cursor, const char *last_char,
230     int match_start_point, int max_return_elements, SBStringList &matches) {
231   LLDB_RECORD_METHOD(int, SBCommandInterpreter, HandleCompletion,
232                      (const char *, const char *, const char *, int, int,
233                       lldb::SBStringList &),
234                      current_line, cursor, last_char, match_start_point,
235                      max_return_elements, matches);
236 
237   SBStringList dummy_descriptions;
238   return HandleCompletionWithDescriptions(
239       current_line, cursor, last_char, match_start_point, max_return_elements,
240       matches, dummy_descriptions);
241 }
242 
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_RECORD_METHOD(int, SBCommandInterpreter,
248                      HandleCompletionWithDescriptions,
249                      (const char *, const char *, const char *, int, int,
250                       lldb::SBStringList &, lldb::SBStringList &),
251                      current_line, cursor, last_char, match_start_point,
252                      max_return_elements, matches, descriptions);
253 
254   // Sanity check the arguments that are passed in: cursor & last_char have to
255   // be within the current_line.
256   if (current_line == nullptr || cursor == nullptr || last_char == nullptr)
257     return 0;
258 
259   if (cursor < current_line || last_char < current_line)
260     return 0;
261 
262   size_t current_line_size = strlen(current_line);
263   if (cursor - current_line > static_cast<ptrdiff_t>(current_line_size) ||
264       last_char - current_line > static_cast<ptrdiff_t>(current_line_size))
265     return 0;
266 
267   if (!IsValid())
268     return 0;
269 
270   lldb_private::StringList lldb_matches, lldb_descriptions;
271   CompletionResult result;
272   CompletionRequest request(current_line, cursor - current_line, result);
273   m_opaque_ptr->HandleCompletion(request);
274   result.GetMatches(lldb_matches);
275   result.GetDescriptions(lldb_descriptions);
276 
277   // Make the result array indexed from 1 again by adding the 'common prefix'
278   // of all completions as element 0. This is done to emulate the old API.
279   if (request.GetParsedLine().GetArgumentCount() == 0) {
280     // If we got an empty string, insert nothing.
281     lldb_matches.InsertStringAtIndex(0, "");
282     lldb_descriptions.InsertStringAtIndex(0, "");
283   } else {
284     // Now figure out if there is a common substring, and if so put that in
285     // element 0, otherwise put an empty string in element 0.
286     std::string command_partial_str = request.GetCursorArgumentPrefix().str();
287 
288     std::string common_prefix = lldb_matches.LongestCommonPrefix();
289     const size_t partial_name_len = command_partial_str.size();
290     common_prefix.erase(0, partial_name_len);
291 
292     // If we matched a unique single command, add a space... Only do this if
293     // the completer told us this was a complete word, however...
294     if (lldb_matches.GetSize() == 1) {
295       char quote_char = request.GetParsedArg().GetQuoteChar();
296       common_prefix =
297           Args::EscapeLLDBCommandArgument(common_prefix, quote_char);
298       if (request.GetParsedArg().IsQuoted())
299         common_prefix.push_back(quote_char);
300       common_prefix.push_back(' ');
301     }
302     lldb_matches.InsertStringAtIndex(0, common_prefix.c_str());
303     lldb_descriptions.InsertStringAtIndex(0, "");
304   }
305 
306   SBStringList temp_matches_list(&lldb_matches);
307   matches.AppendList(temp_matches_list);
308   SBStringList temp_descriptions_list(&lldb_descriptions);
309   descriptions.AppendList(temp_descriptions_list);
310   return result.GetNumberOfResults();
311 }
312 
313 int SBCommandInterpreter::HandleCompletionWithDescriptions(
314     const char *current_line, uint32_t cursor_pos, int match_start_point,
315     int max_return_elements, SBStringList &matches,
316     SBStringList &descriptions) {
317   LLDB_RECORD_METHOD(int, SBCommandInterpreter,
318                      HandleCompletionWithDescriptions,
319                      (const char *, uint32_t, int, int, lldb::SBStringList &,
320                       lldb::SBStringList &),
321                      current_line, cursor_pos, match_start_point,
322                      max_return_elements, matches, descriptions);
323 
324   const char *cursor = current_line + cursor_pos;
325   const char *last_char = current_line + strlen(current_line);
326   return HandleCompletionWithDescriptions(
327       current_line, cursor, last_char, match_start_point, max_return_elements,
328       matches, descriptions);
329 }
330 
331 int SBCommandInterpreter::HandleCompletion(const char *current_line,
332                                            uint32_t cursor_pos,
333                                            int match_start_point,
334                                            int max_return_elements,
335                                            lldb::SBStringList &matches) {
336   LLDB_RECORD_METHOD(int, SBCommandInterpreter, HandleCompletion,
337                      (const char *, uint32_t, int, int, lldb::SBStringList &),
338                      current_line, cursor_pos, match_start_point,
339                      max_return_elements, matches);
340 
341   const char *cursor = current_line + cursor_pos;
342   const char *last_char = current_line + strlen(current_line);
343   return HandleCompletion(current_line, cursor, last_char, match_start_point,
344                           max_return_elements, matches);
345 }
346 
347 bool SBCommandInterpreter::HasCommands() {
348   LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandInterpreter, HasCommands);
349 
350   return (IsValid() ? m_opaque_ptr->HasCommands() : false);
351 }
352 
353 bool SBCommandInterpreter::HasAliases() {
354   LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandInterpreter, HasAliases);
355 
356   return (IsValid() ? m_opaque_ptr->HasAliases() : false);
357 }
358 
359 bool SBCommandInterpreter::HasAliasOptions() {
360   LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandInterpreter, HasAliasOptions);
361 
362   return (IsValid() ? m_opaque_ptr->HasAliasOptions() : false);
363 }
364 
365 SBProcess SBCommandInterpreter::GetProcess() {
366   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess, SBCommandInterpreter, GetProcess);
367 
368   SBProcess sb_process;
369   ProcessSP process_sp;
370   if (IsValid()) {
371     TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
372     if (target_sp) {
373       std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
374       process_sp = target_sp->GetProcessSP();
375       sb_process.SetSP(process_sp);
376     }
377   }
378 
379   return LLDB_RECORD_RESULT(sb_process);
380 }
381 
382 SBDebugger SBCommandInterpreter::GetDebugger() {
383   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBDebugger, SBCommandInterpreter,
384                              GetDebugger);
385 
386   SBDebugger sb_debugger;
387   if (IsValid())
388     sb_debugger.reset(m_opaque_ptr->GetDebugger().shared_from_this());
389 
390   return LLDB_RECORD_RESULT(sb_debugger);
391 }
392 
393 bool SBCommandInterpreter::GetPromptOnQuit() {
394   LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandInterpreter, GetPromptOnQuit);
395 
396   return (IsValid() ? m_opaque_ptr->GetPromptOnQuit() : false);
397 }
398 
399 void SBCommandInterpreter::SetPromptOnQuit(bool b) {
400   LLDB_RECORD_METHOD(void, SBCommandInterpreter, SetPromptOnQuit, (bool), b);
401 
402   if (IsValid())
403     m_opaque_ptr->SetPromptOnQuit(b);
404 }
405 
406 void SBCommandInterpreter::AllowExitCodeOnQuit(bool allow) {
407   LLDB_RECORD_METHOD(void, SBCommandInterpreter, AllowExitCodeOnQuit, (bool),
408                      allow);
409 
410   if (m_opaque_ptr)
411     m_opaque_ptr->AllowExitCodeOnQuit(allow);
412 }
413 
414 bool SBCommandInterpreter::HasCustomQuitExitCode() {
415   LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandInterpreter, HasCustomQuitExitCode);
416 
417   bool exited = false;
418   if (m_opaque_ptr)
419     m_opaque_ptr->GetQuitExitCode(exited);
420   return exited;
421 }
422 
423 int SBCommandInterpreter::GetQuitStatus() {
424   LLDB_RECORD_METHOD_NO_ARGS(int, SBCommandInterpreter, GetQuitStatus);
425 
426   bool exited = false;
427   return (m_opaque_ptr ? m_opaque_ptr->GetQuitExitCode(exited) : 0);
428 }
429 
430 void SBCommandInterpreter::ResolveCommand(const char *command_line,
431                                           SBCommandReturnObject &result) {
432   LLDB_RECORD_METHOD(void, SBCommandInterpreter, ResolveCommand,
433                      (const char *, lldb::SBCommandReturnObject &),
434                      command_line, result);
435 
436   result.Clear();
437   if (command_line && IsValid()) {
438     m_opaque_ptr->ResolveCommand(command_line, result.ref());
439   } else {
440     result->AppendError(
441         "SBCommandInterpreter or the command line is not valid");
442     result->SetStatus(eReturnStatusFailed);
443   }
444 }
445 
446 CommandInterpreter *SBCommandInterpreter::get() { return m_opaque_ptr; }
447 
448 CommandInterpreter &SBCommandInterpreter::ref() {
449   assert(m_opaque_ptr);
450   return *m_opaque_ptr;
451 }
452 
453 void SBCommandInterpreter::reset(
454     lldb_private::CommandInterpreter *interpreter) {
455   m_opaque_ptr = interpreter;
456 }
457 
458 void SBCommandInterpreter::SourceInitFileInHomeDirectory(
459     SBCommandReturnObject &result) {
460   LLDB_RECORD_METHOD(void, SBCommandInterpreter, SourceInitFileInHomeDirectory,
461                      (lldb::SBCommandReturnObject &), result);
462 
463   result.Clear();
464   if (IsValid()) {
465     TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
466     std::unique_lock<std::recursive_mutex> lock;
467     if (target_sp)
468       lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
469     m_opaque_ptr->SourceInitFileHome(result.ref());
470   } else {
471     result->AppendError("SBCommandInterpreter is not valid");
472     result->SetStatus(eReturnStatusFailed);
473   }
474 }
475 
476 void SBCommandInterpreter::SourceInitFileInHomeDirectory(
477     SBCommandReturnObject &result, bool is_repl) {
478   LLDB_RECORD_METHOD(void, SBCommandInterpreter, SourceInitFileInHomeDirectory,
479                      (lldb::SBCommandReturnObject &, bool), result, is_repl);
480 
481   result.Clear();
482   if (IsValid()) {
483     TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
484     std::unique_lock<std::recursive_mutex> lock;
485     if (target_sp)
486       lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
487     m_opaque_ptr->SourceInitFileHome(result.ref(), is_repl);
488   } else {
489     result->AppendError("SBCommandInterpreter is not valid");
490     result->SetStatus(eReturnStatusFailed);
491   }
492 }
493 
494 void SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory(
495     SBCommandReturnObject &result) {
496   LLDB_RECORD_METHOD(void, SBCommandInterpreter,
497                      SourceInitFileInCurrentWorkingDirectory,
498                      (lldb::SBCommandReturnObject &), result);
499 
500   result.Clear();
501   if (IsValid()) {
502     TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
503     std::unique_lock<std::recursive_mutex> lock;
504     if (target_sp)
505       lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
506     m_opaque_ptr->SourceInitFileCwd(result.ref());
507   } else {
508     result->AppendError("SBCommandInterpreter is not valid");
509     result->SetStatus(eReturnStatusFailed);
510   }
511 }
512 
513 SBBroadcaster SBCommandInterpreter::GetBroadcaster() {
514   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBroadcaster, SBCommandInterpreter,
515                              GetBroadcaster);
516 
517 
518   SBBroadcaster broadcaster(m_opaque_ptr, false);
519 
520 
521   return LLDB_RECORD_RESULT(broadcaster);
522 }
523 
524 const char *SBCommandInterpreter::GetBroadcasterClass() {
525   LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBCommandInterpreter,
526                                     GetBroadcasterClass);
527 
528   return CommandInterpreter::GetStaticBroadcasterClass().AsCString();
529 }
530 
531 const char *SBCommandInterpreter::GetArgumentTypeAsCString(
532     const lldb::CommandArgumentType arg_type) {
533   LLDB_RECORD_STATIC_METHOD(const char *, SBCommandInterpreter,
534                             GetArgumentTypeAsCString,
535                             (const lldb::CommandArgumentType), arg_type);
536 
537   return CommandObject::GetArgumentTypeAsCString(arg_type);
538 }
539 
540 const char *SBCommandInterpreter::GetArgumentDescriptionAsCString(
541     const lldb::CommandArgumentType arg_type) {
542   LLDB_RECORD_STATIC_METHOD(const char *, SBCommandInterpreter,
543                             GetArgumentDescriptionAsCString,
544                             (const lldb::CommandArgumentType), arg_type);
545 
546   return CommandObject::GetArgumentDescriptionAsCString(arg_type);
547 }
548 
549 bool SBCommandInterpreter::EventIsCommandInterpreterEvent(
550     const lldb::SBEvent &event) {
551   LLDB_RECORD_STATIC_METHOD(bool, SBCommandInterpreter,
552                             EventIsCommandInterpreterEvent,
553                             (const lldb::SBEvent &), event);
554 
555   return event.GetBroadcasterClass() ==
556          SBCommandInterpreter::GetBroadcasterClass();
557 }
558 
559 bool SBCommandInterpreter::SetCommandOverrideCallback(
560     const char *command_name, lldb::CommandOverrideCallback callback,
561     void *baton) {
562   LLDB_RECORD_DUMMY(bool, SBCommandInterpreter, SetCommandOverrideCallback,
563                     (const char *, lldb::CommandOverrideCallback, void *),
564                     command_name, callback, baton);
565 
566   if (command_name && command_name[0] && IsValid()) {
567     llvm::StringRef command_name_str = command_name;
568     CommandObject *cmd_obj =
569         m_opaque_ptr->GetCommandObjectForCommand(command_name_str);
570     if (cmd_obj) {
571       assert(command_name_str.empty());
572       cmd_obj->SetOverrideCallback(callback, baton);
573       return true;
574     }
575   }
576   return false;
577 }
578 
579 lldb::SBCommand SBCommandInterpreter::AddMultiwordCommand(const char *name,
580                                                           const char *help) {
581   LLDB_RECORD_METHOD(lldb::SBCommand, SBCommandInterpreter, AddMultiwordCommand,
582                      (const char *, const char *), name, help);
583 
584   CommandObjectMultiword *new_command =
585       new CommandObjectMultiword(*m_opaque_ptr, name, help);
586   new_command->SetRemovable(true);
587   lldb::CommandObjectSP new_command_sp(new_command);
588   if (new_command_sp &&
589       m_opaque_ptr->AddUserCommand(name, new_command_sp, true))
590     return LLDB_RECORD_RESULT(lldb::SBCommand(new_command_sp));
591   return LLDB_RECORD_RESULT(lldb::SBCommand());
592 }
593 
594 lldb::SBCommand SBCommandInterpreter::AddCommand(
595     const char *name, lldb::SBCommandPluginInterface *impl, const char *help) {
596   LLDB_RECORD_METHOD(
597       lldb::SBCommand, SBCommandInterpreter, AddCommand,
598       (const char *, lldb::SBCommandPluginInterface *, const char *), name,
599       impl, help);
600 
601   return LLDB_RECORD_RESULT(AddCommand(name, impl, help, /*syntax=*/nullptr,
602                                        /*auto_repeat_command=*/""))
603 }
604 
605 lldb::SBCommand
606 SBCommandInterpreter::AddCommand(const char *name,
607                                  lldb::SBCommandPluginInterface *impl,
608                                  const char *help, const char *syntax) {
609   LLDB_RECORD_METHOD(lldb::SBCommand, SBCommandInterpreter, AddCommand,
610                      (const char *, lldb::SBCommandPluginInterface *,
611                       const char *, const char *),
612                      name, impl, help, syntax);
613   return LLDB_RECORD_RESULT(
614       AddCommand(name, impl, help, syntax, /*auto_repeat_command=*/""))
615 }
616 
617 lldb::SBCommand SBCommandInterpreter::AddCommand(
618     const char *name, lldb::SBCommandPluginInterface *impl, const char *help,
619     const char *syntax, const char *auto_repeat_command) {
620   LLDB_RECORD_METHOD(lldb::SBCommand, SBCommandInterpreter, AddCommand,
621                      (const char *, lldb::SBCommandPluginInterface *,
622                       const char *, const char *, const char *),
623                      name, impl, help, syntax, auto_repeat_command);
624 
625   lldb::CommandObjectSP new_command_sp;
626   new_command_sp = std::make_shared<CommandPluginInterfaceImplementation>(
627       *m_opaque_ptr, name, impl, help, syntax, /*flags=*/0,
628       auto_repeat_command);
629 
630   if (new_command_sp &&
631       m_opaque_ptr->AddUserCommand(name, new_command_sp, true))
632     return LLDB_RECORD_RESULT(lldb::SBCommand(new_command_sp));
633   return LLDB_RECORD_RESULT(lldb::SBCommand());
634 }
635 
636 SBCommand::SBCommand() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommand); }
637 
638 SBCommand::SBCommand(lldb::CommandObjectSP cmd_sp) : m_opaque_sp(cmd_sp) {}
639 
640 bool SBCommand::IsValid() {
641   LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommand, IsValid);
642   return this->operator bool();
643 }
644 SBCommand::operator bool() const {
645   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommand, operator bool);
646 
647   return m_opaque_sp.get() != nullptr;
648 }
649 
650 const char *SBCommand::GetName() {
651   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommand, GetName);
652 
653   return (IsValid() ? ConstString(m_opaque_sp->GetCommandName()).AsCString() : nullptr);
654 }
655 
656 const char *SBCommand::GetHelp() {
657   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommand, GetHelp);
658 
659   return (IsValid() ? ConstString(m_opaque_sp->GetHelp()).AsCString()
660                     : nullptr);
661 }
662 
663 const char *SBCommand::GetHelpLong() {
664   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommand, GetHelpLong);
665 
666   return (IsValid() ? ConstString(m_opaque_sp->GetHelpLong()).AsCString()
667                     : nullptr);
668 }
669 
670 void SBCommand::SetHelp(const char *help) {
671   LLDB_RECORD_METHOD(void, SBCommand, SetHelp, (const char *), help);
672 
673   if (IsValid())
674     m_opaque_sp->SetHelp(help);
675 }
676 
677 void SBCommand::SetHelpLong(const char *help) {
678   LLDB_RECORD_METHOD(void, SBCommand, SetHelpLong, (const char *), help);
679 
680   if (IsValid())
681     m_opaque_sp->SetHelpLong(help);
682 }
683 
684 lldb::SBCommand SBCommand::AddMultiwordCommand(const char *name,
685                                                const char *help) {
686   LLDB_RECORD_METHOD(lldb::SBCommand, SBCommand, AddMultiwordCommand,
687                      (const char *, const char *), name, help);
688 
689   if (!IsValid())
690     return LLDB_RECORD_RESULT(lldb::SBCommand());
691   if (!m_opaque_sp->IsMultiwordObject())
692     return LLDB_RECORD_RESULT(lldb::SBCommand());
693   CommandObjectMultiword *new_command = new CommandObjectMultiword(
694       m_opaque_sp->GetCommandInterpreter(), name, help);
695   new_command->SetRemovable(true);
696   lldb::CommandObjectSP new_command_sp(new_command);
697   if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp))
698     return LLDB_RECORD_RESULT(lldb::SBCommand(new_command_sp));
699   return LLDB_RECORD_RESULT(lldb::SBCommand());
700 }
701 
702 lldb::SBCommand SBCommand::AddCommand(const char *name,
703                                       lldb::SBCommandPluginInterface *impl,
704                                       const char *help) {
705   LLDB_RECORD_METHOD(
706       lldb::SBCommand, SBCommand, AddCommand,
707       (const char *, lldb::SBCommandPluginInterface *, const char *), name,
708       impl, help);
709   return LLDB_RECORD_RESULT(AddCommand(name, impl, help, /*syntax=*/nullptr,
710                                        /*auto_repeat_command=*/""))
711 }
712 
713 lldb::SBCommand SBCommand::AddCommand(const char *name,
714                                       lldb::SBCommandPluginInterface *impl,
715                                       const char *help, const char *syntax) {
716   LLDB_RECORD_METHOD(lldb::SBCommand, SBCommand, AddCommand,
717                      (const char *, lldb::SBCommandPluginInterface *,
718                       const char *, const char *),
719                      name, impl, help, syntax);
720   return LLDB_RECORD_RESULT(
721       AddCommand(name, impl, help, syntax, /*auto_repeat_command=*/""))
722 }
723 
724 lldb::SBCommand SBCommand::AddCommand(const char *name,
725                                       lldb::SBCommandPluginInterface *impl,
726                                       const char *help, const char *syntax,
727                                       const char *auto_repeat_command) {
728   LLDB_RECORD_METHOD(lldb::SBCommand, SBCommand, AddCommand,
729                      (const char *, lldb::SBCommandPluginInterface *,
730                       const char *, const char *, const char *),
731                      name, impl, help, syntax, auto_repeat_command);
732 
733   if (!IsValid())
734     return LLDB_RECORD_RESULT(lldb::SBCommand());
735   if (!m_opaque_sp->IsMultiwordObject())
736     return LLDB_RECORD_RESULT(lldb::SBCommand());
737   lldb::CommandObjectSP new_command_sp;
738   new_command_sp = std::make_shared<CommandPluginInterfaceImplementation>(
739       m_opaque_sp->GetCommandInterpreter(), name, impl, help, syntax,
740       /*flags=*/0, auto_repeat_command);
741   if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp))
742     return LLDB_RECORD_RESULT(lldb::SBCommand(new_command_sp));
743   return LLDB_RECORD_RESULT(lldb::SBCommand());
744 }
745 
746 uint32_t SBCommand::GetFlags() {
747   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBCommand, GetFlags);
748 
749   return (IsValid() ? m_opaque_sp->GetFlags().Get() : 0);
750 }
751 
752 void SBCommand::SetFlags(uint32_t flags) {
753   LLDB_RECORD_METHOD(void, SBCommand, SetFlags, (uint32_t), flags);
754 
755   if (IsValid())
756     m_opaque_sp->GetFlags().Set(flags);
757 }
758 
759 namespace lldb_private {
760 namespace repro {
761 
762 template <> void RegisterMethods<SBCommandInterpreter>(Registry &R) {
763   LLDB_REGISTER_CONSTRUCTOR(SBCommandInterpreter,
764                             (lldb_private::CommandInterpreter *));
765   LLDB_REGISTER_CONSTRUCTOR(SBCommandInterpreter,
766                             (const lldb::SBCommandInterpreter &));
767   LLDB_REGISTER_METHOD(
768       const lldb::SBCommandInterpreter &,
769       SBCommandInterpreter, operator=,(const lldb::SBCommandInterpreter &));
770   LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreter, IsValid, ());
771   LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreter, operator bool, ());
772   LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, CommandExists,
773                        (const char *));
774   LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, AliasExists,
775                        (const char *));
776   LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, IsActive, ());
777   LLDB_REGISTER_METHOD_CONST(bool, SBCommandInterpreter, WasInterrupted, ());
778   LLDB_REGISTER_METHOD(const char *, SBCommandInterpreter,
779                        GetIOHandlerControlSequence, (char));
780   LLDB_REGISTER_METHOD(lldb::ReturnStatus, SBCommandInterpreter,
781                        HandleCommand,
782                        (const char *, lldb::SBCommandReturnObject &, bool));
783   LLDB_REGISTER_METHOD(lldb::ReturnStatus, SBCommandInterpreter,
784                        HandleCommand,
785                        (const char *, lldb::SBExecutionContext &,
786                         lldb::SBCommandReturnObject &, bool));
787   LLDB_REGISTER_METHOD(void, SBCommandInterpreter, HandleCommandsFromFile,
788                        (lldb::SBFileSpec &, lldb::SBExecutionContext &,
789                         lldb::SBCommandInterpreterRunOptions &,
790                         lldb::SBCommandReturnObject));
791   LLDB_REGISTER_METHOD(int, SBCommandInterpreter, HandleCompletion,
792                        (const char *, const char *, const char *, int, int,
793                         lldb::SBStringList &));
794   LLDB_REGISTER_METHOD(int, SBCommandInterpreter,
795                        HandleCompletionWithDescriptions,
796                        (const char *, const char *, const char *, int, int,
797                         lldb::SBStringList &, lldb::SBStringList &));
798   LLDB_REGISTER_METHOD(int, SBCommandInterpreter,
799                        HandleCompletionWithDescriptions,
800                        (const char *, uint32_t, int, int,
801                         lldb::SBStringList &, lldb::SBStringList &));
802   LLDB_REGISTER_METHOD(
803       int, SBCommandInterpreter, HandleCompletion,
804       (const char *, uint32_t, int, int, lldb::SBStringList &));
805   LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, HasCommands, ());
806   LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, HasAliases, ());
807   LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, HasAliasOptions, ());
808   LLDB_REGISTER_METHOD(lldb::SBProcess, SBCommandInterpreter, GetProcess, ());
809   LLDB_REGISTER_METHOD(lldb::SBDebugger, SBCommandInterpreter, GetDebugger,
810                        ());
811   LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, GetPromptOnQuit, ());
812   LLDB_REGISTER_METHOD(void, SBCommandInterpreter, SetPromptOnQuit, (bool));
813   LLDB_REGISTER_METHOD(void, SBCommandInterpreter, AllowExitCodeOnQuit,
814                        (bool));
815   LLDB_REGISTER_METHOD(bool, SBCommandInterpreter, HasCustomQuitExitCode, ());
816   LLDB_REGISTER_METHOD(int, SBCommandInterpreter, GetQuitStatus, ());
817   LLDB_REGISTER_METHOD(void, SBCommandInterpreter, ResolveCommand,
818                        (const char *, lldb::SBCommandReturnObject &));
819   LLDB_REGISTER_METHOD(void, SBCommandInterpreter,
820                        SourceInitFileInHomeDirectory,
821                        (lldb::SBCommandReturnObject &));
822   LLDB_REGISTER_METHOD(void, SBCommandInterpreter,
823                        SourceInitFileInHomeDirectory,
824                        (lldb::SBCommandReturnObject &, bool));
825   LLDB_REGISTER_METHOD(void, SBCommandInterpreter,
826                        SourceInitFileInCurrentWorkingDirectory,
827                        (lldb::SBCommandReturnObject &));
828   LLDB_REGISTER_METHOD(lldb::SBBroadcaster, SBCommandInterpreter,
829                        GetBroadcaster, ());
830   LLDB_REGISTER_STATIC_METHOD(const char *, SBCommandInterpreter,
831                               GetBroadcasterClass, ());
832   LLDB_REGISTER_STATIC_METHOD(const char *, SBCommandInterpreter,
833                               GetArgumentTypeAsCString,
834                               (const lldb::CommandArgumentType));
835   LLDB_REGISTER_STATIC_METHOD(const char *, SBCommandInterpreter,
836                               GetArgumentDescriptionAsCString,
837                               (const lldb::CommandArgumentType));
838   LLDB_REGISTER_STATIC_METHOD(bool, SBCommandInterpreter,
839                               EventIsCommandInterpreterEvent,
840                               (const lldb::SBEvent &));
841   LLDB_REGISTER_METHOD(lldb::SBCommand, SBCommandInterpreter,
842                        AddMultiwordCommand, (const char *, const char *));
843   LLDB_REGISTER_METHOD(
844       lldb::SBCommand, SBCommandInterpreter, AddCommand,
845       (const char *, lldb::SBCommandPluginInterface *, const char *));
846   LLDB_REGISTER_METHOD(lldb::SBCommand, SBCommandInterpreter, AddCommand,
847                        (const char *, lldb::SBCommandPluginInterface *,
848                         const char *, const char *));
849   LLDB_REGISTER_METHOD(lldb::SBCommand, SBCommandInterpreter, AddCommand,
850                        (const char *, lldb::SBCommandPluginInterface *,
851                         const char *, const char *, const char *));
852   LLDB_REGISTER_CONSTRUCTOR(SBCommand, ());
853   LLDB_REGISTER_METHOD(bool, SBCommand, IsValid, ());
854   LLDB_REGISTER_METHOD_CONST(bool, SBCommand, operator bool, ());
855   LLDB_REGISTER_METHOD(const char *, SBCommand, GetName, ());
856   LLDB_REGISTER_METHOD(const char *, SBCommand, GetHelp, ());
857   LLDB_REGISTER_METHOD(const char *, SBCommand, GetHelpLong, ());
858   LLDB_REGISTER_METHOD(void, SBCommand, SetHelp, (const char *));
859   LLDB_REGISTER_METHOD(void, SBCommand, SetHelpLong, (const char *));
860   LLDB_REGISTER_METHOD(lldb::SBCommand, SBCommand, AddMultiwordCommand,
861                        (const char *, const char *));
862   LLDB_REGISTER_METHOD(
863       lldb::SBCommand, SBCommand, AddCommand,
864       (const char *, lldb::SBCommandPluginInterface *, const char *));
865   LLDB_REGISTER_METHOD(lldb::SBCommand, SBCommand, AddCommand,
866                        (const char *, lldb::SBCommandPluginInterface *,
867                         const char *, const char *));
868   LLDB_REGISTER_METHOD(lldb::SBCommand, SBCommand, AddCommand,
869                        (const char *, lldb::SBCommandPluginInterface *,
870                         const char *, const char *, const char *));
871   LLDB_REGISTER_METHOD(uint32_t, SBCommand, GetFlags, ());
872   LLDB_REGISTER_METHOD(void, SBCommand, SetFlags, (uint32_t));
873 }
874 }
875 }
876