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 //===----------------------------------------------------------------------===//
12 // Other libraries and framework includes
14 #include "lldb/Breakpoint/WatchpointOptions.h"
16 #include "lldb/Breakpoint/StoppointCallbackContext.h"
17 #include "lldb/Core/Stream.h"
18 #include "lldb/Core/StringList.h"
19 #include "lldb/Core/Value.h"
20 #include "lldb/Target/Process.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Target/ThreadSpec.h"
25 using namespace lldb_private;
27 bool WatchpointOptions::NullCallback(void *baton,
28 StoppointCallbackContext *context,
29 lldb::user_id_t watch_id) {
33 //----------------------------------------------------------------------
34 // WatchpointOptions constructor
35 //----------------------------------------------------------------------
36 WatchpointOptions::WatchpointOptions()
37 : m_callback(WatchpointOptions::NullCallback), m_callback_baton_sp(),
38 m_callback_is_synchronous(false), m_thread_spec_ap() {}
40 //----------------------------------------------------------------------
41 // WatchpointOptions copy constructor
42 //----------------------------------------------------------------------
43 WatchpointOptions::WatchpointOptions(const WatchpointOptions &rhs)
44 : m_callback(rhs.m_callback), m_callback_baton_sp(rhs.m_callback_baton_sp),
45 m_callback_is_synchronous(rhs.m_callback_is_synchronous),
47 if (rhs.m_thread_spec_ap.get() != nullptr)
48 m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
51 //----------------------------------------------------------------------
52 // WatchpointOptions assignment operator
53 //----------------------------------------------------------------------
54 const WatchpointOptions &WatchpointOptions::
55 operator=(const WatchpointOptions &rhs) {
56 m_callback = rhs.m_callback;
57 m_callback_baton_sp = rhs.m_callback_baton_sp;
58 m_callback_is_synchronous = rhs.m_callback_is_synchronous;
59 if (rhs.m_thread_spec_ap.get() != nullptr)
60 m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
65 WatchpointOptions::CopyOptionsNoCallback(WatchpointOptions &orig) {
66 WatchpointHitCallback orig_callback = orig.m_callback;
67 lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp;
68 bool orig_is_sync = orig.m_callback_is_synchronous;
71 WatchpointOptions *ret_val = new WatchpointOptions(orig);
73 orig.SetCallback(orig_callback, orig_callback_baton_sp, orig_is_sync);
78 //----------------------------------------------------------------------
80 //----------------------------------------------------------------------
81 WatchpointOptions::~WatchpointOptions() = default;
83 //------------------------------------------------------------------
85 //------------------------------------------------------------------
86 void WatchpointOptions::SetCallback(WatchpointHitCallback callback,
87 const BatonSP &callback_baton_sp,
88 bool callback_is_synchronous) {
89 m_callback_is_synchronous = callback_is_synchronous;
90 m_callback = callback;
91 m_callback_baton_sp = callback_baton_sp;
94 void WatchpointOptions::ClearCallback() {
95 m_callback = WatchpointOptions::NullCallback;
96 m_callback_is_synchronous = false;
97 m_callback_baton_sp.reset();
100 Baton *WatchpointOptions::GetBaton() { return m_callback_baton_sp.get(); }
102 const Baton *WatchpointOptions::GetBaton() const {
103 return m_callback_baton_sp.get();
106 bool WatchpointOptions::InvokeCallback(StoppointCallbackContext *context,
107 lldb::user_id_t watch_id) {
108 if (m_callback && context->is_synchronous == IsCallbackSynchronous()) {
109 return m_callback(m_callback_baton_sp ? m_callback_baton_sp->data()
116 bool WatchpointOptions::HasCallback() {
117 return m_callback != WatchpointOptions::NullCallback;
120 const ThreadSpec *WatchpointOptions::GetThreadSpecNoCreate() const {
121 return m_thread_spec_ap.get();
124 ThreadSpec *WatchpointOptions::GetThreadSpec() {
125 if (m_thread_spec_ap.get() == nullptr)
126 m_thread_spec_ap.reset(new ThreadSpec());
128 return m_thread_spec_ap.get();
131 void WatchpointOptions::SetThreadID(lldb::tid_t thread_id) {
132 GetThreadSpec()->SetTID(thread_id);
135 void WatchpointOptions::GetCallbackDescription(
136 Stream *s, lldb::DescriptionLevel level) const {
137 if (m_callback_baton_sp.get()) {
139 m_callback_baton_sp->GetDescription(s, level);
143 void WatchpointOptions::GetDescription(Stream *s,
144 lldb::DescriptionLevel level) const {
145 // Figure out if there are any options not at their default value, and only
147 // anything if there are:
149 if ((GetThreadSpecNoCreate() != nullptr &&
150 GetThreadSpecNoCreate()->HasSpecification())) {
151 if (level == lldb::eDescriptionLevelVerbose) {
155 s->PutCString("Watchpoint Options:\n");
159 s->PutCString(" Options: ");
161 if (m_thread_spec_ap.get())
162 m_thread_spec_ap->GetDescription(s, level);
163 else if (level == eDescriptionLevelBrief)
164 s->PutCString("thread spec: no ");
165 if (level == lldb::eDescriptionLevelFull) {
171 GetCallbackDescription(s, level);
174 void WatchpointOptions::CommandBaton::GetDescription(
175 Stream *s, lldb::DescriptionLevel level) const {
176 const CommandData *data = getItem();
178 if (level == eDescriptionLevelBrief) {
179 s->Printf(", commands = %s",
180 (data && data->user_source.GetSize() > 0) ? "yes" : "no");
185 s->Indent("watchpoint commands:\n");
188 if (data && data->user_source.GetSize() > 0) {
189 const size_t num_strings = data->user_source.GetSize();
190 for (size_t i = 0; i < num_strings; ++i) {
191 s->Indent(data->user_source.GetStringAtIndex(i));
195 s->PutCString("No commands.\n");