blob: 5de137bf1537e6c28a352b7b2ad8a0f7127b9604 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- BreakpointOptions.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/Breakpoint/BreakpointOptions.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/Stream.h"
17#include "lldb/Core/StringList.h"
Jim Inghamd1686902010-10-14 23:45:03 +000018#include "lldb/Core/Value.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Breakpoint/StoppointCallbackContext.h"
Jim Inghamd1686902010-10-14 23:45:03 +000020#include "lldb/Target/Process.h"
Sean Callanana91dd992010-11-19 02:52:21 +000021#include "lldb/Target/Target.h"
Jim Ingham3c7b5b92010-06-16 02:00:15 +000022#include "lldb/Target/ThreadSpec.h"
Jim Ingham14f17cf2012-05-02 00:30:53 +000023#include "lldb/Expression/ClangUserExpression.h"
Chris Lattner24943d22010-06-08 16:52:24 +000024
25using namespace lldb;
26using namespace lldb_private;
27
28bool
29BreakpointOptions::NullCallback (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
30{
31 return true;
32}
33
34//----------------------------------------------------------------------
35// BreakpointOptions constructor
36//----------------------------------------------------------------------
37BreakpointOptions::BreakpointOptions() :
38 m_callback (BreakpointOptions::NullCallback),
Chris Lattner24943d22010-06-08 16:52:24 +000039 m_callback_baton_sp (),
Greg Clayton54e7afa2010-07-09 20:39:50 +000040 m_callback_is_synchronous (false),
Chris Lattner24943d22010-06-08 16:52:24 +000041 m_enabled (true),
42 m_ignore_count (0),
Jim Inghamd1686902010-10-14 23:45:03 +000043 m_thread_spec_ap (NULL),
44 m_condition_ap()
Chris Lattner24943d22010-06-08 16:52:24 +000045{
46}
47
48//----------------------------------------------------------------------
49// BreakpointOptions copy constructor
50//----------------------------------------------------------------------
51BreakpointOptions::BreakpointOptions(const BreakpointOptions& rhs) :
52 m_callback (rhs.m_callback),
53 m_callback_baton_sp (rhs.m_callback_baton_sp),
54 m_callback_is_synchronous (rhs.m_callback_is_synchronous),
55 m_enabled (rhs.m_enabled),
56 m_ignore_count (rhs.m_ignore_count),
Jim Inghamd1686902010-10-14 23:45:03 +000057 m_thread_spec_ap (NULL),
58 m_condition_ap (NULL)
Chris Lattner24943d22010-06-08 16:52:24 +000059{
Jim Ingham3c7b5b92010-06-16 02:00:15 +000060 if (rhs.m_thread_spec_ap.get() != NULL)
61 m_thread_spec_ap.reset (new ThreadSpec(*rhs.m_thread_spec_ap.get()));
Jim Inghamd1686902010-10-14 23:45:03 +000062 if (rhs.m_condition_ap.get())
Sean Callanandaa6efe2011-12-21 22:22:58 +000063 m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText(), NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
Chris Lattner24943d22010-06-08 16:52:24 +000064}
65
66//----------------------------------------------------------------------
67// BreakpointOptions assignment operator
68//----------------------------------------------------------------------
69const BreakpointOptions&
70BreakpointOptions::operator=(const BreakpointOptions& rhs)
71{
72 m_callback = rhs.m_callback;
73 m_callback_baton_sp = rhs.m_callback_baton_sp;
74 m_callback_is_synchronous = rhs.m_callback_is_synchronous;
75 m_enabled = rhs.m_enabled;
76 m_ignore_count = rhs.m_ignore_count;
Jim Ingham3c7b5b92010-06-16 02:00:15 +000077 if (rhs.m_thread_spec_ap.get() != NULL)
78 m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
Jim Inghamd1686902010-10-14 23:45:03 +000079 if (rhs.m_condition_ap.get())
Sean Callanandaa6efe2011-12-21 22:22:58 +000080 m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText(), NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
Chris Lattner24943d22010-06-08 16:52:24 +000081 return *this;
82}
83
Jim Ingham649492b2010-06-18 01:00:58 +000084BreakpointOptions *
85BreakpointOptions::CopyOptionsNoCallback (BreakpointOptions &orig)
86{
87 BreakpointHitCallback orig_callback = orig.m_callback;
88 lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp;
89 bool orig_is_sync = orig.m_callback_is_synchronous;
90
91 orig.ClearCallback();
92 BreakpointOptions *ret_val = new BreakpointOptions(orig);
93
94 orig.SetCallback (orig_callback, orig_callback_baton_sp, orig_is_sync);
95
96 return ret_val;
97}
98
Chris Lattner24943d22010-06-08 16:52:24 +000099//----------------------------------------------------------------------
100// Destructor
101//----------------------------------------------------------------------
102BreakpointOptions::~BreakpointOptions()
103{
104}
105
106//------------------------------------------------------------------
107// Callbacks
108//------------------------------------------------------------------
109void
110BreakpointOptions::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool callback_is_synchronous)
111{
112 m_callback_is_synchronous = callback_is_synchronous;
113 m_callback = callback;
114 m_callback_baton_sp = callback_baton_sp;
115}
116
117void
118BreakpointOptions::ClearCallback ()
119{
Jim Inghamd1686902010-10-14 23:45:03 +0000120 m_callback = BreakpointOptions::NullCallback;
121 m_callback_is_synchronous = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000122 m_callback_baton_sp.reset();
123}
124
125Baton *
126BreakpointOptions::GetBaton ()
127{
128 return m_callback_baton_sp.get();
129}
130
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000131const Baton *
132BreakpointOptions::GetBaton () const
133{
134 return m_callback_baton_sp.get();
135}
136
Chris Lattner24943d22010-06-08 16:52:24 +0000137bool
138BreakpointOptions::InvokeCallback (StoppointCallbackContext *context,
139 lldb::user_id_t break_id,
140 lldb::user_id_t break_loc_id)
141{
142 if (m_callback && context->is_synchronous == IsCallbackSynchronous())
143 {
144 return m_callback (m_callback_baton_sp ? m_callback_baton_sp->m_data : NULL,
145 context,
146 break_id,
147 break_loc_id);
148 }
149 else
150 return true;
151}
152
Jim Ingham649492b2010-06-18 01:00:58 +0000153bool
154BreakpointOptions::HasCallback ()
155{
156 return m_callback != BreakpointOptions::NullCallback;
157}
158
Jim Inghamd1686902010-10-14 23:45:03 +0000159void
160BreakpointOptions::SetCondition (const char *condition)
161{
162 if (condition == NULL || condition[0] == '\0')
163 {
164 if (m_condition_ap.get())
165 m_condition_ap.reset();
166 }
167 else
168 {
Sean Callanandaa6efe2011-12-21 22:22:58 +0000169 m_condition_ap.reset(new ClangUserExpression (condition, NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
Jim Inghamd1686902010-10-14 23:45:03 +0000170 }
171}
172
Jim Inghamd1686902010-10-14 23:45:03 +0000173const char *
Jim Inghamac354422011-06-15 21:16:00 +0000174BreakpointOptions::GetConditionText () const
Jim Inghamd1686902010-10-14 23:45:03 +0000175{
176 if (m_condition_ap.get())
177 return m_condition_ap->GetUserText();
178 else
Jim Inghamac354422011-06-15 21:16:00 +0000179 return NULL;
Jim Inghamd1686902010-10-14 23:45:03 +0000180}
181
Chris Lattner24943d22010-06-08 16:52:24 +0000182//------------------------------------------------------------------
183// Enabled/Ignore Count
184//------------------------------------------------------------------
185bool
186BreakpointOptions::IsEnabled () const
187{
188 return m_enabled;
189}
190
191void
192BreakpointOptions::SetEnabled (bool enabled)
193{
194 m_enabled = enabled;
195}
196
Greg Clayton54e7afa2010-07-09 20:39:50 +0000197uint32_t
Chris Lattner24943d22010-06-08 16:52:24 +0000198BreakpointOptions::GetIgnoreCount () const
199{
200 return m_ignore_count;
201}
202
203void
Greg Clayton54e7afa2010-07-09 20:39:50 +0000204BreakpointOptions::SetIgnoreCount (uint32_t n)
Chris Lattner24943d22010-06-08 16:52:24 +0000205{
206 m_ignore_count = n;
207}
208
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000209const ThreadSpec *
Jim Ingham9c6898b2010-06-22 21:12:54 +0000210BreakpointOptions::GetThreadSpecNoCreate () const
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000211{
212 return m_thread_spec_ap.get();
213}
214
215ThreadSpec *
216BreakpointOptions::GetThreadSpec ()
217{
218 if (m_thread_spec_ap.get() == NULL)
219 m_thread_spec_ap.reset (new ThreadSpec());
220
221 return m_thread_spec_ap.get();
222}
223
Chris Lattner24943d22010-06-08 16:52:24 +0000224void
225BreakpointOptions::SetThreadID (lldb::tid_t thread_id)
226{
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000227 GetThreadSpec()->SetTID(thread_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000228}
229
Chris Lattner24943d22010-06-08 16:52:24 +0000230void
Jim Ingham649492b2010-06-18 01:00:58 +0000231BreakpointOptions::GetDescription (Stream *s, lldb::DescriptionLevel level) const
232{
233
234 // Figure out if there are any options not at their default value, and only print
235 // anything if there are:
236
Jim Ingham9c6898b2010-06-22 21:12:54 +0000237 if (m_ignore_count != 0 || !m_enabled || (GetThreadSpecNoCreate() != NULL && GetThreadSpecNoCreate()->HasSpecification ()))
Jim Ingham649492b2010-06-18 01:00:58 +0000238 {
239 if (level == lldb::eDescriptionLevelVerbose)
240 {
241 s->EOL ();
242 s->IndentMore();
243 s->Indent();
244 s->PutCString("Breakpoint Options:\n");
245 s->IndentMore();
246 s->Indent();
247 }
248 else
249 s->PutCString(" Options: ");
250
251 if (m_ignore_count > 0)
252 s->Printf("ignore: %d ", m_ignore_count);
253 s->Printf("%sabled ", m_enabled ? "en" : "dis");
254
255 if (m_thread_spec_ap.get())
256 m_thread_spec_ap->GetDescription (s, level);
257 else if (level == eDescriptionLevelBrief)
258 s->PutCString ("thread spec: no ");
259 if (level == lldb::eDescriptionLevelFull)
260 {
261 s->IndentLess();
262 s->IndentMore();
263 }
264 }
265
Johnny Chen7aecabb2011-06-20 18:59:49 +0000266 if (m_callback_baton_sp.get())
267 {
268 if (level != eDescriptionLevelBrief)
269 {
270 s->EOL();
271 m_callback_baton_sp->GetDescription (s, level);
272 }
273 }
Jim Inghamd1686902010-10-14 23:45:03 +0000274 if (m_condition_ap.get())
275 {
276 if (level != eDescriptionLevelBrief)
277 {
278 s->EOL();
279 s->Printf("Condition: %s\n", m_condition_ap->GetUserText());
280 }
Greg Clayton12bec712010-06-28 21:30:43 +0000281 }
Jim Ingham649492b2010-06-18 01:00:58 +0000282}
283
284void
Chris Lattner24943d22010-06-08 16:52:24 +0000285BreakpointOptions::CommandBaton::GetDescription (Stream *s, lldb::DescriptionLevel level) const
286{
Chris Lattner24943d22010-06-08 16:52:24 +0000287 CommandData *data = (CommandData *)m_data;
Jim Ingham649492b2010-06-18 01:00:58 +0000288
289 if (level == eDescriptionLevelBrief)
290 {
Greg Clayton12bec712010-06-28 21:30:43 +0000291 s->Printf (", commands = %s", (data && data->user_source.GetSize() > 0) ? "yes" : "no");
Jim Ingham649492b2010-06-18 01:00:58 +0000292 return;
293 }
294
295 s->IndentMore ();
296 s->Indent("Breakpoint commands:\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000297
298 s->IndentMore ();
299 if (data && data->user_source.GetSize() > 0)
300 {
301 const size_t num_strings = data->user_source.GetSize();
302 for (size_t i = 0; i < num_strings; ++i)
303 {
304 s->Indent(data->user_source.GetStringAtIndex(i));
305 s->EOL();
306 }
307 }
308 else
309 {
310 s->PutCString ("No commands.\n");
311 }
312 s->IndentLess ();
Jim Ingham649492b2010-06-18 01:00:58 +0000313 s->IndentLess ();
Chris Lattner24943d22010-06-08 16:52:24 +0000314}
315