Add StructuredData plugin type; showcase with new DarwinLog feature
Take 2, with missing cmake line fixed. Build tested on
Ubuntu 14.04 with clang-3.6.
See docs/structured_data/StructuredDataPlugins.md for details.
differential review: https://reviews.llvm.org/D22976
reviewers: clayborg, jingham
llvm-svn: 279202
diff --git a/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp b/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp
new file mode 100644
index 0000000..b2383e4
--- /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;
+}