1 //===-- WatchpointOptions.cpp -----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Breakpoint/WatchpointOptions.h"
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"
21 using namespace lldb_private;
23 bool WatchpointOptions::NullCallback(void *baton,
24 StoppointCallbackContext *context,
25 lldb::user_id_t watch_id) {
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() {}
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),
43 if (rhs.m_thread_spec_ap.get() != nullptr)
44 m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
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()));
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;
67 WatchpointOptions *ret_val = new WatchpointOptions(orig);
69 orig.SetCallback(orig_callback, orig_callback_baton_sp, orig_is_sync);
74 //----------------------------------------------------------------------
76 //----------------------------------------------------------------------
77 WatchpointOptions::~WatchpointOptions() = default;
79 //------------------------------------------------------------------
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;
90 void WatchpointOptions::ClearCallback() {
91 m_callback = WatchpointOptions::NullCallback;
92 m_callback_is_synchronous = false;
93 m_callback_baton_sp.reset();
96 Baton *WatchpointOptions::GetBaton() { return m_callback_baton_sp.get(); }
98 const Baton *WatchpointOptions::GetBaton() const {
99 return m_callback_baton_sp.get();
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()
112 bool WatchpointOptions::HasCallback() {
113 return m_callback != WatchpointOptions::NullCallback;
116 const ThreadSpec *WatchpointOptions::GetThreadSpecNoCreate() const {
117 return m_thread_spec_ap.get();
120 ThreadSpec *WatchpointOptions::GetThreadSpec() {
121 if (m_thread_spec_ap.get() == nullptr)
122 m_thread_spec_ap.reset(new ThreadSpec());
124 return m_thread_spec_ap.get();
127 void WatchpointOptions::SetThreadID(lldb::tid_t thread_id) {
128 GetThreadSpec()->SetTID(thread_id);
131 void WatchpointOptions::GetCallbackDescription(
132 Stream *s, lldb::DescriptionLevel level) const {
133 if (m_callback_baton_sp.get()) {
135 m_callback_baton_sp->GetDescription(s, level);
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:
144 if ((GetThreadSpecNoCreate() != nullptr &&
145 GetThreadSpecNoCreate()->HasSpecification())) {
146 if (level == lldb::eDescriptionLevelVerbose) {
150 s->PutCString("Watchpoint Options:\n");
154 s->PutCString(" Options: ");
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) {
166 GetCallbackDescription(s, level);
169 void WatchpointOptions::CommandBaton::GetDescription(
170 Stream *s, lldb::DescriptionLevel level) const {
171 const CommandData *data = getItem();
173 if (level == eDescriptionLevelBrief) {
174 s->Printf(", commands = %s",
175 (data && data->user_source.GetSize() > 0) ? "yes" : "no");
180 s->Indent("watchpoint commands:\n");
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));
190 s->PutCString("No commands.\n");