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