Adds tests for breakpoint names, and a FindBreakpointsByName.

Also if you set a breakpoint with an invalid name, we'll
refuse to set the breakpoint rather than silently ignoring
the name.

llvm-svn: 282043
diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h
index ac22586..715c37c 100644
--- a/lldb/include/lldb/API/SBTarget.h
+++ b/lldb/include/lldb/API/SBTarget.h
@@ -666,6 +666,10 @@
 
   lldb::SBBreakpoint FindBreakpointByID(break_id_t break_id);
 
+  // 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);
+
   bool EnableAllBreakpoints();
 
   bool DisableAllBreakpoints();
diff --git a/lldb/include/lldb/Breakpoint/BreakpointList.h b/lldb/include/lldb/Breakpoint/BreakpointList.h
index e93ab3f..2865288 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointList.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointList.h
@@ -103,6 +103,17 @@
   const lldb::BreakpointSP GetBreakpointAtIndex(size_t i) const;
 
   //------------------------------------------------------------------
+  /// Find all the breakpoints with a given name
+  ///
+  /// @param[in] name
+  ///   The breakpoint name for which to search.
+  ///
+  /// @result
+  ///   \bfalse if the input name was not a legal breakpoint name.
+  //------------------------------------------------------------------
+  bool FindBreakpointsByName(const char *name, BreakpointList &matching_bps);
+
+  //------------------------------------------------------------------
   /// Returns the number of elements in this breakpoint list.
   ///
   /// @result
diff --git a/lldb/scripts/interface/SBTarget.i b/lldb/scripts/interface/SBTarget.i
index f490be5..6764d69 100644
--- a/lldb/scripts/interface/SBTarget.i
+++ b/lldb/scripts/interface/SBTarget.i
@@ -708,6 +708,9 @@
     lldb::SBBreakpoint
     FindBreakpointByID (break_id_t break_id);
 
+  
+    bool FindBreakpointsByName(const char *name, SBBreakpointList &bkpt_list);
+
     bool
     EnableAllBreakpoints ();
 
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index 7cf9215..9449e9a 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -1079,6 +1079,23 @@
   return sb_breakpoint;
 }
 
+bool SBTarget::FindBreakpointsByName(const char *name,
+                                     SBBreakpointList &bkpts) {
+  TargetSP target_sp(GetSP());
+  if (target_sp) {
+    std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+    BreakpointList bkpt_list(false);
+    bool is_valid =
+        target_sp->GetBreakpointList().FindBreakpointsByName(name, bkpt_list);
+    if (!is_valid)
+      return false;
+    for (BreakpointSP bkpt_sp : bkpt_list.Breakpoints()) {
+      bkpts.AppendByID(bkpt_sp->GetID());
+    }
+  }
+  return true;
+}
+
 bool SBTarget::EnableAllBreakpoints() {
   TargetSP target_sp(GetSP());
   if (target_sp) {
diff --git a/lldb/source/Breakpoint/BreakpointList.cpp b/lldb/source/Breakpoint/BreakpointList.cpp
index a47a07d..7f35588 100644
--- a/lldb/source/Breakpoint/BreakpointList.cpp
+++ b/lldb/source/Breakpoint/BreakpointList.cpp
@@ -137,6 +137,23 @@
   return stop_sp;
 }
 
+bool BreakpointList::FindBreakpointsByName(const char *name,
+                                           BreakpointList &matching_bps) {
+  Error error;
+  if (!name)
+    return false;
+
+  if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(name), error))
+    return false;
+
+  for (BreakpointSP bkpt_sp : Breakpoints()) {
+    if (bkpt_sp->MatchesName(name)) {
+      matching_bps.Add(bkpt_sp, false);
+    }
+  }
+  return true;
+}
+
 void BreakpointList::Dump(Stream *s) const {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   s->Printf("%p: ", static_cast<const void *>(this));
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp
index bab8ecb..b0c8332 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -249,6 +249,9 @@
       case 'N': {
         if (BreakpointID::StringIsBreakpointName(option_strref, error))
           m_breakpoint_names.push_back(option_arg);
+        else
+          error.SetErrorStringWithFormat("Invalid breakpoint name: %s",
+                                         option_arg);
         break;
       }
 
@@ -622,10 +625,17 @@
         bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
 
       if (!m_options.m_breakpoint_names.empty()) {
-        Error error; // We don't need to check the error here, since the option
-                     // parser checked it...
-        for (auto name : m_options.m_breakpoint_names)
-          bp->AddName(name.c_str(), error);
+        Error name_error;
+        for (auto name : m_options.m_breakpoint_names) {
+          bp->AddName(name.c_str(), name_error);
+          if (name_error.Fail()) {
+            result.AppendErrorWithFormat("Invalid breakpoint name: %s",
+                                         name.c_str());
+            target->RemoveBreakpointByID(bp->GetID());
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+          }
+        }
       }
 
       bp->SetOneShot(m_options.m_one_shot);