Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:56

0001 //===-- ThreadPlanShouldStopHere.h ------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_TARGET_THREADPLANSHOULDSTOPHERE_H
0010 #define LLDB_TARGET_THREADPLANSHOULDSTOPHERE_H
0011 
0012 #include "lldb/Target/ThreadPlan.h"
0013 
0014 namespace lldb_private {
0015 
0016 // This is an interface that ThreadPlans can adopt to allow flexible
0017 // modifications of the behavior when a thread plan comes to a place where it
0018 // would ordinarily stop.  If such modification makes sense for your plan,
0019 // inherit from this class, and when you would be about to stop (in your
0020 // ShouldStop method), call InvokeShouldStopHereCallback, passing in the frame
0021 // comparison between where the step operation started and where you arrived.
0022 // If it returns true, then QueueStepOutFromHere will queue the plan to execute
0023 // instead of stopping.
0024 //
0025 // The classic example of the use of this is ThreadPlanStepInRange not stopping
0026 // in frames that have no debug information.
0027 //
0028 // This class also defines a set of flags to control general aspects of this
0029 // "ShouldStop" behavior.
0030 // A class implementing this protocol needs to define a default set of flags,
0031 // and can provide access to
0032 // changing that default flag set if it wishes.
0033 
0034 class ThreadPlanShouldStopHere {
0035 public:
0036   struct ThreadPlanShouldStopHereCallbacks {
0037     ThreadPlanShouldStopHereCallbacks() {
0038       should_stop_here_callback = nullptr;
0039       step_from_here_callback = nullptr;
0040     }
0041 
0042     ThreadPlanShouldStopHereCallbacks(
0043         ThreadPlanShouldStopHereCallback should_stop,
0044         ThreadPlanStepFromHereCallback step_from_here) {
0045       should_stop_here_callback = should_stop;
0046       step_from_here_callback = step_from_here;
0047     }
0048 
0049     void Clear() {
0050       should_stop_here_callback = nullptr;
0051       step_from_here_callback = nullptr;
0052     }
0053 
0054     ThreadPlanShouldStopHereCallback should_stop_here_callback;
0055     ThreadPlanStepFromHereCallback step_from_here_callback;
0056   };
0057 
0058   enum {
0059     eNone = 0,
0060     eAvoidInlines = (1 << 0),
0061     eStepInAvoidNoDebug = (1 << 1),
0062     eStepOutAvoidNoDebug = (1 << 2)
0063   };
0064 
0065   // Constructors and Destructors
0066   ThreadPlanShouldStopHere(ThreadPlan *owner);
0067 
0068   ThreadPlanShouldStopHere(ThreadPlan *owner,
0069                            const ThreadPlanShouldStopHereCallbacks *callbacks,
0070                            void *baton = nullptr);
0071   virtual ~ThreadPlanShouldStopHere();
0072 
0073   // Set the ShouldStopHere callbacks.  Pass in null to clear them and have no
0074   // special behavior (though you can also call ClearShouldStopHereCallbacks
0075   // for that purpose.  If you pass in a valid pointer, it will adopt the non-
0076   // null fields, and any null fields will be set to the default values.
0077 
0078   void
0079   SetShouldStopHereCallbacks(const ThreadPlanShouldStopHereCallbacks *callbacks,
0080                              void *baton) {
0081     if (callbacks) {
0082       m_callbacks = *callbacks;
0083       if (!m_callbacks.should_stop_here_callback)
0084         m_callbacks.should_stop_here_callback =
0085             ThreadPlanShouldStopHere::DefaultShouldStopHereCallback;
0086       if (!m_callbacks.step_from_here_callback)
0087         m_callbacks.step_from_here_callback =
0088             ThreadPlanShouldStopHere::DefaultStepFromHereCallback;
0089     } else {
0090       ClearShouldStopHereCallbacks();
0091     }
0092     m_baton = baton;
0093   }
0094 
0095   void ClearShouldStopHereCallbacks() { m_callbacks.Clear(); }
0096 
0097   bool InvokeShouldStopHereCallback(lldb::FrameComparison operation,
0098                                     Status &status);
0099 
0100   lldb::ThreadPlanSP
0101   CheckShouldStopHereAndQueueStepOut(lldb::FrameComparison operation,
0102                                      Status &status);
0103 
0104   lldb_private::Flags &GetFlags() { return m_flags; }
0105 
0106   const lldb_private::Flags &GetFlags() const { return m_flags; }
0107 
0108 protected:
0109   static bool DefaultShouldStopHereCallback(ThreadPlan *current_plan,
0110                                             Flags &flags,
0111                                             lldb::FrameComparison operation,
0112                                             Status &status, void *baton);
0113 
0114   static lldb::ThreadPlanSP
0115   DefaultStepFromHereCallback(ThreadPlan *current_plan, Flags &flags,
0116                               lldb::FrameComparison operation, Status &status,
0117                               void *baton);
0118 
0119   virtual lldb::ThreadPlanSP
0120   QueueStepOutFromHerePlan(Flags &flags, lldb::FrameComparison operation,
0121                            Status &status);
0122 
0123   // Implement this, and call it in the plan's constructor to set the default
0124   // flags.
0125   virtual void SetFlagsToDefault() = 0;
0126 
0127   ThreadPlanShouldStopHereCallbacks m_callbacks;
0128   void *m_baton;
0129   ThreadPlan *m_owner;
0130   lldb_private::Flags m_flags;
0131 
0132 private:
0133   ThreadPlanShouldStopHere(const ThreadPlanShouldStopHere &) = delete;
0134   const ThreadPlanShouldStopHere &
0135   operator=(const ThreadPlanShouldStopHere &) = delete;
0136 };
0137 
0138 } // namespace lldb_private
0139 
0140 #endif // LLDB_TARGET_THREADPLANSHOULDSTOPHERE_H