[Lldb-commits] [lldb] r313292 - Make breakpoint names real entities.

Jim Ingham via lldb-commits lldb-commits at lists.llvm.org
Thu Sep 14 13:22:49 PDT 2017


Author: jingham
Date: Thu Sep 14 13:22:49 2017
New Revision: 313292

URL: http://llvm.org/viewvc/llvm-project?rev=313292&view=rev
Log:
Make breakpoint names real entities.

When introduced, breakpoint names were just tags that you could
apply to breakpoints that would allow you to refer to a breakpoint
when you couldn't capture the ID, or to refer to a collection of
breakpoints.  

This change makes the names independent holders of breakpoint options
that you can then apply to breakpoints when you add the name to the
breakpoint.  It adds the "breakpoint name configure" command to set
up or reconfigure breakpoint names.  There is also full support for
then in the SB API, including a new SBBreakpointName class.

The connection between the name and the breakpoints
sharing the name remains live, so if you reconfigure the name, all the
breakpoint options all change as well.  This allows a quick way
to share complex breakpoint behavior among a bunch of breakpoints, and
a convenient way to iterate on the set.

You can also create a name from a breakpoint, allowing a quick way
to copy options from one breakpoint to another.

I also added the ability to make hidden and delete/disable protected
names.  When applied to a breakpoint, you will only be able to list,
delete or disable that breakpoint if you refer to it explicitly by ID.

This feature will allow GUI's that need to use breakpoints for their
own purposes to keep their breakpoints from getting accidentally 
disabled or deleted.

<rdar://problem/22094452>

Added:
    lldb/trunk/include/lldb/API/SBBreakpointName.h
    lldb/trunk/include/lldb/Breakpoint/BreakpointName.h
    lldb/trunk/packages/Python/lldbsuite/test/python_api/default-constructor/sb_breakpointname.py
    lldb/trunk/scripts/interface/SBBreakpointName.i
    lldb/trunk/source/API/SBBreakpointName.cpp
    lldb/trunk/source/API/SBBreakpointOptionCommon.cpp
    lldb/trunk/source/API/SBBreakpointOptionCommon.h
    lldb/trunk/source/Breakpoint/BreakpointName.cpp
Modified:
    lldb/trunk/include/lldb/API/LLDB.h
    lldb/trunk/include/lldb/API/SBBreakpoint.h
    lldb/trunk/include/lldb/API/SBBreakpointLocation.h
    lldb/trunk/include/lldb/API/SBDebugger.h
    lldb/trunk/include/lldb/API/SBDefines.h
    lldb/trunk/include/lldb/API/SBError.h
    lldb/trunk/include/lldb/API/SBStream.h
    lldb/trunk/include/lldb/API/SBStringList.h
    lldb/trunk/include/lldb/API/SBTarget.h
    lldb/trunk/include/lldb/API/SBThread.h
    lldb/trunk/include/lldb/Breakpoint/Breakpoint.h
    lldb/trunk/include/lldb/Breakpoint/BreakpointIDList.h
    lldb/trunk/include/lldb/Breakpoint/BreakpointList.h
    lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h
    lldb/trunk/include/lldb/Target/Target.h
    lldb/trunk/include/lldb/lldb-forward.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/LLDB.xcscheme
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/auto_continue/TestBreakpointAutoContinue.py
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_names/TestBreakpointNames.py
    lldb/trunk/packages/Python/lldbsuite/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py
    lldb/trunk/scripts/Python/python-extensions.swig
    lldb/trunk/scripts/Python/python-swigsafecast.swig
    lldb/trunk/scripts/interface/SBBreakpoint.i
    lldb/trunk/scripts/interface/SBDebugger.i
    lldb/trunk/scripts/interface/SBTarget.i
    lldb/trunk/scripts/lldb.swig
    lldb/trunk/source/API/SBBreakpoint.cpp
    lldb/trunk/source/API/SBDebugger.cpp
    lldb/trunk/source/API/SBTarget.cpp
    lldb/trunk/source/Breakpoint/Breakpoint.cpp
    lldb/trunk/source/Breakpoint/BreakpointID.cpp
    lldb/trunk/source/Breakpoint/BreakpointIDList.cpp
    lldb/trunk/source/Breakpoint/BreakpointList.cpp
    lldb/trunk/source/Breakpoint/BreakpointOptions.cpp
    lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
    lldb/trunk/source/Commands/CommandObjectBreakpoint.h
    lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp
    lldb/trunk/source/Interpreter/CommandObject.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
    lldb/trunk/source/Target/Target.cpp

Modified: lldb/trunk/include/lldb/API/LLDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/LLDB.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/LLDB.h (original)
+++ lldb/trunk/include/lldb/API/LLDB.h Thu Sep 14 13:22:49 2017
@@ -18,6 +18,7 @@
 #include "lldb/API/SBAttachInfo.h"
 #include "lldb/API/SBBlock.h"
 #include "lldb/API/SBBreakpoint.h"
+#include "lldb/API/SBBreakpointName.h"
 #include "lldb/API/SBBreakpointLocation.h"
 #include "lldb/API/SBBroadcaster.h"
 #include "lldb/API/SBCommandInterpreter.h"

Modified: lldb/trunk/include/lldb/API/SBBreakpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBBreakpoint.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBBreakpoint.h (original)
+++ lldb/trunk/include/lldb/API/SBBreakpoint.h Thu Sep 14 13:22:49 2017
@@ -18,9 +18,6 @@ namespace lldb {
 
 class LLDB_API SBBreakpoint {
 public:
-  typedef bool (*BreakpointHitCallback)(void *baton, SBProcess &process,
-                                        SBThread &thread,
-                                        lldb::SBBreakpointLocation &location);
 
   SBBreakpoint();
 
@@ -90,7 +87,7 @@ public:
 
   const char *GetQueueName() const;
 
-  void SetCallback(BreakpointHitCallback callback, void *baton);
+  void SetCallback(SBBreakpointHitCallback callback, void *baton);
 
   void SetScriptCallbackFunction(const char *callback_function_name);
 
@@ -133,14 +130,11 @@ public:
 private:
   friend class SBBreakpointList;
   friend class SBBreakpointLocation;
+  friend class SBBreakpointName;
   friend class SBTarget;
 
   SBBreakpoint(const lldb::BreakpointSP &bp_sp);
 
-  static bool PrivateBreakpointHitCallback(
-      void *baton, lldb_private::StoppointCallbackContext *context,
-      lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
-
   lldb::BreakpointSP GetSP() const;
 
   lldb::BreakpointWP m_opaque_wp;

Modified: lldb/trunk/include/lldb/API/SBBreakpointLocation.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBBreakpointLocation.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBBreakpointLocation.h (original)
+++ lldb/trunk/include/lldb/API/SBBreakpointLocation.h Thu Sep 14 13:22:49 2017
@@ -86,6 +86,7 @@ public:
 
 private:
   friend class SBBreakpoint;
+  friend class SBBreakpointCallbackBaton;
 
   void SetLocation(const lldb::BreakpointLocationSP &break_loc_sp);
   BreakpointLocationSP GetSP() const;

Added: lldb/trunk/include/lldb/API/SBBreakpointName.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBBreakpointName.h?rev=313292&view=auto
==============================================================================
--- lldb/trunk/include/lldb/API/SBBreakpointName.h (added)
+++ lldb/trunk/include/lldb/API/SBBreakpointName.h Thu Sep 14 13:22:49 2017
@@ -0,0 +1,115 @@
+//===-- SBBreakpointName.h ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBBreakpointName_h_
+#define LLDB_SBBreakpointName_h_
+
+#include "lldb/API/SBDefines.h"
+
+class SBBreakpointNameImpl;
+
+namespace lldb {
+
+class LLDB_API SBBreakpointName {
+public:
+//  typedef bool (*BreakpointHitCallback)(void *baton, SBProcess &process,
+//                                        SBThread &thread,
+//                                        lldb::SBBreakpointLocation &location);
+
+  SBBreakpointName();
+  
+  SBBreakpointName(SBTarget &target, const char *name);
+  
+  SBBreakpointName(SBBreakpoint &bkpt, const char *name);
+
+  SBBreakpointName(const lldb::SBBreakpointName &rhs);
+
+  ~SBBreakpointName();
+
+  const lldb::SBBreakpointName &operator=(const lldb::SBBreakpointName &rhs);
+
+  // Tests to see if the opaque breakpoint object in this object matches the
+  // opaque breakpoint object in "rhs".
+  bool operator==(const lldb::SBBreakpointName &rhs);
+
+  bool operator!=(const lldb::SBBreakpointName &rhs);
+
+  bool IsValid() const;
+  
+  const char *GetName() const;
+
+  void SetEnabled(bool enable);
+
+  bool IsEnabled();
+
+  void SetOneShot(bool one_shot);
+
+  bool IsOneShot() const;
+
+  void SetIgnoreCount(uint32_t count);
+
+  uint32_t GetIgnoreCount() const;
+
+  void SetCondition(const char *condition);
+
+  const char *GetCondition();
+
+  void SetAutoContinue(bool auto_continue);
+
+  bool GetAutoContinue();
+
+  void SetThreadID(lldb::tid_t sb_thread_id);
+
+  lldb::tid_t GetThreadID();
+
+  void SetThreadIndex(uint32_t index);
+
+  uint32_t GetThreadIndex() const;
+
+  void SetThreadName(const char *thread_name);
+
+  const char *GetThreadName() const;
+
+  void SetQueueName(const char *queue_name);
+
+  const char *GetQueueName() const;
+
+  void SetCallback(SBBreakpointHitCallback callback, void *baton);
+
+  void SetScriptCallbackFunction(const char *callback_function_name);
+
+  void SetCommandLineCommands(SBStringList &commands);
+
+  bool GetCommandLineCommands(SBStringList &commands);
+
+  SBError SetScriptCallbackBody(const char *script_body_text);
+  
+  bool GetAllowList() const;
+  void SetAllowList(bool value);
+    
+  bool GetAllowDelete();
+  void SetAllowDelete(bool value);
+    
+  bool GetAllowDisable();
+  void SetAllowDisable(bool value);
+
+  bool GetDescription(lldb::SBStream &description);
+
+private:
+  friend class SBTarget;
+  
+  lldb_private::BreakpointName *GetBreakpointName() const;
+  void UpdateName(lldb_private::BreakpointName &bp_name);
+
+  std::unique_ptr<SBBreakpointNameImpl> m_impl_up;
+};
+
+} // namespace lldb
+
+#endif // LLDB_SBBreakpointName_h_

Modified: lldb/trunk/include/lldb/API/SBDebugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDebugger.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBDebugger.h (original)
+++ lldb/trunk/include/lldb/API/SBDebugger.h Thu Sep 14 13:22:49 2017
@@ -109,6 +109,8 @@ public:
                                              const char *archname);
 
   lldb::SBTarget CreateTarget(const char *filename);
+  
+  lldb::SBTarget GetDummyTarget();
 
   // Return true if target is deleted from the target list of the debugger.
   bool DeleteTarget(lldb::SBTarget &target);

Modified: lldb/trunk/include/lldb/API/SBDefines.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDefines.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBDefines.h (original)
+++ lldb/trunk/include/lldb/API/SBDefines.h Thu Sep 14 13:22:49 2017
@@ -32,6 +32,8 @@ class LLDB_API SBAddress;
 class LLDB_API SBBlock;
 class LLDB_API SBBreakpoint;
 class LLDB_API SBBreakpointLocation;
+class LLDB_API SBBreakpointName;
+class LLDB_API SBBreakpointNameImpl;
 class LLDB_API SBBroadcaster;
 class LLDB_API SBCommand;
 class LLDB_API SBCommandInterpreter;
@@ -99,6 +101,10 @@ class LLDB_API SBValueList;
 class LLDB_API SBVariablesOptions;
 class LLDB_API SBWatchpoint;
 class LLDB_API SBUnixSignals;
+
+typedef bool (*SBBreakpointHitCallback)(void *baton, SBProcess &process,
+                                        SBThread &thread,
+                                        lldb::SBBreakpointLocation &location);
 }
 
 #endif // LLDB_SBDefines_h_

Modified: lldb/trunk/include/lldb/API/SBError.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBError.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBError.h (original)
+++ lldb/trunk/include/lldb/API/SBError.h Thu Sep 14 13:22:49 2017
@@ -67,6 +67,7 @@ protected:
   friend class SBWatchpoint;
   friend class SBBreakpoint;
   friend class SBBreakpointLocation;
+  friend class SBBreakpointName;
 
   lldb_private::Status *get();
 

Modified: lldb/trunk/include/lldb/API/SBStream.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBStream.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBStream.h (original)
+++ lldb/trunk/include/lldb/API/SBStream.h Thu Sep 14 13:22:49 2017
@@ -53,6 +53,7 @@ protected:
   friend class SBBlock;
   friend class SBBreakpoint;
   friend class SBBreakpointLocation;
+  friend class SBBreakpointName;
   friend class SBCommandReturnObject;
   friend class SBCompileUnit;
   friend class SBData;

Modified: lldb/trunk/include/lldb/API/SBStringList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBStringList.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBStringList.h (original)
+++ lldb/trunk/include/lldb/API/SBStringList.h Thu Sep 14 13:22:49 2017
@@ -45,6 +45,7 @@ protected:
   friend class SBDebugger;
   friend class SBBreakpoint;
   friend class SBBreakpointLocation;
+  friend class SBBreakpointName;
 
   SBStringList(const lldb_private::StringList *lldb_strings);
 

Modified: lldb/trunk/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTarget.h (original)
+++ lldb/trunk/include/lldb/API/SBTarget.h Thu Sep 14 13:22:49 2017
@@ -716,6 +716,10 @@ public:
   // Finds all breakpoints by name, returning the list in bkpt_list.  Returns
   // false if the name is not a valid breakpoint name, true otherwise.
   bool FindBreakpointsByName(const char *name, SBBreakpointList &bkpt_list);
+  
+  void GetBreakpointNames(SBStringList &names);
+  
+  void DeleteBreakpointName(const char *name);
 
   bool EnableAllBreakpoints();
 
@@ -810,6 +814,7 @@ protected:
   friend class SBAddress;
   friend class SBBlock;
   friend class SBBreakpointList;
+  friend class SBBreakpointNameImpl;
   friend class SBDebugger;
   friend class SBExecutionContext;
   friend class SBFunction;

Modified: lldb/trunk/include/lldb/API/SBThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBThread.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBThread.h (original)
+++ lldb/trunk/include/lldb/API/SBThread.h Thu Sep 14 13:22:49 2017
@@ -196,6 +196,7 @@ public:
 protected:
   friend class SBBreakpoint;
   friend class SBBreakpointLocation;
+  friend class SBBreakpointCallbackBaton;
   friend class SBExecutionContext;
   friend class SBFrame;
   friend class SBProcess;

Modified: lldb/trunk/include/lldb/Breakpoint/Breakpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/Breakpoint.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/Breakpoint.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/Breakpoint.h Thu Sep 14 13:22:49 2017
@@ -22,6 +22,7 @@
 #include "lldb/Breakpoint/BreakpointID.h"
 #include "lldb/Breakpoint/BreakpointLocationCollection.h"
 #include "lldb/Breakpoint/BreakpointLocationList.h"
+#include "lldb/Breakpoint/BreakpointName.h"
 #include "lldb/Breakpoint/BreakpointOptions.h"
 #include "lldb/Breakpoint/Stoppoint.h"
 #include "lldb/Core/Event.h"
@@ -603,6 +604,16 @@ public:
   BreakpointOptions *GetOptions();
 
   //------------------------------------------------------------------
+  /// Returns the BreakpointOptions structure set at the breakpoint level.
+  ///
+  /// Meant to be used by the BreakpointLocation class.
+  ///
+  /// @return
+  ///     A pointer to this breakpoint's BreakpointOptions.
+  //------------------------------------------------------------------
+  const BreakpointOptions *GetOptions() const;
+
+  //------------------------------------------------------------------
   /// Invoke the callback action when the breakpoint is hit.
   ///
   /// Meant to be used by the BreakpointLocation class.
@@ -625,13 +636,16 @@ public:
 
   lldb::SearchFilterSP GetSearchFilter() { return m_filter_sp; }
 
-  bool AddName(llvm::StringRef new_name, Status &error);
+private: // The target needs to manage adding & removing names.  It will do the
+         // checking for name validity as well.
+  bool AddName(llvm::StringRef new_name);
 
   void RemoveName(const char *name_to_remove) {
     if (name_to_remove)
       m_name_list.erase(name_to_remove);
   }
-
+  
+public:
   bool MatchesName(const char *name) {
     return m_name_list.find(name) != m_name_list.end();
   }
@@ -663,6 +677,25 @@ public:
   bool EvaluatePrecondition(StoppointCallbackContext &context);
 
   BreakpointPreconditionSP GetPrecondition() { return m_precondition_sp; }
+  
+  // Produces the OR'ed values for all the names assigned to this breakpoint.
+  const BreakpointName::Permissions &GetPermissions() const { 
+      return m_permissions; 
+  }
+
+  BreakpointName::Permissions &GetPermissions() { 
+      return m_permissions; 
+  }
+  
+  bool AllowList() const {
+    return GetPermissions().GetAllowList();
+  }
+  bool AllowDisable() const {
+    return GetPermissions().GetAllowDisable();
+  }
+  bool AllowDelete() const {
+    return GetPermissions().GetAllowDelete();
+  }
 
 protected:
   friend class Target;
@@ -762,6 +795,7 @@ private:
                         // hit.  This is kept
   // separately from the locations hit counts, since locations can go away when
   // their backing library gets unloaded, and we would lose hit counts.
+  BreakpointName::Permissions m_permissions;
 
   void SendBreakpointChangedEvent(lldb::BreakpointEventType eventKind);
 

Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointIDList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointIDList.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointIDList.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointIDList.h Thu Sep 14 13:22:49 2017
@@ -18,7 +18,9 @@
 // Other libraries and framework includes
 // Project includes
 
+#include "lldb/lldb-enumerations.h"
 #include "lldb/Breakpoint/BreakpointID.h"
+#include "lldb/Breakpoint/BreakpointName.h"
 #include "lldb/lldb-private.h"
 
 namespace lldb_private {
@@ -64,6 +66,8 @@ public:
 
   static void FindAndReplaceIDRanges(Args &old_args, Target *target,
                                      bool allow_locations,
+                                     BreakpointName::Permissions
+                                       ::PermissionKinds purpose,
                                      CommandReturnObject &result,
                                      Args &new_args);
 

Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointList.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointList.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointList.h Thu Sep 14 13:22:49 2017
@@ -154,12 +154,21 @@ public:
 
   void SetEnabledAll(bool enabled);
 
+  void SetEnabledAllowed(bool enabled);
+
   //------------------------------------------------------------------
   /// Removes all the breakpoints from this list.
   //------------------------------------------------------------------
   void RemoveAll(bool notify);
 
   //------------------------------------------------------------------
+  /// Removes all the breakpoints from this list - first checking the
+  /// ePermDelete on the breakpoints.  This call should be used unless you
+  /// are shutting down and need to actually clear them all.
+  //------------------------------------------------------------------
+  void RemoveAllowed(bool notify);
+
+  //------------------------------------------------------------------
   /// Tell all the breakpoints to update themselves due to a change in the
   /// modules in \a module_list.  \a added says whether the module was loaded
   /// or unloaded.

Added: lldb/trunk/include/lldb/Breakpoint/BreakpointName.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointName.h?rev=313292&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointName.h (added)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointName.h Thu Sep 14 13:22:49 2017
@@ -0,0 +1,213 @@
+//===-- BreakpointName.h --------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Breakpoint_Name_h_
+#define liblldb_Breakpoint_Name_h_
+
+// C Includes
+// C++ Includes
+#include <memory>
+#include <string>
+#include <unordered_set>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Breakpoint/BreakpointID.h"
+#include "lldb/Breakpoint/BreakpointLocationCollection.h"
+#include "lldb/Breakpoint/BreakpointLocationList.h"
+#include "lldb/Breakpoint/BreakpointOptions.h"
+#include "lldb/Breakpoint/Stoppoint.h"
+#include "lldb/Core/Event.h"
+#include "lldb/Core/SearchFilter.h"
+#include "lldb/Utility/Flags.h"
+#include "lldb/Utility/StringList.h"
+#include "lldb/Utility/StructuredData.h"
+
+namespace lldb_private {
+
+class BreakpointName {
+public:
+  class Permissions
+  {
+  public:
+  
+    enum PermissionKinds { listPerm = 0, disablePerm = 1, 
+                       deletePerm = 2, allPerms = 3 };
+
+    Permissions(bool in_list, bool in_disable, bool in_delete) 
+    {
+      m_permissions[listPerm]    = in_list;
+      m_permissions[disablePerm] = in_disable;
+      m_permissions[deletePerm]  = in_delete;
+      m_set_mask.Set(permissions_mask[allPerms]);
+    }
+    
+    Permissions(const Permissions &rhs)
+    {
+      m_permissions[listPerm]    = rhs.m_permissions[listPerm];
+      m_permissions[disablePerm] = rhs.m_permissions[disablePerm];
+      m_permissions[deletePerm]  = rhs.m_permissions[deletePerm];
+      m_set_mask = rhs.m_set_mask;
+    }
+    
+    Permissions() 
+    {
+      m_permissions[listPerm]    = true;
+      m_permissions[disablePerm] = true;
+      m_permissions[deletePerm]  = true;
+      m_set_mask.Clear();
+    }
+    
+    const Permissions &operator= (const Permissions &rhs)
+    {
+      if (this != &rhs) {
+        m_permissions[listPerm]    = rhs.m_permissions[listPerm];
+        m_permissions[disablePerm] = rhs.m_permissions[disablePerm];
+        m_permissions[deletePerm]  = rhs.m_permissions[deletePerm];
+        m_set_mask = rhs.m_set_mask;
+      }
+      return *this;
+    }
+    
+    void Clear() {
+      *this = Permissions();
+    }
+    
+    // Merge the permissions from incoming into this set of permissions.
+    // Only merge set permissions, and most restrictive permission wins.
+    void MergeInto(const Permissions &incoming)
+    {
+      MergePermission(incoming, listPerm);
+      MergePermission(incoming, disablePerm);
+      MergePermission(incoming, deletePerm);
+    }
+
+    bool GetAllowList() const { return GetPermission(listPerm); }
+    bool SetAllowList(bool value) { return SetPermission(listPerm, value); }
+    
+    bool GetAllowDelete() const { return GetPermission(deletePerm); }
+    bool SetAllowDelete(bool value) { return SetPermission(deletePerm, value); }
+    
+    bool GetAllowDisable() const { return GetPermission(disablePerm); }
+    bool SetAllowDisable(bool value) { return SetPermission(disablePerm, 
+                                                            value); }
+
+    bool GetPermission(enum PermissionKinds permission) const
+    {
+      return m_permissions[permission];
+    }
+
+    bool GetDescription(Stream *s, lldb::DescriptionLevel level);
+
+    bool IsSet(enum PermissionKinds permission) const
+    {
+      return m_set_mask.Test(permissions_mask[permission]);
+    }
+    
+    bool AnySet() {
+      return m_set_mask.AnySet(permissions_mask[allPerms]);
+    }
+    
+  private:
+    static const Flags::ValueType permissions_mask[allPerms + 1];
+    
+    bool m_permissions[allPerms];
+    Flags m_set_mask;
+    
+    bool SetPermission(enum PermissionKinds permission, bool value)
+    {
+      bool old_value = m_permissions[permission];
+      m_permissions[permission] = value;
+      m_set_mask.Set(permissions_mask[permission]);
+      return old_value;
+    }
+    
+    // If either side disallows the permission, the resultant disallows it.
+    void MergePermission(const Permissions &incoming, 
+                         enum PermissionKinds permission)
+    {
+      if (incoming.IsSet(permission))
+      {
+        SetPermission(permission, !(m_permissions[permission] |
+            incoming.m_permissions[permission]));
+      }
+    }
+  };
+  
+  BreakpointName(const ConstString &name, const char *help = nullptr) :
+      m_name(name), m_options(false)
+   {
+     SetHelp(help);
+   }
+      
+  BreakpointName(const ConstString &name,
+                 BreakpointOptions &options,
+                 const Permissions &permissions = Permissions(),
+                 const char *help = nullptr) :
+      m_name(name), m_options(options), 
+      m_permissions(permissions) {
+        SetHelp(help);
+  };
+  
+  BreakpointName(const BreakpointName &rhs) :
+      m_name(rhs.m_name), m_options(rhs.m_options),
+      m_permissions(rhs.m_permissions), m_help(rhs.m_help)
+  {}
+  
+  BreakpointName(const ConstString &name, const Breakpoint &bkpt,
+                 const char *help);
+      
+  const ConstString &GetName() const { return m_name; }
+  BreakpointOptions &GetOptions() { return m_options; }
+  const BreakpointOptions &GetOptions() const { return m_options; }
+  
+  void SetOptions(const BreakpointOptions &options) {
+    m_options = options;
+  }
+  
+  Permissions &GetPermissions() { return m_permissions; }
+  const Permissions &GetPermissions() const { return m_permissions; }
+  void SetPermissions(const Permissions &permissions) {
+    m_permissions = permissions;
+  }
+  
+  bool GetPermission(Permissions::PermissionKinds permission) const
+  {
+    return m_permissions.GetPermission(permission);
+  }
+  
+  void SetHelp(const char *description)
+  {
+    if (description)
+      m_help.assign(description);
+    else
+      m_help.clear();
+  }
+  
+  const char *GetHelp()
+  {
+    return m_help.c_str();
+  }
+  
+  // Returns true if any options were set in the name
+  bool GetDescription(Stream *s, lldb::DescriptionLevel level);
+  
+  void ConfigureBreakpoint(lldb::BreakpointSP bp_sp);
+  
+private:
+  ConstString        m_name;
+  BreakpointOptions  m_options;
+  Permissions        m_permissions;
+  std::string        m_help;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Breakpoint_Name_h_

Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h Thu Sep 14 13:22:49 2017
@@ -34,6 +34,8 @@ namespace lldb_private {
 
 class BreakpointOptions {
 friend class BreakpointLocation;
+friend class BreakpointName;
+friend class lldb_private::BreakpointOptionGroup;
 friend class Breakpoint;
 
 public:
@@ -44,7 +46,9 @@ public:
     eIgnoreCount  = 1 << 3,
     eThreadSpec   = 1 << 4,
     eCondition    = 1 << 5,
-    eAutoContinue = 1 << 6
+    eAutoContinue = 1 << 6,
+    eAllOptions   = (eCallback | eEnabled | eOneShot | eIgnoreCount | eThreadSpec
+                     | eCondition | eAutoContinue)
   };
   struct CommandData {
     CommandData()
@@ -98,6 +102,10 @@ public:
   typedef std::shared_ptr<CommandBaton> CommandBatonSP;
 
   //------------------------------------------------------------------
+  // Constructors and Destructors
+  //------------------------------------------------------------------
+
+  //------------------------------------------------------------------
   /// This constructor allows you to specify all the breakpoint options
   /// except the callback.  That one is more complicated, and better
   /// to do by hand.
@@ -116,6 +124,13 @@ public:
                     int32_t ignore = 0, bool one_shot = false,
                     bool auto_continue = false);
 
+  //------------------------------------------------------------------
+  /// Breakpoints make options with all flags set.  Locations and Names make options
+  /// with no flags set.
+  //------------------------------------------------------------------
+  BreakpointOptions(bool all_flags_set);
+  BreakpointOptions(const BreakpointOptions &rhs);
+
   virtual ~BreakpointOptions();
 
   static std::unique_ptr<BreakpointOptions>
@@ -131,6 +146,11 @@ public:
   // Operators
   //------------------------------------------------------------------
   const BreakpointOptions &operator=(const BreakpointOptions &rhs);
+  
+  //------------------------------------------------------------------
+  /// Copy over only the options set in the incoming BreakpointOptions.
+  //------------------------------------------------------------------
+  void CopyOverSetOptions(const BreakpointOptions &rhs);
 
   //------------------------------------------------------------------
   // Callbacks
@@ -387,17 +407,13 @@ public:
   //------------------------------------------------------------------
   void SetCommandDataCallback(std::unique_ptr<CommandData> &cmd_data);
   
+  void Clear();
+  
+  bool AnySet() const {
+    return m_set_flags.AnySet(eAllOptions);
+  }
+  
 protected:
-  //------------------------------------------------------------------
-  // Constructors and Destructors
-  //------------------------------------------------------------------
-  //------------------------------------------------------------------
-  /// Breakpoints make options with all flags set.  Locations make options
-  /// with no flags set.  Nobody else should make breakpoint options.
-  //------------------------------------------------------------------
-  BreakpointOptions(bool all_flags_set);
-  BreakpointOptions(const BreakpointOptions &rhs);
-
 //------------------------------------------------------------------
   // Classes that inherit from BreakpointOptions can see and modify these
   //------------------------------------------------------------------

Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Thu Sep 14 13:22:49 2017
@@ -21,6 +21,7 @@
 // Other libraries and framework includes
 // Project includes
 #include "lldb/Breakpoint/BreakpointList.h"
+#include "lldb/Breakpoint/BreakpointName.h"
 #include "lldb/Breakpoint/WatchpointList.h"
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/Broadcaster.h"
@@ -651,12 +652,45 @@ public:
   }
 
   WatchpointList &GetWatchpointList() { return m_watchpoint_list; }
-
+  
+  // Manages breakpoint names:
+  void AddNameToBreakpoint(BreakpointID &id, const char *name, Status &error);
+  
+  void AddNameToBreakpoint(lldb::BreakpointSP &bp_sp, const char *name, 
+                           Status &error);
+  
+  void RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp, 
+                                const ConstString &name);
+  
+  BreakpointName *FindBreakpointName(const ConstString &name, bool can_create, 
+                                     Status &error);
+                                     
+  void DeleteBreakpointName(const ConstString &name);
+  
+  void ConfigureBreakpointName(BreakpointName &bp_name,
+                               const BreakpointOptions &options,
+                               const BreakpointName::Permissions &permissions);
+ void ApplyNameToBreakpoints(BreakpointName &bp_name);
+   
+  
+  // This takes ownership of the name obj passed in.
+  void AddBreakpointName(BreakpointName *bp_name);
+  
+  void GetBreakpointNames(std::vector<std::string> &names);
+                               
+  //This call removes ALL breakpoints regardless of permission.
   void RemoveAllBreakpoints(bool internal_also = false);
+  
+  // This removes all the breakpoints, but obeys the ePermDelete on them.
+  void RemoveAllowedBreakpoints();
 
   void DisableAllBreakpoints(bool internal_also = false);
+  
+  void DisableAllowedBreakpoints();
 
   void EnableAllBreakpoints(bool internal_also = false);
+  
+  void EnableAllowedBreakpoints();
 
   bool DisableBreakpointByID(lldb::break_id_t break_id);
 
@@ -1218,6 +1252,9 @@ protected:
   SectionLoadHistory m_section_load_history;
   BreakpointList m_breakpoint_list;
   BreakpointList m_internal_breakpoint_list;
+  using BreakpointNameList = std::map<ConstString, BreakpointName *>;
+  BreakpointNameList m_breakpoint_names;
+  
   lldb::BreakpointSP m_last_created_breakpoint;
   WatchpointList m_watchpoint_list;
   lldb::WatchpointSP m_last_created_watchpoint;

Modified: lldb/trunk/include/lldb/lldb-forward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Thu Sep 14 13:22:49 2017
@@ -38,6 +38,8 @@ class BreakpointList;
 class BreakpointLocation;
 class BreakpointLocationCollection;
 class BreakpointLocationList;
+class BreakpointName;
+class BreakpointOptionGroup;
 class BreakpointOptions;
 class BreakpointResolver;
 class BreakpointSite;

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Thu Sep 14 13:22:49 2017
@@ -714,18 +714,23 @@
 		49E4F66B1C9CAD16008487EA /* DiagnosticManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49E4F6681C9CAD12008487EA /* DiagnosticManager.cpp */; };
 		49F811F31E931B2100F4E163 /* CPlusPlusNameParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49F811EF1E931B1500F4E163 /* CPlusPlusNameParser.cpp */; };
 		4C0083401B9F9BA900D5CF24 /* UtilityFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C00833F1B9F9BA900D5CF24 /* UtilityFunction.cpp */; };
