1 //===-- SBCommandInterpreter.cpp --------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // C Includes 11 // C++ Includes 12 // Other libraries and framework includes 13 // Project includes 14 #include "lldb/lldb-types.h" 15 16 #include "lldb/Core/Listener.h" 17 #include "lldb/Interpreter/CommandInterpreter.h" 18 #include "lldb/Interpreter/CommandObjectMultiword.h" 19 #include "lldb/Interpreter/CommandReturnObject.h" 20 #include "lldb/Target/Target.h" 21 22 #include "lldb/API/SBBroadcaster.h" 23 #include "lldb/API/SBCommandInterpreter.h" 24 #include "lldb/API/SBCommandReturnObject.h" 25 #include "lldb/API/SBEvent.h" 26 #include "lldb/API/SBExecutionContext.h" 27 #include "lldb/API/SBListener.h" 28 #include "lldb/API/SBProcess.h" 29 #include "lldb/API/SBStream.h" 30 #include "lldb/API/SBStringList.h" 31 #include "lldb/API/SBTarget.h" 32 33 using namespace lldb; 34 using namespace lldb_private; 35 36 SBCommandInterpreterRunOptions::SBCommandInterpreterRunOptions() { 37 m_opaque_up.reset(new CommandInterpreterRunOptions()); 38 } 39 40 SBCommandInterpreterRunOptions::~SBCommandInterpreterRunOptions() = default; 41 42 bool SBCommandInterpreterRunOptions::GetStopOnContinue() const { 43 return m_opaque_up->GetStopOnContinue(); 44 } 45 46 void SBCommandInterpreterRunOptions::SetStopOnContinue(bool stop_on_continue) { 47 m_opaque_up->SetStopOnContinue(stop_on_continue); 48 } 49 50 bool SBCommandInterpreterRunOptions::GetStopOnError() const { 51 return m_opaque_up->GetStopOnError(); 52 } 53 54 void SBCommandInterpreterRunOptions::SetStopOnError(bool stop_on_error) { 55 m_opaque_up->SetStopOnError(stop_on_error); 56 } 57 58 bool SBCommandInterpreterRunOptions::GetStopOnCrash() const { 59 return m_opaque_up->GetStopOnCrash(); 60 } 61 62 void SBCommandInterpreterRunOptions::SetStopOnCrash(bool stop_on_crash) { 63 m_opaque_up->SetStopOnCrash(stop_on_crash); 64 } 65 66 bool SBCommandInterpreterRunOptions::GetEchoCommands() const { 67 return m_opaque_up->GetEchoCommands(); 68 } 69 70 void SBCommandInterpreterRunOptions::SetEchoCommands(bool echo_commands) { 71 m_opaque_up->SetEchoCommands(echo_commands); 72 } 73 74 bool SBCommandInterpreterRunOptions::GetPrintResults() const { 75 return m_opaque_up->GetPrintResults(); 76 } 77 78 void SBCommandInterpreterRunOptions::SetPrintResults(bool print_results) { 79 m_opaque_up->SetPrintResults(print_results); 80 } 81 82 bool SBCommandInterpreterRunOptions::GetAddToHistory() const { 83 return m_opaque_up->GetAddToHistory(); 84 } 85 86 void SBCommandInterpreterRunOptions::SetAddToHistory(bool add_to_history) { 87 m_opaque_up->SetAddToHistory(add_to_history); 88 } 89 90 lldb_private::CommandInterpreterRunOptions * 91 SBCommandInterpreterRunOptions::get() const { 92 return m_opaque_up.get(); 93 } 94 95 lldb_private::CommandInterpreterRunOptions & 96 SBCommandInterpreterRunOptions::ref() const { 97 return *m_opaque_up.get(); 98 } 99 100 class CommandPluginInterfaceImplementation : public CommandObjectParsed { 101 public: 102 CommandPluginInterfaceImplementation(CommandInterpreter &interpreter, 103 const char *name, 104 lldb::SBCommandPluginInterface *backend, 105 const char *help = nullptr, 106 const char *syntax = nullptr, 107 uint32_t flags = 0) 108 : CommandObjectParsed(interpreter, name, help, syntax, flags), 109 m_backend(backend) {} 110 111 bool IsRemovable() const override { return true; } 112 113 protected: 114 bool DoExecute(Args &command, CommandReturnObject &result) override { 115 SBCommandReturnObject sb_return(&result); 116 SBCommandInterpreter sb_interpreter(&m_interpreter); 117 SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this()); 118 bool ret = m_backend->DoExecute( 119 debugger_sb, (char **)command.GetArgumentVector(), sb_return); 120 sb_return.Release(); 121 return ret; 122 } 123 std::shared_ptr<lldb::SBCommandPluginInterface> m_backend; 124 }; 125 126 SBCommandInterpreter::SBCommandInterpreter(CommandInterpreter *interpreter) 127 : m_opaque_ptr(interpreter) { 128 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 129 130 if (log) 131 log->Printf("SBCommandInterpreter::SBCommandInterpreter (interpreter=%p)" 132 " => SBCommandInterpreter(%p)", 133 static_cast<void *>(interpreter), 134 static_cast<void *>(m_opaque_ptr)); 135 } 136 137 SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs) 138 : m_opaque_ptr(rhs.m_opaque_ptr) {} 139 140 SBCommandInterpreter::~SBCommandInterpreter() = default; 141 142 const SBCommandInterpreter &SBCommandInterpreter:: 143 operator=(const SBCommandInterpreter &rhs) { 144 m_opaque_ptr = rhs.m_opaque_ptr; 145 return *this; 146 } 147 148 bool SBCommandInterpreter::IsValid() const { return m_opaque_ptr != nullptr; } 149 150 bool SBCommandInterpreter::CommandExists(const char *cmd) { 151 return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->CommandExists(cmd) 152 : false); 153 } 154 155 bool SBCommandInterpreter::AliasExists(const char *cmd) { 156 return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->AliasExists(cmd) 157 : false); 158 } 159 160 bool SBCommandInterpreter::IsActive() { 161 return (IsValid() ? m_opaque_ptr->IsActive() : false); 162 } 163 164 bool SBCommandInterpreter::WasInterrupted() const { 165 return (IsValid() ? m_opaque_ptr->WasInterrupted() : false); 166 } 167 168 const char *SBCommandInterpreter::GetIOHandlerControlSequence(char ch) { 169 return (IsValid() 170 ? m_opaque_ptr->GetDebugger() 171 .GetTopIOHandlerControlSequence(ch) 172 .GetCString() 173 : nullptr); 174 } 175 176 lldb::ReturnStatus 177 SBCommandInterpreter::HandleCommand(const char *command_line, 178 SBCommandReturnObject &result, 179 bool add_to_history) { 180 SBExecutionContext sb_exe_ctx; 181 return HandleCommand(command_line, sb_exe_ctx, result, add_to_history); 182 } 183 184 lldb::ReturnStatus SBCommandInterpreter::HandleCommand( 185 const char *command_line, SBExecutionContext &override_context, 186 SBCommandReturnObject &result, bool add_to_history) { 187 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 188 189 if (log) 190 log->Printf("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", " 191 "SBCommandReturnObject(%p), add_to_history=%i)", 192 static_cast<void *>(m_opaque_ptr), command_line, 193 static_cast<void *>(result.get()), add_to_history); 194 195 ExecutionContext ctx, *ctx_ptr; 196 if (override_context.get()) { 197 ctx = override_context.get()->Lock(true); 198 ctx_ptr = &ctx; 199 } else 200 ctx_ptr = nullptr; 201 202 result.Clear(); 203 if (command_line && IsValid()) { 204 result.ref().SetInteractive(false); 205 m_opaque_ptr->HandleCommand(command_line, 206 add_to_history ? eLazyBoolYes : eLazyBoolNo, 207 result.ref(), ctx_ptr); 208 } else { 209 result->AppendError( 210 "SBCommandInterpreter or the command line is not valid"); 211 result->SetStatus(eReturnStatusFailed); 212 } 213 214 // We need to get the value again, in case the command disabled the log! 215 log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API); 216 if (log) { 217 SBStream sstr; 218 result.GetDescription(sstr); 219 log->Printf("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", " 220 "SBCommandReturnObject(%p): %s, add_to_history=%i) => %i", 221 static_cast<void *>(m_opaque_ptr), command_line, 222 static_cast<void *>(result.get()), sstr.GetData(), 223 add_to_history, result.GetStatus()); 224 } 225 226 return result.GetStatus(); 227 } 228 229 void SBCommandInterpreter::HandleCommandsFromFile( 230 lldb::SBFileSpec &file, lldb::SBExecutionContext &override_context, 231 lldb::SBCommandInterpreterRunOptions &options, 232 lldb::SBCommandReturnObject result) { 233 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 234 235 if (log) { 236 SBStream s; 237 file.GetDescription(s); 238 log->Printf("SBCommandInterpreter(%p)::HandleCommandsFromFile " 239 "(file=\"%s\", SBCommandReturnObject(%p))", 240 static_cast<void *>(m_opaque_ptr), s.GetData(), 241 static_cast<void *>(result.get())); 242 } 243 244 if (!IsValid()) { 245 result->AppendError("SBCommandInterpreter is not valid."); 246 result->SetStatus(eReturnStatusFailed); 247 return; 248 } 249 250 if (!file.IsValid()) { 251 SBStream s; 252 file.GetDescription(s); 253 result->AppendErrorWithFormat("File is not valid: %s.", s.GetData()); 254 result->SetStatus(eReturnStatusFailed); 255 } 256 257 FileSpec tmp_spec = file.ref(); 258 ExecutionContext ctx, *ctx_ptr; 259 if (override_context.get()) { 260 ctx = override_context.get()->Lock(true); 261 ctx_ptr = &ctx; 262 } else 263 ctx_ptr = nullptr; 264 265 m_opaque_ptr->HandleCommandsFromFile(tmp_spec, ctx_ptr, options.ref(), 266 result.ref()); 267 } 268 269 int SBCommandInterpreter::HandleCompletion( 270 const char *current_line, const char *cursor, const char *last_char, 271 int match_start_point, int max_return_elements, SBStringList &matches) { 272 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 273 int num_completions = 0; 274 275 // Sanity check the arguments that are passed in: 276 // cursor & last_char have to be within the current_line. 277 if (current_line == nullptr || cursor == nullptr || last_char == nullptr) 278 return 0; 279 280 if (cursor < current_line || last_char < current_line) 281 return 0; 282 283 size_t current_line_size = strlen(current_line); 284 if (cursor - current_line > static_cast<ptrdiff_t>(current_line_size) || 285 last_char - current_line > static_cast<ptrdiff_t>(current_line_size)) 286 return 0; 287 288 if (log) 289 log->Printf("SBCommandInterpreter(%p)::HandleCompletion " 290 "(current_line=\"%s\", cursor at: %" PRId64 291 ", last char at: %" PRId64 292 ", match_start_point: %d, max_return_elements: %d)", 293 static_cast<void *>(m_opaque_ptr), current_line, 294 static_cast<uint64_t>(cursor - current_line), 295 static_cast<uint64_t>(last_char - current_line), 296 match_start_point, max_return_elements); 297 298 if (IsValid()) { 299 lldb_private::StringList lldb_matches; 300 num_completions = m_opaque_ptr->HandleCompletion( 301 current_line, cursor, last_char, match_start_point, max_return_elements, 302 lldb_matches); 303 304 SBStringList temp_list(&lldb_matches); 305 matches.AppendList(temp_list); 306 } 307 if (log) 308 log->Printf( 309 "SBCommandInterpreter(%p)::HandleCompletion - Found %d completions.", 310 static_cast<void *>(m_opaque_ptr), num_completions); 311 312 return num_completions; 313 } 314 315 int SBCommandInterpreter::HandleCompletion(const char *current_line, 316 uint32_t cursor_pos, 317 int match_start_point, 318 int max_return_elements, 319 lldb::SBStringList &matches) { 320 const char *cursor = current_line + cursor_pos; 321 const char *last_char = current_line + strlen(current_line); 322 return HandleCompletion(current_line, cursor, last_char, match_start_point, 323 max_return_elements, matches); 324 } 325 326 bool SBCommandInterpreter::HasCommands() { 327 return (IsValid() ? m_opaque_ptr->HasCommands() : false); 328 } 329 330 bool SBCommandInterpreter::HasAliases() { 331 return (IsValid() ? m_opaque_ptr->HasAliases() : false); 332 } 333 334 bool SBCommandInterpreter::HasAliasOptions() { 335 return (IsValid() ? m_opaque_ptr->HasAliasOptions() : false); 336 } 337 338 SBProcess SBCommandInterpreter::GetProcess() { 339 SBProcess sb_process; 340 ProcessSP process_sp; 341 if (IsValid()) { 342 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 343 if (target_sp) { 344 std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex()); 345 process_sp = target_sp->GetProcessSP(); 346 sb_process.SetSP(process_sp); 347 } 348 } 349 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 350 351 if (log) 352 log->Printf("SBCommandInterpreter(%p)::GetProcess () => SBProcess(%p)", 353 static_cast<void *>(m_opaque_ptr), 354 static_cast<void *>(process_sp.get())); 355 356 return sb_process; 357 } 358 359 SBDebugger SBCommandInterpreter::GetDebugger() { 360 SBDebugger sb_debugger; 361 if (IsValid()) 362 sb_debugger.reset(m_opaque_ptr->GetDebugger().shared_from_this()); 363 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 364 365 if (log) 366 log->Printf("SBCommandInterpreter(%p)::GetDebugger () => SBDebugger(%p)", 367 static_cast<void *>(m_opaque_ptr), 368 static_cast<void *>(sb_debugger.get())); 369 370 return sb_debugger; 371 } 372 373 bool SBCommandInterpreter::GetPromptOnQuit() { 374 return (IsValid() ? m_opaque_ptr->GetPromptOnQuit() : false); 375 } 376 377 void SBCommandInterpreter::SetPromptOnQuit(bool b) { 378 if (IsValid()) 379 m_opaque_ptr->SetPromptOnQuit(b); 380 } 381 382 void SBCommandInterpreter::ResolveCommand(const char *command_line, 383 SBCommandReturnObject &result) { 384 result.Clear(); 385 if (command_line && IsValid()) { 386 m_opaque_ptr->ResolveCommand(command_line, result.ref()); 387 } else { 388 result->AppendError( 389 "SBCommandInterpreter or the command line is not valid"); 390 result->SetStatus(eReturnStatusFailed); 391 } 392 } 393 394 CommandInterpreter *SBCommandInterpreter::get() { return m_opaque_ptr; } 395 396 CommandInterpreter &SBCommandInterpreter::ref() { 397 assert(m_opaque_ptr); 398 return *m_opaque_ptr; 399 } 400 401 void SBCommandInterpreter::reset( 402 lldb_private::CommandInterpreter *interpreter) { 403 m_opaque_ptr = interpreter; 404 } 405 406 void SBCommandInterpreter::SourceInitFileInHomeDirectory( 407 SBCommandReturnObject &result) { 408 result.Clear(); 409 if (IsValid()) { 410 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 411 std::unique_lock<std::recursive_mutex> lock; 412 if (target_sp) 413 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); 414 m_opaque_ptr->SourceInitFile(false, result.ref()); 415 } else { 416 result->AppendError("SBCommandInterpreter is not valid"); 417 result->SetStatus(eReturnStatusFailed); 418 } 419 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 420 421 if (log) 422 log->Printf("SBCommandInterpreter(%p)::SourceInitFileInHomeDirectory " 423 "(&SBCommandReturnObject(%p))", 424 static_cast<void *>(m_opaque_ptr), 425 static_cast<void *>(result.get())); 426 } 427 428 void SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory( 429 SBCommandReturnObject &result) { 430 result.Clear(); 431 if (IsValid()) { 432 TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); 433 std::unique_lock<std::recursive_mutex> lock; 434 if (target_sp) 435 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); 436 m_opaque_ptr->SourceInitFile(true, result.ref()); 437 } else { 438 result->AppendError("SBCommandInterpreter is not valid"); 439 result->SetStatus(eReturnStatusFailed); 440 } 441 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 442 443 if (log) 444 log->Printf( 445 "SBCommandInterpreter(%p)::SourceInitFileInCurrentWorkingDirectory " 446 "(&SBCommandReturnObject(%p))", 447 static_cast<void *>(m_opaque_ptr), static_cast<void *>(result.get())); 448 } 449 450 SBBroadcaster SBCommandInterpreter::GetBroadcaster() { 451 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 452 453 SBBroadcaster broadcaster(m_opaque_ptr, false); 454 455 if (log) 456 log->Printf( 457 "SBCommandInterpreter(%p)::GetBroadcaster() => SBBroadcaster(%p)", 458 static_cast<void *>(m_opaque_ptr), 459 static_cast<void *>(broadcaster.get())); 460 461 return broadcaster; 462 } 463 464 const char *SBCommandInterpreter::GetBroadcasterClass() { 465 return CommandInterpreter::GetStaticBroadcasterClass().AsCString(); 466 } 467 468 const char *SBCommandInterpreter::GetArgumentTypeAsCString( 469 const lldb::CommandArgumentType arg_type) { 470 return CommandObject::GetArgumentTypeAsCString(arg_type); 471 } 472 473 const char *SBCommandInterpreter::GetArgumentDescriptionAsCString( 474 const lldb::CommandArgumentType arg_type) { 475 return CommandObject::GetArgumentDescriptionAsCString(arg_type); 476 } 477 478 bool SBCommandInterpreter::EventIsCommandInterpreterEvent( 479 const lldb::SBEvent &event) { 480 return event.GetBroadcasterClass() == 481 SBCommandInterpreter::GetBroadcasterClass(); 482 } 483 484 bool SBCommandInterpreter::SetCommandOverrideCallback( 485 const char *command_name, lldb::CommandOverrideCallback callback, 486 void *baton) { 487 if (command_name && command_name[0] && IsValid()) { 488 llvm::StringRef command_name_str = command_name; 489 CommandObject *cmd_obj = 490 m_opaque_ptr->GetCommandObjectForCommand(command_name_str); 491 if (cmd_obj) { 492 assert(command_name_str.empty()); 493 cmd_obj->SetOverrideCallback(callback, baton); 494 return true; 495 } 496 } 497 return false; 498 } 499 500 lldb::SBCommand SBCommandInterpreter::AddMultiwordCommand(const char *name, 501 const char *help) { 502 CommandObjectMultiword *new_command = 503 new CommandObjectMultiword(*m_opaque_ptr, name, help); 504 new_command->SetRemovable(true); 505 lldb::CommandObjectSP new_command_sp(new_command); 506 if (new_command_sp && 507 m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) 508 return lldb::SBCommand(new_command_sp); 509 return lldb::SBCommand(); 510 } 511 512 lldb::SBCommand SBCommandInterpreter::AddCommand( 513 const char *name, lldb::SBCommandPluginInterface *impl, const char *help) { 514 lldb::CommandObjectSP new_command_sp; 515 new_command_sp.reset(new CommandPluginInterfaceImplementation( 516 *m_opaque_ptr, name, impl, help)); 517 518 if (new_command_sp && 519 m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) 520 return lldb::SBCommand(new_command_sp); 521 return lldb::SBCommand(); 522 } 523 524 lldb::SBCommand 525 SBCommandInterpreter::AddCommand(const char *name, 526 lldb::SBCommandPluginInterface *impl, 527 const char *help, const char *syntax) { 528 lldb::CommandObjectSP new_command_sp; 529 new_command_sp.reset(new CommandPluginInterfaceImplementation( 530 *m_opaque_ptr, name, impl, help, syntax)); 531 532 if (new_command_sp && 533 m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) 534 return lldb::SBCommand(new_command_sp); 535 return lldb::SBCommand(); 536 } 537 538 SBCommand::SBCommand() = default; 539 540 SBCommand::SBCommand(lldb::CommandObjectSP cmd_sp) : m_opaque_sp(cmd_sp) {} 541 542 bool SBCommand::IsValid() { return m_opaque_sp.get() != nullptr; } 543 544 const char *SBCommand::GetName() { 545 return (IsValid() ? ConstString(m_opaque_sp->GetCommandName()).AsCString() : nullptr); 546 } 547 548 const char *SBCommand::GetHelp() { 549 return (IsValid() ? ConstString(m_opaque_sp->GetHelp()).AsCString() 550 : nullptr); 551 } 552 553 const char *SBCommand::GetHelpLong() { 554 return (IsValid() ? ConstString(m_opaque_sp->GetHelpLong()).AsCString() 555 : nullptr); 556 } 557 558 void SBCommand::SetHelp(const char *help) { 559 if (IsValid()) 560 m_opaque_sp->SetHelp(help); 561 } 562 563 void SBCommand::SetHelpLong(const char *help) { 564 if (IsValid()) 565 m_opaque_sp->SetHelpLong(help); 566 } 567 568 lldb::SBCommand SBCommand::AddMultiwordCommand(const char *name, 569 const char *help) { 570 if (!IsValid()) 571 return lldb::SBCommand(); 572 if (!m_opaque_sp->IsMultiwordObject()) 573 return lldb::SBCommand(); 574 CommandObjectMultiword *new_command = new CommandObjectMultiword( 575 m_opaque_sp->GetCommandInterpreter(), name, help); 576 new_command->SetRemovable(true); 577 lldb::CommandObjectSP new_command_sp(new_command); 578 if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp)) 579 return lldb::SBCommand(new_command_sp); 580 return lldb::SBCommand(); 581 } 582 583 lldb::SBCommand SBCommand::AddCommand(const char *name, 584 lldb::SBCommandPluginInterface *impl, 585 const char *help) { 586 if (!IsValid()) 587 return lldb::SBCommand(); 588 if (!m_opaque_sp->IsMultiwordObject()) 589 return lldb::SBCommand(); 590 lldb::CommandObjectSP new_command_sp; 591 new_command_sp.reset(new CommandPluginInterfaceImplementation( 592 m_opaque_sp->GetCommandInterpreter(), name, impl, help)); 593 if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp)) 594 return lldb::SBCommand(new_command_sp); 595 return lldb::SBCommand(); 596 } 597 598 lldb::SBCommand SBCommand::AddCommand(const char *name, 599 lldb::SBCommandPluginInterface *impl, 600 const char *help, const char *syntax) { 601 if (!IsValid()) 602 return lldb::SBCommand(); 603 if (!m_opaque_sp->IsMultiwordObject()) 604 return lldb::SBCommand(); 605 lldb::CommandObjectSP new_command_sp; 606 new_command_sp.reset(new CommandPluginInterfaceImplementation( 607 m_opaque_sp->GetCommandInterpreter(), name, impl, help, syntax)); 608 if (new_command_sp && m_opaque_sp->LoadSubCommand(name, new_command_sp)) 609 return lldb::SBCommand(new_command_sp); 610 return lldb::SBCommand(); 611 } 612 613 uint32_t SBCommand::GetFlags() { 614 return (IsValid() ? m_opaque_sp->GetFlags().Get() : 0); 615 } 616 617 void SBCommand::SetFlags(uint32_t flags) { 618 if (IsValid()) 619 m_opaque_sp->GetFlags().Set(flags); 620 } 621