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