+		4C05332B1F62121E00DED368 /* SBBreakpointOptionCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0533291F6211FB00DED368 /* SBBreakpointOptionCommon.cpp */; };
 		4C2479BD1BA39295009C9A7B /* FunctionCaller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0083321B9A5DE200D5CF24 /* FunctionCaller.cpp */; };
 		4C3ADCD61810D88B00357218 /* BreakpointResolverFileRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CAA56141422D986001FFA01 /* BreakpointResolverFileRegex.cpp */; };
 		4C4EB7811E6A4DCC002035C0 /* DumpDataExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C4EB77F1E6A4DB8002035C0 /* DumpDataExtractor.cpp */; };
+		4C54B27B1F61CE2800D469CA /* SBBreakpointName.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C54B2781F61CE1200D469CA /* SBBreakpointName.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4C54B27E1F61CE6300D469CA /* SBBreakpointName.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C54B27C1F61CE5300D469CA /* SBBreakpointName.cpp */; };
 		4C562CC71CC07DF700C52EAC /* PDBASTParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C562CC21CC07DDD00C52EAC /* PDBASTParser.cpp */; };
 		4C56543119D1EFAA002E9C44 /* ThreadPlanPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C56543019D1EFAA002E9C44 /* ThreadPlanPython.cpp */; };
 		4C56543519D2297A002E9C44 /* SBThreadPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C56543419D2297A002E9C44 /* SBThreadPlan.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		4C56543719D22B32002E9C44 /* SBThreadPlan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C56543619D22B32002E9C44 /* SBThreadPlan.cpp */; };
 		4C7D48241F5099A1005314B4 /* SymbolFileDWARFDwp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D481C1F509963005314B4 /* SymbolFileDWARFDwp.cpp */; };
 		4C7D48251F5099B2005314B4 /* SymbolFileDWARFDwoDwp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D481F1F509964005314B4 /* SymbolFileDWARFDwoDwp.cpp */; };
+		4C7D482C1F509CF5005314B4 /* BreakpointName.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4C7D482B1F509CF5005314B4 /* BreakpointName.h */; };
 		4C877B391F30EF990068FCFB /* SBProcessInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 4987FB201F30EC9900E5C17D /* SBProcessInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		4C88BC2A1BA3722B00AA0964 /* Expression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C88BC291BA3722B00AA0964 /* Expression.cpp */; };
 		4C88BC2D1BA391B000AA0964 /* UserExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0083331B9A5DE200D5CF24 /* UserExpression.cpp */; };
+		4CAA19E61F5A40040099E692 /* BreakpointName.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D48281F509CCD005314B4 /* BreakpointName.cpp */; };
 		4CABA9E0134A8BCD00539BDD /* ValueObjectMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CABA9DF134A8BCD00539BDD /* ValueObjectMemory.cpp */; };
 		4CC7C6501D5298F30076FF94 /* OCamlLanguage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7C64D1D5298E20076FF94 /* OCamlLanguage.cpp */; };
 		4CC7C6571D52997A0076FF94 /* OCamlASTContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7C6551D52996C0076FF94 /* OCamlASTContext.cpp */; };
@@ -1230,6 +1235,7 @@
 			files = (
 				9A20570F1F3B821A00F6C293 /* test-dwarf.cpp in CopyFiles */,
 				9A2057101F3B821A00F6C293 /* test-dwarf.exe in CopyFiles */,
+				4C7D482C1F509CF5005314B4 /* BreakpointName.h in CopyFiles */,
 				AF90106515AB7D3600FF120D /* lldb.1 in CopyFiles */,
 			);
 			runOnlyForDeploymentPostprocessing = 1;
@@ -2523,6 +2529,8 @@
 		4C00833F1B9F9BA900D5CF24 /* UtilityFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UtilityFunction.cpp; path = source/Expression/UtilityFunction.cpp; sourceTree = "<group>"; };
 		4C00986F11500B4300F316B0 /* UnixSignals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UnixSignals.h; path = include/lldb/Target/UnixSignals.h; sourceTree = "<group>"; };
 		4C00987011500B4300F316B0 /* UnixSignals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UnixSignals.cpp; path = source/Target/UnixSignals.cpp; sourceTree = "<group>"; };
+		4C0533291F6211FB00DED368 /* SBBreakpointOptionCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBBreakpointOptionCommon.cpp; path = source/API/SBBreakpointOptionCommon.cpp; sourceTree = "<group>"; };
+		4C05332C1F63092A00DED368 /* SBBreakpointName.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBBreakpointName.i; sourceTree = "<group>"; };
 		4C08CDE711C81EF8001610A8 /* ThreadSpec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadSpec.cpp; path = source/Target/ThreadSpec.cpp; sourceTree = "<group>"; };
 		4C08CDEB11C81F1E001610A8 /* ThreadSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadSpec.h; path = include/lldb/Target/ThreadSpec.h; sourceTree = "<group>"; };
 		4C09CB73116BD98B00C7A725 /* CommandCompletions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandCompletions.h; path = include/lldb/Interpreter/CommandCompletions.h; sourceTree = "<group>"; };
@@ -2539,6 +2547,9 @@
 		4C43DF8A11069C3200E55CBF /* ThreadPlanStepOverRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanStepOverRange.cpp; path = source/Target/ThreadPlanStepOverRange.cpp; sourceTree = "<group>"; };
 		4C4EB77F1E6A4DB8002035C0 /* DumpDataExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DumpDataExtractor.cpp; path = source/Core/DumpDataExtractor.cpp; sourceTree = "<group>"; };
 		4C4EB7821E6A4DE7002035C0 /* DumpDataExtractor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DumpDataExtractor.h; path = include/lldb/Core/DumpDataExtractor.h; sourceTree = "<group>"; };
+		4C54B2781F61CE1200D469CA /* SBBreakpointName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBBreakpointName.h; path = include/lldb/API/SBBreakpointName.h; sourceTree = "<group>"; };
+		4C54B27C1F61CE5300D469CA /* SBBreakpointName.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBBreakpointName.cpp; path = source/API/SBBreakpointName.cpp; sourceTree = "<group>"; };
+		4C54B2811F62081300D469CA /* SBBreakpointOptionCommon.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBBreakpointOptionCommon.h; path = include/lldb/API/SBBreakpointOptionCommon.h; sourceTree = "<group>"; };
 		4C562CC21CC07DDD00C52EAC /* PDBASTParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PDBASTParser.cpp; path = PDB/PDBASTParser.cpp; sourceTree = "<group>"; };
 		4C562CC31CC07DDD00C52EAC /* PDBASTParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PDBASTParser.h; path = PDB/PDBASTParser.h; sourceTree = "<group>"; };
 		4C56543019D1EFAA002E9C44 /* ThreadPlanPython.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanPython.cpp; path = source/Target/ThreadPlanPython.cpp; sourceTree = "<group>"; };
@@ -2555,6 +2566,8 @@
 		4C7D481D1F509964005314B4 /* SymbolFileDWARFDwoDwp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolFileDWARFDwoDwp.h; sourceTree = "<group>"; };
 		4C7D481E1F509964005314B4 /* SymbolFileDWARFDwp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolFileDWARFDwp.h; sourceTree = "<group>"; };
 		4C7D481F1F509964005314B4 /* SymbolFileDWARFDwoDwp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolFileDWARFDwoDwp.cpp; sourceTree = "<group>"; };
+		4C7D48281F509CCD005314B4 /* BreakpointName.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BreakpointName.cpp; path = source/Breakpoint/BreakpointName.cpp; sourceTree = "<group>"; };
+		4C7D482B1F509CF5005314B4 /* BreakpointName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BreakpointName.h; path = include/lldb/Breakpoint/BreakpointName.h; sourceTree = "<group>"; };
 		4C88BC291BA3722B00AA0964 /* Expression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Expression.cpp; path = source/Expression/Expression.cpp; sourceTree = "<group>"; };
 		4C98D3DA118FB96F00E575D0 /* ClangFunctionCaller.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangFunctionCaller.cpp; path = ExpressionParser/Clang/ClangFunctionCaller.cpp; sourceTree = "<group>"; };
 		4C98D3DB118FB96F00E575D0 /* IRExecutionUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRExecutionUnit.cpp; path = source/Expression/IRExecutionUnit.cpp; sourceTree = "<group>"; };
@@ -2575,6 +2588,7 @@
 		4CB443BC1249920C00C13DC2 /* CPPLanguageRuntime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CPPLanguageRuntime.cpp; path = source/Target/CPPLanguageRuntime.cpp; sourceTree = "<group>"; };
 		4CB443F212499B5000C13DC2 /* ObjCLanguageRuntime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjCLanguageRuntime.cpp; path = source/Target/ObjCLanguageRuntime.cpp; sourceTree = "<group>"; };
 		4CB443F612499B6E00C13DC2 /* ObjCLanguageRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjCLanguageRuntime.h; path = include/lldb/Target/ObjCLanguageRuntime.h; sourceTree = "<group>"; };
+		4CBFF0471F579A36004AFA92 /* Flags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Flags.h; path = include/lldb/Utility/Flags.h; sourceTree = "<group>"; };
 		4CC2A148128C73ED001531C4 /* ThreadPlanTracer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanTracer.cpp; path = source/Target/ThreadPlanTracer.cpp; sourceTree = "<group>"; };
 		4CC2A14C128C7409001531C4 /* ThreadPlanTracer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanTracer.h; path = include/lldb/Target/ThreadPlanTracer.h; sourceTree = "<group>"; };
 		4CC7C64C1D5298E20076FF94 /* OCamlLanguage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OCamlLanguage.h; path = Language/OCaml/OCamlLanguage.h; sourceTree = "<group>"; };
@@ -3939,6 +3953,7 @@
 				2611FEF0142D83060017FEA3 /* SBBlock.i */,
 				2611FEF1142D83060017FEA3 /* SBBreakpoint.i */,
 				2611FEF2142D83060017FEA3 /* SBBreakpointLocation.i */,
+				4C05332C1F63092A00DED368 /* SBBreakpointName.i */,
 				2611FEF3142D83060017FEA3 /* SBBroadcaster.i */,
 				2611FEF4142D83060017FEA3 /* SBCommandInterpreter.i */,
 				2611FEF5142D83060017FEA3 /* SBCommandReturnObject.i */,
@@ -4032,6 +4047,10 @@
 				9AF16A9C11402D5B007A7B3F /* SBBreakpoint.cpp */,
 				9AF16CC611408686007A7B3F /* SBBreakpointLocation.h */,
 				9AF16CC7114086A1007A7B3F /* SBBreakpointLocation.cpp */,
+				4C54B2781F61CE1200D469CA /* SBBreakpointName.h */,
+				4C54B27C1F61CE5300D469CA /* SBBreakpointName.cpp */,
+				4C54B2811F62081300D469CA /* SBBreakpointOptionCommon.h */,
+				4C0533291F6211FB00DED368 /* SBBreakpointOptionCommon.cpp */,
 				9A9830F31125FC5800A56CB0 /* SBBroadcaster.h */,
 				9A9830F21125FC5800A56CB0 /* SBBroadcaster.cpp */,
 				9A9830F71125FC5800A56CB0 /* SBCommandInterpreter.h */,
@@ -4353,6 +4372,7 @@
 				26BC7DD310F1B7D500F91463 /* Endian.h */,
 				AFC2DCE61E6E2ED000283714 /* FastDemangle.cpp */,
 				AFC2DCED1E6E2F9800283714 /* FastDemangle.h */,
+				4CBFF0471F579A36004AFA92 /* Flags.h */,
 				AFC2DCF21E6E30CF00283714 /* History.cpp */,
 				AFC2DCF41E6E30D800283714 /* History.h */,
 				236124A61986B50E004EFC37 /* IOObject.h */,
@@ -5041,6 +5061,8 @@
 				26BC7E0F10F1B83100F91463 /* BreakpointLocationCollection.cpp */,
 				26BC7CF410F1B71400F91463 /* BreakpointLocationList.h */,
 				26BC7E1010F1B83100F91463 /* BreakpointLocationList.cpp */,
+				4C7D48281F509CCD005314B4 /* BreakpointName.cpp */,
+				4C7D482B1F509CF5005314B4 /* BreakpointName.h */,
 				26BC7CF510F1B71400F91463 /* BreakpointOptions.h */,
 				26BC7E1110F1B83100F91463 /* BreakpointOptions.cpp */,
 				26BC7CF610F1B71400F91463 /* BreakpointResolver.h */,
@@ -6662,6 +6684,7 @@
 				26C72C94124322890068DC16 /* SBStream.h in Headers */,
 				9A357671116E7B5200E8ED2F /* SBStringList.h in Headers */,
 				26DE205B11618FF600A093E2 /* SBSymbol.h in Headers */,
+				4C54B27B1F61CE2800D469CA /* SBBreakpointName.h in Headers */,
 				262F12B71835469C00AEB384 /* SBPlatform.h in Headers */,
 				23DCBEA31D63E71F0084C36B /* SBStructuredData.h in Headers */,
 				26DE204111618AB900A093E2 /* SBSymbolContext.h in Headers */,
@@ -7266,6 +7289,7 @@
 				2668032C116005E2008E1FE4 /* SBFrame.cpp in Sources */,
 				2668032D116005E3008E1FE4 /* SBFileSpec.cpp in Sources */,
 				2668032E116005E5008E1FE4 /* SBEvent.cpp in Sources */,
