1 //===-- SBBreakpoint.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/API/SBBreakpoint.h"
11 #include "lldb/API/SBBreakpointLocation.h"
12 #include "lldb/API/SBDebugger.h"
13 #include "lldb/API/SBEvent.h"
14 #include "lldb/API/SBProcess.h"
15 #include "lldb/API/SBStream.h"
16 #include "lldb/API/SBThread.h"
17 
18 #include "lldb/Breakpoint/Breakpoint.h"
19 #include "lldb/Breakpoint/BreakpointLocation.h"
20 #include "lldb/Breakpoint/StoppointCallbackContext.h"
21 #include "lldb/Core/Address.h"
22 #include "lldb/Core/Debugger.h"
23 #include "lldb/Core/Log.h"
24 #include "lldb/Core/Stream.h"
25 #include "lldb/Core/StreamFile.h"
26 #include "lldb/Interpreter/CommandInterpreter.h"
27 #include "lldb/Interpreter/ScriptInterpreter.h"
28 #include "lldb/Target/Process.h"
29 #include "lldb/Target/SectionLoadList.h"
30 #include "lldb/Target/Target.h"
31 #include "lldb/Target/Thread.h"
32 #include "lldb/Target/ThreadSpec.h"
33 
34 
35 #include "lldb/lldb-enumerations.h"
36 
37 using namespace lldb;
38 using namespace lldb_private;
39 
40 struct CallbackData
41 {
42     SBBreakpoint::BreakpointHitCallback callback;
43     void *callback_baton;
44 };
45 
46 class SBBreakpointCallbackBaton : public Baton
47 {
48 public:
49 
50     SBBreakpointCallbackBaton (SBBreakpoint::BreakpointHitCallback callback, void *baton) :
51         Baton (new CallbackData)
52     {
53         CallbackData *data = (CallbackData *)m_data;
54         data->callback = callback;
55         data->callback_baton = baton;
56     }
57 
58     virtual ~SBBreakpointCallbackBaton()
59     {
60         CallbackData *data = (CallbackData *)m_data;
61 
62         if (data)
63         {
64             delete data;
65             m_data = NULL;
66         }
67     }
68 };
69 
70 
71 SBBreakpoint::SBBreakpoint () :
72     m_opaque_sp ()
73 {
74 }
75 
76 SBBreakpoint::SBBreakpoint (const SBBreakpoint& rhs) :
77     m_opaque_sp (rhs.m_opaque_sp)
78 {
79 }
80 
81 
82 SBBreakpoint::SBBreakpoint (const lldb::BreakpointSP &bp_sp) :
83     m_opaque_sp (bp_sp)
84 {
85 }
86 
87 SBBreakpoint::~SBBreakpoint()
88 {
89 }
90 
91 const SBBreakpoint &
92 SBBreakpoint::operator = (const SBBreakpoint& rhs)
93 {
94     if (this != &rhs)
95         m_opaque_sp = rhs.m_opaque_sp;
96     return *this;
97 }
98 
99 bool
100 SBBreakpoint::operator == (const lldb::SBBreakpoint& rhs)
101 {
102     if (m_opaque_sp && rhs.m_opaque_sp)
103         return m_opaque_sp.get() == rhs.m_opaque_sp.get();
104     return false;
105 }
106 
107 bool
108 SBBreakpoint::operator != (const lldb::SBBreakpoint& rhs)
109 {
110     if (m_opaque_sp && rhs.m_opaque_sp)
111         return m_opaque_sp.get() != rhs.m_opaque_sp.get();
112     return (m_opaque_sp && !rhs.m_opaque_sp) || (rhs.m_opaque_sp && !m_opaque_sp);
113 }
114 
115 break_id_t
116 SBBreakpoint::GetID () const
117 {
118     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
119 
120     break_id_t break_id = LLDB_INVALID_BREAK_ID;
121     if (m_opaque_sp)
122         break_id = m_opaque_sp->GetID();
123 
124     if (log)
125     {
126         if (break_id == LLDB_INVALID_BREAK_ID)
127             log->Printf ("SBBreakpoint(%p)::GetID () => LLDB_INVALID_BREAK_ID",
128                          static_cast<void*>(m_opaque_sp.get()));
129         else
130             log->Printf ("SBBreakpoint(%p)::GetID () => %u",
131                          static_cast<void*>(m_opaque_sp.get()), break_id);
132     }
133 
134     return break_id;
135 }
136 
137 
138 bool
139 SBBreakpoint::IsValid() const
140 {
141     if (!m_opaque_sp)
142         return false;
143     else if (m_opaque_sp->GetTarget().GetBreakpointByID(m_opaque_sp->GetID()))
144        return true;
145     else
146         return false;
147 }
148 
149 void
150 SBBreakpoint::ClearAllBreakpointSites ()
151 {
152     if (m_opaque_sp)
153     {
154         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
155         m_opaque_sp->ClearAllBreakpointSites ();
156     }
157 }
158 
159 SBBreakpointLocation
160 SBBreakpoint::FindLocationByAddress (addr_t vm_addr)
161 {
162     SBBreakpointLocation sb_bp_location;
163 
164     if (m_opaque_sp)
165     {
166         if (vm_addr != LLDB_INVALID_ADDRESS)
167         {
168             Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
169             Address address;
170             Target &target = m_opaque_sp->GetTarget();
171             if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false)
172             {
173                 address.SetRawAddress (vm_addr);
174             }
175             sb_bp_location.SetLocation (m_opaque_sp->FindLocationByAddress (address));
176         }
177     }
178     return sb_bp_location;
179 }
180 
181 break_id_t
182 SBBreakpoint::FindLocationIDByAddress (addr_t vm_addr)
183 {
184     break_id_t break_id = LLDB_INVALID_BREAK_ID;
185 
186     if (m_opaque_sp && vm_addr != LLDB_INVALID_ADDRESS)
187     {
188         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
189         Address address;
190         Target &target = m_opaque_sp->GetTarget();
191         if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false)
192         {
193             address.SetRawAddress (vm_addr);
194         }
195         break_id = m_opaque_sp->FindLocationIDByAddress (address);
196     }
197 
198     return break_id;
199 }
200 
201 SBBreakpointLocation
202 SBBreakpoint::FindLocationByID (break_id_t bp_loc_id)
203 {
204     SBBreakpointLocation sb_bp_location;
205 
206     if (m_opaque_sp)
207     {
208         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
209         sb_bp_location.SetLocation (m_opaque_sp->FindLocationByID (bp_loc_id));
210     }
211 
212     return sb_bp_location;
213 }
214 
215 SBBreakpointLocation
216 SBBreakpoint::GetLocationAtIndex (uint32_t index)
217 {
218     SBBreakpointLocation sb_bp_location;
219 
220     if (m_opaque_sp)
221     {
222         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
223         sb_bp_location.SetLocation (m_opaque_sp->GetLocationAtIndex (index));
224     }
225 
226     return sb_bp_location;
227 }
228 
229 void
230 SBBreakpoint::SetEnabled (bool enable)
231 {
232     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
233 
234     if (log)
235         log->Printf ("SBBreakpoint(%p)::SetEnabled (enabled=%i)",
236                      static_cast<void*>(m_opaque_sp.get()), enable);
237 
238     if (m_opaque_sp)
239     {
240         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
241         m_opaque_sp->SetEnabled (enable);
242     }
243 }
244 
245 bool
246 SBBreakpoint::IsEnabled ()
247 {
248     if (m_opaque_sp)
249     {
250         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
251         return m_opaque_sp->IsEnabled();
252     }
253     else
254         return false;
255 }
256 
257 void
258 SBBreakpoint::SetOneShot (bool one_shot)
259 {
260     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
261 
262     if (log)
263         log->Printf ("SBBreakpoint(%p)::SetOneShot (one_shot=%i)",
264                      static_cast<void*>(m_opaque_sp.get()), one_shot);
265 
266     if (m_opaque_sp)
267     {
268         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
269         m_opaque_sp->SetOneShot (one_shot);
270     }
271 }
272 
273 bool
274 SBBreakpoint::IsOneShot () const
275 {
276     if (m_opaque_sp)
277     {
278         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
279         return m_opaque_sp->IsOneShot();
280     }
281     else
282         return false;
283 }
284 
285 bool
286 SBBreakpoint::IsInternal ()
287 {
288     if (m_opaque_sp)
289     {
290         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
291         return m_opaque_sp->IsInternal();
292     }
293     else
294         return false;
295 }
296 
297 void
298 SBBreakpoint::SetIgnoreCount (uint32_t count)
299 {
300     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
301 
302     if (log)
303         log->Printf ("SBBreakpoint(%p)::SetIgnoreCount (count=%u)",
304                      static_cast<void*>(m_opaque_sp.get()), count);
305 
306     if (m_opaque_sp)
307     {
308         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
309         m_opaque_sp->SetIgnoreCount (count);
310     }
311 }
312 
313 void
314 SBBreakpoint::SetCondition (const char *condition)
315 {
316     if (m_opaque_sp)
317     {
318         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
319         m_opaque_sp->SetCondition (condition);
320     }
321 }
322 
323 const char *
324 SBBreakpoint::GetCondition ()
325 {
326     if (m_opaque_sp)
327     {
328         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
329         return m_opaque_sp->GetConditionText ();
330     }
331     return NULL;
332 }
333 
334 uint32_t
335 SBBreakpoint::GetHitCount () const
336 {
337     uint32_t count = 0;
338     if (m_opaque_sp)
339     {
340         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
341         count = m_opaque_sp->GetHitCount();
342     }
343 
344     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
345     if (log)
346         log->Printf ("SBBreakpoint(%p)::GetHitCount () => %u",
347                      static_cast<void*>(m_opaque_sp.get()), count);
348 
349     return count;
350 }
351 
352 uint32_t
353 SBBreakpoint::GetIgnoreCount () const
354 {
355     uint32_t count = 0;
356     if (m_opaque_sp)
357     {
358         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
359         count = m_opaque_sp->GetIgnoreCount();
360     }
361 
362     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
363     if (log)
364         log->Printf ("SBBreakpoint(%p)::GetIgnoreCount () => %u",
365                      static_cast<void*>(m_opaque_sp.get()), count);
366 
367     return count;
368 }
369 
370 void
371 SBBreakpoint::SetThreadID (tid_t tid)
372 {
373     if (m_opaque_sp)
374     {
375         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
376         m_opaque_sp->SetThreadID (tid);
377     }
378     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
379     if (log)
380         log->Printf ("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")",
381                      static_cast<void*>(m_opaque_sp.get()), tid);
382 
383 }
384 
385 tid_t
386 SBBreakpoint::GetThreadID ()
387 {
388     tid_t tid = LLDB_INVALID_THREAD_ID;
389     if (m_opaque_sp)
390     {
391         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
392         tid = m_opaque_sp->GetThreadID();
393     }
394 
395     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
396     if (log)
397         log->Printf ("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64,
398                      static_cast<void*>(m_opaque_sp.get()), tid);
399     return tid;
400 }
401 
402 void
403 SBBreakpoint::SetThreadIndex (uint32_t index)
404 {
405     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
406     if (log)
407         log->Printf ("SBBreakpoint(%p)::SetThreadIndex (%u)",
408                      static_cast<void*>(m_opaque_sp.get()), index);
409     if (m_opaque_sp)
410     {
411         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
412         m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex (index);
413     }
414 }
415 
416 uint32_t
417 SBBreakpoint::GetThreadIndex() const
418 {
419     uint32_t thread_idx = UINT32_MAX;
420     if (m_opaque_sp)
421     {
422         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
423         const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
424         if (thread_spec != NULL)
425             thread_idx = thread_spec->GetIndex();
426     }
427     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
428     if (log)
429         log->Printf ("SBBreakpoint(%p)::GetThreadIndex () => %u",
430                      static_cast<void*>(m_opaque_sp.get()), thread_idx);
431 
432     return thread_idx;
433 }
434 
435 void
436 SBBreakpoint::SetThreadName (const char *thread_name)
437 {
438     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
439     if (log)
440         log->Printf ("SBBreakpoint(%p)::SetThreadName (%s)",
441                      static_cast<void*>(m_opaque_sp.get()), thread_name);
442 
443     if (m_opaque_sp)
444     {
445         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
446         m_opaque_sp->GetOptions()->GetThreadSpec()->SetName (thread_name);
447     }
448 }
449 
450 const char *
451 SBBreakpoint::GetThreadName () const
452 {
453     const char *name = NULL;
454     if (m_opaque_sp)
455     {
456         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
457         const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
458         if (thread_spec != NULL)
459             name = thread_spec->GetName();
460     }
461     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
462     if (log)
463         log->Printf ("SBBreakpoint(%p)::GetThreadName () => %s",
464                      static_cast<void*>(m_opaque_sp.get()), name);
465 
466     return name;
467 }
468 
469 void
470 SBBreakpoint::SetQueueName (const char *queue_name)
471 {
472     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
473     if (log)
474         log->Printf ("SBBreakpoint(%p)::SetQueueName (%s)",
475                      static_cast<void*>(m_opaque_sp.get()), queue_name);
476     if (m_opaque_sp)
477     {
478         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
479         m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName (queue_name);
480     }
481 }
482 
483 const char *
484 SBBreakpoint::GetQueueName () const
485 {
486     const char *name = NULL;
487     if (m_opaque_sp)
488     {
489         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
490         const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
491         if (thread_spec)
492             name = thread_spec->GetQueueName();
493     }
494     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
495     if (log)
496         log->Printf ("SBBreakpoint(%p)::GetQueueName () => %s",
497                      static_cast<void*>(m_opaque_sp.get()), name);
498 
499     return name;
500 }
501 
502 size_t
503 SBBreakpoint::GetNumResolvedLocations() const
504 {
505     size_t num_resolved = 0;
506     if (m_opaque_sp)
507     {
508         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
509         num_resolved = m_opaque_sp->GetNumResolvedLocations();
510     }
511     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
512     if (log)
513         log->Printf ("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64,
514                      static_cast<void*>(m_opaque_sp.get()),
515                      static_cast<uint64_t>(num_resolved));
516     return num_resolved;
517 }
518 
519 size_t
520 SBBreakpoint::GetNumLocations() const
521 {
522     size_t num_locs = 0;
523     if (m_opaque_sp)
524     {
525         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
526         num_locs = m_opaque_sp->GetNumLocations();
527     }
528     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
529     if (log)
530         log->Printf ("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64,
531                      static_cast<void*>(m_opaque_sp.get()),
532                      static_cast<uint64_t>(num_locs));
533     return num_locs;
534 }
535 
536 bool
537 SBBreakpoint::GetDescription (SBStream &s)
538 {
539     if (m_opaque_sp)
540     {
541         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
542         s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
543         m_opaque_sp->GetResolverDescription (s.get());
544         m_opaque_sp->GetFilterDescription (s.get());
545         const size_t num_locations = m_opaque_sp->GetNumLocations ();
546         s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
547         return true;
548     }
549     s.Printf ("No value");
550     return false;
551 }
552 
553 bool
554 SBBreakpoint::PrivateBreakpointHitCallback
555 (
556     void *baton,
557     StoppointCallbackContext *ctx,
558     lldb::user_id_t break_id,
559     lldb::user_id_t break_loc_id
560 )
561 {
562     ExecutionContext exe_ctx (ctx->exe_ctx_ref);
563     BreakpointSP bp_sp(exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
564     if (baton && bp_sp)
565     {
566         CallbackData *data = (CallbackData *)baton;
567         lldb_private::Breakpoint *bp = bp_sp.get();
568         if (bp && data->callback)
569         {
570             Process *process = exe_ctx.GetProcessPtr();
571             if (process)
572             {
573                 SBProcess sb_process (process->shared_from_this());
574                 SBThread sb_thread;
575                 SBBreakpointLocation sb_location;
576                 assert (bp_sp);
577                 sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id));
578                 Thread *thread = exe_ctx.GetThreadPtr();
579                 if (thread)
580                     sb_thread.SetThread(thread->shared_from_this());
581 
582                 return data->callback (data->callback_baton,
583                                           sb_process,
584                                           sb_thread,
585                                           sb_location);
586             }
587         }
588     }
589     return true;    // Return true if we should stop at this breakpoint
590 }
591 
592 void
593 SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton)
594 {
595     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
596 
597     if (log)
598     {
599         void *pointer = &callback;
600         log->Printf ("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)",
601                      static_cast<void*>(m_opaque_sp.get()),
602                      *static_cast<void**>(&pointer), static_cast<void*>(baton));
603     }
604 
605     if (m_opaque_sp)
606     {
607         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
608         BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton));
609         m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false);
610     }
611 }
612 
613 void
614 SBBreakpoint::SetScriptCallbackFunction (const char *callback_function_name)
615 {
616     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
617 
618     if (log)
619         log->Printf ("SBBreakpoint(%p)::SetScriptCallbackFunction (callback=%s)",
620                      static_cast<void*>(m_opaque_sp.get()),
621                      callback_function_name);
622 
623     if (m_opaque_sp)
624     {
625         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
626         BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
627         m_opaque_sp->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallbackFunction (bp_options,
628                                                                                                                                                    callback_function_name);
629     }
630 }
631 
632 SBError
633 SBBreakpoint::SetScriptCallbackBody (const char *callback_body_text)
634 {
635     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
636 
637     if (log)
638         log->Printf ("SBBreakpoint(%p)::SetScriptCallbackBody: callback body:\n%s)",
639                      static_cast<void*>(m_opaque_sp.get()), callback_body_text);
640 
641     SBError sb_error;
642     if (m_opaque_sp)
643     {
644         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
645         BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
646         Error error =  m_opaque_sp->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options,
647                                                                                                                                     callback_body_text);
648         sb_error.SetError(error);
649     }
650     else
651         sb_error.SetErrorString("invalid breakpoint");
652 
653     return sb_error;
654 }
655 
656 lldb_private::Breakpoint *
657 SBBreakpoint::operator->() const
658 {
659     return m_opaque_sp.get();
660 }
661 
662 lldb_private::Breakpoint *
663 SBBreakpoint::get() const
664 {
665     return m_opaque_sp.get();
666 }
667 
668 lldb::BreakpointSP &
669 SBBreakpoint::operator *()
670 {
671     return m_opaque_sp;
672 }
673 
674 const lldb::BreakpointSP &
675 SBBreakpoint::operator *() const
676 {
677     return m_opaque_sp;
678 }
679 
680 bool
681 SBBreakpoint::EventIsBreakpointEvent (const lldb::SBEvent &event)
682 {
683     return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) != NULL;
684 
685 }
686 
687 BreakpointEventType
688 SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event)
689 {
690     if (event.IsValid())
691         return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event.GetSP());
692     return eBreakpointEventTypeInvalidType;
693 }
694 
695 SBBreakpoint
696 SBBreakpoint::GetBreakpointFromEvent (const lldb::SBEvent& event)
697 {
698     SBBreakpoint sb_breakpoint;
699     if (event.IsValid())
700         sb_breakpoint.m_opaque_sp = Breakpoint::BreakpointEventData::GetBreakpointFromEvent (event.GetSP());
701     return sb_breakpoint;
702 }
703 
704 SBBreakpointLocation
705 SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx)
706 {
707     SBBreakpointLocation sb_breakpoint_loc;
708     if (event.IsValid())
709         sb_breakpoint_loc.SetLocation (Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (event.GetSP(), loc_idx));
710     return sb_breakpoint_loc;
711 }
712 
713 uint32_t
714 SBBreakpoint::GetNumBreakpointLocationsFromEvent (const lldb::SBEvent &event)
715 {
716     uint32_t num_locations = 0;
717     if (event.IsValid())
718         num_locations = (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (event.GetSP()));
719     return num_locations;
720 }
721 
722 
723