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