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;
+}