diff options
Diffstat (limited to 'lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp')
| -rw-r--r-- | lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp b/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp new file mode 100644 index 00000000000..b2383e4f122 --- /dev/null +++ b/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp @@ -0,0 +1,119 @@ +//===-- ThreadPlanCallOnFunctionExit.cpp ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/ThreadPlanCallOnFunctionExit.h" + +using namespace lldb; +using namespace lldb_private; + +ThreadPlanCallOnFunctionExit::ThreadPlanCallOnFunctionExit(Thread &thread, + const Callback + &callback) : + ThreadPlan(ThreadPlanKind::eKindGeneric, "CallOnFunctionExit", + thread, + eVoteNoOpinion, eVoteNoOpinion // TODO check with Jim on these + ), + m_callback(callback) +{ + // We are not a user-generated plan. + SetIsMasterPlan(false); +} + +void +ThreadPlanCallOnFunctionExit::DidPush() +{ + // We now want to queue the "step out" thread plan so it executes + // and completes. + + // Set stop vote to eVoteNo. + m_step_out_threadplan_sp = GetThread() + .QueueThreadPlanForStepOut(false, // abort other plans + nullptr, // addr_context + true, // first instruction + true, // stop other threads + eVoteNo, // do not say "we're stopping" + eVoteNoOpinion, // don't care about + // run state broadcasting + 0, // frame_idx + eLazyBoolCalculate // avoid code w/o debinfo + ); +} + +// ------------------------------------------------------------------------- +// ThreadPlan API +// ------------------------------------------------------------------------- + +void +ThreadPlanCallOnFunctionExit::GetDescription(Stream *s, lldb::DescriptionLevel + level) +{ + if (!s) + return; + s->Printf("Running until completion of current function, then making " + "callback."); +} + +bool +ThreadPlanCallOnFunctionExit::ValidatePlan(Stream *error) +{ + // We'll say we're always good since I don't know what would make this + // invalid. + return true; +} + +bool +ThreadPlanCallOnFunctionExit::ShouldStop(Event *event_ptr) +{ + // If this is where we find out that an internal stop came in, then: + // Check if the step-out plan completed. If it did, then we want to + // run the callback here (our reason for living...) + if (m_step_out_threadplan_sp && + m_step_out_threadplan_sp->IsPlanComplete()) + { + m_callback(); + + // We no longer need the pointer to the step-out thread plan. + m_step_out_threadplan_sp.reset(); + + // Indicate that this plan is done and can be discarded. + SetPlanComplete(); + + // We're done now, but we want to return false so that we + // don't cause the thread to really stop. + } + + return false; +} + +bool +ThreadPlanCallOnFunctionExit::WillStop() +{ + // The code looks like the return value is ignored via ThreadList:: + // ShouldStop(). + // This is called when we really are going to stop. We don't care + // and don't need to do anything here. + return false; +} + +bool +ThreadPlanCallOnFunctionExit::DoPlanExplainsStop (Event *event_ptr) +{ + // We don't ever explain a stop. The only stop that is relevant + // to us directly is the step_out plan we added to do the heavy lifting + // of getting us past the current method. + return false; +} + +lldb::StateType +ThreadPlanCallOnFunctionExit::GetPlanRunState() +{ + // This value doesn't matter - we'll never be the top thread plan, so + // nobody will ask us this question. + return eStateRunning; +} |

