blob: 60679c94a767c56ae48284040436a5c1c40daeb9 [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),
Jim Ingham2753a022012-10-05 19:16:31 +000042 m_one_shot (false),
Chris Lattner24943d22010-06-08 16:52:24 +000043 m_ignore_count (0),
Jim Inghamd1686902010-10-14 23:45:03 +000044 m_thread_spec_ap (NULL),
45 m_condition_ap()
Chris Lattner24943d22010-06-08 16:52:24 +000046{
47}
48
49//----------------------------------------------------------------------
50// BreakpointOptions copy constructor
51//----------------------------------------------------------------------
52BreakpointOptions::BreakpointOptions(const BreakpointOptions& rhs) :
53 m_callback (rhs.m_callback),
54 m_callback_baton_sp (rhs.m_callback_baton_sp),
55 m_callback_is_synchronous (rhs.m_callback_is_synchronous),
56 m_enabled (rhs.m_enabled),
Jim Ingham2753a022012-10-05 19:16:31 +000057 m_one_shot (rhs.m_one_shot),
Chris Lattner24943d22010-06-08 16:52:24 +000058 m_ignore_count (rhs.m_ignore_count),
Jim Inghamd1686902010-10-14 23:45:03 +000059 m_thread_spec_ap (NULL),
60 m_condition_ap (NULL)
Chris Lattner24943d22010-06-08 16:52:24 +000061{
Jim Ingham3c7b5b92010-06-16 02:00:15 +000062 if (rhs.m_thread_spec_ap.get() != NULL)
63 m_thread_spec_ap.reset (new ThreadSpec(*rhs.m_thread_spec_ap.get()));
Jim Inghamd1686902010-10-14 23:45:03 +000064 if (rhs.m_condition_ap.get())
Sean Callanandaa6efe2011-12-21 22:22:58 +000065 m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText(), NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
Chris Lattner24943d22010-06-08 16:52:24 +000066}
67
68//----------------------------------------------------------------------
69// BreakpointOptions assignment operator
70//----------------------------------------------------------------------
71const BreakpointOptions&
72BreakpointOptions::operator=(const BreakpointOptions& rhs)
73{
74 m_callback = rhs.m_callback;
75 m_callback_baton_sp = rhs.m_callback_baton_sp;
76 m_callback_is_synchronous = rhs.m_callback_is_synchronous;
77 m_enabled = rhs.m_enabled;
Jim Ingham2753a022012-10-05 19:16:31 +000078 m_one_shot = rhs.m_one_shot;
Chris Lattner24943d22010-06-08 16:52:24 +000079 m_ignore_count = rhs.m_ignore_count;
Jim Ingham3c7b5b92010-06-16 02:00:15 +000080 if (rhs.m_thread_spec_ap.get() != NULL)
81 m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
Jim Inghamd1686902010-10-14 23:45:03 +000082 if (rhs.m_condition_ap.get())
Sean Callanandaa6efe2011-12-21 22:22:58 +000083 m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText(), NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
Chris Lattner24943d22010-06-08 16:52:24 +000084 return *this;
85}
86
Jim Ingham649492b2010-06-18 01:00:58 +000087BreakpointOptions *
88BreakpointOptions::CopyOptionsNoCallback (BreakpointOptions &orig)
89{
90 BreakpointHitCallback orig_callback = orig.m_callback;
91 lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp;
92 bool orig_is_sync = orig.m_callback_is_synchronous;
93
94 orig.ClearCallback();
95 BreakpointOptions *ret_val = new BreakpointOptions(orig);
96
97 orig.SetCallback (orig_callback, orig_callback_baton_sp, orig_is_sync);
98
99 return ret_val;
100}
101
Chris Lattner24943d22010-06-08 16:52:24 +0000102//----------------------------------------------------------------------
103// Destructor
104//----------------------------------------------------------------------
105BreakpointOptions::~BreakpointOptions()
106{
107}
108
109//------------------------------------------------------------------
110// Callbacks
111//------------------------------------------------------------------
112void
113BreakpointOptions::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool callback_is_synchronous)
114{
115 m_callback_is_synchronous = callback_is_synchronous;
116 m_callback = callback;
117 m_callback_baton_sp = callback_baton_sp;
118}
119
120void
121BreakpointOptions::ClearCallback ()
122{
Jim Inghamd1686902010-10-14 23:45:03 +0000123 m_callback = BreakpointOptions::NullCallback;
124 m_callback_is_synchronous = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000125 m_callback_baton_sp.reset();
126}
127
128Baton *
129BreakpointOptions::GetBaton ()
130{
131 return m_callback_baton_sp.get();
132}
133
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000134const Baton *
135BreakpointOptions::GetBaton () const
136{
137 return m_callback_baton_sp.get();
138}
139
Chris Lattner24943d22010-06-08 16:52:24 +0000140bool
141BreakpointOptions::InvokeCallback (StoppointCallbackContext *context,
142 lldb::user_id_t break_id,
143 lldb::user_id_t break_loc_id)
144{
145 if (m_callback && context->is_synchronous == IsCallbackSynchronous())
146 {
147 return m_callback (m_callback_baton_sp ? m_callback_baton_sp->m_data : NULL,
148 context,
149 break_id,
150 break_loc_id);
151 }
152 else
153 return true;
154}
155
Jim Ingham649492b2010-06-18 01:00:58 +0000156bool
157BreakpointOptions::HasCallback ()
158{
159 return m_callback != BreakpointOptions::NullCallback;
160}
161
Jim Inghamd1686902010-10-14 23:45:03 +0000162void
163BreakpointOptions::SetCondition (const char *condition)
164{
165 if (condition == NULL || condition[0] == '\0')
166 {
167 if (m_condition_ap.get())
168 m_condition_ap.reset();
169 }
170 else
171 {
Sean Callanandaa6efe2011-12-21 22:22:58 +0000172 m_condition_ap.reset(new ClangUserExpression (condition, NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
Jim Inghamd1686902010-10-14 23:45:03 +0000173 }
174}
175
Jim Inghamd1686902010-10-14 23:45:03 +0000176const char *
Jim Inghamac354422011-06-15 21:16:00 +0000177BreakpointOptions::GetConditionText () const
Jim Inghamd1686902010-10-14 23:45:03 +0000178{
179 if (m_condition_ap.get())
180 return m_condition_ap->GetUserText();
181 else
Jim Inghamac354422011-06-15 21:16:00 +0000182 return NULL;
Jim Inghamd1686902010-10-14 23:45:03 +0000183}
184
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000185const ThreadSpec *
Jim Ingham9c6898b2010-06-22 21:12:54 +0000186BreakpointOptions::GetThreadSpecNoCreate () const
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000187{
188 return m_thread_spec_ap.get();
189}
190
191ThreadSpec *
192BreakpointOptions::GetThreadSpec ()
193{
194 if (m_thread_spec_ap.get() == NULL)
195 m_thread_spec_ap.reset (new ThreadSpec());
196
197 return m_thread_spec_ap.get();
198}
199
Chris Lattner24943d22010-06-08 16:52:24 +0000200void
201BreakpointOptions::SetThreadID (lldb::tid_t thread_id)
202{
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000203 GetThreadSpec()->SetTID(thread_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000204}
205
Chris Lattner24943d22010-06-08 16:52:24 +0000206void
Jim Ingham649492b2010-06-18 01:00:58 +0000207BreakpointOptions::GetDescription (Stream *s, lldb::DescriptionLevel level) const
208{
209
210 // Figure out if there are any options not at their default value, and only print
211 // anything if there are:
212
Jim Ingham2753a022012-10-05 19:16:31 +0000213 if (m_ignore_count != 0 || !m_enabled || m_one_shot || (GetThreadSpecNoCreate() != NULL && GetThreadSpecNoCreate()->HasSpecification ()))
Jim Ingham649492b2010-06-18 01:00:58 +0000214 {
215 if (level == lldb::eDescriptionLevelVerbose)
216 {
217 s->EOL ();
218 s->IndentMore();
219 s->Indent();
220 s->PutCString("Breakpoint Options:\n");
221 s->IndentMore();
222 s->Indent();
223 }
224 else
225 s->PutCString(" Options: ");
226
227 if (m_ignore_count > 0)
228 s->Printf("ignore: %d ", m_ignore_count);
229 s->Printf("%sabled ", m_enabled ? "en" : "dis");
230
Jim Ingham2753a022012-10-05 19:16:31 +0000231 if (m_one_shot)
232 s->Printf ("one-shot ");
233
Jim Ingham649492b2010-06-18 01:00:58 +0000234 if (m_thread_spec_ap.get())
235 m_thread_spec_ap->GetDescription (s, level);
236 else if (level == eDescriptionLevelBrief)
237 s->PutCString ("thread spec: no ");
238 if (level == lldb::eDescriptionLevelFull)
239 {
240 s->IndentLess();
241 s->IndentMore();
242 }
243 }
244
Johnny Chen7aecabb2011-06-20 18:59:49 +0000245 if (m_callback_baton_sp.get())
246 {
247 if (level != eDescriptionLevelBrief)
248 {
249 s->EOL();
250 m_callback_baton_sp->GetDescription (s, level);
251 }
252 }
Jim Inghamd1686902010-10-14 23:45:03 +0000253 if (m_condition_ap.get())
254 {
255 if (level != eDescriptionLevelBrief)
256 {
257 s->EOL();
258 s->Printf("Condition: %s\n", m_condition_ap->GetUserText());
259 }
Greg Clayton12bec712010-06-28 21:30:43 +0000260 }
Jim Ingham649492b2010-06-18 01:00:58 +0000261}
262
263void
Chris Lattner24943d22010-06-08 16:52:24 +0000264BreakpointOptions::CommandBaton::GetDescription (Stream *s, lldb::DescriptionLevel level) const
265{
Chris Lattner24943d22010-06-08 16:52:24 +0000266 CommandData *data = (CommandData *)m_data;
Jim Ingham649492b2010-06-18 01:00:58 +0000267
268 if (level == eDescriptionLevelBrief)
269 {
Greg Clayton12bec712010-06-28 21:30:43 +0000270 s->Printf (", commands = %s", (data && data->user_source.GetSize() > 0) ? "yes" : "no");
Jim Ingham649492b2010-06-18 01:00:58 +0000271 return;
272 }
273
274 s->IndentMore ();
275 s->Indent("Breakpoint commands:\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000276
277 s->IndentMore ();
278 if (data && data->user_source.GetSize() > 0)
279 {
280 const size_t num_strings = data->user_source.GetSize();
281 for (size_t i = 0; i < num_strings; ++i)
282 {
283 s->Indent(data->user_source.GetStringAtIndex(i));
284 s->EOL();
285 }
286 }
287 else
288 {
289 s->PutCString ("No commands.\n");
290 }
291 s->IndentLess ();
Jim Ingham649492b2010-06-18 01:00:58 +0000292 s->IndentLess ();
Chris Lattner24943d22010-06-08 16:52:24 +0000293}
294