blob: 0087dfc920fdfec01f6b0d0d2b35e93f54c30bc4 [file] [log] [blame]
Jim Inghamd1686902010-10-14 23:45:03 +00001//===-- ThreadPlanTestCondition.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/ThreadPlanTestCondition.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16
17#include "lldb/lldb-private-log.h"
18#include "lldb/Breakpoint/BreakpointLocation.h"
19#include "lldb/Core/Log.h"
20#include "lldb/Core/Stream.h"
21#include "lldb/Core/Value.h"
22#include "lldb/Core/ValueObject.h"
23#include "lldb/Symbol/Function.h"
24#include "lldb/Symbol/Symbol.h"
25#include "lldb/Target/Process.h"
26#include "lldb/Target/RegisterContext.h"
27#include "lldb/Target/StopInfo.h"
28#include "lldb/Target/Thread.h"
29
30using namespace lldb;
31using namespace lldb_private;
32
33
34//----------------------------------------------------------------------
35// ThreadPlanTestCondition: Step through a stack range, either stepping over or into
36// based on the value of \a type.
37//----------------------------------------------------------------------
38
39ThreadPlanTestCondition::ThreadPlanTestCondition (
40 Thread& thread,
41 ExecutionContext &exe_ctx,
42 ClangUserExpression *expression,
43 lldb::BreakpointLocationSP break_loc_sp,
44 bool stop_others) :
45 ThreadPlan (ThreadPlan::eKindTestCondition, "test condition", thread, eVoteNoOpinion, eVoteNoOpinion),
46 m_exe_ctx (exe_ctx),
47 m_expression (expression),
48 m_break_loc_sp (break_loc_sp),
49 m_did_stop (false),
50 m_stop_others (stop_others)
51{
52}
53
54ThreadPlanTestCondition::~ThreadPlanTestCondition ()
55{
56}
57
58bool
59ThreadPlanTestCondition::ValidatePlan (Stream *error)
60{
61 return true;
62}
63
64void
65ThreadPlanTestCondition::GetDescription (Stream *s, lldb::DescriptionLevel level)
66{
67
68}
69
70bool
71ThreadPlanTestCondition::ShouldStop (Event *event_ptr)
72{
Greg Claytone005f2c2010-11-06 01:53:30 +000073 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Jim Inghamd1686902010-10-14 23:45:03 +000074 if (m_thread.IsThreadPlanDone(m_expression_plan_sp.get()))
75 {
76 ClangExpressionVariable *expr_result = NULL;
77 StreamString error_stream;
78 m_expression->FinalizeJITExecution(error_stream, m_exe_ctx, expr_result);
79
80 ValueObjectSP result_sp (expr_result->GetExpressionResult(&m_exe_ctx));
81 if (result_sp)
82 {
83 // FIXME: This is not the right answer, we should have a "GetValueAsBoolean..."
84 Scalar scalar_value = result_sp->GetValue().ResolveValue (&m_exe_ctx, result_sp->GetClangAST());
85 if (scalar_value.IsValid())
86 {
87 if (scalar_value.ULongLong(1) == 0)
88 m_did_stop = false;
89 else
90 m_did_stop = true;
91 }
92 if (log)
93 log->Printf("Condition successfully evaluated, result is %s.\n", m_did_stop ? "true" : "false");
94 }
95 else
96 {
97 if (log)
98 log->Printf("Failed to get a result from the expression, error: \"%s\"\n", error_stream.GetData());
99 m_did_stop = true;
100 }
101 }
102 else if (m_exe_ctx.thread->WasThreadPlanDiscarded (m_expression_plan_sp.get()))
103 {
104 if (log)
105 log->Printf("ExecuteExpression thread plan was discarded.\n");
106 m_did_stop = true;
107 }
108
109 // Now we have to change the event to a breakpoint event and mark it up appropriately:
110 Process::ProcessEventData *new_data = new Process::ProcessEventData (m_thread.GetProcess().GetSP(), eStateStopped);
111 event_ptr->SetData(new_data);
112 event_ptr->SetType(Process::eBroadcastBitStateChanged);
Jim Ingham6297a3a2010-10-20 00:39:53 +0000113 SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID (m_thread,
114 m_break_loc_sp->GetBreakpointSite()->GetID(),
115 m_did_stop));
Jim Inghamd1686902010-10-14 23:45:03 +0000116 if (m_did_stop)
117 {
118 Process::ProcessEventData::SetRestartedInEvent (event_ptr, false);
119 }
120 else
121 {
122 Process::ProcessEventData::SetRestartedInEvent (event_ptr, true);
123 }
124
125 SetPlanComplete();
126 return m_did_stop;
127}
128
129bool
130ThreadPlanTestCondition::PlanExplainsStop ()
131{
132 // We explain all stops, and we just can the execution and return true if we stop for any
133 // reason other than that our expression execution is done.
134 return true;
135}
136
137Vote
138ThreadPlanTestCondition::ShouldReportStop (Event *event_ptr)
139{
140 if (m_did_stop)
141 {
142 return eVoteYes;
143 }
144 else
145 {
146 return eVoteNo;
147 }
148}
149
150void
151ThreadPlanTestCondition::DidPush()
152{
153 StreamString error_stream;
154 m_expression_plan_sp.reset(m_expression->GetThreadPlanToExecuteJITExpression (error_stream, m_exe_ctx));
155 m_thread.QueueThreadPlan (m_expression_plan_sp, false);
156}
157
158bool
159ThreadPlanTestCondition::StopOthers ()
160{
161 return m_stop_others;
162}
163
164bool
165ThreadPlanTestCondition::WillStop ()
166{
167 return true;
168}
169
170StateType
Jim Ingham745ac7a2010-11-11 19:26:09 +0000171ThreadPlanTestCondition::GetPlanRunState ()
Jim Inghamd1686902010-10-14 23:45:03 +0000172{
173 return eStateRunning;
174}
175
176bool
177ThreadPlanTestCondition::MischiefManaged ()
178{
179 // If we get a stop we're done, we don't puase in the middle of
180 // condition execution.
181 return true;
182}