//===-- SBBreakpoint.cpp ----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/API/SBBreakpoint.h"
#include "lldb/API/SBBreakpointLocation.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBStringList.h"
#include "lldb/API/SBThread.h"

#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"


#include "lldb/lldb-enumerations.h"

using namespace lldb;
using namespace lldb_private;

struct CallbackData
{
    SBBreakpoint::BreakpointHitCallback callback;
    void *callback_baton;
};

class SBBreakpointCallbackBaton : public Baton
{
public:

    SBBreakpointCallbackBaton (SBBreakpoint::BreakpointHitCallback callback, void *baton) :
        Baton (new CallbackData)
    {
        CallbackData *data = (CallbackData *)m_data;
        data->callback = callback;
        data->callback_baton = baton;
    }
    
    virtual ~SBBreakpointCallbackBaton()
    {
        CallbackData *data = (CallbackData *)m_data;

        if (data)
        {
            delete data;
            m_data = NULL;
        }
    }
};


SBBreakpoint::SBBreakpoint () :
    m_opaque_sp ()
{
}

SBBreakpoint::SBBreakpoint (const SBBreakpoint& rhs) :
    m_opaque_sp (rhs.m_opaque_sp)
{
}


SBBreakpoint::SBBreakpoint (const lldb::BreakpointSP &bp_sp) :
    m_opaque_sp (bp_sp)
{
}

SBBreakpoint::~SBBreakpoint()
{
}

const SBBreakpoint &
SBBreakpoint::operator = (const SBBreakpoint& rhs)
{
    if (this != &rhs)
        m_opaque_sp = rhs.m_opaque_sp;
    return *this;
}

bool
SBBreakpoint::operator == (const lldb::SBBreakpoint& rhs)
{
    if (m_opaque_sp && rhs.m_opaque_sp)
        return m_opaque_sp.get() == rhs.m_opaque_sp.get();
    return false;
}

bool
SBBreakpoint::operator != (const lldb::SBBreakpoint& rhs)
{
    if (m_opaque_sp && rhs.m_opaque_sp)
        return m_opaque_sp.get() != rhs.m_opaque_sp.get();
    return (m_opaque_sp && !rhs.m_opaque_sp) || (rhs.m_opaque_sp && !m_opaque_sp);
}

break_id_t
SBBreakpoint::GetID () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    break_id_t break_id = LLDB_INVALID_BREAK_ID;
    if (m_opaque_sp)
        break_id = m_opaque_sp->GetID();

    if (log)
    {
        if (break_id == LLDB_INVALID_BREAK_ID)
            log->Printf ("SBBreakpoint(%p)::GetID () => LLDB_INVALID_BREAK_ID",
                         static_cast<void*>(m_opaque_sp.get()));
        else
            log->Printf ("SBBreakpoint(%p)::GetID () => %u",
                         static_cast<void*>(m_opaque_sp.get()), break_id);
    }

    return break_id;
}


bool
SBBreakpoint::IsValid() const
{
    if (!m_opaque_sp)
        return false;
    else if (m_opaque_sp->GetTarget().GetBreakpointByID(m_opaque_sp->GetID()))
       return true;
    else
        return false;
}

void
SBBreakpoint::ClearAllBreakpointSites ()
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->ClearAllBreakpointSites ();
    }
}

SBBreakpointLocation
SBBreakpoint::FindLocationByAddress (addr_t vm_addr)
{
    SBBreakpointLocation sb_bp_location;

    if (m_opaque_sp)
    {
        if (vm_addr != LLDB_INVALID_ADDRESS)
        {
            Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
            Address address;
            Target &target = m_opaque_sp->GetTarget();
            if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false)
            {
                address.SetRawAddress (vm_addr);
            }
            sb_bp_location.SetLocation (m_opaque_sp->FindLocationByAddress (address));
        }
    }
    return sb_bp_location;
}

break_id_t
SBBreakpoint::FindLocationIDByAddress (addr_t vm_addr)
{
    break_id_t break_id = LLDB_INVALID_BREAK_ID;

    if (m_opaque_sp && vm_addr != LLDB_INVALID_ADDRESS)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        Address address;
        Target &target = m_opaque_sp->GetTarget();
        if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false)
        {
            address.SetRawAddress (vm_addr);
        }
        break_id = m_opaque_sp->FindLocationIDByAddress (address);
    }

    return break_id;
}

SBBreakpointLocation
SBBreakpoint::FindLocationByID (break_id_t bp_loc_id)
{
    SBBreakpointLocation sb_bp_location;

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        sb_bp_location.SetLocation (m_opaque_sp->FindLocationByID (bp_loc_id));
    }

    return sb_bp_location;
}

SBBreakpointLocation
SBBreakpoint::GetLocationAtIndex (uint32_t index)
{
    SBBreakpointLocation sb_bp_location;

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        sb_bp_location.SetLocation (m_opaque_sp->GetLocationAtIndex (index));
    }

    return sb_bp_location;
}

