Home | History | Annotate | Download | only in Breakpoint
      1 //===-- WatchpointOptions.cpp -----------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "lldb/Breakpoint/WatchpointOptions.h"
     11 
     12 // C Includes
     13 // C++ Includes
     14 // Other libraries and framework includes
     15 // Project includes
     16 #include "lldb/Core/Stream.h"
     17 #include "lldb/Core/StringList.h"
     18 #include "lldb/Core/Value.h"
     19 #include "lldb/Breakpoint/StoppointCallbackContext.h"
     20 #include "lldb/Target/Process.h"
     21 #include "lldb/Target/Target.h"
     22 #include "lldb/Target/ThreadSpec.h"
     23 #include "lldb/Expression/ClangUserExpression.h"
     24 
     25 using namespace lldb;
     26 using namespace lldb_private;
     27 
     28 bool
     29 WatchpointOptions::NullCallback (void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id)
     30 {
     31     return true;
     32 }
     33 
     34 //----------------------------------------------------------------------
     35 // WatchpointOptions constructor
     36 //----------------------------------------------------------------------
     37 WatchpointOptions::WatchpointOptions() :
     38     m_callback (WatchpointOptions::NullCallback),
     39     m_callback_baton_sp (),
     40     m_callback_is_synchronous (false),
     41     m_thread_spec_ap ()
     42 {
     43 }
     44 
     45 //----------------------------------------------------------------------
     46 // WatchpointOptions copy constructor
     47 //----------------------------------------------------------------------
     48 WatchpointOptions::WatchpointOptions(const WatchpointOptions& rhs) :
     49     m_callback (rhs.m_callback),
     50     m_callback_baton_sp (rhs.m_callback_baton_sp),
     51     m_callback_is_synchronous (rhs.m_callback_is_synchronous),
     52     m_thread_spec_ap ()
     53 {
     54     if (rhs.m_thread_spec_ap.get() != NULL)
     55         m_thread_spec_ap.reset (new ThreadSpec(*rhs.m_thread_spec_ap.get()));
     56 }
     57 
     58 //----------------------------------------------------------------------
     59 // WatchpointOptions assignment operator
     60 //----------------------------------------------------------------------
     61 const WatchpointOptions&
     62 WatchpointOptions::operator=(const WatchpointOptions& rhs)
     63 {
     64     m_callback = rhs.m_callback;
     65     m_callback_baton_sp = rhs.m_callback_baton_sp;
     66     m_callback_is_synchronous = rhs.m_callback_is_synchronous;
     67     if (rhs.m_thread_spec_ap.get() != NULL)
     68         m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
     69     return *this;
     70 }
     71 
     72 WatchpointOptions *
     73 WatchpointOptions::CopyOptionsNoCallback (WatchpointOptions &orig)
     74 {
     75     WatchpointHitCallback orig_callback = orig.m_callback;
     76     lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp;
     77     bool orig_is_sync = orig.m_callback_is_synchronous;
     78 
     79     orig.ClearCallback();
     80     WatchpointOptions *ret_val = new WatchpointOptions(orig);
     81 
     82     orig.SetCallback (orig_callback, orig_callback_baton_sp, orig_is_sync);
     83 
     84     return ret_val;
     85 }
     86 
     87 //----------------------------------------------------------------------
     88 // Destructor
     89 //----------------------------------------------------------------------
     90 WatchpointOptions::~WatchpointOptions()
     91 {
     92 }
     93 
     94 //------------------------------------------------------------------
     95 // Callbacks
     96 //------------------------------------------------------------------
     97 void
     98 WatchpointOptions::SetCallback (WatchpointHitCallback callback, const BatonSP &callback_baton_sp, bool callback_is_synchronous)
     99 {
    100     m_callback_is_synchronous = callback_is_synchronous;
    101     m_callback = callback;
    102     m_callback_baton_sp = callback_baton_sp;
    103 }
    104 
    105 void
    106 WatchpointOptions::ClearCallback ()
    107 {
    108     m_callback = WatchpointOptions::NullCallback;
    109     m_callback_is_synchronous = false;
    110     m_callback_baton_sp.reset();
    111 }
    112 
    113 Baton *
    114 WatchpointOptions::GetBaton ()
    115 {
    116     return m_callback_baton_sp.get();
    117 }
    118 
    119 const Baton *
    120 WatchpointOptions::GetBaton () const
    121 {
    122     return m_callback_baton_sp.get();
    123 }
    124 
    125 bool
    126 WatchpointOptions::InvokeCallback (StoppointCallbackContext *context,
    127                                    lldb::user_id_t watch_id)
    128 {
    129     if (m_callback && context->is_synchronous == IsCallbackSynchronous())
    130     {
    131         return m_callback (m_callback_baton_sp ? m_callback_baton_sp->m_data : NULL,
    132                            context,
    133                            watch_id);
    134     }
    135     else
    136         return true;
    137 }
    138 
    139 bool
    140 WatchpointOptions::HasCallback ()
    141 {
    142     return m_callback != WatchpointOptions::NullCallback;
    143 }
    144 
    145 const ThreadSpec *
    146 WatchpointOptions::GetThreadSpecNoCreate () const
    147 {
    148     return m_thread_spec_ap.get();
    149 }
    150 
    151 ThreadSpec *
    152 WatchpointOptions::GetThreadSpec ()
    153 {
    154     if (m_thread_spec_ap.get() == NULL)
    155         m_thread_spec_ap.reset (new ThreadSpec());
    156 
    157     return m_thread_spec_ap.get();
    158 }
    159 
    160 void
    161 WatchpointOptions::SetThreadID (lldb::tid_t thread_id)
    162 {
    163     GetThreadSpec()->SetTID(thread_id);
    164 }
    165 
    166 void
    167 WatchpointOptions::GetCallbackDescription (Stream *s, lldb::DescriptionLevel level) const
    168 {
    169     if (m_callback_baton_sp.get())
    170     {
    171         s->EOL();
    172         m_callback_baton_sp->GetDescription (s, level);
    173     }
    174 }
    175 void
    176 WatchpointOptions::GetDescription (Stream *s, lldb::DescriptionLevel level) const
    177 {
    178 
    179     // Figure out if there are any options not at their default value, and only print
    180     // anything if there are:
    181 
    182     if ((GetThreadSpecNoCreate() != NULL && GetThreadSpecNoCreate()->HasSpecification ()))
    183     {
    184         if (level == lldb::eDescriptionLevelVerbose)
    185         {
    186             s->EOL ();
    187             s->IndentMore();
    188             s->Indent();
    189             s->PutCString("Watchpoint Options:\n");
    190             s->IndentMore();
    191             s->Indent();
    192         }
    193         else
    194             s->PutCString(" Options: ");
    195 
    196         if (m_thread_spec_ap.get())
    197             m_thread_spec_ap->GetDescription (s, level);
    198         else if (level == eDescriptionLevelBrief)
    199             s->PutCString ("thread spec: no ");
    200         if (level == lldb::eDescriptionLevelFull)
    201         {
    202             s->IndentLess();
    203             s->IndentMore();
    204         }
    205     }
    206 
    207     GetCallbackDescription(s, level);
    208 }
    209 
    210 void
    211 WatchpointOptions::CommandBaton::GetDescription (Stream *s, lldb::DescriptionLevel level) const
    212 {
    213     CommandData *data = (CommandData *)m_data;
    214 
    215     if (level == eDescriptionLevelBrief)
    216     {
    217         s->Printf (", commands = %s", (data && data->user_source.GetSize() > 0) ? "yes" : "no");
    218         return;
    219     }
    220 
    221     s->IndentMore ();
    222     s->Indent("watchpoint commands:\n");
    223 
    224     s->IndentMore ();
    225     if (data && data->user_source.GetSize() > 0)
    226     {
    227         const size_t num_strings = data->user_source.GetSize();
    228         for (size_t i = 0; i < num_strings; ++i)
    229         {
    230             s->Indent(data->user_source.GetStringAtIndex(i));
    231             s->EOL();
    232         }
    233     }
    234     else
    235     {
    236         s->PutCString ("No commands.\n");
    237     }
    238     s->IndentLess ();
    239     s->IndentLess ();
    240 }
    241 
    242