]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Breakpoint/WatchpointOptions.cpp
Merge clang 7.0.1 and several follow-up changes
[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 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "lldb/Breakpoint/WatchpointOptions.h"
15
16 #include "lldb/Breakpoint/StoppointCallbackContext.h"
17 #include "lldb/Core/Value.h"
18 #include "lldb/Target/Process.h"
19 #include "lldb/Target/Target.h"
20 #include "lldb/Target/ThreadSpec.h"
21 #include "lldb/Utility/Stream.h"
22 #include "lldb/Utility/StringList.h"
23
24 using namespace lldb;
25 using namespace lldb_private;
26
27 bool WatchpointOptions::NullCallback(void *baton,
28                                      StoppointCallbackContext *context,
29                                      lldb::user_id_t watch_id) {
30   return true;
31 }
32
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() {}
39
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),
46       m_thread_spec_ap() {
47   if (rhs.m_thread_spec_ap.get() != nullptr)
48     m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
49 }
50
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()));
61   return *this;
62 }
63
64 WatchpointOptions *
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;
69
70   orig.ClearCallback();
71   WatchpointOptions *ret_val = new WatchpointOptions(orig);
72
73   orig.SetCallback(orig_callback, orig_callback_baton_sp, orig_is_sync);
74
75   return ret_val;
76 }
77
78 //----------------------------------------------------------------------
79 // Destructor
80 //----------------------------------------------------------------------
81 WatchpointOptions::~WatchpointOptions() = default;
82
83 //------------------------------------------------------------------
84 // Callbacks
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;
92 }
93
94 void WatchpointOptions::ClearCallback() {
95   m_callback = WatchpointOptions::NullCallback;
96   m_callback_is_synchronous = false;
97   m_callback_baton_sp.reset();
98 }
99
100 Baton *WatchpointOptions::GetBaton() { return m_callback_baton_sp.get(); }
101
102 const Baton *WatchpointOptions::GetBaton() const {
103   return m_callback_baton_sp.get();
104 }
105
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()
110                                           : nullptr,
111                       context, watch_id);
112   } else
113     return true;
114 }
115
116 bool WatchpointOptions::HasCallback() {
117   return m_callback != WatchpointOptions::NullCallback;
118 }
119
120 const ThreadSpec *WatchpointOptions::GetThreadSpecNoCreate() const {
121   return m_thread_spec_ap.get();
122 }
123
124 ThreadSpec *WatchpointOptions::GetThreadSpec() {
125   if (m_thread_spec_ap.get() == nullptr)
126     m_thread_spec_ap.reset(new ThreadSpec());
127
128   return m_thread_spec_ap.get();
129 }
130
131 void WatchpointOptions::SetThreadID(lldb::tid_t thread_id) {
132   GetThreadSpec()->SetTID(thread_id);
133 }
134
135 void WatchpointOptions::GetCallbackDescription(
136     Stream *s, lldb::DescriptionLevel level) const {
137   if (m_callback_baton_sp.get()) {
138     s->EOL();
139     m_callback_baton_sp->GetDescription(s, level);
140   }
141 }
142
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
146   // print anything if there are:
147
148   if ((GetThreadSpecNoCreate() != nullptr &&
149        GetThreadSpecNoCreate()->HasSpecification())) {
150     if (level == lldb::eDescriptionLevelVerbose) {
151       s->EOL();
152       s->IndentMore();
153       s->Indent();
154       s->PutCString("Watchpoint Options:\n");
155       s->IndentMore();
156       s->Indent();
157     } else
158       s->PutCString(" Options: ");
159
160     if (m_thread_spec_ap.get())
161       m_thread_spec_ap->GetDescription(s, level);
162     else if (level == eDescriptionLevelBrief)
163       s->PutCString("thread spec: no ");
164     if (level == lldb::eDescriptionLevelFull) {
165       s->IndentLess();
166       s->IndentMore();
167     }
168   }
169
170   GetCallbackDescription(s, level);
171 }
172
173 void WatchpointOptions::CommandBaton::GetDescription(
174     Stream *s, lldb::DescriptionLevel level) const {
175   const CommandData *data = getItem();
176
177   if (level == eDescriptionLevelBrief) {
178     s->Printf(", commands = %s",
179               (data && data->user_source.GetSize() > 0) ? "yes" : "no");
180     return;
181   }
182
183   s->IndentMore();
184   s->Indent("watchpoint commands:\n");
185
186   s->IndentMore();
187   if (data && data->user_source.GetSize() > 0) {
188     const size_t num_strings = data->user_source.GetSize();
189     for (size_t i = 0; i < num_strings; ++i) {
190       s->Indent(data->user_source.GetStringAtIndex(i));
191       s->EOL();
192     }
193   } else {
194     s->PutCString("No commands.\n");
195   }
196   s->IndentLess();
197   s->IndentLess();
198 }