+				4C54B27E1F61CE6300D469CA /* SBBreakpointName.cpp in Sources */,
 				2668032F116005E6008E1FE4 /* SBError.cpp in Sources */,
 				23DCEA461D1C4D0F00A602B4 /* SBMemoryRegionInfo.cpp in Sources */,
 				26680330116005E7008E1FE4 /* SBDebugger.cpp in Sources */,
@@ -7289,6 +7313,7 @@
 				26DE20651161904E00A093E2 /* SBSymbol.cpp in Sources */,
 				9A19A6B01163BBB300E0D453 /* SBValue.cpp in Sources */,
 				261744781168585B005ADD65 /* SBType.cpp in Sources */,
+				4C05332B1F62121E00DED368 /* SBBreakpointOptionCommon.cpp in Sources */,
 				9A35758E116CFE0F00E8ED2F /* SBValueList.cpp in Sources */,
 				9A357673116E7B6400E8ED2F /* SBStringList.cpp in Sources */,
 				9A1E595C1EB2B141002206A5 /* SBTrace.cpp in Sources */,
@@ -7629,6 +7654,7 @@
 				947CF7771DC7B20D00EF980B /* ThreadMinidump.cpp in Sources */,
 				268900C913353E5F00698AC0 /* NameToDIE.cpp in Sources */,
 				268900CA13353E5F00698AC0 /* SymbolFileDWARF.cpp in Sources */,
+				4CAA19E61F5A40040099E692 /* BreakpointName.cpp in Sources */,
 				268900CB13353E5F00698AC0 /* LogChannelDWARF.cpp in Sources */,
 				268900CC13353E5F00698AC0 /* SymbolFileDWARFDebugMap.cpp in Sources */,
 				268900CD13353E5F00698AC0 /* UniqueDWARFASTType.cpp in Sources */,

Modified: lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/LLDB.xcscheme
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/LLDB.xcscheme?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/LLDB.xcscheme (original)
+++ lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/LLDB.xcscheme Thu Sep 14 13:22:49 2017
@@ -26,6 +26,7 @@
       buildConfiguration = "Debug"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
+      language = ""
       shouldUseLaunchSchemeArgsEnv = "YES">
       <Testables>
       </Testables>
@@ -54,6 +55,7 @@
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       displayScaleIsEnabled = "NO"
       displayScale = "1.00"
+      language = ""
       launchStyle = "0"
       useCustomWorkingDirectory = "NO"
       ignoresPersistentStateOnLaunch = "NO"

Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/auto_continue/TestBreakpointAutoContinue.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/auto_continue/TestBreakpointAutoContinue.py?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/auto_continue/TestBreakpointAutoContinue.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/auto_continue/TestBreakpointAutoContinue.py Thu Sep 14 13:22:49 2017
@@ -73,7 +73,7 @@ class BreakpointAutoContinue(TestBase):
         self.assertEqual(bkpt.GetHitCount(), 2, "Should have run through the breakpoint twice")
 
     def auto_continue_with_command(self):
-        bpno = self.make_target_and_bkpt("-N BKPT -d 'break modify --auto-continue 0 BKPT'")
+        bpno = self.make_target_and_bkpt("-N BKPT -C 'break modify --auto-continue 0 BKPT'")
         process = self.launch_it(lldb.eStateStopped)
         state = process.GetState()
         self.assertEqual(state, lldb.eStateStopped, "Process should be stopped")

Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py Thu Sep 14 13:22:49 2017
@@ -287,7 +287,7 @@ class BreakpointCommandTestCase(TestBase
         # Add a breakpoint.
         lldbutil.run_break_set_by_file_and_line(
             self, "main.c", self.line, num_expected_locations=1, loc_exact=True,
-            extra_options='-d bt -d "thread list" -d continue')
+            extra_options='-C bt -C "thread list" -C continue')
 
         bkpt = target.FindBreakpointByID(1)
         self.assertTrue(bkpt.IsValid(), "Couldn't find breakpoint 1")

Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_names/TestBreakpointNames.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_names/TestBreakpointNames.py?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_names/TestBreakpointNames.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_names/TestBreakpointNames.py Thu Sep 14 13:22:49 2017
@@ -17,6 +17,7 @@ from lldbsuite.test import lldbutil
 class BreakpointNames(TestBase):
 
     mydir = TestBase.compute_mydir(__file__)
+    NO_DEBUG_INFO_TESTCASE = True
 
     @add_test_categories(['pyapi'])
     def test_setting_names(self):
@@ -37,6 +38,25 @@ class BreakpointNames(TestBase):
         self.setup_target()
         self.do_check_using_names()
 
+    def test_configuring_names(self):
+        """Use Python APIs to test that configuring options on breakpoint names works correctly."""
+        self.build()
+        self.make_a_dummy_name()
+        self.setup_target()
+        self.do_check_configuring_names()
+
+    def test_configuring_permissions_sb(self):
+        """Use Python APIs to test that configuring permissions on names works correctly."""
+        self.build()
+        self.setup_target()
+        self.do_check_configuring_permissions_sb()
+
+    def test_configuring_permissions_cli(self):
+        """Use Python APIs to test that configuring permissions on names works correctly."""
+        self.build()
+        self.setup_target()
+        self.do_check_configuring_permissions_cli()
+
     def setup_target(self):
         exe = os.path.join(os.getcwd(), "a.out")
 
@@ -45,10 +65,35 @@ class BreakpointNames(TestBase):
         self.assertTrue(self.target, VALID_TARGET)
         self.main_file_spec = lldb.SBFileSpec(os.path.join(os.getcwd(), "main.c"))
         
+    def check_name_in_target(self, bkpt_name):
+        name_list = lldb.SBStringList()
+        self.target.GetBreakpointNames(name_list)
+        found_it = False
+        for name in name_list:
+            if name == bkpt_name:
+                found_it = True
+                break
+        self.assertTrue(found_it, "Didn't find the name %s in the target's name list:"%(bkpt_name))
+       
     def setUp(self):
         # Call super's setUp().
         TestBase.setUp(self)
 
+        # These are the settings we're going to be putting into names & breakpoints:
+        self.bp_name_string = "ABreakpoint"
+        self.is_one_shot = True
+        self.ignore_count = 1000
+        self.condition = "1 == 2"
+        self.auto_continue = True
+        self.tid = 0xaaaa
+        self.tidx = 10
+        self.thread_name = "Fooey"
+        self.queue_name = "Blooey"
+        self.cmd_list = lldb.SBStringList()
+        self.cmd_list.AppendString("frame var")
+        self.cmd_list.AppendString("bt")
+
+
     def do_check_names(self):
         """Use Python APIs to check that we can set & retrieve breakpoint names"""
         bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
@@ -66,11 +111,15 @@ class BreakpointNames(TestBase):
         matches = bkpt.MatchesName("NotABreakpoint")
         self.assertTrue(not matches, "We matched a name we didn't set.")
 
+        # Make sure the name is also in the target:
+        self.check_name_in_target(bkpt_name)
+ 
         # Add another name, make sure that works too:
         bkpt.AddName(other_bkpt_name)
 
         matches = bkpt.MatchesName(bkpt_name)
         self.assertTrue(matches, "Adding a name means we didn't match the name we just set")
+        self.check_name_in_target(other_bkpt_name)
 
         # Remove the name and make sure we no longer match it:
         bkpt.RemoveName(bkpt_name)
@@ -89,26 +138,21 @@ class BreakpointNames(TestBase):
     def do_check_illegal_names(self):
         """Use Python APIs to check that we reject illegal names."""
         bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
-        success = bkpt.AddName("-CantStartWithADash")
-        self.assertTrue(not success,"We allowed a name starting with a dash.")
-
-        success = bkpt.AddName("1CantStartWithANumber")
-        self.assertTrue(not success, "We allowed a name starting with a number.")
-
-        success = bkpt.AddName("^CantStartWithNonAlpha")
-        self.assertTrue(not success, "We allowed a name starting with an ^.")
+        bad_names = ["-CantStartWithADash",
+                     "1CantStartWithANumber",
+                     "^CantStartWithNonAlpha",
+                     "CantHave-ADash",
+                     "Cant Have Spaces"]
+        for bad_name in bad_names:
+            success = bkpt.AddName(bad_name)
+            self.assertTrue(not success,"We allowed an illegal name: %s"%(bad_name))
+            bp_name = lldb.SBBreakpointName(self.target, bad_name)
+            self.assertFalse(bp_name.IsValid(), "We made a breakpoint name with an illegal name: %s"%(bad_name));
+
+            retval =lldb.SBCommandReturnObject()
+            self.dbg.GetCommandInterpreter().HandleCommand("break set -n whatever -N '%s'"%(bad_name), retval)
+            self.assertTrue(not retval.Succeeded(), "break set succeeded with: illegal name: %s"%(bad_name))
 
-        success = bkpt.AddName("CantHave-ADash")
-        self.assertTrue(not success, "We allowed a name with a dash in it.")
-
-        success = bkpt.AddName("Cant Have Spaces")
-        self.assertTrue(not success, "We allowed a name with spaces.")
-
-        # Check from the command line as well:
-        retval =lldb.SBCommandReturnObject()
-        self.dbg.GetCommandInterpreter().HandleCommand("break set -n whatever -N has-dashes", retval)
-        self.assertTrue(not retval.Succeeded(), "break set succeeded with: illegal name")
-        
     def do_check_using_names(self):
         """Use Python APIs to check names work in place of breakpoint ID's."""
         
@@ -133,9 +177,174 @@ class BreakpointNames(TestBase):
         self.assertTrue(not bkpt.IsEnabled(), "We didn't disable the breakpoint.")
 
         # Also make sure we don't apply commands to non-matching names:
-        self.dbg.GetCommandInterpreter().HandleCommand("break modify --one-shot 1 %s"%(bkpt_name), retval)
+        self.dbg.GetCommandInterpreter().HandleCommand("break modify --one-shot 1 %s"%(other_bkpt_name), retval)
         self.assertTrue(retval.Succeeded(), "break modify failed with: %s."%(retval.GetError()))
         self.assertTrue(not bkpt.IsOneShot(), "We applied one-shot to the wrong breakpoint.")
 
+    def check_option_values(self, bp_object):
+        self.assertEqual(bp_object.IsOneShot(), self.is_one_shot, "IsOneShot")
+        self.assertEqual(bp_object.GetIgnoreCount(), self.ignore_count, "IgnoreCount")
+        self.assertEqual(bp_object.GetCondition(), self.condition, "Condition")
+        self.assertEqual(bp_object.GetAutoContinue(), self.auto_continue, "AutoContinue")
+        self.assertEqual(bp_object.GetThreadID(), self.tid, "Thread ID")
+        self.assertEqual(bp_object.GetThreadIndex(), self.tidx, "Thread Index")
+        self.assertEqual(bp_object.GetThreadName(), self.thread_name, "Thread Name")
+        self.assertEqual(bp_object.GetQueueName(), self.queue_name, "Queue Name")
+        set_cmds = lldb.SBStringList()
+        bp_object.GetCommandLineCommands(set_cmds)
+        self.assertEqual(set_cmds.GetSize(), self.cmd_list.GetSize(), "Size of command line commands")
+        for idx in range(0, set_cmds.GetSize()):
+            self.assertEqual(self.cmd_list.GetStringAtIndex(idx), set_cmds.GetStringAtIndex(idx), "Command %d"%(idx))
+
+    def make_a_dummy_name(self):
+        "This makes a breakpoint name in the dummy target to make sure it gets copied over"
+
+        dummy_target = self.dbg.GetDummyTarget()
+        self.assertTrue(dummy_target.IsValid(), "Dummy target was not valid.")
+
+        def cleanup ():
+            self.dbg.GetDummyTarget().DeleteBreakpointName(self.bp_name_string)
+
+        # Execute the cleanup function during test case tear down.
+        self.addTearDownHook(cleanup)
+
+        # Now find it in the dummy target, and make sure these settings took:
+        bp_name = lldb.SBBreakpointName(dummy_target, self.bp_name_string)
+        # Make sure the name is right:
+        self.assertTrue (bp_name.GetName() == self.bp_name_string, "Wrong bp_name: %s"%(bp_name.GetName()))
+        bp_name.SetOneShot(self.is_one_shot)
+        bp_name.SetIgnoreCount(self.ignore_count)
+        bp_name.SetCondition(self.condition)
+        bp_name.SetAutoContinue(self.auto_continue)
+        bp_name.SetThreadID(self.tid)
+        bp_name.SetThreadIndex(self.tidx)
+        bp_name.SetThreadName(self.thread_name)
+        bp_name.SetQueueName(self.queue_name)
+        bp_name.SetCommandLineCommands(self.cmd_list)
+
+        # Now look it up again, and make sure it got set correctly.
+        bp_name = lldb.SBBreakpointName(dummy_target, self.bp_name_string)
+        self.assertTrue(bp_name.IsValid(), "Failed to make breakpoint name.")
+        self.check_option_values(bp_name)
+
+    def do_check_configuring_names(self):
+        """Use Python APIs to check that configuring breakpoint names works correctly."""
+        other_bp_name_string = "AnotherBreakpointName"
+        cl_bp_name_string = "CLBreakpointName"
+
+        # Now find the version copied in from the dummy target, and make sure these settings took:
+        bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
+        self.assertTrue(bp_name.IsValid(), "Failed to make breakpoint name.")
+        self.check_option_values(bp_name)
+
+        # Now add this name to a breakpoint, and make sure it gets configured properly
+        bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
+        success = bkpt.AddName(self.bp_name_string)
+        self.assertTrue(success, "Couldn't add this name to the breakpoint")
+        self.check_option_values(bkpt)
+
+        # Now make a name from this breakpoint, and make sure the new name is properly configured:
+        new_name = lldb.SBBreakpointName(bkpt, other_bp_name_string)
+        self.assertTrue(new_name.IsValid(), "Couldn't make a valid bp_name from a breakpoint.")
+        self.check_option_values(bkpt)
+
+        # Now change the name's option and make sure it gets propagated to
+        # the breakpoint:
+        new_auto_continue = not self.auto_continue
+        bp_name.SetAutoContinue(new_auto_continue)
+        self.assertEqual(bp_name.GetAutoContinue(), new_auto_continue, "Couldn't change auto-continue on the name")
+        self.assertEqual(bkpt.GetAutoContinue(), new_auto_continue, "Option didn't propagate to the breakpoint.")
+        
+        # Now make this same breakpoint name - but from the command line
+        cmd_str = "breakpoint name configure %s -o %d -i %d -c '%s' -G %d -t %d -x %d -T '%s' -q '%s'"%(cl_bp_name_string, 
+                                                                             self.is_one_shot, 
+                                                                             self.ignore_count, 
+                                                                             self.condition, 
+                                                                             self.auto_continue,
+                                                                             self.tid,
+                                                                             self.tidx,
+                                                                             self.thread_name,
+                                                                             self.queue_name)
+        for cmd in self.cmd_list:
+            cmd_str += " -C '%s'"%(cmd)
         
+        result = lldb.SBCommandReturnObject()
+        self.dbg.GetCommandInterpreter().HandleCommand(cmd_str, result)
+        self.assertTrue(result.Succeeded())
+        # Now look up this name again and check its options:
+        cl_name = lldb.SBBreakpointName(self.target, cl_bp_name_string)
+        self.check_option_values(cl_name)
+        
+        # We should have three names now, make sure the target can list them:
+        name_list = lldb.SBStringList()
+        self.target.GetBreakpointNames(name_list)
+        for name_string in [self.bp_name_string, other_bp_name_string, cl_bp_name_string]:
+            self.assertTrue(name_string in name_list, "Didn't find %s in names"%(name_string))
+
+        # Test that deleting the name we injected into the dummy target works (there's also a
+        # cleanup that will do this, but that won't test the result...
+        dummy_target = self.dbg.GetDummyTarget()
+        dummy_target.DeleteBreakpointName(self.bp_name_string)
+        name_list.Clear()
+        dummy_target.GetBreakpointNames(name_list)
+        self.assertTrue(self.bp_name_string not in name_list, "Didn't delete %s from the dummy target"%(self.bp_name_string))
         
+    def check_permission_results(self, bp_name):
+        self.assertEqual(bp_name.GetAllowDelete(), False, "Didn't set allow delete.")
+        protected_bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
+        protected_id = protected_bkpt.GetID()
+
+        unprotected_bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
+        unprotected_id = unprotected_bkpt.GetID()
+
+        success = protected_bkpt.AddName(self.bp_name_string)
+        self.assertTrue(success, "Couldn't add this name to the breakpoint")
+
+        self.target.DisableAllBreakpoints()
+        self.assertEqual(protected_bkpt.IsEnabled(), True, "Didnt' keep breakpoint from being disabled")
+        self.assertEqual(unprotected_bkpt.IsEnabled(), False, "Protected too many breakpoints from disabling.")
+
+        # Try from the command line too:
+        unprotected_bkpt.SetEnabled(True)
+        result = lldb.SBCommandReturnObject()
+        self.dbg.GetCommandInterpreter().HandleCommand("break disable", result)
+        self.assertTrue(result.Succeeded())
+        self.assertEqual(protected_bkpt.IsEnabled(), True, "Didnt' keep breakpoint from being disabled")
+        self.assertEqual(unprotected_bkpt.IsEnabled(), False, "Protected too many breakpoints from disabling.")
+
+        self.target.DeleteAllBreakpoints()
+        bkpt = self.target.FindBreakpointByID(protected_id)
+        self.assertTrue(bkpt.IsValid(), "Didn't keep the breakpoint from being deleted.")
+        bkpt = self.target.FindBreakpointByID(unprotected_id)
+        self.assertFalse(bkpt.IsValid(), "Protected too many breakpoints from deletion.")
+
+        # Remake the unprotected breakpoint and try again from the command line:
+        unprotected_bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
+        unprotected_id = unprotected_bkpt.GetID()
+
+        self.dbg.GetCommandInterpreter().HandleCommand("break delete -f", result)
+        self.assertTrue(result.Succeeded())
+        bkpt = self.target.FindBreakpointByID(protected_id)
+        self.assertTrue(bkpt.IsValid(), "Didn't keep the breakpoint from being deleted.")
+        bkpt = self.target.FindBreakpointByID(unprotected_id)
+        self.assertFalse(bkpt.IsValid(), "Protected too many breakpoints from deletion.")
+
+    def do_check_configuring_permissions_sb(self):
+        bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
+
+        # Make a breakpoint name with delete disallowed:
+        bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
+        self.assertTrue(bp_name.IsValid(), "Failed to make breakpoint name for valid name.")
+
+        bp_name.SetAllowDelete(False)
+        bp_name.SetAllowDisable(False)
+        bp_name.SetAllowList(False)
+        self.check_permission_results(bp_name)
+
+    def do_check_configuring_permissions_cli(self):
+        # Make the name with the right options using the command line:
+        self.runCmd("breakpoint name configure -L 0 -D 0 -A 0 %s"%(self.bp_name_string), check=True)
+        # Now look up the breakpoint we made, and check that it works.
+        bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
+        self.assertTrue(bp_name.IsValid(), "Didn't make a breakpoint name we could find.")
+        self.check_permission_results(bp_name)

Modified: lldb/trunk/packages/Python/lldbsuite/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/python_api/default-constructor/TestDefaultConstructorForAPIObjects.py Thu Sep 14 13:22:49 2017
@@ -73,6 +73,17 @@ class APIDefaultConstructorTestCase(Test
 
     @add_test_categories(['pyapi'])
     @no_debug_info_test
+    def test_SBBreakpointName(self):
+        obj = lldb.SBBreakpointName()
+        if self.TraceOn():
+            print(obj)
+        self.assertFalse(obj)
+        # Do fuzz testing on the invalid obj, it should not crash lldb.
+        import sb_breakpointname
+        sb_breakpointname.fuzz_obj(obj)
+
+    @add_test_categories(['pyapi'])
+    @no_debug_info_test
     def test_SBBroadcaster(self):
         obj = lldb.SBBroadcaster()
         if self.TraceOn():

Added: lldb/trunk/packages/Python/lldbsuite/test/python_api/default-constructor/sb_breakpointname.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/python_api/default-constructor/sb_breakpointname.py?rev=313292&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/python_api/default-constructor/sb_breakpointname.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/python_api/default-constructor/sb_breakpointname.py Thu Sep 14 13:22:49 2017
@@ -0,0 +1,42 @@
+"""
+Fuzz tests an object after the default construction to make sure it does not crash lldb.
+"""
+
+import sys
+import lldb
+
+
+def fuzz_obj(obj):
+    obj.IsValid()
+    obj.GetName()
+    obj.SetEnabled(True)
+    obj.IsEnabled()
+    obj.SetOneShot(True)
+    obj.IsOneShot()
+    obj.SetIgnoreCount(1)
+    obj.GetIgnoreCount()
+    obj.SetCondition("1 == 2")
+    obj.GetCondition()
+    obj.SetAutoContinue(False)
+    obj.GetAutoContinue()
+    obj.SetThreadID(0x1234)
+    obj.GetThreadID()
+    obj.SetThreadIndex(10)
+    obj.GetThreadIndex()
+    obj.SetThreadName("AThread")
+    obj.GetThreadName()
+    obj.SetQueueName("AQueue")
+    obj.GetQueueName()
+    obj.SetScriptCallbackFunction("AFunction")
+    commands = lldb.SBStringList()
+    obj.SetCommandLineCommands(commands)
+    obj.GetCommandLineCommands(commands)
+    obj.SetScriptCallbackBody("Insert Python Code here")
+    obj.GetAllowList()
+    obj.SetAllowList(False)
+    obj.GetAllowDelete()
+    obj.SetAllowDelete(False)
+    obj.GetAllowDisable()
+    obj.SetAllowDisable(False)
+    stream = lldb.SBStream()
+    obj.GetDescription(stream)

Modified: lldb/trunk/scripts/Python/python-extensions.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-extensions.swig?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-extensions.swig (original)
+++ lldb/trunk/scripts/Python/python-extensions.swig Thu Sep 14 13:22:49 2017
@@ -71,6 +71,21 @@
         }
 }
 
