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