blob: f18722a9901642615c76d0ba4f28078610ce701b [file] [log] [blame]
Johnny Chenecd4feb2011-10-14 00:42:25 +00001//===-- Watchpoint.cpp ------------------------------------------*- C++ -*-===//
Chris Lattner24943d22010-06-08 16:52:24 +00002//
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
Johnny Chenecd4feb2011-10-14 00:42:25 +000010#include "lldb/Breakpoint/Watchpoint.h"
Chris Lattner24943d22010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Johnny Chen712a6282011-10-17 18:58:00 +000016#include "lldb/Breakpoint/StoppointCallbackContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Core/Stream.h"
Jim Ingham9e376622012-10-23 07:20:06 +000018#include "lldb/Core/Value.h"
19#include "lldb/Core/ValueObject.h"
20#include "lldb/Core/ValueObjectMemory.h"
21#include "lldb/Symbol/ClangASTContext.h"
Johnny Chen712a6282011-10-17 18:58:00 +000022#include "lldb/Target/Process.h"
23#include "lldb/Target/Target.h"
24#include "lldb/Target/ThreadSpec.h"
Jim Ingham14f17cf2012-05-02 00:30:53 +000025#include "lldb/Expression/ClangUserExpression.h"
Chris Lattner24943d22010-06-08 16:52:24 +000026
27using namespace lldb;
28using namespace lldb_private;
29
Greg Clayton36da2aa2013-01-25 18:06:21 +000030Watchpoint::Watchpoint (Target& target, lldb::addr_t addr, uint32_t size, const ClangASTType *type, bool hardware) :
Johnny Chen116a5cd2012-02-25 06:44:30 +000031 StoppointLocation (0, addr, size, hardware),
Jim Ingham9e376622012-10-23 07:20:06 +000032 m_target(target),
Johnny Chen116a5cd2012-02-25 06:44:30 +000033 m_enabled(false),
Johnny Chen01acfa72011-09-22 18:04:58 +000034 m_is_hardware(hardware),
Johnny Chen9e985592012-08-13 21:09:54 +000035 m_is_watch_variable(false),
Johnny Chenf84e5662012-08-21 23:17:04 +000036 m_is_ephemeral(false),
Johnny Chen258db3a2012-08-23 22:28:26 +000037 m_disabled_count(0),
Chris Lattner24943d22010-06-08 16:52:24 +000038 m_watch_read(0),
39 m_watch_write(0),
40 m_watch_was_read(0),
41 m_watch_was_written(0),
42 m_ignore_count(0),
Johnny Chen0b093662012-08-14 20:56:37 +000043 m_false_alarms(0),
Johnny Chen41a55ef2011-10-14 19:15:48 +000044 m_decl_str(),
Johnny Chen116a5cd2012-02-25 06:44:30 +000045 m_watch_spec_str(),
Jim Ingham9e376622012-10-23 07:20:06 +000046 m_type(),
Johnny Chenf3ec4612012-08-09 23:09:42 +000047 m_error(),
Jim Ingham9c970a32012-12-18 02:03:49 +000048 m_options (),
49 m_being_created(true)
Chris Lattner24943d22010-06-08 16:52:24 +000050{
Jim Ingham9e376622012-10-23 07:20:06 +000051 if (type && type->IsValid())
52 m_type = *type;
53 else
54 {
55 // If we don't have a known type, then we force it to unsigned int of the right size.
56 ClangASTContext *ast_context = target.GetScratchClangASTContext();
Jim Inghamed2b62a2012-10-23 21:09:09 +000057 clang_type_t clang_type = ast_context->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8 * size);
Jim Ingham9e376622012-10-23 07:20:06 +000058 m_type.SetClangType(ast_context->getASTContext(), clang_type);
59 }
60
61 // Set the initial value of the watched variable:
62 if (m_target.GetProcessSP())
63 {
64 ExecutionContext exe_ctx;
65 m_target.GetProcessSP()->CalculateExecutionContext(exe_ctx);
66 CaptureWatchedValue (exe_ctx);
67 }
Jim Ingham9c970a32012-12-18 02:03:49 +000068 m_being_created = false;
Chris Lattner24943d22010-06-08 16:52:24 +000069}
70
Johnny Chenecd4feb2011-10-14 00:42:25 +000071Watchpoint::~Watchpoint()
Chris Lattner24943d22010-06-08 16:52:24 +000072{
73}
74
Johnny Chenf3ec4612012-08-09 23:09:42 +000075// This function is used when "baton" doesn't need to be freed
76void
77Watchpoint::SetCallback (WatchpointHitCallback callback, void *baton, bool is_synchronous)
Chris Lattner24943d22010-06-08 16:52:24 +000078{
Johnny Chenf3ec4612012-08-09 23:09:42 +000079 // The default "Baton" class will keep a copy of "baton" and won't free
80 // or delete it when it goes goes out of scope.
81 m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
82
Jim Ingham9c970a32012-12-18 02:03:49 +000083 SendWatchpointChangedEvent (eWatchpointEventTypeCommandChanged);
Johnny Chenf3ec4612012-08-09 23:09:42 +000084}
85
86// This function is used when a baton needs to be freed and therefore is
87// contained in a "Baton" subclass.
88void
89Watchpoint::SetCallback (WatchpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous)
90{
91 m_options.SetCallback(callback, callback_baton_sp, is_synchronous);
Jim Ingham9c970a32012-12-18 02:03:49 +000092 SendWatchpointChangedEvent (eWatchpointEventTypeCommandChanged);
Johnny Chenf3ec4612012-08-09 23:09:42 +000093}
94
95void
96Watchpoint::ClearCallback ()
97{
98 m_options.ClearCallback ();
Jim Ingham9c970a32012-12-18 02:03:49 +000099 SendWatchpointChangedEvent (eWatchpointEventTypeCommandChanged);
Chris Lattner24943d22010-06-08 16:52:24 +0000100}
101
Johnny Chen10b12b32011-09-16 21:41:42 +0000102void
Johnny Chen9e985592012-08-13 21:09:54 +0000103Watchpoint::SetDeclInfo (const std::string &str)
Johnny Chen10b12b32011-09-16 21:41:42 +0000104{
105 m_decl_str = str;
106 return;
107}
108
Johnny Chen9e985592012-08-13 21:09:54 +0000109std::string
110Watchpoint::GetWatchSpec()
111{
112 return m_watch_spec_str;
113}
114
Johnny Chen116a5cd2012-02-25 06:44:30 +0000115void
Johnny Chen9e985592012-08-13 21:09:54 +0000116Watchpoint::SetWatchSpec (const std::string &str)
Johnny Chen116a5cd2012-02-25 06:44:30 +0000117{
118 m_watch_spec_str = str;
119 return;
120}
121
Johnny Chen51b7c5f2012-01-23 23:03:59 +0000122// Override default impl of StoppointLocation::IsHardware() since m_is_hardware
123// member field is more accurate.
Johnny Chen01acfa72011-09-22 18:04:58 +0000124bool
Johnny Chenecd4feb2011-10-14 00:42:25 +0000125Watchpoint::IsHardware () const
Johnny Chen01acfa72011-09-22 18:04:58 +0000126{
127 return m_is_hardware;
128}
129
Johnny Chen9e985592012-08-13 21:09:54 +0000130bool
131Watchpoint::IsWatchVariable() const
132{
133 return m_is_watch_variable;
134}
135
136void
137Watchpoint::SetWatchVariable(bool val)
138{
139 m_is_watch_variable = val;
140}
141
Jim Ingham9e376622012-10-23 07:20:06 +0000142bool
143Watchpoint::CaptureWatchedValue (const ExecutionContext &exe_ctx)
144{
145 ConstString watch_name("$__lldb__watch_value");
146 m_old_value_sp = m_new_value_sp;
147 Address watch_address(GetLoadAddress());
Jim Inghamed2b62a2012-10-23 21:09:09 +0000148 if (!m_type.IsValid())
149 {
150 // Don't know how to report new & old values, since we couldn't make a scalar type for this watchpoint.
151 // This works around an assert in ValueObjectMemory::Create.
152 // FIXME: This should not happen, but if it does in some case we care about,
153 // we can go grab the value raw and print it as unsigned.
154 return false;
155 }
Jim Ingham9e376622012-10-23 07:20:06 +0000156 m_new_value_sp = ValueObjectMemory::Create (exe_ctx.GetBestExecutionContextScope(), watch_name.AsCString(), watch_address, m_type);
157 m_new_value_sp = m_new_value_sp->CreateConstantValue(watch_name);
158 if (m_new_value_sp && m_new_value_sp->GetError().Success())
159 return true;
160 else
161 return false;
162}
163
Johnny Chen0b093662012-08-14 20:56:37 +0000164void
165Watchpoint::IncrementFalseAlarmsAndReviseHitCount()
166{
167 ++m_false_alarms;
168 if (m_false_alarms)
169 {
170 if (m_hit_count >= m_false_alarms)
171 {
172 m_hit_count -= m_false_alarms;
173 m_false_alarms = 0;
174 }
175 else
176 {
177 m_false_alarms -= m_hit_count;
178 m_hit_count = 0;
179 }
180 }
181}
182
Chris Lattner24943d22010-06-08 16:52:24 +0000183// RETURNS - true if we should stop at this breakpoint, false if we
184// should continue.
185
186bool
Johnny Chenecd4feb2011-10-14 00:42:25 +0000187Watchpoint::ShouldStop (StoppointCallbackContext *context)
Chris Lattner24943d22010-06-08 16:52:24 +0000188{
Johnny Chen51b7c5f2012-01-23 23:03:59 +0000189 IncrementHitCount();
Chris Lattner24943d22010-06-08 16:52:24 +0000190
Johnny Chen01acfa72011-09-22 18:04:58 +0000191 if (!IsEnabled())
192 return false;
Johnny Chen043f8c22011-09-21 22:47:15 +0000193
Johnny Chen51b7c5f2012-01-23 23:03:59 +0000194 if (GetHitCount() <= GetIgnoreCount())
Johnny Chen01acfa72011-09-22 18:04:58 +0000195 return false;
196
Johnny Chen712a6282011-10-17 18:58:00 +0000197 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000198}
199
200void
Johnny Chenecd4feb2011-10-14 00:42:25 +0000201Watchpoint::GetDescription (Stream *s, lldb::DescriptionLevel level)
Johnny Chen34bbf852011-09-12 23:38:44 +0000202{
Johnny Chen10b12b32011-09-16 21:41:42 +0000203 DumpWithLevel(s, level);
Johnny Chen34bbf852011-09-12 23:38:44 +0000204 return;
205}
206
207void
Johnny Chenecd4feb2011-10-14 00:42:25 +0000208Watchpoint::Dump(Stream *s) const
Chris Lattner24943d22010-06-08 16:52:24 +0000209{
Johnny Chen10b12b32011-09-16 21:41:42 +0000210 DumpWithLevel(s, lldb::eDescriptionLevelBrief);
211}
212
Johnny Chenc9c2a9b2012-08-13 23:27:50 +0000213// If prefix is NULL, we display the watch id and ignore the prefix altogether.
Johnny Chen10b12b32011-09-16 21:41:42 +0000214void
Johnny Chenc9c2a9b2012-08-13 23:27:50 +0000215Watchpoint::DumpSnapshots(Stream *s, const char *prefix) const
Johnny Chen9e985592012-08-13 21:09:54 +0000216{
Johnny Chenc9c2a9b2012-08-13 23:27:50 +0000217 if (!prefix)
218 {
219 s->Printf("\nWatchpoint %u hit:", GetID());
220 prefix = "";
221 }
Jim Ingham9e376622012-10-23 07:20:06 +0000222
223 if (m_old_value_sp)
Johnny Chen9e985592012-08-13 21:09:54 +0000224 {
Jim Ingham9e376622012-10-23 07:20:06 +0000225 s->Printf("\n%sold value: %s", prefix, m_old_value_sp->GetValueAsCString());
Johnny Chen9e985592012-08-13 21:09:54 +0000226 }
Jim Ingham9e376622012-10-23 07:20:06 +0000227 if (m_new_value_sp)
Johnny Chen9e985592012-08-13 21:09:54 +0000228 {
Jim Ingham9e376622012-10-23 07:20:06 +0000229 s->Printf("\n%snew value: %s", prefix, m_new_value_sp->GetValueAsCString());
Johnny Chen9e985592012-08-13 21:09:54 +0000230 }
231}
232
233void
Johnny Chenecd4feb2011-10-14 00:42:25 +0000234Watchpoint::DumpWithLevel(Stream *s, lldb::DescriptionLevel description_level) const
Johnny Chen10b12b32011-09-16 21:41:42 +0000235{
Chris Lattner24943d22010-06-08 16:52:24 +0000236 if (s == NULL)
237 return;
238
Johnny Chen10b12b32011-09-16 21:41:42 +0000239 assert(description_level >= lldb::eDescriptionLevelBrief &&
240 description_level <= lldb::eDescriptionLevelVerbose);
241
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000242 s->Printf("Watchpoint %u: addr = 0x%8.8" PRIx64 " size = %u state = %s type = %s%s",
Johnny Chen10b12b32011-09-16 21:41:42 +0000243 GetID(),
Johnny Chen1c2d9412012-01-24 00:11:02 +0000244 GetLoadAddress(),
Johnny Chen10b12b32011-09-16 21:41:42 +0000245 m_byte_size,
Johnny Chen116a5cd2012-02-25 06:44:30 +0000246 IsEnabled() ? "enabled" : "disabled",
Johnny Chen10b12b32011-09-16 21:41:42 +0000247 m_watch_read ? "r" : "",
248 m_watch_write ? "w" : "");
249
Johnny Chen712a6282011-10-17 18:58:00 +0000250 if (description_level >= lldb::eDescriptionLevelFull) {
Johnny Chen55a2d5a2012-01-30 21:46:17 +0000251 if (!m_decl_str.empty())
Johnny Chen712a6282011-10-17 18:58:00 +0000252 s->Printf("\n declare @ '%s'", m_decl_str.c_str());
Johnny Chen116a5cd2012-02-25 06:44:30 +0000253 if (!m_watch_spec_str.empty())
Johnny Chen9e985592012-08-13 21:09:54 +0000254 s->Printf("\n watchpoint spec = '%s'", m_watch_spec_str.c_str());
255
256 // Dump the snapshots we have taken.
Johnny Chenc9c2a9b2012-08-13 23:27:50 +0000257 DumpSnapshots(s, " ");
Johnny Chen9e985592012-08-13 21:09:54 +0000258
Johnny Chen712a6282011-10-17 18:58:00 +0000259 if (GetConditionText())
260 s->Printf("\n condition = '%s'", GetConditionText());
Johnny Chenf3ec4612012-08-09 23:09:42 +0000261 m_options.GetCallbackDescription(s, description_level);
Johnny Chen712a6282011-10-17 18:58:00 +0000262 }
Johnny Chen10b12b32011-09-16 21:41:42 +0000263
264 if (description_level >= lldb::eDescriptionLevelVerbose)
Jason Molendaa4a15872012-02-23 22:32:13 +0000265 {
Johnny Chenf3ec4612012-08-09 23:09:42 +0000266 s->Printf("\n hw_index = %i hit_count = %-4u ignore_count = %-4u",
267 GetHardwareIndex(),
268 GetHitCount(),
269 GetIgnoreCount());
Jason Molendaa4a15872012-02-23 22:32:13 +0000270 }
Chris Lattner24943d22010-06-08 16:52:24 +0000271}
272
273bool
Johnny Chenecd4feb2011-10-14 00:42:25 +0000274Watchpoint::IsEnabled() const
Chris Lattner24943d22010-06-08 16:52:24 +0000275{
276 return m_enabled;
277}
278
Johnny Chenf84e5662012-08-21 23:17:04 +0000279// Within StopInfo.cpp, we purposely turn on the ephemeral mode right before temporarily disable the watchpoint
280// in order to perform possible watchpoint actions without triggering further watchpoint events.
281// After the temporary disabled watchpoint is enabled, we then turn off the ephemeral mode.
282
283void
284Watchpoint::TurnOnEphemeralMode()
285{
286 m_is_ephemeral = true;
287}
288
289void
290Watchpoint::TurnOffEphemeralMode()
291{
292 m_is_ephemeral = false;
Johnny Chen258db3a2012-08-23 22:28:26 +0000293 // Leaving ephemeral mode, reset the m_disabled_count!
294 m_disabled_count = 0;
295}
296
297bool
298Watchpoint::IsDisabledDuringEphemeralMode()
299{
300 return m_disabled_count > 1;
Johnny Chenf84e5662012-08-21 23:17:04 +0000301}
302
Chris Lattner24943d22010-06-08 16:52:24 +0000303void
Jim Ingham9c970a32012-12-18 02:03:49 +0000304Watchpoint::SetEnabled(bool enabled, bool notify)
Chris Lattner24943d22010-06-08 16:52:24 +0000305{
306 if (!enabled)
Johnny Chenc9c2a9b2012-08-13 23:27:50 +0000307 {
Johnny Chenf84e5662012-08-21 23:17:04 +0000308 if (!m_is_ephemeral)
309 SetHardwareIndex(LLDB_INVALID_INDEX32);
Johnny Chen258db3a2012-08-23 22:28:26 +0000310 else
311 ++m_disabled_count;
312
Johnny Chenbd446f12012-08-21 22:06:34 +0000313 // Don't clear the snapshots for now.
314 // Within StopInfo.cpp, we purposely do disable/enable watchpoint while performing watchpoint actions.
Johnny Chenc9c2a9b2012-08-13 23:27:50 +0000315 }
Jim Ingham9c970a32012-12-18 02:03:49 +0000316 bool changed = enabled != m_enabled;
Chris Lattner24943d22010-06-08 16:52:24 +0000317 m_enabled = enabled;
Jim Ingham9c970a32012-12-18 02:03:49 +0000318 if (notify && !m_is_ephemeral && changed)
319 SendWatchpointChangedEvent (enabled ? eWatchpointEventTypeEnabled : eWatchpointEventTypeDisabled);
Chris Lattner24943d22010-06-08 16:52:24 +0000320}
321
322void
Jim Ingham9c970a32012-12-18 02:03:49 +0000323Watchpoint::SetWatchpointType (uint32_t type, bool notify)
Chris Lattner24943d22010-06-08 16:52:24 +0000324{
Jim Ingham9c970a32012-12-18 02:03:49 +0000325 int old_watch_read = m_watch_read;
326 int old_watch_write = m_watch_write;
Chris Lattner24943d22010-06-08 16:52:24 +0000327 m_watch_read = (type & LLDB_WATCH_TYPE_READ) != 0;
328 m_watch_write = (type & LLDB_WATCH_TYPE_WRITE) != 0;
Jim Ingham9c970a32012-12-18 02:03:49 +0000329 if (notify && (old_watch_read != m_watch_read || old_watch_write != m_watch_write))
330 SendWatchpointChangedEvent (eWatchpointEventTypeTypeChanged);
Chris Lattner24943d22010-06-08 16:52:24 +0000331}
332
333bool
Johnny Chenecd4feb2011-10-14 00:42:25 +0000334Watchpoint::WatchpointRead () const
Chris Lattner24943d22010-06-08 16:52:24 +0000335{
336 return m_watch_read != 0;
337}
338bool
Johnny Chenecd4feb2011-10-14 00:42:25 +0000339Watchpoint::WatchpointWrite () const
Chris Lattner24943d22010-06-08 16:52:24 +0000340{
341 return m_watch_write != 0;
342}
Greg Clayton54e7afa2010-07-09 20:39:50 +0000343uint32_t
Johnny Chenecd4feb2011-10-14 00:42:25 +0000344Watchpoint::GetIgnoreCount () const
Chris Lattner24943d22010-06-08 16:52:24 +0000345{
346 return m_ignore_count;
347}
348
349void
Johnny Chenecd4feb2011-10-14 00:42:25 +0000350Watchpoint::SetIgnoreCount (uint32_t n)
Chris Lattner24943d22010-06-08 16:52:24 +0000351{
Jim Ingham9c970a32012-12-18 02:03:49 +0000352 bool changed = m_ignore_count != n;
Chris Lattner24943d22010-06-08 16:52:24 +0000353 m_ignore_count = n;
Jim Ingham9c970a32012-12-18 02:03:49 +0000354 if (changed)
355 SendWatchpointChangedEvent (eWatchpointEventTypeIgnoreChanged);
Chris Lattner24943d22010-06-08 16:52:24 +0000356}
Johnny Chen712a6282011-10-17 18:58:00 +0000357
358bool
359Watchpoint::InvokeCallback (StoppointCallbackContext *context)
360{
Johnny Chenf3ec4612012-08-09 23:09:42 +0000361 return m_options.InvokeCallback (context, GetID());
Johnny Chen712a6282011-10-17 18:58:00 +0000362}
363
364void
365Watchpoint::SetCondition (const char *condition)
366{
367 if (condition == NULL || condition[0] == '\0')
368 {
369 if (m_condition_ap.get())
370 m_condition_ap.reset();
371 }
372 else
373 {
374 // Pass NULL for expr_prefix (no translation-unit level definitions).
Sean Callanandaa6efe2011-12-21 22:22:58 +0000375 m_condition_ap.reset(new ClangUserExpression (condition, NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
Johnny Chen712a6282011-10-17 18:58:00 +0000376 }
Jim Ingham9c970a32012-12-18 02:03:49 +0000377 SendWatchpointChangedEvent (eWatchpointEventTypeConditionChanged);
Johnny Chen712a6282011-10-17 18:58:00 +0000378}
379
380const char *
381Watchpoint::GetConditionText () const
382{
383 if (m_condition_ap.get())
384 return m_condition_ap->GetUserText();
385 else
386 return NULL;
387}
388
Jim Ingham9c970a32012-12-18 02:03:49 +0000389void
390Watchpoint::SendWatchpointChangedEvent (lldb::WatchpointEventType eventKind)
391{
392 if (!m_being_created
393 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitWatchpointChanged))
394 {
395 WatchpointEventData *data = new Watchpoint::WatchpointEventData (eventKind, shared_from_this());
396 GetTarget().BroadcastEvent (Target::eBroadcastBitWatchpointChanged, data);
397 }
398}
399
400void
401Watchpoint::SendWatchpointChangedEvent (WatchpointEventData *data)
402{
403
404 if (data == NULL)
405 return;
406
407 if (!m_being_created
408 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitWatchpointChanged))
409 GetTarget().BroadcastEvent (Target::eBroadcastBitWatchpointChanged, data);
410 else
411 delete data;
412}
413
414Watchpoint::WatchpointEventData::WatchpointEventData (WatchpointEventType sub_type,
415 const WatchpointSP &new_watchpoint_sp) :
416 EventData (),
417 m_watchpoint_event (sub_type),
418 m_new_watchpoint_sp (new_watchpoint_sp)
419{
420}
421
422Watchpoint::WatchpointEventData::~WatchpointEventData ()
423{
424}
425
426const ConstString &
427Watchpoint::WatchpointEventData::GetFlavorString ()
428{
429 static ConstString g_flavor ("Watchpoint::WatchpointEventData");
430 return g_flavor;
431}
432
433const ConstString &
434Watchpoint::WatchpointEventData::GetFlavor () const
435{
436 return WatchpointEventData::GetFlavorString ();
437}
438
439
440WatchpointSP &
441Watchpoint::WatchpointEventData::GetWatchpoint ()
442{
443 return m_new_watchpoint_sp;
444}
445
446WatchpointEventType
447Watchpoint::WatchpointEventData::GetWatchpointEventType () const
448{
449 return m_watchpoint_event;
450}
451
452void
453Watchpoint::WatchpointEventData::Dump (Stream *s) const
454{
455}
456
457const Watchpoint::WatchpointEventData *
458Watchpoint::WatchpointEventData::GetEventDataFromEvent (const Event *event)
459{
460 if (event)
461 {
462 const EventData *event_data = event->GetData();
463 if (event_data && event_data->GetFlavor() == WatchpointEventData::GetFlavorString())
464 return static_cast <const WatchpointEventData *> (event->GetData());
465 }
466 return NULL;
467}
468
469WatchpointEventType
470Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent (const EventSP &event_sp)
471{
472 const WatchpointEventData *data = GetEventDataFromEvent (event_sp.get());
473
474 if (data == NULL)
475 return eWatchpointEventTypeInvalidType;
476 else
477 return data->GetWatchpointEventType();
478}
479
480WatchpointSP
481Watchpoint::WatchpointEventData::GetWatchpointFromEvent (const EventSP &event_sp)
482{
483 WatchpointSP wp_sp;
484
485 const WatchpointEventData *data = GetEventDataFromEvent (event_sp.get());
486 if (data)
487 wp_sp = data->m_new_watchpoint_sp;
488
489 return wp_sp;
490}