+%extend lldb::SBBreakpointName {
+        PyObject *lldb::SBBreakpointName::__str__ (){
+                lldb::SBStream description;
+                $self->GetDescription (description);
+                const char *desc = description.GetData();
+                size_t desc_len = description.GetSize();
+                if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
+                    --desc_len;
+                if (desc_len > 0)
+                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
+                else
+                    return lldb_private::PythonString("").release();
+        }
+}
+
 %extend lldb::SBBroadcaster {
     %pythoncode %{ 
         def __eq__(self, rhs):

Modified: lldb/trunk/scripts/Python/python-swigsafecast.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-swigsafecast.swig?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-swigsafecast.swig (original)
+++ lldb/trunk/scripts/Python/python-swigsafecast.swig Thu Sep 14 13:22:49 2017
@@ -115,6 +115,13 @@ SBTypeToSWIGWrapper (lldb::SBBreakpointL
 
 template <>
 PyObject*
+SBTypeToSWIGWrapper (lldb::SBBreakpointName* breakpoint_name_sb)
+{
+    return SWIG_NewPointerObj((void *) breakpoint_name_sb, SWIGTYPE_p_lldb__SBBreakpointName, 0);
+}
+
+template <>
+PyObject*
 SBTypeToSWIGWrapper (lldb::SBValue* value_sb)
 {
     return SWIG_NewPointerObj((void *) value_sb, SWIGTYPE_p_lldb__SBValue, 0);

Modified: lldb/trunk/scripts/interface/SBBreakpoint.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBBreakpoint.i?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/scripts/interface/SBBreakpoint.i (original)
+++ lldb/trunk/scripts/interface/SBBreakpoint.i Thu Sep 14 13:22:49 2017
@@ -6,7 +6,6 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-
 namespace lldb {
 
 %feature("docstring",
@@ -81,11 +80,6 @@ class SBBreakpoint
 {
 public:
 
-    typedef bool (*BreakpointHitCallback) (void *baton, 
-                                           SBProcess &process,
-                                           SBThread &thread, 
-                                           lldb::SBBreakpointLocation &location);
-
     SBBreakpoint ();
 
     SBBreakpoint (const lldb::SBBreakpoint& rhs);

Added: lldb/trunk/scripts/interface/SBBreakpointName.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBBreakpointName.i?rev=313292&view=auto
==============================================================================
--- lldb/trunk/scripts/interface/SBBreakpointName.i (added)
+++ lldb/trunk/scripts/interface/SBBreakpointName.i Thu Sep 14 13:22:49 2017
@@ -0,0 +1,108 @@
+//===-- SWIG interface for SBBreakpointName.h -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+%feature("docstring",
+"Represents a breakpoint name registered in a given SBTarget.
+
+Breakpoint names provide a way to act on groups of breakpoints.  When you add a
+name to a group of breakpoints, you can then use the name in all the command
+line lldb commands for that name.  You can also configure the SBBreakpointName
+options and those options will be propagated to any SBBreakpoints currently
+using that name.  Adding a name to a breakpoint will also apply any of the
+set options to that breakpoint.
+
+You can also set permissions on a breakpoint name to disable listing, deleting 
+and disabling breakpoints.  That will disallow the given operation for breakpoints
+except when the breakpoint is mentioned by ID.  So for instance deleting all the
+breakpoints won't delete breakpoints so marked."
+) SBBreakpointName;
+class LLDB_API SBBreakpointName {
+public:
+  SBBreakpointName();
+  
+  SBBreakpointName(SBTarget &target, const char *name);
+
+  SBBreakpointName(SBBreakpoint &bkpt, const char *name);
+
+  SBBreakpointName(const lldb::SBBreakpointName &rhs);
+
+  ~SBBreakpointName();
+
+  const lldb::SBBreakpointName &operator=(const lldb::SBBreakpointName &rhs);
+
+  // Tests to see if the opaque breakpoint object in this object matches the
+  // opaque breakpoint object in "rhs".
+  bool operator==(const lldb::SBBreakpointName &rhs);
+
+  bool operator!=(const lldb::SBBreakpointName &rhs);
+
+  bool IsValid() const;
+  
+  const char *GetName() const;
+
+  void SetEnabled(bool enable);
+
+  bool IsEnabled();
+
+  void SetOneShot(bool one_shot);
+
+  bool IsOneShot() const;
+
+  void SetIgnoreCount(uint32_t count);
+
+  uint32_t GetIgnoreCount() const;
+
+  void SetCondition(const char *condition);
+
+  const char *GetCondition();
+
+  void SetAutoContinue(bool auto_continue);
+
+  bool GetAutoContinue();
+
+  void SetThreadID(lldb::tid_t sb_thread_id);
+
+  lldb::tid_t GetThreadID();
+
+  void SetThreadIndex(uint32_t index);
+
+  uint32_t GetThreadIndex() const;
+
+  void SetThreadName(const char *thread_name);
+
+  const char *GetThreadName() const;
+
+  void SetQueueName(const char *queue_name);
+
+  const char *GetQueueName() const;
+
+  void SetScriptCallbackFunction(const char *callback_function_name);
+
+  void SetCommandLineCommands(SBStringList &commands);
+
+  bool GetCommandLineCommands(SBStringList &commands);
+
+  SBError SetScriptCallbackBody(const char *script_body_text);
+
+  bool GetAllowList() const;
+  void SetAllowList(bool value);
+    
+  bool GetAllowDelete();
+  void SetAllowDelete(bool value);
+    
+  bool GetAllowDisable();
+  void SetAllowDisable(bool value);
+
+  bool GetDescription(lldb::SBStream &description);
+
+};
+
+} // namespace lldb
+

Modified: lldb/trunk/scripts/interface/SBDebugger.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBDebugger.i?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/scripts/interface/SBDebugger.i (original)
+++ lldb/trunk/scripts/interface/SBDebugger.i Thu Sep 14 13:22:49 2017
@@ -214,6 +214,11 @@ public:
     CreateTarget (const char *filename);
 
     %feature("docstring",
+    "The dummy target holds breakpoints and breakpoint names that will prime newly created targets."
+    ) GetDummyTarget;
+    lldb::SBTarget GetDummyTarget();
+
+    %feature("docstring",
     "Return true if target is deleted from the target list of the debugger."
     ) DeleteTarget;
     bool

Modified: lldb/trunk/scripts/interface/SBTarget.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBTarget.i?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/scripts/interface/SBTarget.i (original)
+++ lldb/trunk/scripts/interface/SBTarget.i Thu Sep 14 13:22:49 2017
@@ -711,6 +711,10 @@ public:
   
     bool FindBreakpointsByName(const char *name, SBBreakpointList &bkpt_list);
 
+    void DeleteBreakpointName(const char *name);
+
+    void GetBreakpointNames(SBStringList &names);
+
     bool
     EnableAllBreakpoints ();
 

Modified: lldb/trunk/scripts/lldb.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/scripts/lldb.swig (original)
+++ lldb/trunk/scripts/lldb.swig Thu Sep 14 13:22:49 2017
@@ -82,6 +82,7 @@ import six
 #include "lldb/API/SBBlock.h"
 #include "lldb/API/SBBreakpoint.h"
 #include "lldb/API/SBBreakpointLocation.h"
+#include "lldb/API/SBBreakpointName.h"
 #include "lldb/API/SBBroadcaster.h"
 #include "lldb/API/SBCommandInterpreter.h"
 #include "lldb/API/SBCommandReturnObject.h"
@@ -168,6 +169,7 @@ import six
 %include "./interface/SBBlock.i"
 %include "./interface/SBBreakpoint.i"
 %include "./interface/SBBreakpointLocation.i"
+%include "./interface/SBBreakpointName.i"
 %include "./interface/SBBroadcaster.i"
 %include "./interface/SBCommandInterpreter.i"
 %include "./interface/SBCommandReturnObject.i"

Modified: lldb/trunk/source/API/SBBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBBreakpoint.cpp?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/source/API/SBBreakpoint.cpp (original)
+++ lldb/trunk/source/API/SBBreakpoint.cpp Thu Sep 14 13:22:49 2017
@@ -37,6 +37,8 @@
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/Stream.h"
 
+#include "SBBreakpointOptionCommon.h"
+
 #include "lldb/lldb-enumerations.h"
 
 #include "llvm/ADT/STLExtras.h"
@@ -44,21 +46,6 @@
 using namespace lldb;
 using namespace lldb_private;
 
-struct CallbackData {
-  SBBreakpoint::BreakpointHitCallback callback;
-  void *callback_baton;
-};
-
-class SBBreakpointCallbackBaton : public TypedBaton<CallbackData> {
-public:
-  SBBreakpointCallbackBaton(SBBreakpoint::BreakpointHitCallback callback,
-                            void *baton)
-      : TypedBaton(llvm::make_unique<CallbackData>()) {
-    getItem()->callback = callback;
-    getItem()->callback_baton = baton;
-  }
-};
-
 SBBreakpoint::SBBreakpoint() {}
 
 SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)
@@ -500,37 +487,9 @@ bool SBBreakpoint::GetDescription(SBStre
   return false;
 }
 
-bool SBBreakpoint::PrivateBreakpointHitCallback(void *baton,
-                                                StoppointCallbackContext *ctx,
-                                                lldb::user_id_t break_id,
-                                                lldb::user_id_t break_loc_id) {
-  ExecutionContext exe_ctx(ctx->exe_ctx_ref);
-  BreakpointSP bp_sp(
-      exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
-  if (baton && bp_sp) {
-    CallbackData *data = (CallbackData *)baton;
-    lldb_private::Breakpoint *bp = bp_sp.get();
-    if (bp && data->callback) {
-      Process *process = exe_ctx.GetProcessPtr();
-      if (process) {
-        SBProcess sb_process(process->shared_from_this());
-        SBThread sb_thread;
-        SBBreakpointLocation sb_location;
-        assert(bp_sp);
-        sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
-        Thread *thread = exe_ctx.GetThreadPtr();
-        if (thread)
-          sb_thread.SetThread(thread->shared_from_this());
-
-        return data->callback(data->callback_baton, sb_process, sb_thread,
-                              sb_location);
-      }
-    }
-  }
-  return true; // Return true if we should stop at this breakpoint
-}
-
-void SBBreakpoint::SetCallback(BreakpointHitCallback callback, void *baton) {
+void SBBreakpoint
+  ::SetCallback(SBBreakpointHitCallback callback,
+  void *baton) {
   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
   BreakpointSP bkpt_sp = GetSP();
   LLDB_LOG(log, "breakpoint = {0}, callback = {1}, baton = {2}", bkpt_sp.get(),
@@ -540,7 +499,8 @@ void SBBreakpoint::SetCallback(Breakpoin
     std::lock_guard<std::recursive_mutex> guard(
         bkpt_sp->GetTarget().GetAPIMutex());
     BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
-    bkpt_sp->SetCallback(SBBreakpoint::PrivateBreakpointHitCallback, baton_sp,
+    bkpt_sp->SetCallback(SBBreakpointCallbackBaton
+      ::PrivateBreakpointHitCallback, baton_sp,
                          false);
   }
 }
@@ -599,10 +559,17 @@ bool SBBreakpoint::AddName(const char *n
         bkpt_sp->GetTarget().GetAPIMutex());
     Status error; // Think I'm just going to swallow the error here, it's
                   // probably more annoying to have to provide it.
-    return bkpt_sp->AddName(new_name, error);
+    bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error);
+    if (error.Fail())
+    {
+      if (log)
+        log->Printf("Failed to add name: '%s' to breakpoint: %s", 
+            new_name, error.AsCString());
+      return false;
+    }
   }
 
-  return false;
+  return true;
 }
 
 void SBBreakpoint::RemoveName(const char *name_to_remove) {
@@ -613,7 +580,8 @@ void SBBreakpoint::RemoveName(const char
   if (bkpt_sp) {
     std::lock_guard<std::recursive_mutex> guard(
         bkpt_sp->GetTarget().GetAPIMutex());
-    bkpt_sp->RemoveName(name_to_remove);
+    bkpt_sp->GetTarget().RemoveNameFromBreakpoint(bkpt_sp, 
+                                                 ConstString(name_to_remove));
   }
 }
 

Added: lldb/trunk/source/API/SBBreakpointName.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBBreakpointName.cpp?rev=313292&view=auto
==============================================================================
--- lldb/trunk/source/API/SBBreakpointName.cpp (added)
+++ lldb/trunk/source/API/SBBreakpointName.cpp Thu Sep 14 13:22:49 2017
@@ -0,0 +1,662 @@
+//===-- SBBreakpointName.cpp ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/API/SBBreakpointName.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBError.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStringList.h"
+#include "lldb/API/SBTarget.h"
+
+#include "lldb/Breakpoint/BreakpointName.h"
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadSpec.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Stream.h"
+
+#include "SBBreakpointOptionCommon.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace lldb
+{
+class SBBreakpointNameImpl {
+public:
+  SBBreakpointNameImpl(SBTarget &sb_target, const char *name)
+  {
+    if (!name || name[0] == '\0')
+      return;
+    m_name.assign(name);
+    
+    if (!sb_target.IsValid())
+      return;
+    
+    TargetSP target_sp = sb_target.GetSP();
+    if (!target_sp)
+      return;
+    
+    m_target_wp = target_sp;
+  }
+  
+  SBBreakpointNameImpl(TargetSP target_sp, const char *name)
+  {
+    if (!name || name[0] == '\0')
+      return;
+    m_name.assign(name);
+    
+    if (!target_sp)
+      return;
+    
+    m_target_wp = target_sp;
+  }
+  
+  bool operator==(const SBBreakpointNameImpl &rhs) {
+    return m_name == rhs.m_name
+           && m_target_wp.lock() == rhs.m_target_wp.lock();
+  }
+  
+  bool operator!=(const SBBreakpointNameImpl &rhs) {
+    return m_name != rhs.m_name
+           || m_target_wp.lock() != rhs.m_target_wp.lock();
+  }
+  // For now we take a simple approach and only keep the name, and relook
+  // up the location when we need it.
+  
+  TargetSP GetTarget() {
+    return m_target_wp.lock();
+  }
+  
+  const char *GetName() {
+    return m_name.c_str();
+  }
+  
+  bool IsValid() {
+    return !m_name.empty() && m_target_wp.lock();
+  }
+  
+  lldb_private::BreakpointName *GetBreakpointName()
+  {
+    if (!IsValid())
+      return nullptr;
+    TargetSP target_sp = GetTarget();
+    if (!target_sp)
+      return nullptr;
+    Status error;
+    return target_sp->FindBreakpointName(ConstString(m_name), true, error);
+  }
+  
+  const lldb_private::BreakpointName *GetBreakpointName() const
+  {
+    return GetBreakpointName();
+  }
+  
+private:
+  TargetWP m_target_wp;
+  std::string m_name;
+};
+} // namespace lldb
+
+SBBreakpointName::SBBreakpointName() {}
+
+SBBreakpointName::SBBreakpointName(SBTarget &sb_target, const char *name)
+{
+  m_impl_up.reset(new SBBreakpointNameImpl(sb_target, name));
+  // Call FindBreakpointName here to make sure the name is valid, reset if
+  // not:
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    m_impl_up.reset();
+}
+
+SBBreakpointName::SBBreakpointName(SBBreakpoint &sb_bkpt, const char *name)
+{
+  if (!sb_bkpt.IsValid()) {
+    m_impl_up.reset();
+    return;
+  }
+  BreakpointSP bkpt_sp = sb_bkpt.GetSP();
+  Target &target = bkpt_sp->GetTarget();
+
+  m_impl_up.reset(new SBBreakpointNameImpl(target.shared_from_this(), name));
+  
+  // Call FindBreakpointName here to make sure the name is valid, reset if
+  // not:
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name) {
+    m_impl_up.reset();
+    return;
+  }
+  
+  // Now copy over the breakpoint's options:
+  target.ConfigureBreakpointName(*bp_name, *bkpt_sp->GetOptions(),
+                                 BreakpointName::Permissions());
+}
+
+SBBreakpointName::SBBreakpointName(const SBBreakpointName &rhs)
+{
+  if (!rhs.m_impl_up)
+    return;
+  else
+    m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(),
+                                             rhs.m_impl_up->GetName()));
+}
+
+SBBreakpointName::~SBBreakpointName() = default;
+
+const SBBreakpointName &SBBreakpointName::operator=(const SBBreakpointName &rhs) 
+{
+  if (!rhs.m_impl_up) {
+    m_impl_up.reset();
+    return *this;
+  }
+  
+  m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(),
+                                           rhs.m_impl_up->GetName()));
+  return *this;
+}
+
+bool SBBreakpointName::operator==(const lldb::SBBreakpointName &rhs) {
+  return *m_impl_up.get() == *rhs.m_impl_up.get();
+}
+
+bool SBBreakpointName::operator!=(const lldb::SBBreakpointName &rhs) {
+  return *m_impl_up.get() != *rhs.m_impl_up.get();
+}
+
+bool SBBreakpointName::IsValid() const {
+  if (!m_impl_up)
+    return false;
+  return m_impl_up->IsValid();
+}
+
+const char *SBBreakpointName::GetName() const {
+  if (!m_impl_up)
+    return "<Invalid Breakpoint Name Object>";
+  return m_impl_up->GetName();
+}
+
+void SBBreakpointName::SetEnabled(bool enable) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return;
+ 
+  LLDB_LOG(log, "Name: {0} enabled: {1}\n", bp_name->GetName(), enable);
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  bp_name->GetOptions().SetEnabled(enable);
+}
+
+void SBBreakpointName::UpdateName(BreakpointName &bp_name) {
+  if (!IsValid())
+    return;
+
+  TargetSP target_sp = m_impl_up->GetTarget();
+  if (!target_sp)
+    return;
+  target_sp->ApplyNameToBreakpoints(bp_name);
+
+}
+
+bool SBBreakpointName::IsEnabled() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return false;
+ 
+  LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  return bp_name->GetOptions().IsEnabled();
+}
+
+void SBBreakpointName::SetOneShot(bool one_shot) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return;
+ 
+  LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(), one_shot);
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  bp_name->GetOptions().SetOneShot(one_shot);
+  UpdateName(*bp_name);
+}
+
+bool SBBreakpointName::IsOneShot() const {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  const BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return false;
+ 
+  LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  return bp_name->GetOptions().IsOneShot();
+}
+
+void SBBreakpointName::SetIgnoreCount(uint32_t count) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return;
+ 
+  LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(), count);
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  bp_name->GetOptions().SetIgnoreCount(count);
+  UpdateName(*bp_name);
+}
+
+uint32_t SBBreakpointName::GetIgnoreCount() const {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return false;
+ 
+  LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  return bp_name->GetOptions().GetIgnoreCount();
+}
+
+void SBBreakpointName::SetCondition(const char *condition) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return;
+ 
+  LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(),
+          condition ? condition : "<NULL>");
+  
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  bp_name->GetOptions().SetCondition(condition);
+  UpdateName(*bp_name);
+}
+
+const char *SBBreakpointName::GetCondition() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return nullptr;
+ 
+  LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  return bp_name->GetOptions().GetConditionText();
+}
+
+void SBBreakpointName::SetAutoContinue(bool auto_continue) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return;
+ 
+  LLDB_LOG(log, "Name: {0} auto-continue: {1}\n", bp_name->GetName(), auto_continue);
+  
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  bp_name->GetOptions().SetAutoContinue(auto_continue);
+  UpdateName(*bp_name);
+}
+
+bool SBBreakpointName::GetAutoContinue() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return nullptr;
+ 
+  LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  return bp_name->GetOptions().IsAutoContinue();
+}
+
+void SBBreakpointName::SetThreadID(tid_t tid) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return;
+ 
+  LLDB_LOG(log, "Name: {0} tid: {1:x}\n", bp_name->GetName(), tid);
+  
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  bp_name->GetOptions().SetThreadID(tid);
+  UpdateName(*bp_name);
+}
+
+tid_t SBBreakpointName::GetThreadID() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return LLDB_INVALID_THREAD_ID;
+ 
+  LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  return bp_name->GetOptions().GetThreadSpec()->GetTID();
+}
+
+void SBBreakpointName::SetThreadIndex(uint32_t index) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return;
+ 
+  LLDB_LOG(log, "Name: {0} thread index: {1}\n", bp_name->GetName(), index);
+  
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  bp_name->GetOptions().GetThreadSpec()->SetIndex(index);
+  UpdateName(*bp_name);
+}
+
+uint32_t SBBreakpointName::GetThreadIndex() const {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return LLDB_INVALID_THREAD_ID;
+ 
+  LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  return bp_name->GetOptions().GetThreadSpec()->GetIndex();
+}
+
+void SBBreakpointName::SetThreadName(const char *thread_name) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return;
+ 
+  LLDB_LOG(log, "Name: {0} thread name: {1}\n", bp_name->GetName(), thread_name);
+  
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  bp_name->GetOptions().GetThreadSpec()->SetName(thread_name);
+  UpdateName(*bp_name);
+}
+
+const char *SBBreakpointName::GetThreadName() const {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return nullptr;
+ 
+  LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  return bp_name->GetOptions().GetThreadSpec()->GetName();
+}
+
+void SBBreakpointName::SetQueueName(const char *queue_name) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return;
+ 
+  LLDB_LOG(log, "Name: {0} queue name: {1}\n", bp_name->GetName(), queue_name);
+  
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  bp_name->GetOptions().GetThreadSpec()->SetQueueName(queue_name);
+  UpdateName(*bp_name);
+}
+
+const char *SBBreakpointName::GetQueueName() const {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return nullptr;
+ 
+  LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  return bp_name->GetOptions().GetThreadSpec()->GetQueueName();
+}
+
+void SBBreakpointName::SetCommandLineCommands(SBStringList &commands) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return;
+  if (commands.GetSize() == 0)
+    return;
+
+  LLDB_LOG(log, "Name: {0} commands\n", bp_name->GetName());
+
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+  std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(
+      new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));
+
+  bp_name->GetOptions().SetCommandDataCallback(cmd_data_up);
+  UpdateName(*bp_name);
+}
+
+bool SBBreakpointName::GetCommandLineCommands(SBStringList &commands) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return false;
+ 
+  LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+  StringList command_list;
+  bool has_commands =
+      bp_name->GetOptions().GetCommandLineCallbacks(command_list);
+  if (has_commands)
+    commands.AppendList(command_list);
+  return has_commands;
+}
+
+bool SBBreakpointName::GetDescription(SBStream &s) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+  {
+    s.Printf("No value");
+    return false;
+  }
+ 
+  LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+  bp_name->GetDescription(s.get(), eDescriptionLevelFull);
+  return true;
+}
+
+void SBBreakpointName::SetCallback(SBBreakpointHitCallback callback,
+                                   void *baton) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return;
+  LLDB_LOG(log, "callback = {1}, baton = {2}", callback, baton);
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
+  bp_name->GetOptions().SetCallback(SBBreakpointCallbackBaton
+                                       ::PrivateBreakpointHitCallback,
+                                    baton_sp,
+                                    false);
+  UpdateName(*bp_name);
+}
+
+void SBBreakpointName::SetScriptCallbackFunction(
+    const char *callback_function_name) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return;
+ 
+  LLDB_LOG(log, "Name: {0} callback: {1}\n", bp_name->GetName(),
+           callback_function_name);
+  
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  BreakpointOptions &bp_options = bp_name->GetOptions();
+  m_impl_up->GetTarget()
+      ->GetDebugger()
+      .GetCommandInterpreter()
+      .GetScriptInterpreter()
+      ->SetBreakpointCommandCallbackFunction(&bp_options,
+                                             callback_function_name);
+  UpdateName(*bp_name);
+}
+
+SBError SBBreakpointName::SetScriptCallbackBody(const char *callback_body_text)
+{
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  SBError sb_error;
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return sb_error;
+ 
+  LLDB_LOG(log, "Name: {0} callback: {1}\n", bp_name->GetName(),
+           callback_body_text);
+  
+  std::lock_guard<std::recursive_mutex> guard(
+        m_impl_up->GetTarget()->GetAPIMutex());
+
+  BreakpointOptions &bp_options = bp_name->GetOptions();
+  Status error =
+      m_impl_up->GetTarget()
+          ->GetDebugger()
+          .GetCommandInterpreter()
+          .GetScriptInterpreter()
+          ->SetBreakpointCommandCallback(&bp_options, callback_body_text);
+  sb_error.SetError(error);
+  if (!sb_error.Fail())
+    UpdateName(*bp_name);
+
+  return sb_error;
+}
+
+bool SBBreakpointName::GetAllowList() const
+{
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return false;
+  return bp_name->GetPermissions().GetAllowList();
+}
+
+void SBBreakpointName::SetAllowList(bool value)
+{
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return;
+  if (log)
+    log->Printf("Setting allow list to %u for %s.", value, 
+                bp_name->GetName().AsCString());
+  bp_name->GetPermissions().SetAllowList(value);
+}
+  
+bool SBBreakpointName::GetAllowDelete()
+{
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return false;
+  return bp_name->GetPermissions().GetAllowDelete();
+}
+
+void SBBreakpointName::SetAllowDelete(bool value)
+{
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return;
+  if (log)
+    log->Printf("Setting allow delete to %u for %s.", value, 
+                bp_name->GetName().AsCString());
+  bp_name->GetPermissions().SetAllowDelete(value);
+}
+  
+bool SBBreakpointName::GetAllowDisable()
+{
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return false;
+  return bp_name->GetPermissions().GetAllowDisable();
+}
+
+void SBBreakpointName::SetAllowDisable(bool value)
+{
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+  BreakpointName *bp_name = GetBreakpointName();
+  if (!bp_name)
+    return;
+  if (log)
+    log->Printf("Setting allow disable to %u for %s.", value, 
+                bp_name->GetName().AsCString());
+  bp_name->GetPermissions().SetAllowDisable(value);
+}
+
+lldb_private::BreakpointName *SBBreakpointName::GetBreakpointName() const
+{
+  if (!IsValid())
+    return nullptr;
+  return m_impl_up->GetBreakpointName();
+}
+

