1254721Semaste//===-- Breakpoint.cpp ------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste
11254721Semaste// C Includes
12254721Semaste// C++ Includes
13254721Semaste// Other libraries and framework includes
14254721Semaste// Project includes
15254721Semaste
16254721Semaste#include "lldb/Core/Address.h"
17254721Semaste#include "lldb/Breakpoint/Breakpoint.h"
18254721Semaste#include "lldb/Breakpoint/BreakpointLocation.h"
19254721Semaste#include "lldb/Breakpoint/BreakpointLocationCollection.h"
20254721Semaste#include "lldb/Breakpoint/BreakpointResolver.h"
21254721Semaste#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
22254721Semaste#include "lldb/Core/Log.h"
23254721Semaste#include "lldb/Core/ModuleList.h"
24254721Semaste#include "lldb/Core/SearchFilter.h"
25254721Semaste#include "lldb/Core/Section.h"
26254721Semaste#include "lldb/Core/Stream.h"
27254721Semaste#include "lldb/Core/StreamString.h"
28254721Semaste#include "lldb/Symbol/SymbolContext.h"
29254721Semaste#include "lldb/Target/Target.h"
30254721Semaste#include "lldb/Target/ThreadSpec.h"
31254721Semaste#include "lldb/lldb-private-log.h"
32254721Semaste#include "llvm/Support/Casting.h"
33254721Semaste
34254721Semasteusing namespace lldb;
35254721Semasteusing namespace lldb_private;
36254721Semasteusing namespace llvm;
37254721Semaste
38254721Semasteconst ConstString &
39254721SemasteBreakpoint::GetEventIdentifier ()
40254721Semaste{
41254721Semaste    static ConstString g_identifier("event-identifier.breakpoint.changed");
42254721Semaste    return g_identifier;
43254721Semaste}
44254721Semaste
45254721Semaste//----------------------------------------------------------------------
46254721Semaste// Breakpoint constructor
47254721Semaste//----------------------------------------------------------------------
48254721SemasteBreakpoint::Breakpoint(Target &target, SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp) :
49254721Semaste    m_being_created(true),
50254721Semaste    m_target (target),
51254721Semaste    m_filter_sp (filter_sp),
52254721Semaste    m_resolver_sp (resolver_sp),
53254721Semaste    m_options (),
54254721Semaste    m_locations (*this)
55254721Semaste{
56254721Semaste    m_being_created = false;
57254721Semaste}
58254721Semaste
59254721Semaste//----------------------------------------------------------------------
60254721Semaste// Destructor
61254721Semaste//----------------------------------------------------------------------
62254721SemasteBreakpoint::~Breakpoint()
63254721Semaste{
64254721Semaste}
65254721Semaste
66254721Semastebool
67254721SemasteBreakpoint::IsInternal () const
68254721Semaste{
69254721Semaste    return LLDB_BREAK_ID_IS_INTERNAL(m_bid);
70254721Semaste}
71254721Semaste
72254721Semaste
73254721Semaste
74254721SemasteTarget&
75254721SemasteBreakpoint::GetTarget ()
76254721Semaste{
77254721Semaste    return m_target;
78254721Semaste}
79254721Semaste
80254721Semasteconst Target&
81254721SemasteBreakpoint::GetTarget () const
82254721Semaste{
83254721Semaste    return m_target;
84254721Semaste}
85254721Semaste
86254721SemasteBreakpointLocationSP
87254721SemasteBreakpoint::AddLocation (const Address &addr, bool *new_location)
88254721Semaste{
89254721Semaste    return m_locations.AddLocation (addr, new_location);
90254721Semaste}
91254721Semaste
92254721SemasteBreakpointLocationSP
93254721SemasteBreakpoint::FindLocationByAddress (const Address &addr)
94254721Semaste{
95254721Semaste    return m_locations.FindByAddress(addr);
96254721Semaste}
97254721Semaste
98254721Semastebreak_id_t
99254721SemasteBreakpoint::FindLocationIDByAddress (const Address &addr)
100254721Semaste{
101254721Semaste    return m_locations.FindIDByAddress(addr);
102254721Semaste}
103254721Semaste
104254721SemasteBreakpointLocationSP
105254721SemasteBreakpoint::FindLocationByID (break_id_t bp_loc_id)
106254721Semaste{
107254721Semaste    return m_locations.FindByID(bp_loc_id);
108254721Semaste}
109254721Semaste
110254721SemasteBreakpointLocationSP
111254721SemasteBreakpoint::GetLocationAtIndex (size_t index)
112254721Semaste{
113254721Semaste    return m_locations.GetByIndex(index);
114254721Semaste}
115254721Semaste
116254721Semaste// For each of the overall options we need to decide how they propagate to
117254721Semaste// the location options.  This will determine the precedence of options on
118254721Semaste// the breakpoint vs. its locations.
119254721Semaste
120254721Semaste// Disable at the breakpoint level should override the location settings.
121254721Semaste// That way you can conveniently turn off a whole breakpoint without messing
122254721Semaste// up the individual settings.
123254721Semaste
124254721Semastevoid
125254721SemasteBreakpoint::SetEnabled (bool enable)
126254721Semaste{
127254721Semaste    if (enable == m_options.IsEnabled())
128254721Semaste        return;
129254721Semaste
130254721Semaste    m_options.SetEnabled(enable);
131254721Semaste    if (enable)
132254721Semaste        m_locations.ResolveAllBreakpointSites();
133254721Semaste    else
134254721Semaste        m_locations.ClearAllBreakpointSites();
135254721Semaste
136254721Semaste    SendBreakpointChangedEvent (enable ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
137254721Semaste
138254721Semaste}
139254721Semaste
140254721Semastebool
141254721SemasteBreakpoint::IsEnabled ()
142254721Semaste{
143254721Semaste    return m_options.IsEnabled();
144254721Semaste}
145254721Semaste
146254721Semastevoid
147254721SemasteBreakpoint::SetIgnoreCount (uint32_t n)
148254721Semaste{
149254721Semaste    if (m_options.GetIgnoreCount() == n)
150254721Semaste        return;
151254721Semaste
152254721Semaste    m_options.SetIgnoreCount(n);
153254721Semaste    SendBreakpointChangedEvent (eBreakpointEventTypeIgnoreChanged);
154254721Semaste}
155254721Semaste
156254721Semastevoid
157254721SemasteBreakpoint::DecrementIgnoreCount ()
158254721Semaste{
159254721Semaste    uint32_t ignore = m_options.GetIgnoreCount();
160254721Semaste    if (ignore != 0)
161254721Semaste        m_options.SetIgnoreCount(ignore - 1);
162254721Semaste}
163254721Semaste
164254721Semasteuint32_t
165254721SemasteBreakpoint::GetIgnoreCount () const
166254721Semaste{
167254721Semaste    return m_options.GetIgnoreCount();
168254721Semaste}
169254721Semaste
170254721Semastebool
171254721SemasteBreakpoint::IgnoreCountShouldStop ()
172254721Semaste{
173254721Semaste    uint32_t ignore = GetIgnoreCount();
174254721Semaste    if (ignore != 0)
175254721Semaste    {
176254721Semaste        // When we get here we know the location that caused the stop doesn't have an ignore count,
177254721Semaste        // since by contract we call it first...  So we don't have to find & decrement it, we only have
178254721Semaste        // to decrement our own ignore count.
179254721Semaste        DecrementIgnoreCount();
180254721Semaste        return false;
181254721Semaste    }
182254721Semaste    else
183254721Semaste        return true;
184254721Semaste}
185254721Semaste
186254721Semasteuint32_t
187254721SemasteBreakpoint::GetHitCount () const
188254721Semaste{
189254721Semaste    return m_locations.GetHitCount();
190254721Semaste}
191254721Semaste
192254721Semastebool
193254721SemasteBreakpoint::IsOneShot () const
194254721Semaste{
195254721Semaste    return m_options.IsOneShot();
196254721Semaste}
197254721Semaste
198254721Semastevoid
199254721SemasteBreakpoint::SetOneShot (bool one_shot)
200254721Semaste{
201254721Semaste    m_options.SetOneShot (one_shot);
202254721Semaste}
203254721Semaste
204254721Semastevoid
205254721SemasteBreakpoint::SetThreadID (lldb::tid_t thread_id)
206254721Semaste{
207254721Semaste    if (m_options.GetThreadSpec()->GetTID() == thread_id)
208254721Semaste        return;
209254721Semaste
210254721Semaste    m_options.GetThreadSpec()->SetTID(thread_id);
211254721Semaste    SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
212254721Semaste}
213254721Semaste
214254721Semastelldb::tid_t
215254721SemasteBreakpoint::GetThreadID () const
216254721Semaste{
217254721Semaste    if (m_options.GetThreadSpecNoCreate() == NULL)
218254721Semaste        return LLDB_INVALID_THREAD_ID;
219254721Semaste    else
220254721Semaste        return m_options.GetThreadSpecNoCreate()->GetTID();
221254721Semaste}
222254721Semaste
223254721Semastevoid
224254721SemasteBreakpoint::SetThreadIndex (uint32_t index)
225254721Semaste{
226254721Semaste    if (m_options.GetThreadSpec()->GetIndex() == index)
227254721Semaste        return;
228254721Semaste
229254721Semaste    m_options.GetThreadSpec()->SetIndex(index);
230254721Semaste    SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
231254721Semaste}
232254721Semaste
233254721Semasteuint32_t
234254721SemasteBreakpoint::GetThreadIndex() const
235254721Semaste{
236254721Semaste    if (m_options.GetThreadSpecNoCreate() == NULL)
237254721Semaste        return 0;
238254721Semaste    else
239254721Semaste        return m_options.GetThreadSpecNoCreate()->GetIndex();
240254721Semaste}
241254721Semaste
242254721Semastevoid
243254721SemasteBreakpoint::SetThreadName (const char *thread_name)
244254721Semaste{
245254721Semaste    if (m_options.GetThreadSpec()->GetName() != NULL
246254721Semaste        && ::strcmp (m_options.GetThreadSpec()->GetName(), thread_name) == 0)
247254721Semaste        return;
248254721Semaste
249254721Semaste    m_options.GetThreadSpec()->SetName (thread_name);
250254721Semaste    SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
251254721Semaste}
252254721Semaste
253254721Semasteconst char *
254254721SemasteBreakpoint::GetThreadName () const
255254721Semaste{
256254721Semaste    if (m_options.GetThreadSpecNoCreate() == NULL)
257254721Semaste        return NULL;
258254721Semaste    else
259254721Semaste        return m_options.GetThreadSpecNoCreate()->GetName();
260254721Semaste}
261254721Semaste
262254721Semastevoid
263254721SemasteBreakpoint::SetQueueName (const char *queue_name)
264254721Semaste{
265254721Semaste    if (m_options.GetThreadSpec()->GetQueueName() != NULL
266254721Semaste        && ::strcmp (m_options.GetThreadSpec()->GetQueueName(), queue_name) == 0)
267254721Semaste        return;
268254721Semaste
269254721Semaste    m_options.GetThreadSpec()->SetQueueName (queue_name);
270254721Semaste    SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
271254721Semaste}
272254721Semaste
273254721Semasteconst char *
274254721SemasteBreakpoint::GetQueueName () const
275254721Semaste{
276254721Semaste    if (m_options.GetThreadSpecNoCreate() == NULL)
277254721Semaste        return NULL;
278254721Semaste    else
279254721Semaste        return m_options.GetThreadSpecNoCreate()->GetQueueName();
280254721Semaste}
281254721Semaste
282254721Semastevoid
283254721SemasteBreakpoint::SetCondition (const char *condition)
284254721Semaste{
285254721Semaste    m_options.SetCondition (condition);
286254721Semaste    SendBreakpointChangedEvent (eBreakpointEventTypeConditionChanged);
287254721Semaste}
288254721Semaste
289254721Semasteconst char *
290254721SemasteBreakpoint::GetConditionText () const
291254721Semaste{
292254721Semaste    return m_options.GetConditionText();
293254721Semaste}
294254721Semaste
295254721Semaste// This function is used when "baton" doesn't need to be freed
296254721Semastevoid
297254721SemasteBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton, bool is_synchronous)
298254721Semaste{
299254721Semaste    // The default "Baton" class will keep a copy of "baton" and won't free
300254721Semaste    // or delete it when it goes goes out of scope.
301254721Semaste    m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
302254721Semaste
303254721Semaste    SendBreakpointChangedEvent (eBreakpointEventTypeCommandChanged);
304254721Semaste}
305254721Semaste
306254721Semaste// This function is used when a baton needs to be freed and therefore is
307254721Semaste// contained in a "Baton" subclass.
308254721Semastevoid
309254721SemasteBreakpoint::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous)
310254721Semaste{
311254721Semaste    m_options.SetCallback(callback, callback_baton_sp, is_synchronous);
312254721Semaste}
313254721Semaste
314254721Semastevoid
315254721SemasteBreakpoint::ClearCallback ()
316254721Semaste{
317254721Semaste    m_options.ClearCallback ();
318254721Semaste}
319254721Semaste
320254721Semastebool
321254721SemasteBreakpoint::InvokeCallback (StoppointCallbackContext *context, break_id_t bp_loc_id)
322254721Semaste{
323254721Semaste    return m_options.InvokeCallback (context, GetID(), bp_loc_id);
324254721Semaste}
325254721Semaste
326254721SemasteBreakpointOptions *
327254721SemasteBreakpoint::GetOptions ()
328254721Semaste{
329254721Semaste    return &m_options;
330254721Semaste}
331254721Semaste
332254721Semastevoid
333254721SemasteBreakpoint::ResolveBreakpoint ()
334254721Semaste{
335254721Semaste    if (m_resolver_sp)
336254721Semaste        m_resolver_sp->ResolveBreakpoint(*m_filter_sp);
337254721Semaste}
338254721Semaste
339254721Semastevoid
340254721SemasteBreakpoint::ResolveBreakpointInModules (ModuleList &module_list)
341254721Semaste{
342254721Semaste    if (m_resolver_sp)
343254721Semaste        m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list);
344254721Semaste}
345254721Semaste
346254721Semastevoid
347254721SemasteBreakpoint::ClearAllBreakpointSites ()
348254721Semaste{
349254721Semaste    m_locations.ClearAllBreakpointSites();
350254721Semaste}
351254721Semaste
352254721Semaste//----------------------------------------------------------------------
353254721Semaste// ModulesChanged: Pass in a list of new modules, and
354254721Semaste//----------------------------------------------------------------------
355254721Semaste
356254721Semastevoid
357254721SemasteBreakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_locations)
358254721Semaste{
359254721Semaste    Mutex::Locker modules_mutex(module_list.GetMutex());
360254721Semaste    if (load)
361254721Semaste    {
362254721Semaste        // The logic for handling new modules is:
363254721Semaste        // 1) If the filter rejects this module, then skip it.
364254721Semaste        // 2) Run through the current location list and if there are any locations
365254721Semaste        //    for that module, we mark the module as "seen" and we don't try to re-resolve
366254721Semaste        //    breakpoint locations for that module.
367254721Semaste        //    However, we do add breakpoint sites to these locations if needed.
368254721Semaste        // 3) If we don't see this module in our breakpoint location list, call ResolveInModules.
369254721Semaste
370254721Semaste        ModuleList new_modules;  // We'll stuff the "unseen" modules in this list, and then resolve
371254721Semaste                                 // them after the locations pass.  Have to do it this way because
372254721Semaste                                 // resolving breakpoints will add new locations potentially.
373254721Semaste
374254721Semaste        const size_t num_locs = m_locations.GetSize();
375254721Semaste        size_t num_modules = module_list.GetSize();
376254721Semaste        for (size_t i = 0; i < num_modules; i++)
377254721Semaste        {
378254721Semaste            bool seen = false;
379254721Semaste            ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i));
380254721Semaste            if (!m_filter_sp->ModulePasses (module_sp))
381254721Semaste                continue;
382254721Semaste
383254721Semaste            for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++)
384254721Semaste            {
385254721Semaste                BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx);
386254721Semaste                if (!break_loc->IsEnabled())
387254721Semaste                    continue;
388254721Semaste                SectionSP section_sp (break_loc->GetAddress().GetSection());
389254721Semaste                if (!section_sp || section_sp->GetModule() == module_sp)
390254721Semaste                {
391254721Semaste                    if (!seen)
392254721Semaste                        seen = true;
393254721Semaste
394254721Semaste                    if (!break_loc->ResolveBreakpointSite())
395254721Semaste                    {
396254721Semaste                        Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
397254721Semaste                        if (log)
398254721Semaste                            log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n",
399254721Semaste                                         break_loc->GetID(), GetID());
400254721Semaste                    }
401254721Semaste                }
402254721Semaste            }
403254721Semaste
404254721Semaste            if (!seen)
405254721Semaste                new_modules.AppendIfNeeded (module_sp);
406254721Semaste
407254721Semaste        }
408254721Semaste
409254721Semaste        if (new_modules.GetSize() > 0)
410254721Semaste        {
411254721Semaste            // If this is not an internal breakpoint, set up to record the new locations, then dispatch
412254721Semaste            // an event with the new locations.
413254721Semaste            if (!IsInternal())
414254721Semaste            {
415254721Semaste                BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded,
416254721Semaste                                                                                    shared_from_this());
417254721Semaste
418254721Semaste                m_locations.StartRecordingNewLocations(new_locations_event->GetBreakpointLocationCollection());
419254721Semaste
420254721Semaste                ResolveBreakpointInModules(new_modules);
421254721Semaste
422254721Semaste                m_locations.StopRecordingNewLocations();
423254721Semaste                if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0)
424254721Semaste                {
425254721Semaste                    SendBreakpointChangedEvent (new_locations_event);
426254721Semaste                }
427254721Semaste                else
428254721Semaste                    delete new_locations_event;
429254721Semaste            }
430254721Semaste            else
431254721Semaste                ResolveBreakpointInModules(new_modules);
432254721Semaste
433254721Semaste        }
434254721Semaste    }
435254721Semaste    else
436254721Semaste    {
437254721Semaste        // Go through the currently set locations and if any have breakpoints in
438254721Semaste        // the module list, then remove their breakpoint sites, and their locations if asked to.
439254721Semaste
440254721Semaste        BreakpointEventData *removed_locations_event;
441254721Semaste        if (!IsInternal())
442254721Semaste            removed_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved,
443254721Semaste                                                               shared_from_this());
444254721Semaste        else
445254721Semaste            removed_locations_event = NULL;
446254721Semaste
447254721Semaste        size_t num_modules = module_list.GetSize();
448254721Semaste        for (size_t i = 0; i < num_modules; i++)
449254721Semaste        {
450254721Semaste            ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i));
451254721Semaste            if (m_filter_sp->ModulePasses (module_sp))
452254721Semaste            {
453254721Semaste                size_t loc_idx = 0;
454254721Semaste                size_t num_locations = m_locations.GetSize();
455254721Semaste                BreakpointLocationCollection locations_to_remove;
456254721Semaste                for (loc_idx = 0; loc_idx < num_locations; loc_idx++)
457254721Semaste                {
458254721Semaste                    BreakpointLocationSP break_loc_sp (m_locations.GetByIndex(loc_idx));
459254721Semaste                    SectionSP section_sp (break_loc_sp->GetAddress().GetSection());
460254721Semaste                    if (section_sp && section_sp->GetModule() == module_sp)
461254721Semaste                    {
462254721Semaste                        // Remove this breakpoint since the shared library is
463254721Semaste                        // unloaded, but keep the breakpoint location around
464254721Semaste                        // so we always get complete hit count and breakpoint
465254721Semaste                        // lifetime info
466254721Semaste                        break_loc_sp->ClearBreakpointSite();
467254721Semaste                        if (removed_locations_event)
468254721Semaste                        {
469254721Semaste                            removed_locations_event->GetBreakpointLocationCollection().Add(break_loc_sp);
470254721Semaste                        }
471254721Semaste                        if (delete_locations)
472254721Semaste                            locations_to_remove.Add (break_loc_sp);
473254721Semaste
474254721Semaste                    }
475254721Semaste                }
476254721Semaste
477254721Semaste                if (delete_locations)
478254721Semaste                {
479254721Semaste                    size_t num_locations_to_remove = locations_to_remove.GetSize();
480254721Semaste                    for (loc_idx = 0; loc_idx < num_locations_to_remove; loc_idx++)
481254721Semaste                        m_locations.RemoveLocation  (locations_to_remove.GetByIndex(loc_idx));
482254721Semaste                }
483254721Semaste            }
484254721Semaste        }
485254721Semaste        SendBreakpointChangedEvent (removed_locations_event);
486254721Semaste    }
487254721Semaste}
488254721Semaste
489254721Semastevoid
490254721SemasteBreakpoint::ModuleReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
491254721Semaste{
492254721Semaste    ModuleList temp_list;
493254721Semaste    temp_list.Append (new_module_sp);
494254721Semaste    ModulesChanged (temp_list, true);
495254721Semaste
496254721Semaste    // TO DO: For now I'm just adding locations for the new module and removing the
497254721Semaste    // breakpoint locations that were in the old module.
498254721Semaste    // We should really go find the ones that are in the new module & if we can determine that they are "equivalent"
499254721Semaste    // carry over the options from the old location to the new.
500254721Semaste
501254721Semaste    temp_list.Clear();
502254721Semaste    temp_list.Append (old_module_sp);
503254721Semaste    ModulesChanged (temp_list, false, true);
504254721Semaste}
505254721Semaste
506254721Semastevoid
507254721SemasteBreakpoint::Dump (Stream *)
508254721Semaste{
509254721Semaste}
510254721Semaste
511254721Semastesize_t
512254721SemasteBreakpoint::GetNumResolvedLocations() const
513254721Semaste{
514254721Semaste    // Return the number of breakpoints that are actually resolved and set
515254721Semaste    // down in the inferior process.
516254721Semaste    return m_locations.GetNumResolvedLocations();
517254721Semaste}
518254721Semaste
519254721Semastesize_t
520254721SemasteBreakpoint::GetNumLocations() const
521254721Semaste{
522254721Semaste    return m_locations.GetSize();
523254721Semaste}
524254721Semaste
525254721Semastevoid
526254721SemasteBreakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations)
527254721Semaste{
528254721Semaste    assert (s != NULL);
529254721Semaste
530254721Semaste    if (!m_kind_description.empty())
531254721Semaste    {
532254721Semaste        if (eDescriptionLevelBrief)
533254721Semaste        {
534254721Semaste            s->PutCString (GetBreakpointKind());
535254721Semaste            return;
536254721Semaste        }
537254721Semaste        else
538254721Semaste            s->Printf("Kind: %s\n", GetBreakpointKind ());
539254721Semaste    }
540254721Semaste
541254721Semaste    const size_t num_locations = GetNumLocations ();
542254721Semaste    const size_t num_resolved_locations = GetNumResolvedLocations ();
543254721Semaste
544254721Semaste    // They just made the breakpoint, they don't need to be told HOW they made it...
545254721Semaste    // Also, we'll print the breakpoint number differently depending on whether there is 1 or more locations.
546254721Semaste    if (level != eDescriptionLevelInitial)
547254721Semaste    {
548254721Semaste        s->Printf("%i: ", GetID());
549254721Semaste        GetResolverDescription (s);
550254721Semaste        GetFilterDescription (s);
551254721Semaste    }
552254721Semaste
553254721Semaste    switch (level)
554254721Semaste    {
555254721Semaste    case lldb::eDescriptionLevelBrief:
556254721Semaste    case lldb::eDescriptionLevelFull:
557254721Semaste        if (num_locations > 0)
558254721Semaste        {
559254721Semaste            s->Printf(", locations = %" PRIu64, (uint64_t)num_locations);
560254721Semaste            if (num_resolved_locations > 0)
561254721Semaste                s->Printf(", resolved = %" PRIu64, (uint64_t)num_resolved_locations);
562254721Semaste        }
563254721Semaste        else
564254721Semaste        {
565254721Semaste            // Don't print the pending notification for exception resolvers since we don't generally
566254721Semaste            // know how to set them until the target is run.
567254721Semaste            if (m_resolver_sp->getResolverID() != BreakpointResolver::ExceptionResolver)
568254721Semaste                s->Printf(", locations = 0 (pending)");
569254721Semaste        }
570254721Semaste
571254721Semaste        GetOptions()->GetDescription(s, level);
572254721Semaste
573254721Semaste        if (level == lldb::eDescriptionLevelFull)
574254721Semaste        {
575254721Semaste            s->IndentLess();
576254721Semaste            s->EOL();
577254721Semaste        }
578254721Semaste        break;
579254721Semaste
580254721Semaste    case lldb::eDescriptionLevelInitial:
581254721Semaste        s->Printf ("Breakpoint %i: ", GetID());
582254721Semaste        if (num_locations == 0)
583254721Semaste        {
584254721Semaste            s->Printf ("no locations (pending).");
585254721Semaste        }
586254721Semaste        else if (num_locations == 1)
587254721Semaste        {
588254721Semaste            // If there is one location only, we'll just print that location information.  But don't do this if
589254721Semaste            // show locations is true, then that will be handled below.
590254721Semaste            if (show_locations == false)
591254721Semaste            {
592254721Semaste                GetLocationAtIndex(0)->GetDescription(s, level);
593254721Semaste            }
594254721Semaste            else
595254721Semaste            {
596254721Semaste                s->Printf ("%zd locations.", num_locations);
597254721Semaste            }
598254721Semaste        }
599254721Semaste        else
600254721Semaste        {
601254721Semaste            s->Printf ("%zd locations.", num_locations);
602254721Semaste        }
603254721Semaste        s->EOL();
604254721Semaste        break;
605254721Semaste    case lldb::eDescriptionLevelVerbose:
606254721Semaste        // Verbose mode does a debug dump of the breakpoint
607254721Semaste        Dump (s);
608254721Semaste        s->EOL ();
609254721Semaste            //s->Indent();
610254721Semaste        GetOptions()->GetDescription(s, level);
611254721Semaste        break;
612254721Semaste
613254721Semaste    default:
614254721Semaste        break;
615254721Semaste    }
616254721Semaste
617254721Semaste    // The brief description is just the location name (1.2 or whatever).  That's pointless to
618254721Semaste    // show in the breakpoint's description, so suppress it.
619254721Semaste    if (show_locations && level != lldb::eDescriptionLevelBrief)
620254721Semaste    {
621254721Semaste        s->IndentMore();
622254721Semaste        for (size_t i = 0; i < num_locations; ++i)
623254721Semaste        {
624254721Semaste            BreakpointLocation *loc = GetLocationAtIndex(i).get();
625254721Semaste            loc->GetDescription(s, level);
626254721Semaste            s->EOL();
627254721Semaste        }
628254721Semaste        s->IndentLess();
629254721Semaste    }
630254721Semaste}
631254721Semaste
632254721Semastevoid
633254721SemasteBreakpoint::GetResolverDescription (Stream *s)
634254721Semaste{
635254721Semaste    if (m_resolver_sp)
636254721Semaste        m_resolver_sp->GetDescription (s);
637254721Semaste}
638254721Semaste
639254721Semaste
640254721Semastebool
641254721SemasteBreakpoint::GetMatchingFileLine (const ConstString &filename, uint32_t line_number, BreakpointLocationCollection &loc_coll)
642254721Semaste{
643254721Semaste    // TODO: To be correct, this method needs to fill the breakpoint location collection
644254721Semaste    //       with the location IDs which match the filename and line_number.
645254721Semaste    //
646254721Semaste
647254721Semaste    if (m_resolver_sp)
648254721Semaste    {
649254721Semaste        BreakpointResolverFileLine *resolverFileLine = dyn_cast<BreakpointResolverFileLine>(m_resolver_sp.get());
650254721Semaste        if (resolverFileLine &&
651254721Semaste            resolverFileLine->m_file_spec.GetFilename() == filename &&
652254721Semaste            resolverFileLine->m_line_number == line_number)
653254721Semaste        {
654254721Semaste            return true;
655254721Semaste        }
656254721Semaste    }
657254721Semaste    return false;
658254721Semaste}
659254721Semaste
660254721Semastevoid
661254721SemasteBreakpoint::GetFilterDescription (Stream *s)
662254721Semaste{
663254721Semaste    m_filter_sp->GetDescription (s);
664254721Semaste}
665254721Semaste
666254721Semastevoid
667254721SemasteBreakpoint::SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind)
668254721Semaste{
669254721Semaste    if (!m_being_created
670254721Semaste        && !IsInternal()
671254721Semaste        && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
672254721Semaste    {
673254721Semaste        BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, shared_from_this());
674254721Semaste
675254721Semaste        GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
676254721Semaste    }
677254721Semaste}
678254721Semaste
679254721Semastevoid
680254721SemasteBreakpoint::SendBreakpointChangedEvent (BreakpointEventData *data)
681254721Semaste{
682254721Semaste
683254721Semaste    if (data == NULL)
684254721Semaste        return;
685254721Semaste
686254721Semaste    if (!m_being_created
687254721Semaste        && !IsInternal()
688254721Semaste        && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
689254721Semaste        GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
690254721Semaste    else
691254721Semaste        delete data;
692254721Semaste}
693254721Semaste
694254721SemasteBreakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type,
695254721Semaste                                                      const BreakpointSP &new_breakpoint_sp) :
696254721Semaste    EventData (),
697254721Semaste    m_breakpoint_event (sub_type),
698254721Semaste    m_new_breakpoint_sp (new_breakpoint_sp)
699254721Semaste{
700254721Semaste}
701254721Semaste
702254721SemasteBreakpoint::BreakpointEventData::~BreakpointEventData ()
703254721Semaste{
704254721Semaste}
705254721Semaste
706254721Semasteconst ConstString &
707254721SemasteBreakpoint::BreakpointEventData::GetFlavorString ()
708254721Semaste{
709254721Semaste    static ConstString g_flavor ("Breakpoint::BreakpointEventData");
710254721Semaste    return g_flavor;
711254721Semaste}
712254721Semaste
713254721Semasteconst ConstString &
714254721SemasteBreakpoint::BreakpointEventData::GetFlavor () const
715254721Semaste{
716254721Semaste    return BreakpointEventData::GetFlavorString ();
717254721Semaste}
718254721Semaste
719254721Semaste
720254721SemasteBreakpointSP &
721254721SemasteBreakpoint::BreakpointEventData::GetBreakpoint ()
722254721Semaste{
723254721Semaste    return m_new_breakpoint_sp;
724254721Semaste}
725254721Semaste
726254721SemasteBreakpointEventType
727254721SemasteBreakpoint::BreakpointEventData::GetBreakpointEventType () const
728254721Semaste{
729254721Semaste    return m_breakpoint_event;
730254721Semaste}
731254721Semaste
732254721Semastevoid
733254721SemasteBreakpoint::BreakpointEventData::Dump (Stream *s) const
734254721Semaste{
735254721Semaste}
736254721Semaste
737254721Semasteconst Breakpoint::BreakpointEventData *
738254721SemasteBreakpoint::BreakpointEventData::GetEventDataFromEvent (const Event *event)
739254721Semaste{
740254721Semaste    if (event)
741254721Semaste    {
742254721Semaste        const EventData *event_data = event->GetData();
743254721Semaste        if (event_data && event_data->GetFlavor() == BreakpointEventData::GetFlavorString())
744254721Semaste            return static_cast <const BreakpointEventData *> (event->GetData());
745254721Semaste    }
746254721Semaste    return NULL;
747254721Semaste}
748254721Semaste
749254721SemasteBreakpointEventType
750254721SemasteBreakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp)
751254721Semaste{
752254721Semaste    const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
753254721Semaste
754254721Semaste    if (data == NULL)
755254721Semaste        return eBreakpointEventTypeInvalidType;
756254721Semaste    else
757254721Semaste        return data->GetBreakpointEventType();
758254721Semaste}
759254721Semaste
760254721SemasteBreakpointSP
761254721SemasteBreakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp)
762254721Semaste{
763254721Semaste    BreakpointSP bp_sp;
764254721Semaste
765254721Semaste    const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
766254721Semaste    if (data)
767254721Semaste        bp_sp = data->m_new_breakpoint_sp;
768254721Semaste
769254721Semaste    return bp_sp;
770254721Semaste}
771254721Semaste
772254721Semastesize_t
773254721SemasteBreakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (const EventSP &event_sp)
774254721Semaste{
775254721Semaste    const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
776254721Semaste    if (data)
777254721Semaste        return data->m_locations.GetSize();
778254721Semaste
779254721Semaste    return 0;
780254721Semaste}
781254721Semaste
782254721Semastelldb::BreakpointLocationSP
783254721SemasteBreakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t bp_loc_idx)
784254721Semaste{
785254721Semaste    lldb::BreakpointLocationSP bp_loc_sp;
786254721Semaste
787254721Semaste    const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
788254721Semaste    if (data)
789254721Semaste    {
790254721Semaste        bp_loc_sp = data->m_locations.GetByIndex(bp_loc_idx);
791254721Semaste    }
792254721Semaste
793254721Semaste    return bp_loc_sp;
794254721Semaste}
795