]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp
MFV r323911:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Target / ThreadPlanCallOnFunctionExit.cpp
1 //===-- ThreadPlanCallOnFunctionExit.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 #include "lldb/Target/ThreadPlanCallOnFunctionExit.h"
11
12 using namespace lldb;
13 using namespace lldb_private;
14
15 ThreadPlanCallOnFunctionExit::ThreadPlanCallOnFunctionExit(
16     Thread &thread, const Callback &callback)
17     : ThreadPlan(ThreadPlanKind::eKindGeneric, "CallOnFunctionExit", thread,
18                  eVoteNoOpinion, eVoteNoOpinion // TODO check with Jim on these
19                  ),
20       m_callback(callback) {
21   // We are not a user-generated plan.
22   SetIsMasterPlan(false);
23 }
24
25 void ThreadPlanCallOnFunctionExit::DidPush() {
26   // We now want to queue the "step out" thread plan so it executes
27   // and completes.
28
29   // Set stop vote to eVoteNo.
30   m_step_out_threadplan_sp = GetThread().QueueThreadPlanForStepOut(
31       false,             // abort other plans
32       nullptr,           // addr_context
33       true,              // first instruction
34       true,              // stop other threads
35       eVoteNo,           // do not say "we're stopping"
36       eVoteNoOpinion,    // don't care about
37                          // run state broadcasting
38       0,                 // frame_idx
39       eLazyBoolCalculate // avoid code w/o debinfo
40       );
41 }
42
43 // -------------------------------------------------------------------------
44 // ThreadPlan API
45 // -------------------------------------------------------------------------
46
47 void ThreadPlanCallOnFunctionExit::GetDescription(
48     Stream *s, lldb::DescriptionLevel level) {
49   if (!s)
50     return;
51   s->Printf("Running until completion of current function, then making "
52             "callback.");
53 }
54
55 bool ThreadPlanCallOnFunctionExit::ValidatePlan(Stream *error) {
56   // We'll say we're always good since I don't know what would make this
57   // invalid.
58   return true;
59 }
60
61 bool ThreadPlanCallOnFunctionExit::ShouldStop(Event *event_ptr) {
62   // If this is where we find out that an internal stop came in, then:
63   // Check if the step-out plan completed.  If it did, then we want to
64   // run the callback here (our reason for living...)
65   if (m_step_out_threadplan_sp && m_step_out_threadplan_sp->IsPlanComplete()) {
66     m_callback();
67
68     // We no longer need the pointer to the step-out thread plan.
69     m_step_out_threadplan_sp.reset();
70
71     // Indicate that this plan is done and can be discarded.
72     SetPlanComplete();
73
74     // We're done now, but we want to return false so that we
75     // don't cause the thread to really stop.
76   }
77
78   return false;
79 }
80
81 bool ThreadPlanCallOnFunctionExit::WillStop() {
82   // The code looks like the return value is ignored via ThreadList::
83   // ShouldStop().
84   // This is called when we really are going to stop.  We don't care
85   // and don't need to do anything here.
86   return false;
87 }
88
89 bool ThreadPlanCallOnFunctionExit::DoPlanExplainsStop(Event *event_ptr) {
90   // We don't ever explain a stop.  The only stop that is relevant
91   // to us directly is the step_out plan we added to do the heavy lifting
92   // of getting us past the current method.
93   return false;
94 }
95
96 lldb::StateType ThreadPlanCallOnFunctionExit::GetPlanRunState() {
97   // This value doesn't matter - we'll never be the top thread plan, so
98   // nobody will ask us this question.
99   return eStateRunning;
100 }