Added: lldb/trunk/source/API/SBBreakpointOptionCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBBreakpointOptionCommon.cpp?rev=313292&view=auto
==============================================================================
--- lldb/trunk/source/API/SBBreakpointOptionCommon.cpp (added)
+++ lldb/trunk/source/API/SBBreakpointOptionCommon.cpp Thu Sep 14 13:22:49 2017
@@ -0,0 +1,84 @@
+//===-- SBBreakpointName.cpp ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/API/SBBreakpointName.h"
+#include "lldb/API/SBBreakpointLocation.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBEvent.h"
+#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/API/SBStringList.h"
+#include "lldb/API/SBThread.h"
+
+#include "lldb/Breakpoint/BreakpointName.h"
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadSpec.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Stream.h"
+
+#include "lldb/lldb-enumerations.h"
+
+#include "SBBreakpointOptionCommon.h"
+
+#include "llvm/ADT/STLExtras.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBBreakpointCallbackBaton::SBBreakpointCallbackBaton(SBBreakpointHitCallback 
+                                                         callback,
+                                                     void *baton)
+      : TypedBaton(llvm::make_unique<CallbackData>()) {
+    getItem()->callback = callback;
+    getItem()->callback_baton = baton;
+  }
+
+ bool SBBreakpointCallbackBaton::PrivateBreakpointHitCallback(void *baton,
+                                                  StoppointCallbackContext *ctx,
+                                                  lldb::user_id_t break_id,
+                                                  lldb::user_id_t break_loc_id)
+{
+  ExecutionContext exe_ctx(ctx->exe_ctx_ref);
+  BreakpointSP bp_sp(
+      exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
+  if (baton && bp_sp) {
+    CallbackData *data = (CallbackData *)baton;
+    lldb_private::Breakpoint *bp = bp_sp.get();
+    if (bp && data->callback) {
+      Process *process = exe_ctx.GetProcessPtr();
+      if (process) {
+        SBProcess sb_process(process->shared_from_this());
+        SBThread sb_thread;
+        SBBreakpointLocation sb_location;
+        assert(bp_sp);
+        sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
+        Thread *thread = exe_ctx.GetThreadPtr();
+        if (thread)
+          sb_thread.SetThread(thread->shared_from_this());
+
+        return data->callback(data->callback_baton, sb_process, sb_thread,
+                              sb_location);
+      }
+    }
+  }
+  return true; // Return true if we should stop at this breakpoint
+}
+

Added: lldb/trunk/source/API/SBBreakpointOptionCommon.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBBreakpointOptionCommon.h?rev=313292&view=auto
==============================================================================
--- lldb/trunk/source/API/SBBreakpointOptionCommon.h (added)
+++ lldb/trunk/source/API/SBBreakpointOptionCommon.h Thu Sep 14 13:22:49 2017
@@ -0,0 +1,35 @@
+//===-- SBBreakpointOptionCommon.h ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBBreakpointOptionCommons_h_
+#define LLDB_SBBreakpointOptionCommons_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/Utility/Baton.h"
+
+namespace lldb
+{
+struct CallbackData {
+  SBBreakpointHitCallback callback;
+  void *callback_baton;
+};
+
+class SBBreakpointCallbackBaton : public lldb_private::TypedBaton<CallbackData> {
+public:
+  SBBreakpointCallbackBaton(SBBreakpointHitCallback callback,
+                            void *baton);
+
+  static bool PrivateBreakpointHitCallback(void *baton,
+                                           lldb_private::StoppointCallbackContext *ctx,
+                                           lldb::user_id_t break_id,
+                                           lldb::user_id_t break_loc_id);
+};
+
+} // namespace lldb
+#endif // LLDB_SBBreakpointOptionCommons_h_

Modified: lldb/trunk/source/API/SBDebugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBDebugger.cpp?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/source/API/SBDebugger.cpp (original)
+++ lldb/trunk/source/API/SBDebugger.cpp Thu Sep 14 13:22:49 2017
@@ -622,6 +622,20 @@ SBTarget SBDebugger::CreateTarget(const
   return sb_target;
 }
 
+SBTarget SBDebugger::GetDummyTarget() {
+  SBTarget sb_target;
+  if (m_opaque_sp) {
+      sb_target.SetSP(m_opaque_sp->GetDummyTarget()->shared_from_this());
+  }
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  if (log)
+    log->Printf(
+        "SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)",
+        static_cast<void *>(m_opaque_sp.get()),
+        static_cast<void *>(sb_target.GetSP().get()));
+  return sb_target;
+}
+
 bool SBDebugger::DeleteTarget(lldb::SBTarget &target) {
   bool result = false;
   if (m_opaque_sp) {

Modified: lldb/trunk/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTarget.cpp (original)
+++ lldb/trunk/source/API/SBTarget.cpp Thu Sep 14 13:22:49 2017
@@ -1087,11 +1087,38 @@ bool SBTarget::FindBreakpointsByName(con
   return true;
 }
 
+void SBTarget::GetBreakpointNames(SBStringList &names)
+{
+  names.Clear();
+
+  TargetSP target_sp(GetSP());
+  if (target_sp) {
+    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+
+    std::vector<std::string> name_vec;
+    target_sp->GetBreakpointNames(name_vec);
+    for (auto name : name_vec)
+      names.AppendString(name.c_str());
+  }
+}
+
+void SBTarget::DeleteBreakpointName(const char *name)
+{
+  TargetSP target_sp(GetSP());
+  if (target_sp) {
+    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+
+    std::vector<std::string> name_vec;
+    target_sp->DeleteBreakpointName(ConstString(name));
+
+  }
+}
+
 bool SBTarget::EnableAllBreakpoints() {
   TargetSP target_sp(GetSP());
   if (target_sp) {
     std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
-    target_sp->EnableAllBreakpoints();
+    target_sp->EnableAllowedBreakpoints();
     return true;
   }
   return false;
@@ -1101,7 +1128,7 @@ bool SBTarget::DisableAllBreakpoints() {
   TargetSP target_sp(GetSP());
   if (target_sp) {
     std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
-    target_sp->DisableAllBreakpoints();
+    target_sp->DisableAllowedBreakpoints();
     return true;
   }
   return false;
@@ -1111,7 +1138,7 @@ bool SBTarget::DeleteAllBreakpoints() {
   TargetSP target_sp(GetSP());
   if (target_sp) {
     std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
-    target_sp->RemoveAllBreakpoints();
+    target_sp->RemoveAllowedBreakpoints();
     return true;
   }
   return false;

Modified: lldb/trunk/source/Breakpoint/Breakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/Breakpoint.cpp?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/Breakpoint.cpp (original)
+++ lldb/trunk/source/Breakpoint/Breakpoint.cpp Thu Sep 14 13:22:49 2017
@@ -210,7 +210,7 @@ lldb::BreakpointSP Breakpoint::CreateFro
       llvm::StringRef name;
       Status error;
       success = names_array->GetItemAtIndexAsString(i, name);
-      result_sp->AddName(name, error);
+      target.AddNameToBreakpoint(result_sp, name.str().c_str(), error);
     }
   }
 
@@ -455,6 +455,10 @@ bool Breakpoint::InvokeCallback(Stoppoin
 
 BreakpointOptions *Breakpoint::GetOptions() { return m_options_up.get(); }
 
+const BreakpointOptions *Breakpoint::GetOptions() const {
+  return m_options_up.get();
+}
+
 void Breakpoint::ResolveBreakpoint() {
   if (m_resolver_sp)
     m_resolver_sp->ResolveBreakpoint(*m_filter_sp);
@@ -841,18 +845,8 @@ size_t Breakpoint::GetNumResolvedLocatio
 
 size_t Breakpoint::GetNumLocations() const { return m_locations.GetSize(); }
 
-bool Breakpoint::AddName(llvm::StringRef new_name, Status &error) {
-  if (new_name.empty())
-    return false;
-  if (!BreakpointID::StringIsBreakpointName(new_name, error)) {
-    error.SetErrorStringWithFormatv("input name \"{0}\" not a breakpoint name.",
-                                    new_name);
-    return false;
-  }
-  if (!error.Success())
-    return false;
-
-  m_name_list.insert(new_name);
+bool Breakpoint::AddName(llvm::StringRef new_name) {
+  m_name_list.insert(new_name.str().c_str());
   return true;
 }
 

Modified: lldb/trunk/source/Breakpoint/BreakpointID.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointID.cpp?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointID.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointID.cpp Thu Sep 14 13:22:49 2017
@@ -101,15 +101,24 @@ BreakpointID::ParseCanonicalReference(ll
 bool BreakpointID::StringIsBreakpointName(llvm::StringRef str, Status &error) {
   error.Clear();
   if (str.empty())
+  {
+    error.SetErrorStringWithFormat("Empty breakpoint names are not allowed");
     return false;
+  }
 
   // First character must be a letter or _
   if (!isalpha(str[0]) && str[0] != '_')
+  {
+    error.SetErrorStringWithFormat("Breakpoint names must start with a "
+                                   "character or underscore: %s",
+                                   str.str().c_str());
     return false;
+  }
 
   // Cannot contain ., -, or space.
   if (str.find_first_of(".- ") != llvm::StringRef::npos) {
-    error.SetErrorStringWithFormat("invalid breakpoint name: \"%s\"",
+    error.SetErrorStringWithFormat("Breakpoint names cannot contain "
+                                   "'.' or '-': \"%s\"",
                                    str.str().c_str());
     return false;
   }

Modified: lldb/trunk/source/Breakpoint/BreakpointIDList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointIDList.cpp?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointIDList.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointIDList.cpp Thu Sep 14 13:22:49 2017
@@ -11,6 +11,7 @@
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
+#include "lldb/lldb-enumerations.h"
 #include "lldb/Breakpoint/BreakpointIDList.h"
 
 #include "lldb/Breakpoint/Breakpoint.h"
@@ -117,6 +118,8 @@ void BreakpointIDList::InsertStringArray
 
 void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target,
                                               bool allow_locations,
+                                              BreakpointName::Permissions
+                                                  ::PermissionKinds purpose,
                                               CommandReturnObject &result,
                                               Args &new_args) {
   llvm::StringRef range_from;
@@ -302,14 +305,29 @@ void BreakpointIDList::FindAndReplaceIDR
   }
 
   // Okay, now see if we found any names, and if we did, add them:
-  if (target && names_found.size()) {
-    for (BreakpointSP bkpt_sp : target->GetBreakpointList().Breakpoints()) {
-      for (std::string name : names_found) {
-        if (bkpt_sp->MatchesName(name.c_str())) {
-          StreamString canonical_id_str;
-          BreakpointID::GetCanonicalReference(
-              &canonical_id_str, bkpt_sp->GetID(), LLDB_INVALID_BREAK_ID);
-          new_args.AppendArgument(canonical_id_str.GetString());
+  if (target && !names_found.empty()) {
+    Status error;
+    // Remove any names that aren't visible for this purpose:
+    auto iter = names_found.begin();
+    while (iter != names_found.end()) {
+      BreakpointName *bp_name = target->FindBreakpointName(ConstString(*iter),
+                                                           true,
+                                                           error);
+      if (bp_name && !bp_name->GetPermission(purpose))
+        iter = names_found.erase(iter);
+      else
+        iter++;
+    }
+    
+    if (!names_found.empty()) {
+      for (BreakpointSP bkpt_sp : target->GetBreakpointList().Breakpoints()) {
+        for (std::string name : names_found) {
+          if (bkpt_sp->MatchesName(name.c_str())) {
+            StreamString canonical_id_str;
+            BreakpointID::GetCanonicalReference(
+                &canonical_id_str, bkpt_sp->GetID(), LLDB_INVALID_BREAK_ID);
+            new_args.AppendArgument(canonical_id_str.GetString());
+          }
         }
       }
     }

Modified: lldb/trunk/source/Breakpoint/BreakpointList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointList.cpp?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointList.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointList.cpp Thu Sep 14 13:22:49 2017
@@ -71,6 +71,13 @@ void BreakpointList::SetEnabledAll(bool
     bp_sp->SetEnabled(enabled);
 }
 
+void BreakpointList::SetEnabledAllowed(bool enabled) {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  for (const auto &bp_sp : m_breakpoints)
+    if (bp_sp->AllowDisable())
+      bp_sp->SetEnabled(enabled);
+}
+
 void BreakpointList::RemoveAll(bool notify) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   ClearAllBreakpointSites();
@@ -90,6 +97,32 @@ void BreakpointList::RemoveAll(bool noti
   m_breakpoints.erase(m_breakpoints.begin(), m_breakpoints.end());
 }
 
+void BreakpointList::RemoveAllowed(bool notify) {
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
+  
+  bp_collection::iterator pos, end = m_breakpoints.end();
+  if (notify) {
+    for (pos = m_breakpoints.begin(); pos != end; ++pos) {
+      if(!(*pos)->AllowDelete())
+        continue;
+      if ((*pos)->GetTarget().EventTypeHasListeners(
+              Target::eBroadcastBitBreakpointChanged)) {
+        (*pos)->GetTarget().BroadcastEvent(
+            Target::eBroadcastBitBreakpointChanged,
+            new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved,
+                                                *pos));
+      }
+    }
+  }
+  pos = m_breakpoints.begin();
+  while ( pos != end) {
+      if((*pos)->AllowDelete())
+        pos = m_breakpoints.erase(pos);
+      else
+        pos++;
+  }
+}
+
 class BreakpointIDMatches {
 public:
   BreakpointIDMatches(break_id_t break_id) : m_break_id(break_id) {}

Added: lldb/trunk/source/Breakpoint/BreakpointName.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointName.cpp?rev=313292&view=auto
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointName.cpp (added)
+++ lldb/trunk/source/Breakpoint/BreakpointName.cpp Thu Sep 14 13:22:49 2017
@@ -0,0 +1,88 @@
+//===-- Breakpoint.cpp ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details->
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/Support/Casting.h"
+
+// Project includes
+#include "lldb/Breakpoint/Breakpoint.h"
+#include "lldb/Breakpoint/BreakpointOptions.h"
+#include "lldb/Breakpoint/BreakpointLocationCollection.h"
+#include "lldb/Breakpoint/BreakpointResolver.h"
+#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/Utility/StreamString.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+const Flags::ValueType BreakpointName::Permissions::permissions_mask
+    [BreakpointName::Permissions::PermissionKinds::allPerms + 1] =  { 
+      (1u << 0),
+      (1u << 1),
+      (1u << 2),
+      (0x5u)
+};
+
+BreakpointName::BreakpointName(const ConstString &name, const Breakpoint &bkpt,
+                 const char *help) :
+      m_name(name), m_options(bkpt.GetOptions())
+{
+  SetHelp(help);
+}
+
+bool BreakpointName::Permissions::GetDescription(Stream *s,
+                                                 lldb::DescriptionLevel level) {
+    if (!AnySet())
+      return false;
+    s->IndentMore();
+    s->Indent();
+    if (IsSet(listPerm))
+      s->Printf("list: %s", GetAllowList() ? "allowed" : "disallowed");
+  
+    if (IsSet(disablePerm))
+      s->Printf("disable: %s", GetAllowDisable() ? "allowed" : "disallowed");
+  
+    if (IsSet(deletePerm))
+      s->Printf("delete: %s", GetAllowDelete() ? "allowed" : "disallowed");
+    s->IndentLess();
+    return true;
+}
+
+bool BreakpointName::GetDescription(Stream *s, lldb::DescriptionLevel level) {
+  bool printed_any = false;
+  if (GetOptions().AnySet())
+  {
+    s->PutCString("Options: \n");
+    s->IndentMore();
+    s->Indent();
+    GetOptions().GetDescription(s, level);
+    printed_any = true;
+    s->IndentLess();
+  }
+  if (GetPermissions().AnySet())
+  {
+    s->PutCString("Permissions: \n");
+    s->IndentMore();
+    s->Indent();
+    GetPermissions().GetDescription(s, level);
+    printed_any = true;
+    s->IndentLess();
+ }
+  return printed_any;
+}
+
+void BreakpointName::ConfigureBreakpoint(lldb::BreakpointSP bp_sp)
+{
+   bp_sp->GetOptions()->CopyOverSetOptions(GetOptions());
+   bp_sp->GetPermissions().MergeInto(GetPermissions());
+}

Modified: lldb/trunk/source/Breakpoint/BreakpointOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointOptions.cpp?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointOptions.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointOptions.cpp Thu Sep 14 13:22:49 2017
@@ -132,7 +132,7 @@ BreakpointOptions::BreakpointOptions(boo
       m_baton_is_command_baton(false), m_callback_is_synchronous(false),
       m_enabled(true), m_one_shot(false), m_ignore_count(0), m_thread_spec_ap(),
       m_condition_text(), m_condition_text_hash(0), m_auto_continue(false),
-      m_set_flags() {
+      m_set_flags(0) {
         if (all_flags_set)
           m_set_flags.Set(~((Flags::ValueType) 0));
       }
@@ -142,11 +142,14 @@ BreakpointOptions::BreakpointOptions(con
                                      bool auto_continue)
     : m_callback(nullptr), m_baton_is_command_baton(false),
       m_callback_is_synchronous(false), m_enabled(enabled),
-      m_one_shot(one_shot), m_ignore_count(ignore), m_condition_text(condition),
+      m_one_shot(one_shot), m_ignore_count(ignore),
       m_condition_text_hash(0), m_auto_continue(auto_continue)
 {
     m_set_flags.Set(eEnabled | eIgnoreCount | eOneShot 
-                   | eCondition | eAutoContinue);
+                   | eAutoContinue);
+    if (condition && *condition != '\0') {
+      SetCondition(condition);
+    }
 }
 
 //----------------------------------------------------------------------
@@ -187,6 +190,59 @@ operator=(const BreakpointOptions &rhs)
   return *this;
 }
 
+void BreakpointOptions::CopyOverSetOptions(const BreakpointOptions &incoming)
+{
+  if (incoming.m_set_flags.Test(eEnabled))
+  {
+    m_enabled = incoming.m_enabled;
+    m_set_flags.Set(eEnabled);
+  }
+  if (incoming.m_set_flags.Test(eOneShot))
+  {
+    m_one_shot = incoming.m_one_shot;
+    m_set_flags.Set(eOneShot);
+  }
+  if (incoming.m_set_flags.Test(eCallback))
+  {
+    m_callback = incoming.m_callback;
+    m_callback_baton_sp = incoming.m_callback_baton_sp;
+    m_callback_is_synchronous = incoming.m_callback_is_synchronous;
+    m_baton_is_command_baton = incoming.m_baton_is_command_baton;
+    m_set_flags.Set(eCallback);
+  }
+  if (incoming.m_set_flags.Test(eIgnoreCount))
+  {
+    m_ignore_count = incoming.m_ignore_count;
+    m_set_flags.Set(eIgnoreCount);
+  }
+  if (incoming.m_set_flags.Test(eCondition))
+  {
+    // If we're copying over an empty condition, mark it as unset.
+    if (incoming.m_condition_text.empty()) {
+      m_condition_text.clear();
+      m_condition_text_hash = 0;
+      m_set_flags.Clear(eCondition);
+    } else {
+      m_condition_text = incoming.m_condition_text;
+      m_condition_text_hash = incoming.m_condition_text_hash;
+      m_set_flags.Set(eCondition);
+    }
+  }
+  if (incoming.m_set_flags.Test(eAutoContinue))
+  {
+    m_auto_continue = incoming.m_auto_continue;
+    m_set_flags.Set(eAutoContinue);
+  }
+  if (incoming.m_set_flags.Test(eThreadSpec) && incoming.m_thread_spec_ap)
+  {
+    if (!m_thread_spec_ap)
+      m_thread_spec_ap.reset(new ThreadSpec(*incoming.m_thread_spec_ap.get()));
+    else
+      *m_thread_spec_ap.get() = *incoming.m_thread_spec_ap.get();
+    m_set_flags.Set(eThreadSpec);
+  }
+}
+
 //----------------------------------------------------------------------
 // Destructor
 //----------------------------------------------------------------------
@@ -327,23 +383,23 @@ std::unique_ptr<BreakpointOptions> Break
 StructuredData::ObjectSP BreakpointOptions::SerializeToStructuredData() {
   StructuredData::DictionarySP options_dict_sp(
       new StructuredData::Dictionary());
-  if (m_set_flags.Set(eEnabled))
+  if (m_set_flags.Test(eEnabled))
     options_dict_sp->AddBooleanItem(GetKey(OptionNames::EnabledState),
                                     m_enabled);
-  if (m_set_flags.Set(eOneShot))
+  if (m_set_flags.Test(eOneShot))
     options_dict_sp->AddBooleanItem(GetKey(OptionNames::OneShotState),
                                m_one_shot);
-  if (m_set_flags.Set(eAutoContinue))
+  if (m_set_flags.Test(eAutoContinue))
     options_dict_sp->AddBooleanItem(GetKey(OptionNames::AutoContinue),
                                m_auto_continue);
-  if (m_set_flags.Set(eIgnoreCount))
+  if (m_set_flags.Test(eIgnoreCount))
     options_dict_sp->AddIntegerItem(GetKey(OptionNames::IgnoreCount),
                                     m_ignore_count);
-  if (m_set_flags.Set(eCondition))
+  if (m_set_flags.Test(eCondition))
     options_dict_sp->AddStringItem(GetKey(OptionNames::ConditionText),
                                    m_condition_text);
          
-  if (m_set_flags.Set(eCallback) && m_baton_is_command_baton) {
+  if (m_set_flags.Test(eCallback) && m_baton_is_command_baton) {
     auto cmd_baton =
         std::static_pointer_cast<CommandBaton>(m_callback_baton_sp);
     StructuredData::ObjectSP commands_sp =
@@ -353,7 +409,7 @@ StructuredData::ObjectSP BreakpointOptio
           BreakpointOptions::CommandData::GetSerializationKey(), commands_sp);
     }
   }
-  if (m_set_flags.Set(eThreadSpec) && m_thread_spec_ap) {
+  if (m_set_flags.Test(eThreadSpec) && m_thread_spec_ap) {
     StructuredData::ObjectSP thread_spec_sp =
         m_thread_spec_ap->SerializeToStructuredData();
     options_dict_sp->AddItem(ThreadSpec::GetSerializationKey(), thread_spec_sp);
@@ -618,3 +674,18 @@ bool BreakpointOptions::BreakpointOption
   }
   return ret_value;
 }
+
+void BreakpointOptions::Clear()
+{
+  m_set_flags.Clear();
+  m_thread_spec_ap.release();
+  m_one_shot = false;
+  m_ignore_count = 0;
+  m_auto_continue = false;
+  m_callback = nullptr;
+  m_callback_baton_sp.reset();
+  m_baton_is_command_baton = false;
+  m_callback_is_synchronous = false;
+  m_enabled = false;
+  m_condition_text.clear();
+}

Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Thu Sep 14 13:22:49 2017
@@ -45,6 +45,203 @@ static void AddBreakpointDescription(Str
   s->EOL();
 }
 
+//-------------------------------------------------------------------------
+// Modifiable Breakpoint Options
+//-------------------------------------------------------------------------
+#pragma mark Modify::CommandOptions
+static OptionDefinition g_breakpoint_modify_options[] = {
+    // clang-format off
+  { LLDB_OPT_SET_1, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount,       "Set the number of times this breakpoint is skipped before stopping." },
+  { LLDB_OPT_SET_1, false, "one-shot",     'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,     "The breakpoint is deleted the first time it stop causes a stop." },
+  { LLDB_OPT_SET_1, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." },
+  { LLDB_OPT_SET_1, false, "thread-id",    't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID,    "The breakpoint stops only for the thread whose TID matches this argument." },
+  { LLDB_OPT_SET_1, false, "thread-name",  'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName,  "The breakpoint stops only for the thread whose thread name matches this argument." },
+  { LLDB_OPT_SET_1, false, "queue-name",   'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName,   "The breakpoint stops only for threads in the queue whose name is given by this argument." },
+  { LLDB_OPT_SET_1, false, "condition",    'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression,  "The breakpoint stops only if this condition expression evaluates to true." },
+  { LLDB_OPT_SET_1, false, "auto-continue",'G', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,     "The breakpoint will auto-continue after running its commands." },
+  { LLDB_OPT_SET_2, false, "enable",       'e', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,        "Enable the breakpoint." },
+  { LLDB_OPT_SET_3, false, "disable",      'd', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,        "Disable the breakpoint." },
+  { LLDB_OPT_SET_4, false, "command",      'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCommand,     "A command to run when the breakpoint is hit, can be provided more than once, the commands will get run in order left to right." },
+    // clang-format on
+};
+class lldb_private::BreakpointOptionGroup : public OptionGroup
+{
+public:
+  BreakpointOptionGroup() :
+          OptionGroup(),
+          m_bp_opts(false) {}
+  
+  ~BreakpointOptionGroup() override = default;
+
+  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+    return llvm::makeArrayRef(g_breakpoint_modify_options);
+  }
+
+  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+                          ExecutionContext *execution_context) override {
+    Status error;
+    const int short_option = g_breakpoint_modify_options[option_idx].short_option;
+
+    switch (short_option) {
+    case 'c':
+      // Normally an empty breakpoint condition marks is as unset.
+      // But we need to say it was passed in.
+      m_bp_opts.SetCondition(option_arg.str().c_str());
+      m_bp_opts.m_set_flags.Set(BreakpointOptions::eCondition);
+      break;
+    case 'C':
+      m_commands.push_back(option_arg);
+      break;
+    case 'd':
+      m_bp_opts.SetEnabled(false);
+      break;
+    case 'e':
+      m_bp_opts.SetEnabled(true);
+      break;
+    case 'G': {
+      bool value, success;
+      value = Args::StringToBoolean(option_arg, false, &success);
+      if (success) {
+        m_bp_opts.SetAutoContinue(value);
+      } else
+        error.SetErrorStringWithFormat(
+            "invalid boolean value '%s' passed for -G option",
+            option_arg.str().c_str());
+    }
+    break;
+    case 'i':
+    {
+      uint32_t ignore_count;
+      if (option_arg.getAsInteger(0, ignore_count))
+        error.SetErrorStringWithFormat("invalid ignore count '%s'",
+                                       option_arg.str().c_str());
+      else
+        m_bp_opts.SetIgnoreCount(ignore_count);
+    }
+    break;
+    case 'o': {
+      bool value, success;
+      value = Args::StringToBoolean(option_arg, false, &success);
+      if (success) {
+        m_bp_opts.SetOneShot(value);
+      } else
+        error.SetErrorStringWithFormat(
+            "invalid boolean value '%s' passed for -o option",
+            option_arg.str().c_str());
+    } break;
+    case 't':
+    {
+      lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID;
+      if (option_arg[0] != '\0') {
+        if (option_arg.getAsInteger(0, thread_id))
+          error.SetErrorStringWithFormat("invalid thread id string '%s'",
+                                         option_arg.str().c_str());
+      }
+      m_bp_opts.SetThreadID(thread_id);
+    }
+    break;
+    case 'T':
+      m_bp_opts.GetThreadSpec()->SetName(option_arg.str().c_str());
+      break;
+    case 'q':
+      m_bp_opts.GetThreadSpec()->SetQueueName(option_arg.str().c_str());
+      break;
+    case 'x':
+    {
+      uint32_t thread_index = UINT32_MAX;
+      if (option_arg[0] != '\n') {
+        if (option_arg.getAsInteger(0, thread_index))
+          error.SetErrorStringWithFormat("invalid thread index string '%s'",
+                                         option_arg.str().c_str());
+      }
+      m_bp_opts.GetThreadSpec()->SetIndex(thread_index);
+    }
+    break;
+    default:
+      error.SetErrorStringWithFormat("unrecognized option '%c'",
+                                     short_option);
+      break;
+    }
+
+    return error;
+  }
+
+  void OptionParsingStarting(ExecutionContext *execution_context) override {
+    m_bp_opts.Clear();
+    m_commands.clear();
+  }
+  
+  Status OptionParsingFinished(ExecutionContext *execution_context) override {
+    if (!m_commands.empty())
+    {
+      if (!m_commands.empty())
+      {
+          auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>();
+        
+          for (std::string &str : m_commands)
+            cmd_data->user_source.AppendString(str); 
+
+          cmd_data->stop_on_error = true;
+          m_bp_opts.SetCommandDataCallback(cmd_data);
+      }
+    }
+    return Status();
+  }
+  
+  const BreakpointOptions &GetBreakpointOptions()
+  {
+    return m_bp_opts;
+  }
+
+  std::vector<std::string> m_commands;
+  BreakpointOptions m_bp_opts;
+
+};
+static OptionDefinition g_breakpoint_dummy_options[] = {
+    // clang-format off
+  { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Act on Dummy breakpoints - i.e. breakpoints set before a file is provided, "
+  "which prime new targets." },
+    // clang-format on
+};
+
+class BreakpointDummyOptionGroup : public OptionGroup
+{
+public:
+  BreakpointDummyOptionGroup() :
+          OptionGroup() {}
+  
+  ~BreakpointDummyOptionGroup() override = default;
+
+  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+    return llvm::makeArrayRef(g_breakpoint_dummy_options);
+  }
+
+  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+                          ExecutionContext *execution_context) override {
+    Status error;
+    const int short_option = g_breakpoint_modify_options[option_idx].short_option;
+
+    switch (short_option) {
+      case 'D':
+        m_use_dummy = true;
+        break;
+    default:
+      error.SetErrorStringWithFormat("unrecognized option '%c'",
+                                     short_option);
+      break;
+    }
+
+    return error;
+  }
+
+  void OptionParsingStarting(ExecutionContext *execution_context) override {
+    m_use_dummy = false;
+  }
+
+  bool m_use_dummy;
+
+};
+
 // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
 // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
 #define LLDB_OPT_FILE (LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2)
@@ -58,18 +255,7 @@ static OptionDefinition g_breakpoint_set
     // clang-format off
   { LLDB_OPT_NOT_10,               false, "shlib",                  's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion,     eArgTypeShlibName,           "Set the breakpoint only in this shared library.  Can repeat this option "
   "multiple times to specify multiple shared libraries." },
-  { LLDB_OPT_SET_ALL,              false, "ignore-count",           'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeCount,               "Set the number of times this breakpoint is skipped before stopping." },
-  { LLDB_OPT_SET_ALL,              false, "one-shot",               'o', OptionParser::eNoArgument,       nullptr, nullptr, 0,                                         eArgTypeNone,                "The breakpoint is deleted the first time it causes a stop." },
-  { LLDB_OPT_SET_ALL,              false, "auto-continue",          'G', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeBoolean,             "The breakpoint will auto-continue after running its commands." },
-  { LLDB_OPT_SET_ALL,              false, "condition",              'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeExpression,          "The breakpoint stops only if this condition expression evaluates to true." },
-  { LLDB_OPT_SET_ALL,              false, "command",                'd', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeCommand,             "A command to run when the breakpoint is hit, can be provided more than once, the commands will get run in order left to right." },
-  { LLDB_OPT_SET_ALL,              false, "thread-index",           'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeThreadIndex,         "The breakpoint stops only for the thread whose indeX matches this argument." },
-  { LLDB_OPT_SET_ALL,              false, "thread-id",              't', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeThreadID,            "The breakpoint stops only for the thread whose TID matches this argument." },
-  { LLDB_OPT_SET_ALL,              false, "thread-name",            'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeThreadName,          "The breakpoint stops only for the thread whose thread name matches this "
-  "argument." },
   { LLDB_OPT_SET_ALL,              false, "hardware",               'H', OptionParser::eNoArgument,       nullptr, nullptr, 0,                                         eArgTypeNone,                "Require the breakpoint to use hardware breakpoints." },
-  { LLDB_OPT_SET_ALL,              false, "queue-name",             'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeQueueName,           "The breakpoint stops only for threads in the queue whose name is given by "
-  "this argument." },
   { LLDB_OPT_FILE,                 false, "file",                   'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,            "Specifies the source file in which to set this breakpoint.  Note, by default "
   "lldb only looks for files that are #included if they use the standard include "
   "file extensions.  To set breakpoints on .c/.cpp/.m/.mm files that are "
@@ -127,8 +313,6 @@ static OptionDefinition g_breakpoint_set
   "If not set the target.language setting is used." },
   { LLDB_OPT_SKIP_PROLOGUE,        false, "skip-prologue",          'K', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeBoolean,             "sKip the prologue if the breakpoint is at the beginning of a function.  "
   "If not set the target.skip-prologue setting is used." },
-  { LLDB_OPT_SET_ALL,              false, "dummy-breakpoints",      'D', OptionParser::eNoArgument,       nullptr, nullptr, 0,                                         eArgTypeNone,                "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, "
-  "which prime new targets." },
   { LLDB_OPT_SET_ALL,              false, "breakpoint-name",        'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeBreakpointName,      "Adds this to the list of names for this breakpoint." },
   { LLDB_OPT_OFFSET_APPLIES,       false, "address-slide",          'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                         eArgTypeAddress,             "Add the specified offset to whatever address(es) the breakpoint resolves to.  "
   "At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries." },
@@ -158,24 +342,30 @@ public:
             interpreter, "breakpoint set",
             "Sets a breakpoint or set of breakpoints in the executable.",
             "breakpoint set <cmd-options>"),
-        m_options() {}
+        m_bp_opts(), m_options() {
+          // We're picking up all the normal options, commands and disable.
+          m_all_options.Append(&m_bp_opts, 
+                               LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4, 
+                               LLDB_OPT_SET_ALL);
+          m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
+          m_all_options.Append(&m_options);
+          m_all_options.Finalize();
+        }
 
   ~CommandObjectBreakpointSet() override = default;
 
-  Options *GetOptions() override { return &m_options; }
+  Options *GetOptions() override { return &m_all_options; }
 
-  class CommandOptions : public Options {
+  class CommandOptions : public OptionGroup {
   public:
     CommandOptions()
-        : Options(), m_condition(), m_filenames(), m_line_num(0), m_column(0),
+        : OptionGroup(), m_condition(), m_filenames(), m_line_num(0), m_column(0),
           m_func_names(), m_func_name_type_mask(eFunctionNameTypeNone),
           m_func_regexp(), m_source_text_regexp(), m_modules(), m_load_addr(),
-          m_ignore_count(0), m_thread_id(LLDB_INVALID_THREAD_ID),
-          m_thread_index(UINT32_MAX), m_thread_name(), m_queue_name(),
           m_catch_bp(false), m_throw_bp(true), m_hardware(false),
           m_exception_language(eLanguageTypeUnknown),
           m_language(lldb::eLanguageTypeUnknown),
-          m_skip_prologue(eLazyBoolCalculate), m_one_shot(false),
+          m_skip_prologue(eLazyBoolCalculate),
           m_all_files(false), m_move_to_nearest_code(eLazyBoolCalculate) {}
 
     ~CommandOptions() override = default;
@@ -183,7 +373,7 @@ public:
     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
                           ExecutionContext *execution_context) override {
       Status error;
-      const int short_option = m_getopt_table[option_idx].val;
+      const int short_option = g_breakpoint_set_options[option_idx].short_option;
 
       switch (short_option) {
       case 'a': {
@@ -206,18 +396,6 @@ public:
                                          option_arg.str().c_str());
         break;
 
-      case 'c':
-        m_condition.assign(option_arg);
-        break;
-
-      case 'd':
-        m_commands.push_back(option_arg);
-        break;
-        
-      case 'D':
-        m_use_dummy = true;
-        break;
-
       case 'E': {
         LanguageType language = Language::GetLanguageTypeFromString(option_arg);
 
@@ -262,15 +440,6 @@ public:
         m_func_name_type_mask |= eFunctionNameTypeFull;
         break;
         
-      case 'G' : {
-        bool success;
-        m_auto_continue = Args::StringToBoolean(option_arg, true, &success);
-        if (!success)
-          error.SetErrorStringWithFormat(
-              "Invalid boolean value for auto-continue option: '%s'",
-              option_arg.str().c_str());
-      } break;
-
       case 'h': {
         bool success;
         m_catch_bp = Args::StringToBoolean(option_arg, true, &success);
@@ -284,12 +453,6 @@ public:
         m_hardware = true;
         break;
 
-      case 'i':
-        if (option_arg.getAsInteger(0, m_ignore_count))
-          error.SetErrorStringWithFormat("invalid ignore count '%s'",
-                                         option_arg.str().c_str());
-        break;
-
       case 'K': {
         bool success;
         bool value;
@@ -362,10 +525,6 @@ public:
           m_offset_addr = tmp_offset_addr;
       } break;
 
-      case 'o':
-        m_one_shot = true;
-        break;
-
       case 'O':
         m_exception_extra_args.AppendArgument("-O");
         m_exception_extra_args.AppendArgument(option_arg);
@@ -375,10 +534,6 @@ public:
         m_source_text_regexp.assign(option_arg);
         break;
 
-      case 'q':
-        m_queue_name.assign(option_arg);
-        break;
-
       case 'r':
         m_func_regexp.assign(option_arg);
         break;
@@ -392,16 +547,6 @@ public:
         m_func_name_type_mask |= eFunctionNameTypeSelector;
         break;
 
-      case 't':
-        if (option_arg.getAsInteger(0, m_thread_id))
-          error.SetErrorStringWithFormat("invalid thread id string '%s'",
-                                         option_arg.str().c_str());
-        break;
-
-      case 'T':
-        m_thread_name.assign(option_arg);
-        break;
-
       case 'w': {
         bool success;
         m_throw_bp = Args::StringToBoolean(option_arg, true, &success);
@@ -411,12 +556,6 @@ public:
               option_arg.str().c_str());
       } break;
 
-      case 'x':
-        if (option_arg.getAsInteger(0, m_thread_index))
-          error.SetErrorStringWithFormat("invalid thread index string '%s'",
-                                         option_arg.str().c_str());
-        break;
-
       case 'X':
         m_source_regex_func_names.insert(option_arg);
         break;
@@ -431,7 +570,6 @@ public:
     }
 
     void OptionParsingStarting(ExecutionContext *execution_context) override {
-      m_condition.clear();
       m_filenames.Clear();
       m_line_num = 0;
       m_column = 0;
@@ -442,26 +580,17 @@ public:
       m_modules.Clear();
       m_load_addr = LLDB_INVALID_ADDRESS;
       m_offset_addr = 0;
-      m_ignore_count = 0;
-      m_thread_id = LLDB_INVALID_THREAD_ID;
-      m_thread_index = UINT32_MAX;
-      m_thread_name.clear();
-      m_queue_name.clear();
       m_catch_bp = false;
       m_throw_bp = true;
       m_hardware = false;
       m_exception_language = eLanguageTypeUnknown;
       m_language = lldb::eLanguageTypeUnknown;
       m_skip_prologue = eLazyBoolCalculate;
-      m_one_shot = false;
-      m_use_dummy = false;
       m_breakpoint_names.clear();
       m_all_files = false;
       m_exception_extra_args.Clear();
       m_move_to_nearest_code = eLazyBoolCalculate;
       m_source_regex_func_names.clear();
-      m_commands.clear();
-      m_auto_continue = false;
     }
 
     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
@@ -482,30 +611,21 @@ public:
     FileSpecList m_modules;
     lldb::addr_t m_load_addr;
     lldb::addr_t m_offset_addr;
-    uint32_t m_ignore_count;
-    lldb::tid_t m_thread_id;
-    uint32_t m_thread_index;
-    std::string m_thread_name;
-    std::string m_queue_name;
     bool m_catch_bp;
     bool m_throw_bp;
     bool m_hardware; // Request to use hardware breakpoints
     lldb::LanguageType m_exception_language;
     lldb::LanguageType m_language;
     LazyBool m_skip_prologue;
-    bool m_one_shot;
-    bool m_use_dummy;
     bool m_all_files;
     Args m_exception_extra_args;
     LazyBool m_move_to_nearest_code;
     std::unordered_set<std::string> m_source_regex_func_names;
-    std::vector<std::string> m_commands;
-    bool m_auto_continue;
   };
 
 protected:
   bool DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+    Target *target = GetSelectedOrDummyTarget(m_dummy_options.m_use_dummy);
 
     if (target == nullptr) {
       result.AppendError("Invalid target.  Must set target before setting "
@@ -540,7 +660,7 @@ protected:
     else if (m_options.m_exception_language != eLanguageTypeUnknown)
       break_type = eSetTypeException;
 
-    Breakpoint *bp = nullptr;
+    BreakpointSP bp_sp = nullptr;
     FileSpec module_spec;
     const bool internal = false;
 
@@ -572,35 +692,32 @@ protected:
       // Only check for inline functions if
       LazyBool check_inlines = eLazyBoolCalculate;
 
-      bp = target
-               ->CreateBreakpoint(&(m_options.m_modules), file,
-                                  m_options.m_line_num, m_options.m_offset_addr,
-                                  check_inlines, m_options.m_skip_prologue,
-                                  internal, m_options.m_hardware,
-                                  m_options.m_move_to_nearest_code)
-               .get();
+      bp_sp = target->CreateBreakpoint(&(m_options.m_modules), 
+                                       file,
+                                       m_options.m_line_num, 
+                                       m_options.m_offset_addr,
+                                       check_inlines, 
+                                       m_options.m_skip_prologue,
+                                       internal, 
+                                       m_options.m_hardware,
+                                       m_options.m_move_to_nearest_code);
     } break;
 
     case eSetTypeAddress: // Breakpoint by address
     {
       // If a shared library has been specified, make an lldb_private::Address
-      // with the library, and
-      // use that.  That way the address breakpoint will track the load location
-      // of the library.
+      // with the library, and use that.  That way the address breakpoint
+      //  will track the load location of the library.
       size_t num_modules_specified = m_options.m_modules.GetSize();
       if (num_modules_specified == 1) {
         const FileSpec *file_spec =
             m_options.m_modules.GetFileSpecPointerAtIndex(0);
-        bp = target
-                 ->CreateAddressInModuleBreakpoint(m_options.m_load_addr,
-                                                   internal, file_spec,
-                                                   m_options.m_hardware)
-                 .get();
+        bp_sp = target->CreateAddressInModuleBreakpoint(m_options.m_load_addr,
+                                                        internal, file_spec,
+                                                        m_options.m_hardware);
       } else if (num_modules_specified == 0) {
-        bp = target
-                 ->CreateBreakpoint(m_options.m_load_addr, internal,
-                                    m_options.m_hardware)
-                 .get();
+        bp_sp = target->CreateBreakpoint(m_options.m_load_addr, internal,
+                                         m_options.m_hardware);
       } else {
         result.AppendError("Only one shared library can be specified for "
                            "address breakpoints.");
@@ -616,13 +733,15 @@ protected:
       if (name_type_mask == 0)
         name_type_mask = eFunctionNameTypeAuto;
 
-      bp = target
-               ->CreateBreakpoint(
-                   &(m_options.m_modules), &(m_options.m_filenames),
-                   m_options.m_func_names, name_type_mask, m_options.m_language,
-                   m_options.m_offset_addr, m_options.m_skip_prologue, internal,
-                   m_options.m_hardware)
-               .get();
+      bp_sp = target->CreateBreakpoint(&(m_options.m_modules), 
+                                       &(m_options.m_filenames),
+                                       m_options.m_func_names, 
+                                       name_type_mask, 
+                                       m_options.m_language,
+                                       m_options.m_offset_addr, 
+                                       m_options.m_skip_prologue, 
+                                       internal,
+                                       m_options.m_hardware);
     } break;
 
     case eSetTypeFunctionRegexp: // Breakpoint by regular expression function
@@ -639,12 +758,13 @@ protected:
           return false;
         }
 
-        bp = target
-                 ->CreateFuncRegexBreakpoint(
-                     &(m_options.m_modules), &(m_options.m_filenames), regexp,
-                     m_options.m_language, m_options.m_skip_prologue, internal,
-                     m_options.m_hardware)
-                 .get();
+        bp_sp = target->CreateFuncRegexBreakpoint(&(m_options.m_modules), 
+                                                  &(m_options.m_filenames), 
+                                                  regexp,
+                                                  m_options.m_language, 
+                                                  m_options.m_skip_prologue, 
+                                                  internal,
+                                                  m_options.m_hardware);
       }
       break;
     case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
@@ -673,26 +793,30 @@ protected:
         result.SetStatus(eReturnStatusFailed);
         return false;
       }
-      bp = target
-               ->CreateSourceRegexBreakpoint(
-                   &(m_options.m_modules), &(m_options.m_filenames),
-                   m_options.m_source_regex_func_names, regexp, internal,
-                   m_options.m_hardware, m_options.m_move_to_nearest_code)
-               .get();
+      bp_sp = 
+          target->CreateSourceRegexBreakpoint(&(m_options.m_modules), 
+                                              &(m_options.m_filenames),
+                                              m_options
+                                                  .m_source_regex_func_names,
+                                              regexp,
+                                              internal,
+                                              m_options.m_hardware,
+                                              m_options.m_move_to_nearest_code);
     } break;
     case eSetTypeException: {
       Status precond_error;
-      bp = target
-               ->CreateExceptionBreakpoint(
-                   m_options.m_exception_language, m_options.m_catch_bp,
-                   m_options.m_throw_bp, internal,
-                   &m_options.m_exception_extra_args, &precond_error)
-               .get();
+      bp_sp = target->CreateExceptionBreakpoint(m_options.m_exception_language, 
+                                                m_options.m_catch_bp,
+                                                m_options.m_throw_bp, 
+                                                internal,
+                                                &m_options
+                                                    .m_exception_extra_args, 
+                                                &precond_error);
       if (precond_error.Fail()) {
         result.AppendErrorWithFormat(
             "Error setting extra exception arguments: %s",
             precond_error.AsCString());
-        target->RemoveBreakpointByID(bp->GetID());
+        target->RemoveBreakpointByID(bp_sp->GetID());
         result.SetStatus(eReturnStatusFailed);
         return false;
       }
@@ -702,76 +826,43 @@ protected:
     }
 
     // Now set the various options that were passed in:
-    if (bp) {
-      if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
-        bp->SetThreadID(m_options.m_thread_id);
-
-      if (m_options.m_thread_index != UINT32_MAX)
-        bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
-
-      if (!m_options.m_thread_name.empty())
-        bp->GetOptions()->GetThreadSpec()->SetName(
-            m_options.m_thread_name.c_str());
-
-      if (!m_options.m_queue_name.empty())
-        bp->GetOptions()->GetThreadSpec()->SetQueueName(
-            m_options.m_queue_name.c_str());
-
-      if (m_options.m_ignore_count != 0)
-        bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
-
-      if (!m_options.m_condition.empty())
-        bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
+    if (bp_sp) {
+      bp_sp->GetOptions()->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
 
       if (!m_options.m_breakpoint_names.empty()) {
         Status name_error;
         for (auto name : m_options.m_breakpoint_names) {
-          bp->AddName(name.c_str(), name_error);
+          target->AddNameToBreakpoint(bp_sp, name.c_str(), name_error);
           if (name_error.Fail()) {
             result.AppendErrorWithFormat("Invalid breakpoint name: %s",
                                          name.c_str());
-            target->RemoveBreakpointByID(bp->GetID());
+            target->RemoveBreakpointByID(bp_sp->GetID());
             result.SetStatus(eReturnStatusFailed);
             return false;
           }
         }
       }
-
-      bp->SetOneShot(m_options.m_one_shot);
-      bp->SetAutoContinue(m_options.m_auto_continue);
-      
-      if (!m_options.m_commands.empty())
-      {
-          auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>();
-        
-          for (std::string &str : m_options.m_commands)
-            cmd_data->user_source.AppendString(str); 
-
-          cmd_data->stop_on_error = true;
-          bp->GetOptions()->SetCommandDataCallback(cmd_data);
-      }
     }
-
-    if (bp) {
+    
+    if (bp_sp) {
       Stream &output_stream = result.GetOutputStream();
       const bool show_locations = false;
-      bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
+      bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
                          show_locations);
       if (target == m_interpreter.GetDebugger().GetDummyTarget())
         output_stream.Printf("Breakpoint set in dummy target, will get copied "
                              "into future targets.\n");
       else {
         // Don't print out this warning for exception breakpoints.  They can get
-        // set before the target
-        // is set, but we won't know how to actually set the breakpoint till we
-        // run.
-        if (bp->GetNumLocations() == 0 && break_type != eSetTypeException) {
+        // set before the target is set, but we won't know how to actually set
+        // the breakpoint till we run.
+        if (bp_sp->GetNumLocations() == 0 && break_type != eSetTypeException) {
           output_stream.Printf("WARNING:  Unable to resolve breakpoint to any "
                                "actual locations.\n");
         }
       }
       result.SetStatus(eReturnStatusSuccessFinishResult);
-    } else if (!bp) {
+    } else if (!bp_sp) {
       result.AppendError("Breakpoint creation failed: No breakpoint created.");
       result.SetStatus(eReturnStatusFailed);
     }
@@ -813,30 +904,15 @@ private:
     return true;
   }
 
+  BreakpointOptionGroup m_bp_opts;
+  BreakpointDummyOptionGroup m_dummy_options;
   CommandOptions m_options;
+  OptionGroupOptions m_all_options;
 };
 
 //-------------------------------------------------------------------------
 // CommandObjectBreakpointModify
 //-------------------------------------------------------------------------
-
-#pragma mark Modify::CommandOptions
-static OptionDefinition g_breakpoint_modify_options[] = {
-    // clang-format off
-  { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount,       "Set the number of times this breakpoint is skipped before stopping." },
-  { LLDB_OPT_SET_ALL, false, "one-shot",     'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,     "The breakpoint is deleted the first time it stop causes a stop." },
-  { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." },
-  { LLDB_OPT_SET_ALL, false, "thread-id",    't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID,    "The breakpoint stops only for the thread whose TID matches this argument." },
-  { LLDB_OPT_SET_ALL, false, "thread-name",  'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName,  "The breakpoint stops only for the thread whose thread name matches this argument." },
-  { LLDB_OPT_SET_ALL, false, "queue-name",   'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName,   "The breakpoint stops only for threads in the queue whose name is given by this argument." },
-  { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression,  "The breakpoint stops only if this condition expression evaluates to true." },
-  { LLDB_OPT_SET_1,   false, "enable",       'e', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,        "Enable the breakpoint." },
-  { LLDB_OPT_SET_2,   false, "disable",      'd', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,        "Disable the breakpoint." },
-  { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument,  nullptr, nullptr, 0, eArgTypeNone,        "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
-  { LLDB_OPT_SET_ALL, false, "auto-continue",     'G', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint will auto-continue after running its commands." },
-    // clang-format on
-};
-
 #pragma mark Modify
 
 class CommandObjectBreakpointModify : public CommandObjectParsed {
@@ -857,163 +933,21 @@ public:
     // Add the entry for the first argument for this command to the object's
     // arguments vector.
     m_arguments.push_back(arg);
+    
+    m_options.Append(&m_bp_opts, 
+                     LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3, 
+                     LLDB_OPT_SET_ALL);
+    m_options.Append(&m_dummy_opts, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
+    m_options.Finalize();
   }
 
   ~CommandObjectBreakpointModify() override = default;
 
   Options *GetOptions() override { return &m_options; }
 
-  class CommandOptions : public Options {
-  public:
-    CommandOptions()
-        : Options(), m_ignore_count(0), m_thread_id(LLDB_INVALID_THREAD_ID),
-          m_thread_id_passed(false), m_thread_index(UINT32_MAX),
-          m_thread_index_passed(false), m_thread_name(), m_queue_name(),
-          m_condition(), m_one_shot(false), m_enable_passed(false),
-          m_enable_value(false), m_name_passed(false), m_queue_passed(false),
-          m_condition_passed(false), m_one_shot_passed(false),
-          m_use_dummy(false) {}
-
-    ~CommandOptions() override = default;
-
-    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
-                          ExecutionContext *execution_context) override {
-      Status error;
-      const int short_option = m_getopt_table[option_idx].val;
-
-      switch (short_option) {
-      case 'c':
-        m_condition = option_arg;
-        m_condition_passed = true;
-        break;
-      case 'd':
-        m_enable_passed = true;
-        m_enable_value = false;
-        break;
-      case 'D':
-        m_use_dummy = true;
-        break;
-      case 'e':
-        m_enable_passed = true;
-        m_enable_value = true;
-        break;
-      case 'G': {
-        bool value, success;
-        value = Args::StringToBoolean(option_arg, false, &success);
-        if (success) {
-          m_auto_continue_passed = true;
-          m_auto_continue = value;
-        } else
-          error.SetErrorStringWithFormat(
-              "invalid boolean value '%s' passed for -G option",
-              option_arg.str().c_str());
-      } break;
-      case 'i':
-        if (option_arg.getAsInteger(0, m_ignore_count))
-          error.SetErrorStringWithFormat("invalid ignore count '%s'",
-                                         option_arg.str().c_str());
-        break;
-      case 'o': {
-        bool value, success;
-        value = Args::StringToBoolean(option_arg, false, &success);
-        if (success) {
-          m_one_shot_passed = true;
-          m_one_shot = value;
-        } else
-          error.SetErrorStringWithFormat(
-              "invalid boolean value '%s' passed for -o option",
-              option_arg.str().c_str());
-      } break;
-      case 't':
-        if (option_arg[0] == '\0') {
-          m_thread_id = LLDB_INVALID_THREAD_ID;
-          m_thread_id_passed = true;
-        } else {
-          if (option_arg.getAsInteger(0, m_thread_id))
-            error.SetErrorStringWithFormat("invalid thread id string '%s'",
-                                           option_arg.str().c_str());
-          else
-            m_thread_id_passed = true;
-        }
-        break;
-      case 'T':
-        m_thread_name = option_arg;
-        m_name_passed = true;
-        break;
-      case 'q':
-        m_queue_name = option_arg;
-        m_queue_passed = true;
-        break;
-      case 'x':
-        if (option_arg[0] == '\n') {
-          m_thread_index = UINT32_MAX;
-          m_thread_index_passed = true;
-        } else {
-          if (option_arg.getAsInteger(0, m_thread_index))
-            error.SetErrorStringWithFormat("invalid thread index string '%s'",
-                                           option_arg.str().c_str());
-          else
-            m_thread_index_passed = true;
-        }
-        break;
-      default:
-        error.SetErrorStringWithFormat("unrecognized option '%c'",
-                                       short_option);
-        break;
-      }
-
-      return error;
-    }
-
-    void OptionParsingStarting(ExecutionContext *execution_context) override {
-      m_ignore_count = 0;
-      m_thread_id = LLDB_INVALID_THREAD_ID;
-      m_thread_id_passed = false;
-      m_thread_index = UINT32_MAX;
-      m_thread_index_passed = false;
-      m_thread_name.clear();
-      m_queue_name.clear();
-      m_condition.clear();
-      m_one_shot = false;
-      m_enable_passed = false;
-      m_queue_passed = false;
-      m_name_passed = false;
-      m_condition_passed = false;
-      m_one_shot_passed = false;
-      m_use_dummy = false;
-      m_auto_continue = false;
-      m_auto_continue_passed = false;
-    }
-
-    llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
-      return llvm::makeArrayRef(g_breakpoint_modify_options);
-    }
-
-    // Instance variables to hold the values for command options.
-
-    uint32_t m_ignore_count;
-    lldb::tid_t m_thread_id;
-    bool m_thread_id_passed;
-    uint32_t m_thread_index;
-    bool m_thread_index_passed;
-    std::string m_thread_name;
-    std::string m_queue_name;
-    std::string m_condition;
-    bool m_one_shot;
-    bool m_enable_passed;
-    bool m_enable_value;
-    bool m_name_passed;
-    bool m_queue_passed;
-    bool m_condition_passed;
-    bool m_one_shot_passed;
-    bool m_use_dummy;
-    bool m_auto_continue;
-    bool m_auto_continue_passed;
-  };
-
 protected:
   bool DoExecute(Args &command, CommandReturnObject &result) override {
-    Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+    Target *target = GetSelectedOrDummyTarget(m_dummy_opts.m_use_dummy);
     if (target == nullptr) {
       result.AppendError("Invalid target.  No existing target or breakpoints.");
       result.SetStatus(eReturnStatusFailed);
@@ -1026,7 +960,8 @@ protected:
     BreakpointIDList valid_bp_ids;
 
     CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
-        command, target, result, &valid_bp_ids);
+        command, target, result, &valid_bp_ids, 
+        BreakpointName::Permissions::PermissionKinds::disablePerm);
 
     if (result.Succeeded()) {
       const size_t count = valid_bp_ids.GetSize();
@@ -1039,55 +974,12 @@ protected:
           if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
             BreakpointLocation *location =
                 bp->FindLocationByID(cur_bp_id.GetLocationID()).get();
-            if (location) {
-              if (m_options.m_thread_id_passed)
-                location->SetThreadID(m_options.m_thread_id);
-
-              if (m_options.m_thread_index_passed)
-                location->SetThreadIndex(m_options.m_thread_index);
-
-              if (m_options.m_name_passed)
-                location->SetThreadName(m_options.m_thread_name.c_str());
-
-              if (m_options.m_queue_passed)
-                location->SetQueueName(m_options.m_queue_name.c_str());
-
-              if (m_options.m_ignore_count != 0)
-                location->SetIgnoreCount(m_options.m_ignore_count);
-
-              if (m_options.m_enable_passed)
-                location->SetEnabled(m_options.m_enable_value);
-
-              if (m_options.m_condition_passed)
-                location->SetCondition(m_options.m_condition.c_str());
-                
-              if (m_options.m_auto_continue_passed)
-                location->SetAutoContinue(m_options.m_auto_continue);
-            }
+            if (location)
+              location->GetLocationOptions()
+                  ->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
           } else {
-            if (m_options.m_thread_id_passed)
-              bp->SetThreadID(m_options.m_thread_id);
-
-            if (m_options.m_thread_index_passed)
-              bp->SetThreadIndex(m_options.m_thread_index);
-
-            if (m_options.m_name_passed)
-              bp->SetThreadName(m_options.m_thread_name.c_str());
-
-            if (m_options.m_queue_passed)
-              bp->SetQueueName(m_options.m_queue_name.c_str());
-
-            if (m_options.m_ignore_count != 0)
-              bp->SetIgnoreCount(m_options.m_ignore_count);
-
-            if (m_options.m_enable_passed)
-              bp->SetEnabled(m_options.m_enable_value);
-
-            if (m_options.m_condition_passed)
-              bp->SetCondition(m_options.m_condition.c_str());
-            
-            if (m_options.m_auto_continue_passed)
-              bp->SetAutoContinue(m_options.m_auto_continue);
+            bp->GetOptions()
+                ->CopyOverSetOptions(m_bp_opts.GetBreakpointOptions());
           }
         }
       }
@@ -1097,7 +989,9 @@ protected:
   }
 
 private:
-  CommandOptions m_options;
+  BreakpointOptionGroup m_bp_opts;
+  BreakpointDummyOptionGroup m_dummy_opts;
+  OptionGroupOptions m_options;
 };
 
 //-------------------------------------------------------------------------
@@ -1146,7 +1040,7 @@ protected:
 
     if (command.empty()) {
       // No breakpoint selected; enable all currently set breakpoints.
-      target->EnableAllBreakpoints();
+      target->EnableAllowedBreakpoints();
       result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64
                                      " breakpoints)\n",
                                      (uint64_t)num_breakpoints);
@@ -1155,7 +1049,8 @@ protected:
       // Particular breakpoint selected; enable that breakpoint.
       BreakpointIDList valid_bp_ids;
       CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
-          command, target, result, &valid_bp_ids);
+          command, target, result, &valid_bp_ids, 
+          BreakpointName::Permissions::PermissionKinds::disablePerm);
 
       if (result.Succeeded()) {
         int enable_count = 0;
@@ -1259,7 +1154,7 @@ protected:
 
     if (command.empty()) {
       // No breakpoint selected; disable all currently set breakpoints.
-      target->DisableAllBreakpoints();
+      target->DisableAllowedBreakpoints();
       result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64
                                      " breakpoints)\n",
                                      (uint64_t)num_breakpoints);
@@ -1269,7 +1164,8 @@ protected:
       BreakpointIDList valid_bp_ids;
 
       CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
-          command, target, result, &valid_bp_ids);
+          command, target, result, &valid_bp_ids, 
+          BreakpointName::Permissions::PermissionKinds::disablePerm);
 
       if (result.Succeeded()) {
         int disable_count = 0;
@@ -1436,14 +1332,17 @@ protected:
       result.AppendMessage("Current breakpoints:");
       for (size_t i = 0; i < num_breakpoints; ++i) {
         Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex(i).get();
-        AddBreakpointDescription(&output_stream, breakpoint, m_options.m_level);
+        if (breakpoint->AllowList())
+          AddBreakpointDescription(&output_stream, breakpoint, 
+                                   m_options.m_level);
       }
       result.SetStatus(eReturnStatusSuccessFinishNoResult);
     } else {
       // Particular breakpoints selected; show info about that breakpoint.
       BreakpointIDList valid_bp_ids;
       CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
-          command, target, result, &valid_bp_ids);
+          command, target, result, &valid_bp_ids, 
+          BreakpointName::Permissions::PermissionKinds::listPerm);
 
       if (result.Succeeded()) {
         for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) {
@@ -1731,7 +1630,7 @@ protected:
               true)) {
         result.AppendMessage("Operation cancelled...");
       } else {
-        target->RemoveAllBreakpoints();
+        target->RemoveAllowedBreakpoints();
         result.AppendMessageWithFormat(
             "All breakpoints removed. (%" PRIu64 " breakpoint%s)\n",
             (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
@@ -1741,7 +1640,8 @@ protected:
       // Particular breakpoint selected; disable that breakpoint.
       BreakpointIDList valid_bp_ids;
       CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
-          command, target, result, &valid_bp_ids);
+          command, target, result, &valid_bp_ids, 
+          BreakpointName::Permissions::PermissionKinds::deletePerm);
 
       if (result.Succeeded()) {
         int delete_count = 0;
@@ -1789,7 +1689,7 @@ static OptionDefinition g_breakpoint_nam
     // clang-format off
   {LLDB_OPT_SET_1,   false, "name",              'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
   {LLDB_OPT_SET_2,   false, "breakpoint-id",     'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointID,   "Specify a breakpoint ID to use."},
-  {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,           "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+  {LLDB_OPT_SET_3, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,           "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
     // clang-format on
 };
 class BreakpointNameOptionGroup : public OptionGroup {
@@ -1849,6 +1749,188 @@ public:
   OptionValueBoolean m_use_dummy;
 };
 
+static OptionDefinition g_breakpoint_access_options[] = {
+    // clang-format off
+  {LLDB_OPT_SET_1,   false, "allow-list",    'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint will show up in break list if not referred to explicitly."},
+  {LLDB_OPT_SET_2,   false, "allow-disable", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint can be disabled by name or when all breakpoints are disabled."},
+  {LLDB_OPT_SET_3,   false, "allow-delete",  'D', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint can be deleted by name or when all breakpoints are deleted."},
+    // clang-format on
+};
+
+class BreakpointAccessOptionGroup : public OptionGroup
+{
+public:
+  BreakpointAccessOptionGroup() :
+          OptionGroup()
+   {}
+  
+  ~BreakpointAccessOptionGroup() override = default;
+  
+  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+    return llvm::makeArrayRef(g_breakpoint_access_options);
+  }
+  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+                        ExecutionContext *execution_context) override {
+    Status error;
+    const int short_option 
+        = g_breakpoint_access_options[option_idx].short_option;
+
+    switch (short_option) {
+      case 'L': {
+        bool value, success;
+        value = Args::StringToBoolean(option_arg, false, &success);
+        if (success) {
+          m_permissions.SetAllowList(value);
+        } else
+          error.SetErrorStringWithFormat(
+              "invalid boolean value '%s' passed for -L option",
+              option_arg.str().c_str());
+      } break;
+      case 'A': {
+        bool value, success;
+        value = Args::StringToBoolean(option_arg, false, &success);
+        if (success) {
+          m_permissions.SetAllowDisable(value);
+        } else
+          error.SetErrorStringWithFormat(
+              "invalid boolean value '%s' passed for -L option",
+              option_arg.str().c_str());
+      } break;
+      case 'D': {
+        bool value, success;
+        value = Args::StringToBoolean(option_arg, false, &success);
+        if (success) {
+          m_permissions.SetAllowDelete(value);
+        } else
+          error.SetErrorStringWithFormat(
+              "invalid boolean value '%s' passed for -L option",
+              option_arg.str().c_str());
+      } break;
+
+    }
+    
+    return error;
+  }
+  
+  void OptionParsingStarting(ExecutionContext *execution_context) override {
+  }
+  
+  const BreakpointName::Permissions &GetPermissions() const
+  {
+    return m_permissions;
+  }
+  BreakpointName::Permissions m_permissions;  
+};
+
+class CommandObjectBreakpointNameConfigure : public CommandObjectParsed {
+public:
+  CommandObjectBreakpointNameConfigure(CommandInterpreter &interpreter)
+      : CommandObjectParsed(
+            interpreter, "configure", "Configure the options for the breakpoint"
+            " name provided.  "
+            "If you provide a breakpoint id, the options will be copied from "
+            "the breakpoint, otherwise only the options specified will be set "
+            "on the name.",
+            "breakpoint name configure <command-options> "
+            "<breakpoint-name-list>"),
+        m_bp_opts(), m_option_group() {
+    // Create the first variant for the first (and only) argument for this
+    // command.
+    CommandArgumentEntry arg1;
+    CommandArgumentData id_arg;
+    id_arg.arg_type = eArgTypeBreakpointName;
+    id_arg.arg_repetition = eArgRepeatOptional;
+    arg1.push_back(id_arg);
+    m_arguments.push_back(arg1);
+
+    m_option_group.Append(&m_bp_opts, 
+                          LLDB_OPT_SET_ALL, 
+                          LLDB_OPT_SET_1);
+    m_option_group.Append(&m_access_options, 
+                          LLDB_OPT_SET_ALL, 
+                          LLDB_OPT_SET_ALL);
+    m_option_group.Append(&m_bp_id, LLDB_OPT_SET_2, LLDB_OPT_SET_2);
+    m_option_group.Finalize();
+  }
+
+  ~CommandObjectBreakpointNameConfigure() override = default;
+
+  Options *GetOptions() override { return &m_option_group; }
+
+protected:
+  bool DoExecute(Args &command, CommandReturnObject &result) override {
+
+    const size_t argc = command.GetArgumentCount();
+    if (argc == 0) {
+      result.AppendError("No names provided.");
+      result.SetStatus(eReturnStatusFailed);
+      return false;
+    }
+    
+    Target *target =
+        GetSelectedOrDummyTarget(false);
+
+    if (target == nullptr) {
+      result.AppendError("Invalid target. No existing target or breakpoints.");
+      result.SetStatus(eReturnStatusFailed);
+      return false;
+    }
+
+    std::unique_lock<std::recursive_mutex> lock;
+    target->GetBreakpointList().GetListMutex(lock);
+
+    // Make a pass through first to see that all the names are legal.
+    for (auto &entry : command.entries()) {
+      Status error;
+      if (!BreakpointID::StringIsBreakpointName(entry.ref, error))
+      {
+        result.AppendErrorWithFormat("Invalid breakpoint name: %s - %s",
+                                     entry.c_str(), error.AsCString());
+        result.SetStatus(eReturnStatusFailed);
+        return false;
+      }
+    }
+    // Now configure them, we already pre-checked the names so we don't need
+    // to check the error:
+    BreakpointSP bp_sp;
+    if (m_bp_id.m_breakpoint.OptionWasSet())
+    {
+      lldb::break_id_t bp_id = m_bp_id.m_breakpoint.GetUInt64Value();
+      bp_sp = target->GetBreakpointByID(bp_id);
+      if (!bp_sp)
+      {
+        result.AppendErrorWithFormatv("Could not find specified breakpoint {0}",
+                           bp_id);
+        result.SetStatus(eReturnStatusFailed);
+        return false;
+      }
+    }
+
+    Status error;
+    for (auto &entry : command.entries()) {
+      ConstString name(entry.c_str());
+      BreakpointName *bp_name = target->FindBreakpointName(name, true, error);
+      if (!bp_name)
+        continue;
+      if (bp_sp)
+        target->ConfigureBreakpointName(*bp_name,
+                                       *bp_sp->GetOptions(),
+                                       m_access_options.GetPermissions());
+      else
+        target->ConfigureBreakpointName(*bp_name,
+                                       m_bp_opts.GetBreakpointOptions(),
+                                       m_access_options.GetPermissions());
+    }
+    return true;
+  }
+
+private:
+  BreakpointNameOptionGroup m_bp_id; // Only using the id part of this.
+  BreakpointOptionGroup m_bp_opts;
+  BreakpointAccessOptionGroup m_access_options;
+  OptionGroupOptions m_option_group;
+};
+
 class CommandObjectBreakpointNameAdd : public CommandObjectParsed {
 public:
   CommandObjectBreakpointNameAdd(CommandInterpreter &interpreter)
@@ -1904,7 +1986,8 @@ protected:
     // Particular breakpoint selected; disable that breakpoint.
     BreakpointIDList valid_bp_ids;
     CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
-        command, target, result, &valid_bp_ids);
+        command, target, result, &valid_bp_ids, 
+        BreakpointName::Permissions::PermissionKinds::listPerm);
 
     if (result.Succeeded()) {
       if (valid_bp_ids.GetSize() == 0) {
@@ -1913,13 +1996,14 @@ protected:
         return false;
       }
       size_t num_valid_ids = valid_bp_ids.GetSize();
+      const char *bp_name = m_name_options.m_name.GetCurrentValue();
+      Status error; // This error reports illegal names, but we've already 
+                    // checked that, so we don't need to check it again here.
       for (size_t index = 0; index < num_valid_ids; index++) {
         lldb::break_id_t bp_id =
             valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
         BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
-        Status error; // We don't need to check the error here, since the option
-                      // parser checked it...
-        bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
+        target->AddNameToBreakpoint(bp_sp, bp_name, error);
       }
     }
 
@@ -1987,7 +2071,8 @@ protected:
     // Particular breakpoint selected; disable that breakpoint.
     BreakpointIDList valid_bp_ids;
     CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
-        command, target, result, &valid_bp_ids);
+        command, target, result, &valid_bp_ids, 
+        BreakpointName::Permissions::PermissionKinds::deletePerm);
 
     if (result.Succeeded()) {
       if (valid_bp_ids.GetSize() == 0) {
@@ -1995,12 +2080,13 @@ protected:
         result.SetStatus(eReturnStatusFailed);
         return false;
       }
+      ConstString bp_name(m_name_options.m_name.GetCurrentValue());
       size_t num_valid_ids = valid_bp_ids.GetSize();
       for (size_t index = 0; index < num_valid_ids; index++) {
         lldb::break_id_t bp_id =
             valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
         BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
-        bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
+        target->RemoveNameFromBreakpoint(bp_sp, bp_name);
       }
     }
 
@@ -2016,11 +2102,12 @@ class CommandObjectBreakpointNameList :
 public:
   CommandObjectBreakpointNameList(CommandInterpreter &interpreter)
       : CommandObjectParsed(interpreter, "list",
-                            "List either the names for a breakpoint or the "
-                            "breakpoints for a given name.",
+                            "List either the names for a breakpoint or info "
+                            "about a given name.  With no arguments, lists all "
+                            "names",
                             "breakpoint name list <command-options>"),
         m_name_options(), m_option_group() {
-    m_option_group.Append(&m_name_options);
+    m_option_group.Append(&m_name_options, LLDB_OPT_SET_3, LLDB_OPT_SET_ALL);
     m_option_group.Finalize();
   }
 
@@ -2038,42 +2125,57 @@ protected:
       result.SetStatus(eReturnStatusFailed);
       return false;
     }
-
-    if (m_name_options.m_name.OptionWasSet()) {
-      const char *name = m_name_options.m_name.GetCurrentValue();
-      std::unique_lock<std::recursive_mutex> lock;
-      target->GetBreakpointList().GetListMutex(lock);
-
-      BreakpointList &breakpoints = target->GetBreakpointList();
-      for (BreakpointSP bp_sp : breakpoints.Breakpoints()) {
-        if (bp_sp->MatchesName(name)) {
-          StreamString s;
-          bp_sp->GetDescription(&s, eDescriptionLevelBrief);
-          s.EOL();
-          result.AppendMessage(s.GetString());
-        }
+    
+    
+    std::vector<std::string> name_list;
+    if (command.empty()) {
+      target->GetBreakpointNames(name_list);
+    } else {
+      for (const Args::ArgEntry &arg : command)
+      {
+        name_list.push_back(arg.c_str());
       }
+    }
+    
+    if (name_list.empty()) {
+      result.AppendMessage("No breakpoint names found.");
+    } else {
+      for (const std::string &name_str : name_list) {
+        const char *name = name_str.c_str();
+        // First print out the options for the name:
+        Status error;
+        BreakpointName *bp_name = target->FindBreakpointName(ConstString(name),
+                                                             false,
+                                                             error);
+        if (bp_name)
+        {
+          StreamString s;
+          result.AppendMessageWithFormat("Name: %s\n", name);
+          if (bp_name->GetDescription(&s, eDescriptionLevelFull))
+          {
+            result.AppendMessage(s.GetString());
+          }
+        
+          std::unique_lock<std::recursive_mutex> lock;
+          target->GetBreakpointList().GetListMutex(lock);
 
-    } else if (m_name_options.m_breakpoint.OptionWasSet()) {
-      BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(
-          m_name_options.m_breakpoint.GetCurrentValue());
-      if (bp_sp) {
-        std::vector<std::string> names;
-        bp_sp->GetNames(names);
-        result.AppendMessage("Names:");
-        for (auto name : names)
-          result.AppendMessageWithFormat("    %s\n", name.c_str());
-      } else {
-        result.AppendErrorWithFormat(
-            "Could not find breakpoint %" PRId64 ".\n",
-            m_name_options.m_breakpoint.GetCurrentValue());
-        result.SetStatus(eReturnStatusFailed);
-        return false;
+          BreakpointList &breakpoints = target->GetBreakpointList();
+          bool any_set = false;
+          for (BreakpointSP bp_sp : breakpoints.Breakpoints()) {
+            if (bp_sp->MatchesName(name)) {
+              StreamString s;
+              any_set = true;
+              bp_sp->GetDescription(&s, eDescriptionLevelBrief);
+              s.EOL();
+              result.AppendMessage(s.GetString());
+            }
+          }
+          if (!any_set)
+            result.AppendMessage("No breakpoints using this name.");
+        } else {
+          result.AppendMessageWithFormat("Name: %s not found.\n", name);
+        }
       }
-    } else {
-      result.SetError("Must specify -N or -B option to list.");
-      result.SetStatus(eReturnStatusFailed);
-      return false;
     }
     return true;
   }
@@ -2098,10 +2200,13 @@ public:
         new CommandObjectBreakpointNameDelete(interpreter));
     CommandObjectSP list_command_object(
         new CommandObjectBreakpointNameList(interpreter));
+    CommandObjectSP configure_command_object(
+        new CommandObjectBreakpointNameConfigure(interpreter));
 
     LoadSubCommand("add", add_command_object);
     LoadSubCommand("delete", delete_command_object);
     LoadSubCommand("list", list_command_object);
+    LoadSubCommand("configure", configure_command_object);
   }
 
   ~CommandObjectBreakpointName() override = default;
@@ -2327,7 +2432,8 @@ protected:
     BreakpointIDList valid_bp_ids;
     if (!command.empty()) {
       CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
-          command, target, result, &valid_bp_ids);
+          command, target, result, &valid_bp_ids, 
+          BreakpointName::Permissions::PermissionKinds::listPerm);
 
       if (!result.Succeeded()) {
         result.SetStatus(eReturnStatusFailed);
@@ -2412,7 +2518,10 @@ CommandObjectMultiwordBreakpoint::~Comma
 void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target,
                                                  bool allow_locations,
                                                  CommandReturnObject &result,
-                                                 BreakpointIDList *valid_ids) {
+                                                 BreakpointIDList *valid_ids,
+                                                 BreakpointName::Permissions
+                                                     ::PermissionKinds 
+                                                     purpose) {
   // args can be strings representing 1). integers (for breakpoint ids)
   //                                  2). the full breakpoint & location
   //                                  canonical representation
@@ -2446,8 +2555,8 @@ void CommandObjectMultiwordBreakpoint::V
   // all the breakpoint ids in the range, and shove all of those breakpoint id
   // strings into TEMP_ARGS.
 
-  BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations,
-                                           result, temp_args);
+  BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations, 
+                                           purpose, result, temp_args);
 
   // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual
   // BreakpointIDList:

Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.h?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectBreakpoint.h (original)
+++ lldb/trunk/source/Commands/CommandObjectBreakpoint.h Thu Sep 14 13:22:49 2017
@@ -18,11 +18,14 @@
 
 // Other libraries and framework includes
 // Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Breakpoint/BreakpointName.h"
 #include "lldb/Core/Address.h"
 #include "lldb/Core/STLUtils.h"
 #include "lldb/Interpreter/CommandObjectMultiword.h"
 #include "lldb/Interpreter/Options.h"
 
+
 namespace lldb_private {
 
 //-------------------------------------------------------------------------
@@ -37,20 +40,26 @@ public:
 
   static void VerifyBreakpointOrLocationIDs(Args &args, Target *target,
                                             CommandReturnObject &result,
-                                            BreakpointIDList *valid_ids) {
-    VerifyIDs(args, target, true, result, valid_ids);
+                                            BreakpointIDList *valid_ids,
+                                            BreakpointName::Permissions
+                                                 ::PermissionKinds purpose) {
+    VerifyIDs(args, target, true, result, valid_ids, purpose);
   }
 
   static void VerifyBreakpointIDs(Args &args, Target *target,
                                   CommandReturnObject &result,
-                                  BreakpointIDList *valid_ids) {
-    VerifyIDs(args, target, false, result, valid_ids);
+                                  BreakpointIDList *valid_ids,
+                                  BreakpointName::Permissions::PermissionKinds 
+                                      purpose) {
+    VerifyIDs(args, target, false, result, valid_ids, purpose);
   }
 
 private:
   static void VerifyIDs(Args &args, Target *target, bool allow_locations,
                         CommandReturnObject &result,
-                        BreakpointIDList *valid_ids);
+                        BreakpointIDList *valid_ids,
+                        BreakpointName::Permissions::PermissionKinds 
+                                      purpose);
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp Thu Sep 14 13:22:49 2017
@@ -390,7 +390,8 @@ protected:
 
     BreakpointIDList valid_bp_ids;
     CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
-        command, target, result, &valid_bp_ids);
+        command, target, result, &valid_bp_ids,
+        BreakpointName::Permissions::PermissionKinds::listPerm);
 
     m_bp_options_vec.clear();
 
@@ -571,7 +572,8 @@ protected:
 
     BreakpointIDList valid_bp_ids;
     CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
-        command, target, result, &valid_bp_ids);
+        command, target, result, &valid_bp_ids, 
+        BreakpointName::Permissions::PermissionKinds::listPerm);
 
     if (result.Succeeded()) {
       const size_t count = valid_bp_ids.GetSize();
@@ -662,7 +664,8 @@ protected:
 
     BreakpointIDList valid_bp_ids;
     CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
-        command, target, result, &valid_bp_ids);
+        command, target, result, &valid_bp_ids, 
+        BreakpointName::Permissions::PermissionKinds::listPerm);
 
     if (result.Succeeded()) {
       const size_t count = valid_bp_ids.GetSize();

Modified: lldb/trunk/source/Interpreter/CommandObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObject.cpp?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandObject.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandObject.cpp Thu Sep 14 13:22:49 2017
@@ -1113,7 +1113,8 @@ CommandObject::ArgumentTableEntry Comman
     { eArgTypeWatchpointID, "watchpt-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Watchpoint IDs are positive integers." },
     { eArgTypeWatchpointIDRange, "watchpt-id-list", CommandCompletions::eNoCompletion, { nullptr, false }, "For example, '1-3' or '1 to 3'." },
     { eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify the type for a watchpoint." },
-    { eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes.  To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." }
+    { eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes.  To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." },
+    { eArgTypeCommand, "command", CommandCompletions::eNoCompletion, { nullptr, false }, "An LLDB Command line command." }
     // clang-format on
 };
 

Modified: lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp Thu Sep 14 13:22:49 2017
@@ -3615,13 +3615,15 @@ RenderScriptRuntime::CreateKernelBreakpo
   }
 
   BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name));
-  BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
+  Target &target = GetProcess()->GetTarget();
+  BreakpointSP bp = target.CreateBreakpoint(
       m_filtersp, resolver_sp, false, false, false);
 
   // Give RS breakpoints a specific name, so the user can manipulate them as a
   // group.
   Status err;
-  if (!bp->AddName("RenderScriptKernel", err))
+  target.AddNameToBreakpoint(bp, "RenderScriptKernel", err);
+  if (err.Fail() && log)
     if (log)
       log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
                   err.AsCString());
@@ -3643,14 +3645,15 @@ RenderScriptRuntime::CreateReductionBrea
 
   BreakpointResolverSP resolver_sp(new RSReduceBreakpointResolver(
       nullptr, name, &m_rsmodules, kernel_types));
-  BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
+  Target &target = GetProcess()->GetTarget();
+  BreakpointSP bp = target.CreateBreakpoint(
       m_filtersp, resolver_sp, false, false, false);
 
   // Give RS breakpoints a specific name, so the user can manipulate them as a
   // group.
   Status err;
-  if (!bp->AddName("RenderScriptReduction", err))
-    if (log)
+  target.AddNameToBreakpoint(bp, "RenderScriptReduction", err);
+  if (err.Fail() && log)
       log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
                   err.AsCString());
 
@@ -3885,15 +3888,16 @@ RenderScriptRuntime::CreateScriptGroupBr
 
   BreakpointResolverSP resolver_sp(new RSScriptGroupBreakpointResolver(
       nullptr, name, m_scriptGroups, stop_on_all));
-  BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
+  Target &target = GetProcess()->GetTarget();
+  BreakpointSP bp = target.CreateBreakpoint(
       m_filtersp, resolver_sp, false, false, false);
   // Give RS breakpoints a specific name, so the user can manipulate them as a
   // group.
   Status err;
-  if (!bp->AddName(name.AsCString(), err))
-    if (log)
-      log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
-                  err.AsCString());
+  target.AddNameToBreakpoint(bp, name.GetCString(), err);
+  if (err.Fail() && log)
+    log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
+                err.AsCString());
   // ask the breakpoint to resolve itself
   bp->ResolveBreakpoint();
   return bp;

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=313292&r1=313291&r2=313292&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Thu Sep 14 13:22:49 2017
@@ -123,6 +123,13 @@ void Target::PrimeFromDummyTarget(Target
     BreakpointSP new_bp(new Breakpoint(*this, *breakpoint_sp.get()));
     AddBreakpoint(new_bp, false);
   }
+  
+  for (auto bp_name_entry : target->m_breakpoint_names)
+  {
+    
+    BreakpointName *new_bp_name = new BreakpointName(*bp_name_entry.second);
+    AddBreakpointName(new_bp_name);
+  }
 }
 
 void Target::Dump(Stream *s, lldb::DescriptionLevel description_level) {
@@ -601,6 +608,112 @@ void Target::AddBreakpoint(lldb::Breakpo
   }
 }
 
+void Target::AddNameToBreakpoint(BreakpointID &id,
+                                 const char *name,
+                                 Status &error)
+ {
+   BreakpointSP bp_sp 
+       = m_breakpoint_list.FindBreakpointByID(id.GetBreakpointID());
+   if (!bp_sp)
+   {
+     StreamString s;
+     id.GetDescription(&s, eDescriptionLevelBrief);
+     error.SetErrorStringWithFormat("Could not find breakpoint %s", 
+                                    s.GetData());
+     return;
+   }
+   AddNameToBreakpoint(bp_sp, name, error);
+ }
+
+void Target::AddNameToBreakpoint(BreakpointSP &bp_sp,
+                                 const char *name, 
+                                 Status &error)
+ {
+   if (!bp_sp)
+     return;
+     
+   BreakpointName *bp_name = FindBreakpointName(ConstString(name), true, error);
+   if (!bp_name)
+     return;
+
+   bp_name->ConfigureBreakpoint(bp_sp);
+   bp_sp->AddName(name);
+ }
+
+void Target::AddBreakpointName(BreakpointName *bp_name) {
+  m_breakpoint_names.insert(std::make_pair(bp_name->GetName(), bp_name));
+}
+
+BreakpointName *Target::FindBreakpointName(const ConstString &name, 
+                                           bool can_create, 
+                                           Status &error)
+{
+  BreakpointID::StringIsBreakpointName(name.GetStringRef(), error);
+  if (!error.Success())
+    return nullptr;
+
+  BreakpointNameList::iterator iter = m_breakpoint_names.find(name);
+  if (iter == m_breakpoint_names.end()) {
+    if (!can_create)
+    {
+      error.SetErrorStringWithFormat("Breakpoint name \"%s\" doesn't exist and "
+                                     "can_create is false.", name.AsCString());
+      return nullptr;
+    }
+
+    iter = m_breakpoint_names.insert(std::make_pair(name,
+                                                    new BreakpointName(name)))
+                                                        .first;
+  }
+  return (iter->second);
+}
+
+void
+Target::DeleteBreakpointName(const ConstString &name)
+{
+  BreakpointNameList::iterator iter = m_breakpoint_names.find(name);
+  
+  if (iter != m_breakpoint_names.end()) {
+    const char *name_cstr = name.AsCString();
+    m_breakpoint_names.erase(iter);
+    for (auto bp_sp : m_breakpoint_list.Breakpoints())
+      bp_sp->RemoveName(name_cstr);
+  }
+}
+
+void Target::RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp,
+                                const ConstString &name)
+{
+  bp_sp->RemoveName(name.AsCString());
+}
+
+void Target::ConfigureBreakpointName(BreakpointName &bp_name,
+                               const BreakpointOptions &new_options,
+                               const BreakpointName::Permissions &new_permissions)
+{
+  bp_name.GetOptions().CopyOverSetOptions(new_options);
+  bp_name.GetPermissions().MergeInto(new_permissions);
+  ApplyNameToBreakpoints(bp_name);
+}
+
+void Target::ApplyNameToBreakpoints(BreakpointName &bp_name) {
+  BreakpointList bkpts_with_name(false);
+  m_breakpoint_list.FindBreakpointsByName(bp_name.GetName().AsCString(), 
+                                          bkpts_with_name);
+
+  for (auto bp_sp : bkpts_with_name.Breakpoints())
+    bp_name.ConfigureBreakpoint(bp_sp);
+}
+
+void Target::GetBreakpointNames(std::vector<std::string> &names)
+{
+  names.clear();
+  for (auto bp_name : m_breakpoint_names) {
+    names.push_back(bp_name.first.AsCString());
+  }
+  std::sort(names.begin(), names.end());
+}
+
 bool Target::ProcessIsValid() {
   return (m_process_sp && m_process_sp->IsAlive());
 }
@@ -703,6 +816,17 @@ WatchpointSP Target::CreateWatchpoint(ll
   return wp_sp;
 }
 
+void Target::RemoveAllowedBreakpoints ()
+{
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+  if (log)
+    log->Printf("Target::%s \n", __FUNCTION__);
+
+  m_breakpoint_list.RemoveAllowed(true);
+  
+  m_last_created_breakpoint.reset();
+}
+
 void Target::RemoveAllBreakpoints(bool internal_also) {
   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
   if (log)
@@ -727,6 +851,14 @@ void Target::DisableAllBreakpoints(bool
     m_internal_breakpoint_list.SetEnabledAll(false);
 }
 
+void Target::DisableAllowedBreakpoints() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+  if (log)
+    log->Printf("Target::%s", __FUNCTION__);
+
+  m_breakpoint_list.SetEnabledAllowed(false);
+}
+
 void Target::EnableAllBreakpoints(bool internal_also) {
   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
   if (log)
@@ -738,6 +870,14 @@ void Target::EnableAllBreakpoints(bool i
     m_internal_breakpoint_list.SetEnabledAll(true);
 }
 
+void Target::EnableAllowedBreakpoints() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+  if (log)
+    log->Printf("Target::%s", __FUNCTION__);
+
+  m_breakpoint_list.SetEnabledAllowed(true);
+}
+
 bool Target::RemoveBreakpointByID(break_id_t break_id) {
   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
   if (log)




More information about the lldb-commits mailing list