1 //===-- BreakpointLocation.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/Breakpoint/BreakpointLocation.h" 15 #include "lldb/Breakpoint/BreakpointID.h" 16 #include "lldb/Breakpoint/StoppointCallbackContext.h" 17 #include "lldb/Core/Debugger.h" 18 #include "lldb/Core/Log.h" 19 #include "lldb/Core/Module.h" 20 #include "lldb/Core/StreamString.h" 21 #include "lldb/Core/ValueObject.h" 22 #include "lldb/Expression/ExpressionVariable.h" 23 #include "lldb/Expression/UserExpression.h" 24 #include "lldb/Symbol/CompileUnit.h" 25 #include "lldb/Symbol/Symbol.h" 26 #include "lldb/Symbol/TypeSystem.h" 27 #include "lldb/Target/Target.h" 28 #include "lldb/Target/Process.h" 29 #include "lldb/Target/Thread.h" 30 #include "lldb/Target/ThreadSpec.h" 31 32 using namespace lldb; 33 using namespace lldb_private; 34 35 BreakpointLocation::BreakpointLocation 36 ( 37 break_id_t loc_id, 38 Breakpoint &owner, 39 const Address &addr, 40 lldb::tid_t tid, 41 bool hardware, 42 bool check_for_resolver 43 ) : 44 StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware), 45 m_being_created(true), 46 m_should_resolve_indirect_functions (false), 47 m_is_reexported (false), 48 m_is_indirect (false), 49 m_address (addr), 50 m_owner (owner), 51 m_options_ap (), 52 m_bp_site_sp (), 53 m_condition_mutex () 54 { 55 if (check_for_resolver) 56 { 57 Symbol *symbol = m_address.CalculateSymbolContextSymbol(); 58 if (symbol && symbol->IsIndirect()) 59 { 60 SetShouldResolveIndirectFunctions (true); 61 } 62 } 63 64 SetThreadID (tid); 65 m_being_created = false; 66 } 67 68 BreakpointLocation::~BreakpointLocation() 69 { 70 ClearBreakpointSite(); 71 } 72 73 lldb::addr_t 74 BreakpointLocation::GetLoadAddress () const 75 { 76 return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()); 77 } 78 79 Address & 80 BreakpointLocation::GetAddress () 81 { 82 return m_address; 83 } 84 85 Breakpoint & 86 BreakpointLocation::GetBreakpoint () 87 { 88 return m_owner; 89 } 90 91 Target & 92 BreakpointLocation::GetTarget() 93 { 94 return m_owner.GetTarget(); 95 } 96 97 bool 98 BreakpointLocation::IsEnabled () const 99 { 100 if (!m_owner.IsEnabled()) 101 return false; 102 else if (m_options_ap.get() != nullptr) 103 return m_options_ap->IsEnabled(); 104 else 105 return true; 106 } 107 108 void 109 BreakpointLocation::SetEnabled (bool enabled) 110 { 111 GetLocationOptions()->SetEnabled(enabled); 112 if (enabled) 113 { 114 ResolveBreakpointSite(); 115 } 116 else 117 { 118 ClearBreakpointSite(); 119 } 120 SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled); 121 } 122 123 void 124 BreakpointLocation::SetThreadID (lldb::tid_t thread_id) 125 { 126 if (thread_id != LLDB_INVALID_THREAD_ID) 127 GetLocationOptions()->SetThreadID(thread_id); 128 else 129 { 130 // If we're resetting this to an invalid thread id, then 131 // don't make an options pointer just to do that. 132 if (m_options_ap.get() != nullptr) 133 m_options_ap->SetThreadID (thread_id); 134 } 135 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 136 } 137 138 lldb::tid_t 139 BreakpointLocation::GetThreadID () 140 { 141 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 142 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(); 143 else 144 return LLDB_INVALID_THREAD_ID; 145 } 146 147 void 148 BreakpointLocation::SetThreadIndex (uint32_t index) 149 { 150 if (index != 0) 151 GetLocationOptions()->GetThreadSpec()->SetIndex(index); 152 else 153 { 154 // If we're resetting this to an invalid thread id, then 155 // don't make an options pointer just to do that. 156 if (m_options_ap.get() != nullptr) 157 m_options_ap->GetThreadSpec()->SetIndex(index); 158 } 159 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 160 } 161 162 uint32_t 163 BreakpointLocation::GetThreadIndex() const 164 { 165 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 166 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex(); 167 else 168 return 0; 169 } 170 171 void 172 BreakpointLocation::SetThreadName (const char *thread_name) 173 { 174 if (thread_name != nullptr) 175 GetLocationOptions()->GetThreadSpec()->SetName(thread_name); 176 else 177 { 178 // If we're resetting this to an invalid thread id, then 179 // don't make an options pointer just to do that. 180 if (m_options_ap.get() != nullptr) 181 m_options_ap->GetThreadSpec()->SetName(thread_name); 182 } 183 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 184 } 185 186 const char * 187 BreakpointLocation::GetThreadName () const 188 { 189 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 190 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName(); 191 else 192 return nullptr; 193 } 194 195 void 196 BreakpointLocation::SetQueueName (const char *queue_name) 197 { 198 if (queue_name != nullptr) 199 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name); 200 else 201 { 202 // If we're resetting this to an invalid thread id, then 203 // don't make an options pointer just to do that. 204 if (m_options_ap.get() != nullptr) 205 m_options_ap->GetThreadSpec()->SetQueueName(queue_name); 206 } 207 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 208 } 209 210 const char * 211 BreakpointLocation::GetQueueName () const 212 { 213 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 214 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName(); 215 else 216 return nullptr; 217 } 218 219 bool 220 BreakpointLocation::InvokeCallback (StoppointCallbackContext *context) 221 { 222 if (m_options_ap.get() != nullptr && m_options_ap->HasCallback()) 223 return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID()); 224 else 225 return m_owner.InvokeCallback (context, GetID()); 226 } 227 228 void 229 BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton, 230 bool is_synchronous) 231 { 232 // The default "Baton" class will keep a copy of "baton" and won't free 233 // or delete it when it goes goes out of scope. 234 GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous); 235 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged); 236 } 237 238 void 239 BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp, 240 bool is_synchronous) 241 { 242 GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous); 243 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged); 244 } 245 246 void 247 BreakpointLocation::ClearCallback () 248 { 249 GetLocationOptions()->ClearCallback(); 250 } 251 252 void 253 BreakpointLocation::SetCondition (const char *condition) 254 { 255 GetLocationOptions()->SetCondition (condition); 256 SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged); 257 } 258 259 const char * 260 BreakpointLocation::GetConditionText (size_t *hash) const 261 { 262 return GetOptionsNoCreate()->GetConditionText(hash); 263 } 264 265 bool 266 BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error) 267 { 268 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 269 270 Mutex::Locker evaluation_locker(m_condition_mutex); 271 272 size_t condition_hash; 273 const char *condition_text = GetConditionText(&condition_hash); 274 275 if (!condition_text) 276 { 277 m_user_expression_sp.reset(); 278 return false; 279 } 280 281 if (condition_hash != m_condition_hash || 282 !m_user_expression_sp || 283 !m_user_expression_sp->MatchesContext(exe_ctx)) 284 { 285 LanguageType language = eLanguageTypeUnknown; 286 // See if we can figure out the language from the frame, otherwise use the default language: 287 CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit(); 288 if (comp_unit) 289 language = comp_unit->GetLanguage(); 290 291 Error error; 292 m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(condition_text, 293 nullptr, 294 language, 295 Expression::eResultTypeAny, 296 error)); 297 if (error.Fail()) 298 { 299 if (log) 300 log->Printf("Error getting condition expression: %s.", error.AsCString()); 301 m_user_expression_sp.reset(); 302 return true; 303 } 304 305 StreamString errors; 306 307 if (!m_user_expression_sp->Parse(errors, 308 exe_ctx, 309 eExecutionPolicyOnlyWhenNeeded, 310 true, 311 false)) 312 { 313 error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s", 314 errors.GetData()); 315 m_user_expression_sp.reset(); 316 return false; 317 } 318 319 m_condition_hash = condition_hash; 320 } 321 322 // We need to make sure the user sees any parse errors in their condition, so we'll hook the 323 // constructor errors up to the debugger's Async I/O. 324 325 ValueObjectSP result_value_sp; 326 327 EvaluateExpressionOptions options; 328 options.SetUnwindOnError(true); 329 options.SetIgnoreBreakpoints(true); 330 options.SetTryAllThreads(true); 331 332 Error expr_error; 333 334 StreamString execution_errors; 335 336 ExpressionVariableSP result_variable_sp; 337 338 ExpressionResults result_code = 339 m_user_expression_sp->Execute(execution_errors, 340 exe_ctx, 341 options, 342 m_user_expression_sp, 343 result_variable_sp); 344 345 bool ret; 346 347 if (result_code == eExpressionCompleted) 348 { 349 if (!result_variable_sp) 350 { 351 error.SetErrorString("Expression did not return a result"); 352 return false; 353 } 354 355 result_value_sp = result_variable_sp->GetValueObject(); 356 357 if (result_value_sp) 358 { 359 ret = result_value_sp->IsLogicalTrue(error); 360 if (log) 361 { 362 if (error.Success()) 363 { 364 log->Printf("Condition successfully evaluated, result is %s.\n", 365 ret ? "true" : "false"); 366 } 367 else 368 { 369 error.SetErrorString("Failed to get an integer result from the expression"); 370 ret = false; 371 } 372 373 } 374 } 375 else 376 { 377 ret = false; 378 error.SetErrorString("Failed to get any result from the expression"); 379 } 380 } 381 else 382 { 383 ret = false; 384 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData()); 385 } 386 387 return ret; 388 } 389 390 uint32_t 391 BreakpointLocation::GetIgnoreCount () 392 { 393 return GetOptionsNoCreate()->GetIgnoreCount(); 394 } 395 396 void 397 BreakpointLocation::SetIgnoreCount (uint32_t n) 398 { 399 GetLocationOptions()->SetIgnoreCount(n); 400 SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged); 401 } 402 403 void 404 BreakpointLocation::DecrementIgnoreCount() 405 { 406 if (m_options_ap.get() != nullptr) 407 { 408 uint32_t loc_ignore = m_options_ap->GetIgnoreCount(); 409 if (loc_ignore != 0) 410 m_options_ap->SetIgnoreCount(loc_ignore - 1); 411 } 412 } 413 414 bool 415 BreakpointLocation::IgnoreCountShouldStop() 416 { 417 if (m_options_ap.get() != nullptr) 418 { 419 uint32_t loc_ignore = m_options_ap->GetIgnoreCount(); 420 if (loc_ignore != 0) 421 { 422 m_owner.DecrementIgnoreCount(); 423 DecrementIgnoreCount(); // Have to decrement our owners' ignore count, since it won't get a 424 // chance to. 425 return false; 426 } 427 } 428 return true; 429 } 430 431 const BreakpointOptions * 432 BreakpointLocation::GetOptionsNoCreate () const 433 { 434 if (m_options_ap.get() != nullptr) 435 return m_options_ap.get(); 436 else 437 return m_owner.GetOptions (); 438 } 439 440 BreakpointOptions * 441 BreakpointLocation::GetLocationOptions () 442 { 443 // If we make the copy we don't copy the callbacks because that is potentially 444 // expensive and we don't want to do that for the simple case where someone is 445 // just disabling the location. 446 if (m_options_ap.get() == nullptr) 447 m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ())); 448 449 return m_options_ap.get(); 450 } 451 452 bool 453 BreakpointLocation::ValidForThisThread (Thread *thread) 454 { 455 return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate()); 456 } 457 458 // RETURNS - true if we should stop at this breakpoint, false if we 459 // should continue. Note, we don't check the thread spec for the breakpoint 460 // here, since if the breakpoint is not for this thread, then the event won't 461 // even get reported, so the check is redundant. 462 463 bool 464 BreakpointLocation::ShouldStop (StoppointCallbackContext *context) 465 { 466 bool should_stop = true; 467 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 468 469 // Do this first, if a location is disabled, it shouldn't increment its hit count. 470 if (!IsEnabled()) 471 return false; 472 473 if (!IgnoreCountShouldStop()) 474 return false; 475 476 if (!m_owner.IgnoreCountShouldStop()) 477 return false; 478 479 // We only run synchronous callbacks in ShouldStop: 480 context->is_synchronous = true; 481 should_stop = InvokeCallback (context); 482 483 if (log) 484 { 485 StreamString s; 486 GetDescription (&s, lldb::eDescriptionLevelVerbose); 487 log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing"); 488 } 489 490 return should_stop; 491 } 492 493 void 494 BreakpointLocation::BumpHitCount() 495 { 496 if (IsEnabled()) 497 { 498 // Step our hit count, and also step the hit count of the owner. 499 IncrementHitCount(); 500 m_owner.IncrementHitCount(); 501 } 502 } 503 504 void 505 BreakpointLocation::UndoBumpHitCount() 506 { 507 if (IsEnabled()) 508 { 509 // Step our hit count, and also step the hit count of the owner. 510 DecrementHitCount(); 511 m_owner.DecrementHitCount(); 512 } 513 } 514 515 bool 516 BreakpointLocation::IsResolved () const 517 { 518 return m_bp_site_sp.get() != nullptr; 519 } 520 521 lldb::BreakpointSiteSP 522 BreakpointLocation::GetBreakpointSite() const 523 { 524 return m_bp_site_sp; 525 } 526 527 bool 528 BreakpointLocation::ResolveBreakpointSite () 529 { 530 if (m_bp_site_sp) 531 return true; 532 533 Process *process = m_owner.GetTarget().GetProcessSP().get(); 534 if (process == nullptr) 535 return false; 536 537 lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), m_owner.IsHardware()); 538 539 if (new_id == LLDB_INVALID_BREAK_ID) 540 { 541 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 542 if (log) 543 log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n", 544 m_address.GetOpcodeLoadAddress (&m_owner.GetTarget())); 545 return false; 546 } 547 548 return true; 549 } 550 551 bool 552 BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp) 553 { 554 m_bp_site_sp = bp_site_sp; 555 SendBreakpointLocationChangedEvent (eBreakpointEventTypeLocationsResolved); 556 return true; 557 } 558 559 bool 560 BreakpointLocation::ClearBreakpointSite () 561 { 562 if (m_bp_site_sp.get()) 563 { 564 ProcessSP process_sp(m_owner.GetTarget().GetProcessSP()); 565 // If the process exists, get it to remove the owner, it will remove the physical implementation 566 // of the breakpoint as well if there are no more owners. Otherwise just remove this owner. 567 if (process_sp) 568 process_sp->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(), 569 GetID(), m_bp_site_sp); 570 else 571 m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID()); 572 573 m_bp_site_sp.reset(); 574 return true; 575 } 576 return false; 577 } 578 579 void 580 BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level) 581 { 582 SymbolContext sc; 583 584 // If the description level is "initial" then the breakpoint is printing out our initial state, 585 // and we should let it decide how it wants to print our label. 586 if (level != eDescriptionLevelInitial) 587 { 588 s->Indent(); 589 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID()); 590 } 591 592 if (level == lldb::eDescriptionLevelBrief) 593 return; 594 595 if (level != eDescriptionLevelInitial) 596 s->PutCString(": "); 597 598 if (level == lldb::eDescriptionLevelVerbose) 599 s->IndentMore(); 600 601 if (m_address.IsSectionOffset()) 602 { 603 m_address.CalculateSymbolContext(&sc); 604 605 if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial) 606 { 607 if (IsReExported()) 608 s->PutCString ("re-exported target = "); 609 else 610 s->PutCString("where = "); 611 sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false, true, true); 612 } 613 else 614 { 615 if (sc.module_sp) 616 { 617 s->EOL(); 618 s->Indent("module = "); 619 sc.module_sp->GetFileSpec().Dump (s); 620 } 621 622 if (sc.comp_unit != nullptr) 623 { 624 s->EOL(); 625 s->Indent("compile unit = "); 626 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s); 627 628 if (sc.function != nullptr) 629 { 630 s->EOL(); 631 s->Indent("function = "); 632 s->PutCString (sc.function->GetName().AsCString("<unknown>")); 633 } 634 635 if (sc.line_entry.line > 0) 636 { 637 s->EOL(); 638 s->Indent("location = "); 639 sc.line_entry.DumpStopContext (s, true); 640 } 641 642 } 643 else 644 { 645 // If we don't have a comp unit, see if we have a symbol we can print. 646 if (sc.symbol) 647 { 648 s->EOL(); 649 if (IsReExported()) 650 s->Indent ("re-exported target = "); 651 else 652 s->Indent("symbol = "); 653 s->PutCString(sc.symbol->GetName().AsCString("<unknown>")); 654 } 655 } 656 } 657 } 658 659 if (level == lldb::eDescriptionLevelVerbose) 660 { 661 s->EOL(); 662 s->Indent(); 663 } 664 665 if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)) 666 s->Printf (", "); 667 s->Printf ("address = "); 668 669 ExecutionContextScope *exe_scope = nullptr; 670 Target *target = &m_owner.GetTarget(); 671 if (target) 672 exe_scope = target->GetProcessSP().get(); 673 if (exe_scope == nullptr) 674 exe_scope = target; 675 676 if (level == eDescriptionLevelInitial) 677 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); 678 else 679 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress); 680 681 if (IsIndirect() && m_bp_site_sp) 682 { 683 Address resolved_address; 684 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target); 685 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol(); 686 if (resolved_symbol) 687 { 688 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial) 689 s->Printf (", "); 690 else if (level == lldb::eDescriptionLevelVerbose) 691 { 692 s->EOL(); 693 s->Indent(); 694 } 695 s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString()); 696 } 697 } 698 699 if (level == lldb::eDescriptionLevelVerbose) 700 { 701 s->EOL(); 702 s->Indent(); 703 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false"); 704 705 s->Indent(); 706 s->Printf ("hit count = %-4u\n", GetHitCount()); 707 708 if (m_options_ap.get()) 709 { 710 s->Indent(); 711 m_options_ap->GetDescription (s, level); 712 s->EOL(); 713 } 714 s->IndentLess(); 715 } 716 else if (level != eDescriptionLevelInitial) 717 { 718 s->Printf(", %sresolved, hit count = %u ", 719 (IsResolved() ? "" : "un"), 720 GetHitCount()); 721 if (m_options_ap.get()) 722 { 723 m_options_ap->GetDescription (s, level); 724 } 725 } 726 } 727 728 void 729 BreakpointLocation::Dump(Stream *s) const 730 { 731 if (s == nullptr) 732 return; 733 734 s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64 " state = %s type = %s breakpoint " 735 "hw_index = %i hit_count = %-4u ignore_count = %-4u", 736 GetID(), 737 GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(), 738 (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()), 739 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled", 740 IsHardware() ? "hardware" : "software", 741 GetHardwareIndex(), 742 GetHitCount(), 743 GetOptionsNoCreate()->GetIgnoreCount()); 744 } 745 746 void 747 BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind) 748 { 749 if (!m_being_created 750 && !m_owner.IsInternal() 751 && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 752 { 753 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, 754 m_owner.shared_from_this()); 755 data->GetBreakpointLocationCollection().Add (shared_from_this()); 756 m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 757 } 758 } 759 760 void 761 BreakpointLocation::SwapLocation (BreakpointLocationSP swap_from) 762 { 763 m_address = swap_from->m_address; 764 m_should_resolve_indirect_functions = swap_from->m_should_resolve_indirect_functions; 765 m_is_reexported = swap_from->m_is_reexported; 766 m_is_indirect = swap_from->m_is_indirect; 767 m_user_expression_sp.reset(); 768 } 769