This is the main part of a change to add breakpoint save and restore to lldb.

Still to come:
1) SB API's
2) Testcases
3) Loose ends:
   a) serialize Thread options
   b) serialize Exception resolvers
4) "break list --file" should list breakpoints contained in a file and
   "break read -f 1 3 5" should then read in only those breakpoints.

<rdar://problem/12611863>

llvm-svn: 281273
diff --git a/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp b/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp
index 8d08908..da8b7b3 100644
--- a/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp
@@ -36,6 +36,70 @@
 
 BreakpointResolverFileRegex::~BreakpointResolverFileRegex() {}
 
+BreakpointResolver *BreakpointResolverFileRegex::CreateFromStructuredData(
+    Breakpoint *bkpt, StructuredData::Dictionary &options_dict, Error &error) {
+  bool success;
+
+  std::string regex_string;
+  success = options_dict.GetValueForKeyAsString(
+      GetKey(OptionNames::RegexString), regex_string);
+  if (!success) {
+    error.SetErrorString("BRFR::CFSD: Couldn't find regex entry.");
+    return nullptr;
+  }
+  RegularExpression regex(regex_string.c_str());
+
+  bool exact_match;
+  success = options_dict.GetValueForKeyAsBoolean(
+      GetKey(OptionNames::ExactMatch), exact_match);
+  if (!success) {
+    error.SetErrorString("BRFL::CFSD: Couldn't find exact match entry.");
+    return nullptr;
+  }
+
+  // The names array is optional:
+  std::unordered_set<std::string> names_set;
+  StructuredData::Array *names_array;
+  success = options_dict.GetValueForKeyAsArray(
+      GetKey(OptionNames::SymbolNameArray), names_array);
+  if (success && names_array) {
+    size_t num_names = names_array->GetSize();
+    for (size_t i = 0; i < num_names; i++) {
+      std::string name;
+      success = names_array->GetItemAtIndexAsString(i, name);
+      if (!success) {
+        error.SetErrorStringWithFormat(
+            "BRFR::CFSD: Malformed element %zu in the names array.", i);
+        return nullptr;
+      }
+      names_set.insert(name);
+    }
+  }
+
+  return new BreakpointResolverFileRegex(bkpt, regex, names_set, exact_match);
+}
+
+StructuredData::ObjectSP
+BreakpointResolverFileRegex::SerializeToStructuredData() {
+  StructuredData::DictionarySP options_dict_sp(
+      new StructuredData::Dictionary());
+
+  options_dict_sp->AddStringItem(GetKey(OptionNames::RegexString),
+                                 m_regex.GetText());
+  options_dict_sp->AddBooleanItem(GetKey(OptionNames::ExactMatch),
+                                  m_exact_match);
+  if (!m_function_names.empty()) {
+    StructuredData::ArraySP names_array_sp(new StructuredData::Array());
+    for (std::string name : m_function_names) {
+      StructuredData::StringSP item(new StructuredData::String(name));
+      names_array_sp->AddItem(item);
+    }
+    options_dict_sp->AddItem(GetKey(OptionNames::LineNumber), names_array_sp);
+  }
+
+  return WrapOptionsDict(options_dict_sp);
+}
+
 Searcher::CallbackReturn
 BreakpointResolverFileRegex::SearchCallback(SearchFilter &filter,
                                             SymbolContext &context,