void
SBBreakpoint::SetEnabled (bool enable)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBreakpoint(%p)::SetEnabled (enabled=%i)",
                     static_cast<void*>(m_opaque_sp.get()), enable);

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->SetEnabled (enable);
    }
}

bool
SBBreakpoint::IsEnabled ()
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        return m_opaque_sp->IsEnabled();
    }
    else
        return false;
}

void
SBBreakpoint::SetOneShot (bool one_shot)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBreakpoint(%p)::SetOneShot (one_shot=%i)",
                     static_cast<void*>(m_opaque_sp.get()), one_shot);

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->SetOneShot (one_shot);
    }
}

bool
SBBreakpoint::IsOneShot () const
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        return m_opaque_sp->IsOneShot();
    }
    else
        return false;
}

bool
SBBreakpoint::IsInternal ()
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        return m_opaque_sp->IsInternal();
    }
    else
        return false;
}

void
SBBreakpoint::SetIgnoreCount (uint32_t count)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBreakpoint(%p)::SetIgnoreCount (count=%u)",
                     static_cast<void*>(m_opaque_sp.get()), count);

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->SetIgnoreCount (count);
    }
}

void
SBBreakpoint::SetCondition (const char *condition)
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->SetCondition (condition);
    }
}

const char *
SBBreakpoint::GetCondition ()
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        return m_opaque_sp->GetConditionText ();
    }
    return NULL;
}

uint32_t
SBBreakpoint::GetHitCount () const
{
    uint32_t count = 0;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        count = m_opaque_sp->GetHitCount();
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetHitCount () => %u",
                     static_cast<void*>(m_opaque_sp.get()), count);

    return count;
}

uint32_t
SBBreakpoint::GetIgnoreCount () const
{
    uint32_t count = 0;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        count = m_opaque_sp->GetIgnoreCount();
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetIgnoreCount () => %u",
                     static_cast<void*>(m_opaque_sp.get()), count);

    return count;
}

void
SBBreakpoint::SetThreadID (tid_t tid)
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->SetThreadID (tid);
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")",
                     static_cast<void*>(m_opaque_sp.get()), tid);

}

tid_t
SBBreakpoint::GetThreadID ()
{
    tid_t tid = LLDB_INVALID_THREAD_ID;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        tid = m_opaque_sp->GetThreadID();
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64,
                     static_cast<void*>(m_opaque_sp.get()), tid);
    return tid;
}

void
SBBreakpoint::SetThreadIndex (uint32_t index)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::SetThreadIndex (%u)",
                     static_cast<void*>(m_opaque_sp.get()), index);
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex (index);
    }
}

uint32_t
SBBreakpoint::GetThreadIndex() const
{
    uint32_t thread_idx = UINT32_MAX;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
        if (thread_spec != NULL)
            thread_idx = thread_spec->GetIndex();
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetThreadIndex () => %u",
                     static_cast<void*>(m_opaque_sp.get()), thread_idx);

    return thread_idx;
}

void
SBBreakpoint::SetThreadName (const char *thread_name)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::SetThreadName (%s)",
                     static_cast<void*>(m_opaque_sp.get()), thread_name);

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->GetOptions()->GetThreadSpec()->SetName (thread_name);
    }
}

const char *
SBBreakpoint::GetThreadName () const
{
    const char *name = NULL;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
        if (thread_spec != NULL)
            name = thread_spec->GetName();
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetThreadName () => %s",
                     static_cast<void*>(m_opaque_sp.get()), name);

    return name;
}

void
SBBreakpoint::SetQueueName (const char *queue_name)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::SetQueueName (%s)",
                     static_cast<void*>(m_opaque_sp.get()), queue_name);
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName (queue_name);
    }
}

const char *
SBBreakpoint::GetQueueName () const
{
    const char *name = NULL;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
        if (thread_spec)
            name = thread_spec->GetQueueName();
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetQueueName () => %s",
                     static_cast<void*>(m_opaque_sp.get()), name);

    return name;
}

size_t
SBBreakpoint::GetNumResolvedLocations() const
{
    size_t num_resolved = 0;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        num_resolved = m_opaque_sp->GetNumResolvedLocations();
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64,
                     static_cast<void*>(m_opaque_sp.get()),
                     static_cast<uint64_t>(num_resolved));
    return num_resolved;
}

size_t
SBBreakpoint::GetNumLocations() const
{
    size_t num_locs = 0;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        num_locs = m_opaque_sp->GetNumLocations();
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64,
                     static_cast<void*>(m_opaque_sp.get()),
                     static_cast<uint64_t>(num_locs));
    return num_locs;
}

bool
SBBreakpoint::GetDescription (SBStream &s)
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
        m_opaque_sp->GetResolverDescription (s.get());
        m_opaque_sp->GetFilterDescription (s.get());
        const size_t num_locations = m_opaque_sp->GetNumLocations ();
        s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
        return true;
    }
    s.Printf ("No value");
    return false;
}

