1 //===-- SBEvent.cpp -------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/API/SBEvent.h"
10 #include "SBReproducerPrivate.h"
11 #include "lldb/API/SBBroadcaster.h"
12 #include "lldb/API/SBStream.h"
13 
14 #include "lldb/Breakpoint/Breakpoint.h"
15 #include "lldb/Core/StreamFile.h"
16 #include "lldb/Interpreter/CommandInterpreter.h"
17 #include "lldb/Target/Process.h"
18 #include "lldb/Utility/ConstString.h"
19 #include "lldb/Utility/Event.h"
20 #include "lldb/Utility/Stream.h"
21 
22 using namespace lldb;
23 using namespace lldb_private;
24 
25 SBEvent::SBEvent() : m_event_sp() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBEvent); }
26 
27 SBEvent::SBEvent(uint32_t event_type, const char *cstr, uint32_t cstr_len)
28     : m_event_sp(new Event(event_type, new EventDataBytes(cstr, cstr_len))),
29       m_opaque_ptr(m_event_sp.get()) {
30   LLDB_RECORD_CONSTRUCTOR(SBEvent, (uint32_t, const char *, uint32_t),
31                           event_type, cstr, cstr_len);
32 }
33 
34 SBEvent::SBEvent(EventSP &event_sp)
35     : m_event_sp(event_sp), m_opaque_ptr(event_sp.get()) {
36   LLDB_RECORD_CONSTRUCTOR(SBEvent, (lldb::EventSP &), event_sp);
37 }
38 
39 SBEvent::SBEvent(Event *event_ptr) : m_event_sp(), m_opaque_ptr(event_ptr) {
40   LLDB_RECORD_CONSTRUCTOR(SBEvent, (lldb_private::Event *), event_ptr);
41 }
42 
43 SBEvent::SBEvent(const SBEvent &rhs)
44     : m_event_sp(rhs.m_event_sp), m_opaque_ptr(rhs.m_opaque_ptr) {
45   LLDB_RECORD_CONSTRUCTOR(SBEvent, (const lldb::SBEvent &), rhs);
46 }
47 
48 const SBEvent &SBEvent::operator=(const SBEvent &rhs) {
49   LLDB_RECORD_METHOD(const lldb::SBEvent &,
50                      SBEvent, operator=,(const lldb::SBEvent &), rhs);
51 
52   if (this != &rhs) {
53     m_event_sp = rhs.m_event_sp;
54     m_opaque_ptr = rhs.m_opaque_ptr;
55   }
56   return LLDB_RECORD_RESULT(*this);
57 }
58 
59 SBEvent::~SBEvent() = default;
60 
61 const char *SBEvent::GetDataFlavor() {
62   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBEvent, GetDataFlavor);
63 
64   Event *lldb_event = get();
65   if (lldb_event) {
66     EventData *event_data = lldb_event->GetData();
67     if (event_data)
68       return lldb_event->GetData()->GetFlavor().AsCString();
69   }
70   return nullptr;
71 }
72 
73 uint32_t SBEvent::GetType() const {
74   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBEvent, GetType);
75 
76 
77   const Event *lldb_event = get();
78   uint32_t event_type = 0;
79   if (lldb_event)
80     event_type = lldb_event->GetType();
81 
82 
83   return event_type;
84 }
85 
86 SBBroadcaster SBEvent::GetBroadcaster() const {
87   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBBroadcaster, SBEvent,
88                                    GetBroadcaster);
89 
90   SBBroadcaster broadcaster;
91   const Event *lldb_event = get();
92   if (lldb_event)
93     broadcaster.reset(lldb_event->GetBroadcaster(), false);
94   return LLDB_RECORD_RESULT(broadcaster);
95 }
96 
97 const char *SBEvent::GetBroadcasterClass() const {
98   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBEvent, GetBroadcasterClass);
99 
100   const Event *lldb_event = get();
101   if (lldb_event)
102     return lldb_event->GetBroadcaster()->GetBroadcasterClass().AsCString();
103   else
104     return "unknown class";
105 }
106 
107 bool SBEvent::BroadcasterMatchesPtr(const SBBroadcaster *broadcaster) {
108   LLDB_RECORD_METHOD(bool, SBEvent, BroadcasterMatchesPtr,
109                      (const lldb::SBBroadcaster *), broadcaster);
110 
111   if (broadcaster)
112     return BroadcasterMatchesRef(*broadcaster);
113   return false;
114 }
115 
116 bool SBEvent::BroadcasterMatchesRef(const SBBroadcaster &broadcaster) {
117   LLDB_RECORD_METHOD(bool, SBEvent, BroadcasterMatchesRef,
118                      (const lldb::SBBroadcaster &), broadcaster);
119 
120   Event *lldb_event = get();
121   bool success = false;
122   if (lldb_event)
123     success = lldb_event->BroadcasterIs(broadcaster.get());
124 
125 
126   return success;
127 }
128 
129 void SBEvent::Clear() {
130   LLDB_RECORD_METHOD_NO_ARGS(void, SBEvent, Clear);
131 
132   Event *lldb_event = get();
133   if (lldb_event)
134     lldb_event->Clear();
135 }
136 
137 EventSP &SBEvent::GetSP() const { return m_event_sp; }
138 
139 Event *SBEvent::get() const {
140   // There is a dangerous accessor call GetSharedPtr which can be used, so if
141   // we have anything valid in m_event_sp, we must use that since if it gets
142   // used by a function that puts something in there, then it won't update
143   // m_opaque_ptr...
144   if (m_event_sp)
145     m_opaque_ptr = m_event_sp.get();
146 
147   return m_opaque_ptr;
148 }
149 
150 void SBEvent::reset(EventSP &event_sp) {
151   m_event_sp = event_sp;
152   m_opaque_ptr = m_event_sp.get();
153 }
154 
155 void SBEvent::reset(Event *event_ptr) {
156   m_opaque_ptr = event_ptr;
157   m_event_sp.reset();
158 }
159 
160 bool SBEvent::IsValid() const {
161   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBEvent, IsValid);
162   return this->operator bool();
163 }
164 SBEvent::operator bool() const {
165   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBEvent, operator bool);
166 
167   // Do NOT use m_opaque_ptr directly!!! Must use the SBEvent::get() accessor.
168   // See comments in SBEvent::get()....
169   return SBEvent::get() != nullptr;
170 }
171 
172 const char *SBEvent::GetCStringFromEvent(const SBEvent &event) {
173   LLDB_RECORD_STATIC_METHOD(const char *, SBEvent, GetCStringFromEvent,
174                             (const lldb::SBEvent &), event);
175 
176   return static_cast<const char *>(
177       EventDataBytes::GetBytesFromEvent(event.get()));
178 }
179 
180 bool SBEvent::GetDescription(SBStream &description) {
181   LLDB_RECORD_METHOD(bool, SBEvent, GetDescription, (lldb::SBStream &),
182                      description);
183 
184   Stream &strm = description.ref();
185 
186   if (get()) {
187     m_opaque_ptr->Dump(&strm);
188   } else
189     strm.PutCString("No value");
190 
191   return true;
192 }
193 
194 bool SBEvent::GetDescription(SBStream &description) const {
195   LLDB_RECORD_METHOD_CONST(bool, SBEvent, GetDescription, (lldb::SBStream &),
196                            description);
197 
198   Stream &strm = description.ref();
199 
200   if (get()) {
201     m_opaque_ptr->Dump(&strm);
202   } else
203     strm.PutCString("No value");
204 
205   return true;
206 }
207 
208 namespace lldb_private {
209 namespace repro {
210 
211 template <>
212 void RegisterMethods<SBEvent>(Registry &R) {
213   LLDB_REGISTER_CONSTRUCTOR(SBEvent, ());
214   LLDB_REGISTER_CONSTRUCTOR(SBEvent, (uint32_t, const char *, uint32_t));
215   LLDB_REGISTER_CONSTRUCTOR(SBEvent, (lldb::EventSP &));
216   LLDB_REGISTER_CONSTRUCTOR(SBEvent, (lldb_private::Event *));
217   LLDB_REGISTER_CONSTRUCTOR(SBEvent, (const lldb::SBEvent &));
218   LLDB_REGISTER_METHOD(const lldb::SBEvent &,
219                        SBEvent, operator=,(const lldb::SBEvent &));
220   LLDB_REGISTER_METHOD(const char *, SBEvent, GetDataFlavor, ());
221   LLDB_REGISTER_METHOD_CONST(uint32_t, SBEvent, GetType, ());
222   LLDB_REGISTER_METHOD_CONST(lldb::SBBroadcaster, SBEvent, GetBroadcaster,
223                              ());
224   LLDB_REGISTER_METHOD_CONST(const char *, SBEvent, GetBroadcasterClass, ());
225   LLDB_REGISTER_METHOD(bool, SBEvent, BroadcasterMatchesPtr,
226                        (const lldb::SBBroadcaster *));
227   LLDB_REGISTER_METHOD(bool, SBEvent, BroadcasterMatchesRef,
228                        (const lldb::SBBroadcaster &));
229   LLDB_REGISTER_METHOD(void, SBEvent, Clear, ());
230   LLDB_REGISTER_METHOD_CONST(bool, SBEvent, IsValid, ());
231   LLDB_REGISTER_METHOD_CONST(bool, SBEvent, operator bool, ());
232   LLDB_REGISTER_STATIC_METHOD(const char *, SBEvent, GetCStringFromEvent,
233                               (const lldb::SBEvent &));
234   LLDB_REGISTER_METHOD(bool, SBEvent, GetDescription, (lldb::SBStream &));
235   LLDB_REGISTER_METHOD_CONST(bool, SBEvent, GetDescription,
236                              (lldb::SBStream &));
237 }
238 
239 }
240 }
241