Coverage Report

Created: 2023-09-21 18:56

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h
Line
Count
Source (jump to first uncovered line)
1
//===-- ThreadPlanShouldStopHere.h ------------------------------*- 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
#ifndef LLDB_TARGET_THREADPLANSHOULDSTOPHERE_H
10
#define LLDB_TARGET_THREADPLANSHOULDSTOPHERE_H
11
12
#include "lldb/Target/ThreadPlan.h"
13
14
namespace lldb_private {
15
16
// This is an interface that ThreadPlans can adopt to allow flexible
17
// modifications of the behavior when a thread plan comes to a place where it
18
// would ordinarily stop.  If such modification makes sense for your plan,
19
// inherit from this class, and when you would be about to stop (in your
20
// ShouldStop method), call InvokeShouldStopHereCallback, passing in the frame
21
// comparison between where the step operation started and where you arrived.
22
// If it returns true, then QueueStepOutFromHere will queue the plan to execute
23
// instead of stopping.
24
//
25
// The classic example of the use of this is ThreadPlanStepInRange not stopping
26
// in frames that have no debug information.
27
//
28
// This class also defines a set of flags to control general aspects of this
29
// "ShouldStop" behavior.
30
// A class implementing this protocol needs to define a default set of flags,
31
// and can provide access to
32
// changing that default flag set if it wishes.
33
34
class ThreadPlanShouldStopHere {
35
public:
36
  struct ThreadPlanShouldStopHereCallbacks {
37
695
    ThreadPlanShouldStopHereCallbacks() {
38
695
      should_stop_here_callback = nullptr;
39
695
      step_from_here_callback = nullptr;
40
695
    }
41
42
    ThreadPlanShouldStopHereCallbacks(
43
        ThreadPlanShouldStopHereCallback should_stop,
44
188
        ThreadPlanStepFromHereCallback step_from_here) {
45
188
      should_stop_here_callback = should_stop;
46
188
      step_from_here_callback = step_from_here;
47
188
    }
48
49
100
    void Clear() {
50
100
      should_stop_here_callback = nullptr;
51
100
      step_from_here_callback = nullptr;
52
100
    }
53
54
    ThreadPlanShouldStopHereCallback should_stop_here_callback;
55
    ThreadPlanStepFromHereCallback step_from_here_callback;
56
  };
57
58
  enum {
59
    eNone = 0,
60
    eAvoidInlines = (1 << 0),
61
    eStepInAvoidNoDebug = (1 << 1),
62
    eStepOutAvoidNoDebug = (1 << 2)
63
  };
64
65
  // Constructors and Destructors
66
  ThreadPlanShouldStopHere(ThreadPlan *owner);
67
68
  ThreadPlanShouldStopHere(ThreadPlan *owner,
69
                           const ThreadPlanShouldStopHereCallbacks *callbacks,
70
                           void *baton = nullptr);
71
  virtual ~ThreadPlanShouldStopHere();
72
73
  // Set the ShouldStopHere callbacks.  Pass in null to clear them and have no
74
  // special behavior (though you can also call ClearShouldStopHereCallbacks
75
  // for that purpose.  If you pass in a valid pointer, it will adopt the non-
76
  // null fields, and any null fields will be set to the default values.
77
78
  void
79
  SetShouldStopHereCallbacks(const ThreadPlanShouldStopHereCallbacks *callbacks,
80
188
                             void *baton) {
81
188
    if (callbacks) {
82
188
      m_callbacks = *callbacks;
83
188
      if (!m_callbacks.should_stop_here_callback)
84
0
        m_callbacks.should_stop_here_callback =
85
0
            ThreadPlanShouldStopHere::DefaultShouldStopHereCallback;
86
188
      if (!m_callbacks.step_from_here_callback)
87
188
        m_callbacks.step_from_here_callback =
88
188
            ThreadPlanShouldStopHere::DefaultStepFromHereCallback;
89
188
    } else {
90
0
      ClearShouldStopHereCallbacks();
91
0
    }
92
188
    m_baton = baton;
93
188
  }
94
95
100
  void ClearShouldStopHereCallbacks() { m_callbacks.Clear(); }
96
97
  bool InvokeShouldStopHereCallback(lldb::FrameComparison operation,
98
                                    Status &status);
99
100
  lldb::ThreadPlanSP
101
  CheckShouldStopHereAndQueueStepOut(lldb::FrameComparison operation,
102
                                     Status &status);
103
104
1.83k
  lldb_private::Flags &GetFlags() { return m_flags; }
105
106
0
  const lldb_private::Flags &GetFlags() const { return m_flags; }
107
108
protected:
109
  static bool DefaultShouldStopHereCallback(ThreadPlan *current_plan,
110
                                            Flags &flags,
111
                                            lldb::FrameComparison operation,
112
                                            Status &status, void *baton);
113
114
  static lldb::ThreadPlanSP
115
  DefaultStepFromHereCallback(ThreadPlan *current_plan, Flags &flags,
116
                              lldb::FrameComparison operation, Status &status,
117
                              void *baton);
118
119
  virtual lldb::ThreadPlanSP
120
  QueueStepOutFromHerePlan(Flags &flags, lldb::FrameComparison operation,
121
                           Status &status);
122
123
  // Implement this, and call it in the plan's constructor to set the default
124
  // flags.
125
  virtual void SetFlagsToDefault() = 0;
126
127
  ThreadPlanShouldStopHereCallbacks m_callbacks;
128
  void *m_baton;
129
  ThreadPlan *m_owner;
130
  lldb_private::Flags m_flags;
131
132
private:
133
  ThreadPlanShouldStopHere(const ThreadPlanShouldStopHere &) = delete;
134
  const ThreadPlanShouldStopHere &
135
  operator=(const ThreadPlanShouldStopHere &) = delete;
136
};
137
138
} // namespace lldb_private
139
140
#endif // LLDB_TARGET_THREADPLANSHOULDSTOPHERE_H