bool
SBBreakpoint::PrivateBreakpointHitCallback 
(
    void *baton, 
    StoppointCallbackContext *ctx, 
    lldb::user_id_t break_id, 
    lldb::user_id_t break_loc_id
)
{
    ExecutionContext exe_ctx (ctx->exe_ctx_ref);
    BreakpointSP bp_sp(exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
    if (baton && bp_sp)
    {
        CallbackData *data = (CallbackData *)baton;
        lldb_private::Breakpoint *bp = bp_sp.get();
        if (bp && data->callback)
        {
            Process *process = exe_ctx.GetProcessPtr();
            if (process)
            {
                SBProcess sb_process (process->shared_from_this());
                SBThread sb_thread;
                SBBreakpointLocation sb_location;
                assert (bp_sp);
                sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id));
                Thread *thread = exe_ctx.GetThreadPtr();
                if (thread)
                    sb_thread.SetThread(thread->shared_from_this());

                return data->callback (data->callback_baton, 
                                          sb_process, 
                                          sb_thread, 
                                          sb_location);
            }
        }
    }
    return true;    // Return true if we should stop at this breakpoint
}

void
SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
    {
        void *pointer = &callback;
        log->Printf ("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)",
                     static_cast<void*>(m_opaque_sp.get()),
                     *static_cast<void**>(&pointer), static_cast<void*>(baton));
    }

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton));
        m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false);
    }
}

void
SBBreakpoint::SetScriptCallbackFunction (const char *callback_function_name)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBreakpoint(%p)::SetScriptCallbackFunction (callback=%s)",
                     static_cast<void*>(m_opaque_sp.get()),
                     callback_function_name);

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
        m_opaque_sp->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallbackFunction (bp_options,
                                                                                                                                                   callback_function_name);
    }
}

SBError
SBBreakpoint::SetScriptCallbackBody (const char *callback_body_text)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBreakpoint(%p)::SetScriptCallbackBody: callback body:\n%s)",
                     static_cast<void*>(m_opaque_sp.get()), callback_body_text);

    SBError sb_error;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
        Error error =  m_opaque_sp->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options,
                                                                                                                                    callback_body_text);
        sb_error.SetError(error);
    }
    else
        sb_error.SetErrorString("invalid breakpoint");

    return sb_error;
}

bool
SBBreakpoint::AddName (const char *new_name)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBreakpoint(%p)::AddName (name=%s)",
                     static_cast<void*>(m_opaque_sp.get()),
                     new_name);

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        Error error;  // Think I'm just going to swallow the error here, it's probably more annoying to have to provide it.
        return m_opaque_sp->AddName(new_name, error);
    }

    return false;
}

void
SBBreakpoint::RemoveName (const char *name_to_remove)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBreakpoint(%p)::RemoveName (name=%s)",
                     static_cast<void*>(m_opaque_sp.get()),
                     name_to_remove);

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->RemoveName(name_to_remove);
    }
}

bool
SBBreakpoint::MatchesName (const char *name)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBreakpoint(%p)::MatchesName (name=%s)",
                     static_cast<void*>(m_opaque_sp.get()),
                     name);

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        return m_opaque_sp->MatchesName(name);
    }

    return false;
}

void
SBBreakpoint::GetNames (SBStringList &names)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBreakpoint(%p)::GetNames ()",
                     static_cast<void*>(m_opaque_sp.get()));

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        std::vector<std::string> names_vec;
        m_opaque_sp->GetNames(names_vec);
        for (std::string name : names_vec)
        {
            names.AppendString (name.c_str());
        }
    }
}

lldb_private::Breakpoint *
SBBreakpoint::operator->() const
{
    return m_opaque_sp.get();
}

lldb_private::Breakpoint *
SBBreakpoint::get() const
{
    return m_opaque_sp.get();
}

lldb::BreakpointSP &
SBBreakpoint::operator *()
{
    return m_opaque_sp;
}

const lldb::BreakpointSP &
SBBreakpoint::operator *() const
{
    return m_opaque_sp;
}

bool
SBBreakpoint::EventIsBreakpointEvent (const lldb::SBEvent &event)
{
    return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) != NULL;

}

BreakpointEventType
SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event)
{
    if (event.IsValid())
        return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event.GetSP());
    return eBreakpointEventTypeInvalidType;
}

SBBreakpoint
SBBreakpoint::GetBreakpointFromEvent (const lldb::SBEvent& event)
{
    SBBreakpoint sb_breakpoint;
    if (event.IsValid())
        sb_breakpoint.m_opaque_sp = Breakpoint::BreakpointEventData::GetBreakpointFromEvent (event.GetSP());
    return sb_breakpoint;
}

SBBreakpointLocation
SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx)
{
    SBBreakpointLocation sb_breakpoint_loc;
    if (event.IsValid())
        sb_breakpoint_loc.SetLocation (Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (event.GetSP(), loc_idx));
    return sb_breakpoint_loc;
}

uint32_t
SBBreakpoint::GetNumBreakpointLocationsFromEvent (const lldb::SBEvent &event)
{
    uint32_t num_locations = 0;
    if (event.IsValid())
        num_locations = (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (event.GetSP()));
    return num_locations;
}


