1 //===-- SBBreakpointName.cpp ----------------------------------------*- C++ -*-===//
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/SBBreakpointName.h"
10 #include "SBReproducerPrivate.h"
11 #include "lldb/API/SBDebugger.h"
12 #include "lldb/API/SBError.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/API/SBStringList.h"
15 #include "lldb/API/SBTarget.h"
16 
17 #include "lldb/Breakpoint/BreakpointName.h"
18 #include "lldb/Breakpoint/StoppointCallbackContext.h"
19 #include "lldb/Core/Debugger.h"
20 #include "lldb/Interpreter/CommandInterpreter.h"
21 #include "lldb/Interpreter/ScriptInterpreter.h"
22 #include "lldb/Target/Target.h"
23 #include "lldb/Target/ThreadSpec.h"
24 #include "lldb/Utility/Log.h"
25 #include "lldb/Utility/Stream.h"
26 
27 #include "SBBreakpointOptionCommon.h"
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 
32 namespace lldb
33 {
34 class SBBreakpointNameImpl {
35 public:
36   SBBreakpointNameImpl(TargetSP target_sp, const char *name) {
37     if (!name || name[0] == '\0')
38       return;
39     m_name.assign(name);
40 
41     if (!target_sp)
42       return;
43 
44     m_target_wp = target_sp;
45   }
46 
47   SBBreakpointNameImpl(SBTarget &sb_target, const char *name);
48   bool operator==(const SBBreakpointNameImpl &rhs);
49   bool operator!=(const SBBreakpointNameImpl &rhs);
50 
51   // For now we take a simple approach and only keep the name, and relook up
52   // the location when we need it.
53 
54   TargetSP GetTarget() const {
55     return m_target_wp.lock();
56   }
57 
58   const char *GetName() const {
59     return m_name.c_str();
60   }
61 
62   bool IsValid() const {
63     return !m_name.empty() && m_target_wp.lock();
64   }
65 
66   lldb_private::BreakpointName *GetBreakpointName() const;
67 
68 private:
69   TargetWP m_target_wp;
70   std::string m_name;
71 };
72 
73 SBBreakpointNameImpl::SBBreakpointNameImpl(SBTarget &sb_target,
74                                            const char *name) {
75   if (!name || name[0] == '\0')
76     return;
77   m_name.assign(name);
78 
79   if (!sb_target.IsValid())
80     return;
81 
82   TargetSP target_sp = sb_target.GetSP();
83   if (!target_sp)
84     return;
85 
86   m_target_wp = target_sp;
87 }
88 
89 bool SBBreakpointNameImpl::operator==(const SBBreakpointNameImpl &rhs) {
90   return m_name == rhs.m_name && m_target_wp.lock() == rhs.m_target_wp.lock();
91 }
92 
93 bool SBBreakpointNameImpl::operator!=(const SBBreakpointNameImpl &rhs) {
94   return m_name != rhs.m_name || m_target_wp.lock() != rhs.m_target_wp.lock();
95 }
96 
97 lldb_private::BreakpointName *SBBreakpointNameImpl::GetBreakpointName() const {
98   if (!IsValid())
99     return nullptr;
100   TargetSP target_sp = GetTarget();
101   if (!target_sp)
102     return nullptr;
103   Status error;
104   return target_sp->FindBreakpointName(ConstString(m_name), true, error);
105 }
106 
107 } // namespace lldb
108 
109 SBBreakpointName::SBBreakpointName() {
110   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBBreakpointName);
111 }
112 
113 SBBreakpointName::SBBreakpointName(SBTarget &sb_target, const char *name) {
114   LLDB_RECORD_CONSTRUCTOR(SBBreakpointName, (lldb::SBTarget &, const char *),
115                           sb_target, name);
116 
117   m_impl_up.reset(new SBBreakpointNameImpl(sb_target, name));
118   // Call FindBreakpointName here to make sure the name is valid, reset if not:
119   BreakpointName *bp_name = GetBreakpointName();
120   if (!bp_name)
121     m_impl_up.reset();
122 }
123 
124 SBBreakpointName::SBBreakpointName(SBBreakpoint &sb_bkpt, const char *name) {
125   LLDB_RECORD_CONSTRUCTOR(SBBreakpointName,
126                           (lldb::SBBreakpoint &, const char *), sb_bkpt, name);
127 
128   if (!sb_bkpt.IsValid()) {
129     m_impl_up.reset();
130     return;
131   }
132   BreakpointSP bkpt_sp = sb_bkpt.GetSP();
133   Target &target = bkpt_sp->GetTarget();
134 
135   m_impl_up.reset(new SBBreakpointNameImpl(target.shared_from_this(), name));
136 
137   // Call FindBreakpointName here to make sure the name is valid, reset if not:
138   BreakpointName *bp_name = GetBreakpointName();
139   if (!bp_name) {
140     m_impl_up.reset();
141     return;
142   }
143 
144   // Now copy over the breakpoint's options:
145   target.ConfigureBreakpointName(*bp_name, *bkpt_sp->GetOptions(),
146                                  BreakpointName::Permissions());
147 }
148 
149 SBBreakpointName::SBBreakpointName(const SBBreakpointName &rhs) {
150   LLDB_RECORD_CONSTRUCTOR(SBBreakpointName, (const lldb::SBBreakpointName &),
151                           rhs);
152 
153   if (!rhs.m_impl_up)
154     return;
155   else
156     m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(),
157                                              rhs.m_impl_up->GetName()));
158 }
159 
160 SBBreakpointName::~SBBreakpointName() = default;
161 
162 const SBBreakpointName &SBBreakpointName::
163 operator=(const SBBreakpointName &rhs) {
164   LLDB_RECORD_METHOD(
165       const lldb::SBBreakpointName &,
166       SBBreakpointName, operator=,(const lldb::SBBreakpointName &), rhs);
167 
168   if (!rhs.m_impl_up) {
169     m_impl_up.reset();
170     return *this;
171   }
172 
173   m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(),
174                                            rhs.m_impl_up->GetName()));
175   return *this;
176 }
177 
178 bool SBBreakpointName::operator==(const lldb::SBBreakpointName &rhs) {
179   LLDB_RECORD_METHOD(
180       bool, SBBreakpointName, operator==,(const lldb::SBBreakpointName &), rhs);
181 
182   return *m_impl_up == *rhs.m_impl_up;
183 }
184 
185 bool SBBreakpointName::operator!=(const lldb::SBBreakpointName &rhs) {
186   LLDB_RECORD_METHOD(
187       bool, SBBreakpointName, operator!=,(const lldb::SBBreakpointName &), rhs);
188 
189   return *m_impl_up != *rhs.m_impl_up;
190 }
191 
192 bool SBBreakpointName::IsValid() const {
193   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpointName, IsValid);
194 
195   if (!m_impl_up)
196     return false;
197   return m_impl_up->IsValid();
198 }
199 
200 const char *SBBreakpointName::GetName() const {
201   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpointName, GetName);
202 
203   if (!m_impl_up)
204     return "<Invalid Breakpoint Name Object>";
205   return m_impl_up->GetName();
206 }
207 
208 void SBBreakpointName::SetEnabled(bool enable) {
209   LLDB_RECORD_METHOD(void, SBBreakpointName, SetEnabled, (bool), enable);
210 
211   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
212 
213   BreakpointName *bp_name = GetBreakpointName();
214   if (!bp_name)
215     return;
216 
217   LLDB_LOG(log, "Name: {0} enabled: {1}\n", bp_name->GetName(), enable);
218   std::lock_guard<std::recursive_mutex> guard(
219         m_impl_up->GetTarget()->GetAPIMutex());
220 
221   bp_name->GetOptions().SetEnabled(enable);
222 }
223 
224 void SBBreakpointName::UpdateName(BreakpointName &bp_name) {
225   if (!IsValid())
226     return;
227 
228   TargetSP target_sp = m_impl_up->GetTarget();
229   if (!target_sp)
230     return;
231   target_sp->ApplyNameToBreakpoints(bp_name);
232 
233 }
234 
235 bool SBBreakpointName::IsEnabled() {
236   LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpointName, IsEnabled);
237 
238   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
239 
240   BreakpointName *bp_name = GetBreakpointName();
241   if (!bp_name)
242     return false;
243 
244   LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
245   std::lock_guard<std::recursive_mutex> guard(
246         m_impl_up->GetTarget()->GetAPIMutex());
247 
248   return bp_name->GetOptions().IsEnabled();
249 }
250 
251 void SBBreakpointName::SetOneShot(bool one_shot) {
252   LLDB_RECORD_METHOD(void, SBBreakpointName, SetOneShot, (bool), one_shot);
253 
254   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
255 
256   BreakpointName *bp_name = GetBreakpointName();
257   if (!bp_name)
258     return;
259 
260   LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(), one_shot);
261   std::lock_guard<std::recursive_mutex> guard(
262         m_impl_up->GetTarget()->GetAPIMutex());
263 
264   bp_name->GetOptions().SetOneShot(one_shot);
265   UpdateName(*bp_name);
266 }
267 
268 bool SBBreakpointName::IsOneShot() const {
269   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpointName, IsOneShot);
270 
271   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
272 
273   const BreakpointName *bp_name = GetBreakpointName();
274   if (!bp_name)
275     return false;
276 
277   LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
278   std::lock_guard<std::recursive_mutex> guard(
279         m_impl_up->GetTarget()->GetAPIMutex());
280 
281   return bp_name->GetOptions().IsOneShot();
282 }
283 
284 void SBBreakpointName::SetIgnoreCount(uint32_t count) {
285   LLDB_RECORD_METHOD(void, SBBreakpointName, SetIgnoreCount, (uint32_t), count);
286 
287   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
288 
289   BreakpointName *bp_name = GetBreakpointName();
290   if (!bp_name)
291     return;
292 
293   LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(), count);
294   std::lock_guard<std::recursive_mutex> guard(
295         m_impl_up->GetTarget()->GetAPIMutex());
296 
297   bp_name->GetOptions().SetIgnoreCount(count);
298   UpdateName(*bp_name);
299 }
300 
301 uint32_t SBBreakpointName::GetIgnoreCount() const {
302   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpointName, GetIgnoreCount);
303 
304   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
305 
306   BreakpointName *bp_name = GetBreakpointName();
307   if (!bp_name)
308     return false;
309 
310   LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
311   std::lock_guard<std::recursive_mutex> guard(
312         m_impl_up->GetTarget()->GetAPIMutex());
313 
314   return bp_name->GetOptions().GetIgnoreCount();
315 }
316 
317 void SBBreakpointName::SetCondition(const char *condition) {
318   LLDB_RECORD_METHOD(void, SBBreakpointName, SetCondition, (const char *),
319                      condition);
320 
321   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
322 
323   BreakpointName *bp_name = GetBreakpointName();
324   if (!bp_name)
325     return;
326 
327   LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(),
328           condition ? condition : "<NULL>");
329 
330   std::lock_guard<std::recursive_mutex> guard(
331         m_impl_up->GetTarget()->GetAPIMutex());
332 
333   bp_name->GetOptions().SetCondition(condition);
334   UpdateName(*bp_name);
335 }
336 
337 const char *SBBreakpointName::GetCondition() {
338   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBBreakpointName, GetCondition);
339 
340   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
341 
342   BreakpointName *bp_name = GetBreakpointName();
343   if (!bp_name)
344     return nullptr;
345 
346   LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
347   std::lock_guard<std::recursive_mutex> guard(
348         m_impl_up->GetTarget()->GetAPIMutex());
349 
350   return bp_name->GetOptions().GetConditionText();
351 }
352 
353 void SBBreakpointName::SetAutoContinue(bool auto_continue) {
354   LLDB_RECORD_METHOD(void, SBBreakpointName, SetAutoContinue, (bool),
355                      auto_continue);
356 
357   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
358 
359   BreakpointName *bp_name = GetBreakpointName();
360   if (!bp_name)
361     return;
362 
363   LLDB_LOG(log, "Name: {0} auto-continue: {1}\n", bp_name->GetName(), auto_continue);
364 
365   std::lock_guard<std::recursive_mutex> guard(
366         m_impl_up->GetTarget()->GetAPIMutex());
367 
368   bp_name->GetOptions().SetAutoContinue(auto_continue);
369   UpdateName(*bp_name);
370 }
371 
372 bool SBBreakpointName::GetAutoContinue() {
373   LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpointName, GetAutoContinue);
374 
375   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
376 
377   BreakpointName *bp_name = GetBreakpointName();
378   if (!bp_name)
379     return false;
380 
381   LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
382   std::lock_guard<std::recursive_mutex> guard(
383         m_impl_up->GetTarget()->GetAPIMutex());
384 
385   return bp_name->GetOptions().IsAutoContinue();
386 }
387 
388 void SBBreakpointName::SetThreadID(tid_t tid) {
389   LLDB_RECORD_METHOD(void, SBBreakpointName, SetThreadID, (lldb::tid_t), tid);
390 
391   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
392 
393   BreakpointName *bp_name = GetBreakpointName();
394   if (!bp_name)
395     return;
396 
397   LLDB_LOG(log, "Name: {0} tid: {1:x}\n", bp_name->GetName(), tid);
398 
399   std::lock_guard<std::recursive_mutex> guard(
400         m_impl_up->GetTarget()->GetAPIMutex());
401 
402   bp_name->GetOptions().SetThreadID(tid);
403   UpdateName(*bp_name);
404 }
405 
406 tid_t SBBreakpointName::GetThreadID() {
407   LLDB_RECORD_METHOD_NO_ARGS(lldb::tid_t, SBBreakpointName, GetThreadID);
408 
409   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
410 
411   BreakpointName *bp_name = GetBreakpointName();
412   if (!bp_name)
413     return LLDB_INVALID_THREAD_ID;
414 
415   LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
416   std::lock_guard<std::recursive_mutex> guard(
417         m_impl_up->GetTarget()->GetAPIMutex());
418 
419   return bp_name->GetOptions().GetThreadSpec()->GetTID();
420 }
421 
422 void SBBreakpointName::SetThreadIndex(uint32_t index) {
423   LLDB_RECORD_METHOD(void, SBBreakpointName, SetThreadIndex, (uint32_t), index);
424 
425   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
426 
427   BreakpointName *bp_name = GetBreakpointName();
428   if (!bp_name)
429     return;
430 
431   LLDB_LOG(log, "Name: {0} thread index: {1}\n", bp_name->GetName(), index);
432 
433   std::lock_guard<std::recursive_mutex> guard(
434         m_impl_up->GetTarget()->GetAPIMutex());
435 
436   bp_name->GetOptions().GetThreadSpec()->SetIndex(index);
437   UpdateName(*bp_name);
438 }
439 
440 uint32_t SBBreakpointName::GetThreadIndex() const {
441   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpointName, GetThreadIndex);
442 
443   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
444 
445   BreakpointName *bp_name = GetBreakpointName();
446   if (!bp_name)
447     return LLDB_INVALID_THREAD_ID;
448 
449   LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
450   std::lock_guard<std::recursive_mutex> guard(
451         m_impl_up->GetTarget()->GetAPIMutex());
452 
453   return bp_name->GetOptions().GetThreadSpec()->GetIndex();
454 }
455 
456 void SBBreakpointName::SetThreadName(const char *thread_name) {
457   LLDB_RECORD_METHOD(void, SBBreakpointName, SetThreadName, (const char *),
458                      thread_name);
459 
460   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
461 
462   BreakpointName *bp_name = GetBreakpointName();
463   if (!bp_name)
464     return;
465 
466   LLDB_LOG(log, "Name: {0} thread name: {1}\n", bp_name->GetName(), thread_name);
467 
468   std::lock_guard<std::recursive_mutex> guard(
469         m_impl_up->GetTarget()->GetAPIMutex());
470 
471   bp_name->GetOptions().GetThreadSpec()->SetName(thread_name);
472   UpdateName(*bp_name);
473 }
474 
475 const char *SBBreakpointName::GetThreadName() const {
476   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpointName,
477                                    GetThreadName);
478 
479   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
480 
481   BreakpointName *bp_name = GetBreakpointName();
482   if (!bp_name)
483     return nullptr;
484 
485   LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
486   std::lock_guard<std::recursive_mutex> guard(
487         m_impl_up->GetTarget()->GetAPIMutex());
488 
489   return bp_name->GetOptions().GetThreadSpec()->GetName();
490 }
491 
492 void SBBreakpointName::SetQueueName(const char *queue_name) {
493   LLDB_RECORD_METHOD(void, SBBreakpointName, SetQueueName, (const char *),
494                      queue_name);
495 
496   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
497 
498   BreakpointName *bp_name = GetBreakpointName();
499   if (!bp_name)
500     return;
501 
502   LLDB_LOG(log, "Name: {0} queue name: {1}\n", bp_name->GetName(), queue_name);
503 
504   std::lock_guard<std::recursive_mutex> guard(
505         m_impl_up->GetTarget()->GetAPIMutex());
506 
507   bp_name->GetOptions().GetThreadSpec()->SetQueueName(queue_name);
508   UpdateName(*bp_name);
509 }
510 
511 const char *SBBreakpointName::GetQueueName() const {
512   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpointName,
513                                    GetQueueName);
514 
515   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
516 
517   BreakpointName *bp_name = GetBreakpointName();
518   if (!bp_name)
519     return nullptr;
520 
521   LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
522   std::lock_guard<std::recursive_mutex> guard(
523         m_impl_up->GetTarget()->GetAPIMutex());
524 
525   return bp_name->GetOptions().GetThreadSpec()->GetQueueName();
526 }
527 
528 void SBBreakpointName::SetCommandLineCommands(SBStringList &commands) {
529   LLDB_RECORD_METHOD(void, SBBreakpointName, SetCommandLineCommands,
530                      (lldb::SBStringList &), commands);
531 
532   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
533   BreakpointName *bp_name = GetBreakpointName();
534   if (!bp_name)
535     return;
536   if (commands.GetSize() == 0)
537     return;
538 
539   LLDB_LOG(log, "Name: {0} commands\n", bp_name->GetName());
540 
541   std::lock_guard<std::recursive_mutex> guard(
542         m_impl_up->GetTarget()->GetAPIMutex());
543   std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(
544       new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));
545 
546   bp_name->GetOptions().SetCommandDataCallback(cmd_data_up);
547   UpdateName(*bp_name);
548 }
549 
550 bool SBBreakpointName::GetCommandLineCommands(SBStringList &commands) {
551   LLDB_RECORD_METHOD(bool, SBBreakpointName, GetCommandLineCommands,
552                      (lldb::SBStringList &), commands);
553 
554   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
555 
556   BreakpointName *bp_name = GetBreakpointName();
557   if (!bp_name)
558     return false;
559 
560   LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
561   StringList command_list;
562   bool has_commands =
563       bp_name->GetOptions().GetCommandLineCallbacks(command_list);
564   if (has_commands)
565     commands.AppendList(command_list);
566   return has_commands;
567 }
568 
569 const char *SBBreakpointName::GetHelpString() const {
570   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpointName,
571                                    GetHelpString);
572 
573   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
574 
575   BreakpointName *bp_name = GetBreakpointName();
576   if (!bp_name)
577     return "";
578 
579   LLDB_LOG(log, "Help: {0}\n", bp_name->GetHelp());
580   return bp_name->GetHelp();
581 }
582 
583 void SBBreakpointName::SetHelpString(const char *help_string) {
584   LLDB_RECORD_METHOD(void, SBBreakpointName, SetHelpString, (const char *),
585                      help_string);
586 
587   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
588   BreakpointName *bp_name = GetBreakpointName();
589   if (!bp_name)
590     return;
591 
592   LLDB_LOG(log, "Name: {0} help: {1}\n", bp_name->GetName(), help_string);
593 
594   std::lock_guard<std::recursive_mutex> guard(
595         m_impl_up->GetTarget()->GetAPIMutex());
596   bp_name->SetHelp(help_string);
597 }
598 
599 bool SBBreakpointName::GetDescription(SBStream &s) {
600   LLDB_RECORD_METHOD(bool, SBBreakpointName, GetDescription, (lldb::SBStream &),
601                      s);
602 
603   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
604 
605   BreakpointName *bp_name = GetBreakpointName();
606   if (!bp_name)
607   {
608     s.Printf("No value");
609     return false;
610   }
611 
612   LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
613   std::lock_guard<std::recursive_mutex> guard(
614         m_impl_up->GetTarget()->GetAPIMutex());
615   bp_name->GetDescription(s.get(), eDescriptionLevelFull);
616   return true;
617 }
618 
619 void SBBreakpointName::SetCallback(SBBreakpointHitCallback callback,
620                                    void *baton) {
621   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
622   BreakpointName *bp_name = GetBreakpointName();
623   if (!bp_name)
624     return;
625   LLDB_LOG(log, "callback = {1}, baton = {2}", callback, baton);
626   std::lock_guard<std::recursive_mutex> guard(
627         m_impl_up->GetTarget()->GetAPIMutex());
628 
629   BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
630   bp_name->GetOptions().SetCallback(SBBreakpointCallbackBaton
631                                        ::PrivateBreakpointHitCallback,
632                                     baton_sp,
633                                     false);
634   UpdateName(*bp_name);
635 }
636 
637 void SBBreakpointName::SetScriptCallbackFunction(
638     const char *callback_function_name) {
639   LLDB_RECORD_METHOD(void, SBBreakpointName, SetScriptCallbackFunction,
640                      (const char *), callback_function_name);
641 
642   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
643 
644   BreakpointName *bp_name = GetBreakpointName();
645   if (!bp_name)
646     return;
647 
648   LLDB_LOG(log, "Name: {0} callback: {1}\n", bp_name->GetName(),
649            callback_function_name);
650 
651   std::lock_guard<std::recursive_mutex> guard(
652         m_impl_up->GetTarget()->GetAPIMutex());
653 
654   BreakpointOptions &bp_options = bp_name->GetOptions();
655   m_impl_up->GetTarget()
656       ->GetDebugger()
657       .GetCommandInterpreter()
658       .GetScriptInterpreter()
659       ->SetBreakpointCommandCallbackFunction(&bp_options,
660                                              callback_function_name);
661   UpdateName(*bp_name);
662 }
663 
664 SBError
665 SBBreakpointName::SetScriptCallbackBody(const char *callback_body_text) {
666   LLDB_RECORD_METHOD(lldb::SBError, SBBreakpointName, SetScriptCallbackBody,
667                      (const char *), callback_body_text);
668 
669   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
670   SBError sb_error;
671   BreakpointName *bp_name = GetBreakpointName();
672   if (!bp_name)
673     return LLDB_RECORD_RESULT(sb_error);
674 
675   LLDB_LOG(log, "Name: {0} callback: {1}\n", bp_name->GetName(),
676            callback_body_text);
677 
678   std::lock_guard<std::recursive_mutex> guard(
679         m_impl_up->GetTarget()->GetAPIMutex());
680 
681   BreakpointOptions &bp_options = bp_name->GetOptions();
682   Status error =
683       m_impl_up->GetTarget()
684           ->GetDebugger()
685           .GetCommandInterpreter()
686           .GetScriptInterpreter()
687           ->SetBreakpointCommandCallback(&bp_options, callback_body_text);
688   sb_error.SetError(error);
689   if (!sb_error.Fail())
690     UpdateName(*bp_name);
691 
692   return LLDB_RECORD_RESULT(sb_error);
693 }
694 
695 bool SBBreakpointName::GetAllowList() const {
696   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpointName, GetAllowList);
697 
698   BreakpointName *bp_name = GetBreakpointName();
699   if (!bp_name)
700     return false;
701   return bp_name->GetPermissions().GetAllowList();
702 }
703 
704 void SBBreakpointName::SetAllowList(bool value) {
705   LLDB_RECORD_METHOD(void, SBBreakpointName, SetAllowList, (bool), value);
706 
707   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
708 
709   BreakpointName *bp_name = GetBreakpointName();
710   if (!bp_name)
711     return;
712   if (log)
713     log->Printf("Setting allow list to %u for %s.", value,
714                 bp_name->GetName().AsCString());
715   bp_name->GetPermissions().SetAllowList(value);
716 }
717 
718 bool SBBreakpointName::GetAllowDelete() {
719   LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpointName, GetAllowDelete);
720 
721   BreakpointName *bp_name = GetBreakpointName();
722   if (!bp_name)
723     return false;
724   return bp_name->GetPermissions().GetAllowDelete();
725 }
726 
727 void SBBreakpointName::SetAllowDelete(bool value) {
728   LLDB_RECORD_METHOD(void, SBBreakpointName, SetAllowDelete, (bool), value);
729 
730   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
731 
732   BreakpointName *bp_name = GetBreakpointName();
733   if (!bp_name)
734     return;
735   if (log)
736     log->Printf("Setting allow delete to %u for %s.", value,
737                 bp_name->GetName().AsCString());
738   bp_name->GetPermissions().SetAllowDelete(value);
739 }
740 
741 bool SBBreakpointName::GetAllowDisable() {
742   LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpointName, GetAllowDisable);
743 
744   BreakpointName *bp_name = GetBreakpointName();
745   if (!bp_name)
746     return false;
747   return bp_name->GetPermissions().GetAllowDisable();
748 }
749 
750 void SBBreakpointName::SetAllowDisable(bool value) {
751   LLDB_RECORD_METHOD(void, SBBreakpointName, SetAllowDisable, (bool), value);
752 
753   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
754 
755   BreakpointName *bp_name = GetBreakpointName();
756   if (!bp_name)
757     return;
758   if (log)
759     log->Printf("Setting allow disable to %u for %s.", value,
760                 bp_name->GetName().AsCString());
761   bp_name->GetPermissions().SetAllowDisable(value);
762 }
763 
764 lldb_private::BreakpointName *SBBreakpointName::GetBreakpointName() const
765 {
766   if (!IsValid())
767     return nullptr;
768   return m_impl_up->GetBreakpointName();
769 }
770 
771