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