]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Breakpoint/WatchpointOptions.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Breakpoint / WatchpointOptions.cpp
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 #include "lldb/Breakpoint/StoppointCallbackContext.h"
13 #include "lldb/Core/Value.h"
14 #include "lldb/Target/Process.h"
15 #include "lldb/Target/Target.h"
16 #include "lldb/Target/ThreadSpec.h"
17 #include "lldb/Utility/Stream.h"
18 #include "lldb/Utility/StringList.h"
19
20 using namespace lldb;
21 using namespace lldb_private;
22
23 bool WatchpointOptions::NullCallback(void *baton,
24                                      StoppointCallbackContext *context,
25                                      lldb::user_id_t watch_id) {
26   return true;
27 }
28
29 //----------------------------------------------------------------------
30 // WatchpointOptions constructor
31 //----------------------------------------------------------------------
32 WatchpointOptions::WatchpointOptions()
33     : m_callback(WatchpointOptions::NullCallback), m_callback_baton_sp(),
34       m_callback_is_synchronous(false), m_thread_spec_ap() {}
35
36 //----------------------------------------------------------------------
37 // WatchpointOptions copy constructor
38 //----------------------------------------------------------------------
39 WatchpointOptions::WatchpointOptions(const WatchpointOptions &rhs)
40     : m_callback(rhs.m_callback), m_callback_baton_sp(rhs.m_callback_baton_sp),
41       m_callback_is_synchronous(rhs.m_callback_is_synchronous),
42       m_thread_spec_ap() {
43   if (rhs.m_thread_spec_ap.get() != nullptr)
44     m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
45 }
46
47 //----------------------------------------------------------------------
48 // WatchpointOptions assignment operator
49 //----------------------------------------------------------------------
50 const WatchpointOptions &WatchpointOptions::
51 operator=(const WatchpointOptions &rhs) {
52   m_callback = rhs.m_callback;
53   m_callback_baton_sp = rhs.m_callback_baton_sp;
54   m_callback_is_synchronous = rhs.m_callback_is_synchronous;
55   if (rhs.m_thread_spec_ap.get() != nullptr)
56     m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
57   return *this;
58 }
59
60 WatchpointOptions *
61 WatchpointOptions::CopyOptionsNoCallback(WatchpointOptions &orig) {
62   WatchpointHitCallback orig_callback = orig.m_callback;
63   lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp;
64   bool orig_is_sync = orig.m_callback_is_synchronous;
65
66   orig.ClearCallback();
67   WatchpointOptions *ret_val = new WatchpointOptions(orig);
68
69   orig.SetCallback(orig_callback, orig_callback_baton_sp, orig_is_sync);
70
71   return ret_val;
72 }
73
74 //----------------------------------------------------------------------
75 // Destructor
76 //----------------------------------------------------------------------
77 WatchpointOptions::~WatchpointOptions() = default;
78
79 //------------------------------------------------------------------
80 // Callbacks
81 //------------------------------------------------------------------
82 void WatchpointOptions::SetCallback(WatchpointHitCallback callback,
83                                     const BatonSP &callback_baton_sp,
84                                     bool callback_is_synchronous) {
85   m_callback_is_synchronous = callback_is_synchronous;
86   m_callback = callback;
87   m_callback_baton_sp = callback_baton_sp;
88 }
89
90 void WatchpointOptions::ClearCallback() {
91   m_callback = WatchpointOptions::NullCallback;
92   m_callback_is_synchronous = false;
93   m_callback_baton_sp.reset();
94 }
95
96 Baton *WatchpointOptions::GetBaton() { return m_callback_baton_sp.get(); }
97
98 const Baton *WatchpointOptions::GetBaton() const {
99   return m_callback_baton_sp.get();
100 }
101
102 bool WatchpointOptions::InvokeCallback(StoppointCallbackContext *context,
103                                        lldb::user_id_t watch_id) {
104   if (m_callback && context->is_synchronous == IsCallbackSynchronous()) {
105     return m_callback(m_callback_baton_sp ? m_callback_baton_sp->data()
106                                           : nullptr,
107                       context, watch_id);
108   } else
109     return true;
110 }
111
112 bool WatchpointOptions::HasCallback() {
113   return m_callback != WatchpointOptions::NullCallback;
114 }
115
116 const ThreadSpec *WatchpointOptions::GetThreadSpecNoCreate() const {
117   return m_thread_spec_ap.get();
118 }
119
120 ThreadSpec *WatchpointOptions::GetThreadSpec() {
121   if (m_thread_spec_ap.get() == nullptr)
122     m_thread_spec_ap.reset(new ThreadSpec());
123
124   return m_thread_spec_ap.get();
125 }
126
127 void WatchpointOptions::SetThreadID(lldb::tid_t thread_id) {
128   GetThreadSpec()->SetTID(thread_id);
129 }
130
131 void WatchpointOptions::GetCallbackDescription(
132     Stream *s, lldb::DescriptionLevel level) const {
133   if (m_callback_baton_sp.get()) {
134     s->EOL();
135     m_callback_baton_sp->GetDescription(s, level);
136   }
137 }
138
139 void WatchpointOptions::GetDescription(Stream *s,
140                                        lldb::DescriptionLevel level) const {
141   // Figure out if there are any options not at their default value, and only
142   // print anything if there are:
143
144   if ((GetThreadSpecNoCreate() != nullptr &&
145        GetThreadSpecNoCreate()->HasSpecification())) {
146     if (level == lldb::eDescriptionLevelVerbose) {
147       s->EOL();
148       s->IndentMore();
149       s->Indent();
150       s->PutCString("Watchpoint Options:\n");
151       s->IndentMore();
152       s->Indent();
153     } else
154       s->PutCString(" Options: ");
155
156     if (m_thread_spec_ap.get())
157       m_thread_spec_ap->GetDescription(s, level);
158     else if (level == eDescriptionLevelBrief)
159       s->PutCString("thread spec: no ");
160     if (level == lldb::eDescriptionLevelFull) {
161       s->IndentLess();
162       s->IndentMore();
163     }
164   }
165
166   GetCallbackDescription(s, level);
167 }
168
169 void WatchpointOptions::CommandBaton::GetDescription(
170     Stream *s, lldb::DescriptionLevel level) const {
171   const CommandData *data = getItem();
172
173   if (level == eDescriptionLevelBrief) {
174     s->Printf(", commands = %s",
175               (data && data->user_source.GetSize() > 0) ? "yes" : "no");
176     return;
177   }
178
179   s->IndentMore();
180   s->Indent("watchpoint commands:\n");
181
182   s->IndentMore();
183   if (data && data->user_source.GetSize() > 0) {
184     const size_t num_strings = data->user_source.GetSize();
185     for (size_t i = 0; i < num_strings; ++i) {
186       s->Indent(data->user_source.GetStringAtIndex(i));
187       s->EOL();
188     }
189   } else {
190     s->PutCString("No commands.\n");
191   }
192   s->IndentLess();
193   s->IndentLess();
194 }