<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Mon, Sep 12, 2016 at 4:19 PM Jim Ingham via lldb-commits <<a href="mailto:lldb-commits@lists.llvm.org">lldb-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: jingham<br class="gmail_msg">
Date: Mon Sep 12 18:10:56 2016<br class="gmail_msg">
New Revision: 281273<br class="gmail_msg">
<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=281273&view=rev" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project?rev=281273&view=rev</a><br class="gmail_msg">
Log:<br class="gmail_msg">
This is the main part of a change to add breakpoint save and restore to lldb.<br class="gmail_msg">
<br class="gmail_msg">
Still to come:<br class="gmail_msg">
1) SB API's<br class="gmail_msg">
2) Testcases<br class="gmail_msg">
3) Loose ends:<br class="gmail_msg">
   a) serialize Thread options<br class="gmail_msg">
   b) serialize Exception resolvers<br class="gmail_msg">
4) "break list --file" should list breakpoints contained in a file and<br class="gmail_msg">
   "break read -f 1 3 5" should then read in only those breakpoints.<br class="gmail_msg">
<br class="gmail_msg">
<rdar://problem/12611863><br class="gmail_msg">
<br class="gmail_msg">
Modified:<br class="gmail_msg">
    lldb/trunk/include/lldb/Breakpoint/Breakpoint.h<br class="gmail_msg">
    lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h<br class="gmail_msg">
    lldb/trunk/include/lldb/Breakpoint/BreakpointResolver.h<br class="gmail_msg">
    lldb/trunk/include/lldb/Breakpoint/BreakpointResolverAddress.h<br class="gmail_msg">
    lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileLine.h<br class="gmail_msg">
    lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h<br class="gmail_msg">
    lldb/trunk/include/lldb/Breakpoint/BreakpointResolverName.h<br class="gmail_msg">
    lldb/trunk/include/lldb/Core/SearchFilter.h<br class="gmail_msg">
    lldb/trunk/include/lldb/Core/StructuredData.h<br class="gmail_msg">
    lldb/trunk/include/lldb/Target/LanguageRuntime.h<br class="gmail_msg">
    lldb/trunk/source/Breakpoint/Breakpoint.cpp<br class="gmail_msg">
    lldb/trunk/source/Breakpoint/BreakpointOptions.cpp<br class="gmail_msg">
    lldb/trunk/source/Breakpoint/BreakpointResolver.cpp<br class="gmail_msg">
    lldb/trunk/source/Breakpoint/BreakpointResolverAddress.cpp<br class="gmail_msg">
    lldb/trunk/source/Breakpoint/BreakpointResolverFileLine.cpp<br class="gmail_msg">
    lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp<br class="gmail_msg">
    lldb/trunk/source/Breakpoint/BreakpointResolverName.cpp<br class="gmail_msg">
    lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp<br class="gmail_msg">
    lldb/trunk/source/Commands/CommandObjectBreakpointCommand.cpp<br class="gmail_msg">
    lldb/trunk/source/Core/SearchFilter.cpp<br class="gmail_msg">
    lldb/trunk/source/Core/StructuredData.cpp<br class="gmail_msg">
    lldb/trunk/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp<br class="gmail_msg">
    lldb/trunk/source/Target/LanguageRuntime.cpp<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/include/lldb/Breakpoint/Breakpoint.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/Breakpoint.h?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/Breakpoint.h?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/include/lldb/Breakpoint/Breakpoint.h (original)<br class="gmail_msg">
+++ lldb/trunk/include/lldb/Breakpoint/Breakpoint.h Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -27,6 +27,7 @@<br class="gmail_msg">
 #include "lldb/Core/Event.h"<br class="gmail_msg">
 #include "lldb/Core/SearchFilter.h"<br class="gmail_msg">
 #include "lldb/Core/StringList.h"<br class="gmail_msg">
+#include "lldb/Core/StructuredData.h"<br class="gmail_msg">
<br class="gmail_msg">
 namespace lldb_private {<br class="gmail_msg">
<br class="gmail_msg">
@@ -164,6 +165,13 @@ public:<br class="gmail_msg">
<br class="gmail_msg">
   typedef std::shared_ptr<BreakpointPrecondition> BreakpointPreconditionSP;<br class="gmail_msg">
<br class="gmail_msg">
+  // Saving & restoring breakpoints:<br class="gmail_msg">
+  static lldb::BreakpointSP CreateFromStructuredData(<br class="gmail_msg">
+      Target &target, StructuredData::ObjectSP &data_object_sp, Error &error);<br class="gmail_msg">
+<br class="gmail_msg">
+  virtual StructuredData::ObjectSP SerializeToStructuredData();<br class="gmail_msg">
+<br class="gmail_msg">
+  static const char *GetSerializationKey() { return "Breakpoint"; } </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
   //------------------------------------------------------------------<br class="gmail_msg">
   /// Destructor.<br class="gmail_msg">
   ///<br class="gmail_msg">
@@ -717,7 +725,8 @@ private:<br class="gmail_msg">
   // to skip certain breakpoint hits.  For instance, exception breakpoints<br class="gmail_msg">
   // use this to limit the stop to certain exception classes, while leaving<br class="gmail_msg">
   // the condition & callback free for user specification.<br class="gmail_msg">
-  BreakpointOptions m_options; // Settable breakpoint options<br class="gmail_msg">
+  std::unique_ptr<BreakpointOptions><br class="gmail_msg">
+      m_options_up; // Settable breakpoint options<br class="gmail_msg">
   BreakpointLocationList<br class="gmail_msg">
       m_locations; // The list of locations currently found for this breakpoint.<br class="gmail_msg">
   std::string m_kind_description;<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h (original)<br class="gmail_msg">
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -19,6 +19,7 @@<br class="gmail_msg">
 // Project includes<br class="gmail_msg">
 #include "lldb/Core/Baton.h"<br class="gmail_msg">
 #include "lldb/Core/StringList.h"<br class="gmail_msg">
+#include "lldb/Core/StructuredData.h"<br class="gmail_msg">
 #include "lldb/lldb-private.h"<br class="gmail_msg">
<br class="gmail_msg">
 namespace lldb_private {<br class="gmail_msg">
@@ -32,6 +33,52 @@ namespace lldb_private {<br class="gmail_msg">
<br class="gmail_msg">
 class BreakpointOptions {<br class="gmail_msg">
 public:<br class="gmail_msg">
+  struct CommandData {<br class="gmail_msg">
+    CommandData() : user_source(), script_source(), stop_on_error(true) {}<br class="gmail_msg">
+<br class="gmail_msg">
+    ~CommandData() = default;<br class="gmail_msg">
+<br class="gmail_msg">
+    static const char *GetSerializationKey() { return "BKPTCMDData"; }<br class="gmail_msg">
+<br class="gmail_msg">
+    StructuredData::ObjectSP SerializeToStructuredData();<br class="gmail_msg">
+<br class="gmail_msg">
+    static CommandData *<br class="gmail_msg">
+    CreateFromStructuredData(StructuredData::Dictionary &options_dict,<br class="gmail_msg">
+                             Error &error);<br class="gmail_msg"></blockquote><div>This should probably return a unique_ptr to prevent memory leaks.  And the dictionary should be const.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br class="gmail_msg">
+    StringList user_source;<br class="gmail_msg">
+    std::string script_source;<br class="gmail_msg">
+    bool stop_on_error;<br class="gmail_msg">
+<br class="gmail_msg">
+  private:<br class="gmail_msg">
+    enum OptionNames {<br class="gmail_msg">
+      UserSource = 0,<br class="gmail_msg">
+      ScriptSource,<br class="gmail_msg">
+      StopOnError,<br class="gmail_msg">
+      LastOptionName<br class="gmail_msg">
+    };<br class="gmail_msg">
+<br class="gmail_msg">
+    static const char *g_option_names[LastOptionName];<br class="gmail_msg">
+<br class="gmail_msg">
+    static const char *GetKey(enum OptionNames enum_value) {<br class="gmail_msg">
+      return g_option_names[enum_value];<br class="gmail_msg">
+    }<br class="gmail_msg">
+  };<br class="gmail_msg">
+<br class="gmail_msg">
+  class CommandBaton : public Baton {<br class="gmail_msg">
+  public:<br class="gmail_msg">
+    CommandBaton(CommandData *data) : Baton(data) {}<br class="gmail_msg">
+<br class="gmail_msg">
+    ~CommandBaton() override {<br class="gmail_msg">
+      delete ((CommandData *)m_data);<br class="gmail_msg">
+      m_data = nullptr;<br class="gmail_msg">
+    }<br class="gmail_msg">
+<br class="gmail_msg">
+    void GetDescription(Stream *s, lldb::DescriptionLevel level) const override;<br class="gmail_msg">
+  };<br class="gmail_msg">
+<br class="gmail_msg">
+  typedef std::shared_ptr<CommandBaton> CommandBatonSP;<br class="gmail_msg">
+<br class="gmail_msg"></blockquote><div>Seems like it might be useful to have a PtrBaton<T> class that holds a unique_ptr<T>, then you wouldn't need to even make a new class for each type of Baton, they could all just used PtrBaton<T></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
   //------------------------------------------------------------------<br class="gmail_msg">
   // Constructors and Destructors<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
@@ -43,35 +90,34 @@ public:<br class="gmail_msg">
   BreakpointOptions(const BreakpointOptions &rhs);<br class="gmail_msg">
<br class="gmail_msg">
   static BreakpointOptions *CopyOptionsNoCallback(BreakpointOptions &rhs);<br class="gmail_msg">
+<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
-  /// This constructor allows you to specify all the breakpoint options.<br class="gmail_msg">
+  /// This constructor allows you to specify all the breakpoint options<br class="gmail_msg">
+  /// except the callback.  That one is more complicated, and better<br class="gmail_msg">
+  /// to do by hand.<br class="gmail_msg">
   ///<br class="gmail_msg">
   /// @param[in] condition<br class="gmail_msg">
   ///    The expression which if it evaluates to \b true if we are to stop<br class="gmail_msg">
   ///<br class="gmail_msg">
-  /// @param[in] callback<br class="gmail_msg">
-  ///    This is the plugin for some code that gets run, returns \b true if we<br class="gmail_msg">
-  ///    are to stop.<br class="gmail_msg">
-  ///<br class="gmail_msg">
-  /// @param[in] baton<br class="gmail_msg">
-  ///    Client data that will get passed to the callback.<br class="gmail_msg">
-  ///<br class="gmail_msg">
   /// @param[in] enabled<br class="gmail_msg">
   ///    Is this breakpoint enabled.<br class="gmail_msg">
   ///<br class="gmail_msg">
   /// @param[in] ignore<br class="gmail_msg">
   ///    How many breakpoint hits we should ignore before stopping.<br class="gmail_msg">
   ///<br class="gmail_msg">
-  /// @param[in] thread_id<br class="gmail_msg">
-  ///    Only stop if \a thread_id hits the breakpoint.<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
-  BreakpointOptions(void *condition, BreakpointHitCallback callback,<br class="gmail_msg">
-                    void *baton, bool enabled = true, int32_t ignore = 0,<br class="gmail_msg">
-                    lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID,<br class="gmail_msg">
-                    bool one_shot = false);<br class="gmail_msg">
+  BreakpointOptions(const char *condition, bool enabled = true,<br class="gmail_msg">
+                    int32_t ignore = 0, bool one_shot = false);<br class="gmail_msg"></blockquote><div>StringRef condition</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br class="gmail_msg">
   virtual ~BreakpointOptions();<br class="gmail_msg">
<br class="gmail_msg">
+  static BreakpointOptions *<br class="gmail_msg">
+  CreateFromStructuredData(StructuredData::Dictionary &data_dict, Error &error);<br class="gmail_msg"></blockquote><div>unique_ptr<BreakpointOptions></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br class="gmail_msg">
+  virtual StructuredData::ObjectSP SerializeToStructuredData();<br class="gmail_msg">
+<br class="gmail_msg">
+  static const char *GetSerializationKey() { return "BKPTOptions"; }<br class="gmail_msg"></blockquote><div>StringRef GetSerializationKey</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
   // Operators<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
@@ -131,6 +177,10 @@ public:<br class="gmail_msg">
   void SetCallback(BreakpointHitCallback callback,<br class="gmail_msg">
                    const lldb::BatonSP &baton_sp, bool synchronous = false);<br class="gmail_msg">
<br class="gmail_msg">
+  void SetCallback(BreakpointHitCallback callback,<br class="gmail_msg">
+                   const BreakpointOptions::CommandBatonSP &command_baton_sp,<br class="gmail_msg">
+                   bool synchronous = false);<br class="gmail_msg">
+<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
   /// Remove the callback from this option set.<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
@@ -279,40 +329,39 @@ public:<br class="gmail_msg">
<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
   /// This is the default empty callback.<br class="gmail_msg">
-  /// @return<br class="gmail_msg">
-  ///     The thread id for which the breakpoint hit will stop,<br class="gmail_msg">
-  ///     LLDB_INVALID_THREAD_ID for all threads.<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
   static bool NullCallback(void *baton, StoppointCallbackContext *context,<br class="gmail_msg">
                            lldb::user_id_t break_id,<br class="gmail_msg">
                            lldb::user_id_t break_loc_id);<br class="gmail_msg">
<br class="gmail_msg">
-  struct CommandData {<br class="gmail_msg">
-    CommandData() : user_source(), script_source(), stop_on_error(true) {}<br class="gmail_msg">
-<br class="gmail_msg">
-    ~CommandData() = default;<br class="gmail_msg">
-<br class="gmail_msg">
-    StringList user_source;<br class="gmail_msg">
-    std::string script_source;<br class="gmail_msg">
-    bool stop_on_error;<br class="gmail_msg">
-  };<br class="gmail_msg">
-<br class="gmail_msg">
-  class CommandBaton : public Baton {<br class="gmail_msg">
-  public:<br class="gmail_msg">
-    CommandBaton(CommandData *data) : Baton(data) {}<br class="gmail_msg">
-<br class="gmail_msg">
-    ~CommandBaton() override {<br class="gmail_msg">
-      delete ((CommandData *)m_data);<br class="gmail_msg">
-      m_data = nullptr;<br class="gmail_msg">
-    }<br class="gmail_msg">
-<br class="gmail_msg">
-    void GetDescription(Stream *s, lldb::DescriptionLevel level) const override;<br class="gmail_msg">
-  };<br class="gmail_msg">
+  //------------------------------------------------------------------<br class="gmail_msg">
+  /// Set a callback based on BreakpointOptions::CommandData.<br class="gmail_msg">
+  /// @param[in] cmd_data<br class="gmail_msg">
+  ///     A new'ed CommandData object.  The breakpoint will take ownership<br class="gmail_msg">
+  ///     of this object.<br class="gmail_msg">
+  //------------------------------------------------------------------<br class="gmail_msg">
+  void SetCommandDataCallback(CommandData *cmd_data);<br class="gmail_msg">
<br class="gmail_msg">
 protected:<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
   // Classes that inherit from BreakpointOptions can see and modify these<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
+  enum OptionNames {<br class="gmail_msg">
+    ConditionText = 0,<br class="gmail_msg">
+    IgnoreCount,<br class="gmail_msg">
+    EnabledState,<br class="gmail_msg">
+    OneShotState,<br class="gmail_msg">
+    LastOptionName<br class="gmail_msg">
+  };<br class="gmail_msg">
+  static const char *g_option_names[LastOptionName];<br class="gmail_msg">
+<br class="gmail_msg">
+  static const char *GetKey(enum OptionNames enum_value) {<br class="gmail_msg">
+    return g_option_names[enum_value];<br class="gmail_msg">
+  }<br class="gmail_msg"></blockquote><div>static StringRef GetKey().  </div><div><br></div><div>Also this can be an enum class if you use llvm/ADT/BitmaskEnu.h</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br class="gmail_msg">
+  static bool BreakpointOptionsCallbackFunction(<br class="gmail_msg">
+      void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,<br class="gmail_msg">
+      lldb::user_id_t break_loc_id);<br class="gmail_msg">
<br class="gmail_msg">
 private:<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
@@ -320,6 +369,7 @@ private:<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
   BreakpointHitCallback m_callback;  // This is the callback function pointer<br class="gmail_msg">
   lldb::BatonSP m_callback_baton_sp; // This is the client data for the callback<br class="gmail_msg">
+  bool m_baton_is_command_baton;<br class="gmail_msg">
   bool m_callback_is_synchronous;<br class="gmail_msg">
   bool m_enabled;<br class="gmail_msg">
   bool m_one_shot;<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointResolver.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointResolver.h?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointResolver.h?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/include/lldb/Breakpoint/BreakpointResolver.h (original)<br class="gmail_msg">
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointResolver.h Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -136,30 +136,96 @@ public:<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
   virtual void Dump(Stream *s) const = 0;<br class="gmail_msg">
<br class="gmail_msg">
+  /// This section handles serializing and deserializing from StructuredData<br class="gmail_msg">
+  /// objects.<br class="gmail_msg">
+<br class="gmail_msg">
+  static lldb::BreakpointResolverSP<br class="gmail_msg">
+  CreateFromStructuredData(StructuredData::Dictionary &resolver_dict,<br class="gmail_msg">
+                           Error &error);<br class="gmail_msg">
+<br class="gmail_msg">
+  virtual StructuredData::ObjectSP SerializeToStructuredData() {<br class="gmail_msg">
+    return StructuredData::ObjectSP();<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  static const char *GetSerializationKey() { return "BKPTResolver"; }<br class="gmail_msg">
+<br class="gmail_msg">
+  static const char *GetSerializationSubclassKey() { return "Type"; }<br class="gmail_msg">
+<br class="gmail_msg">
+  static const char *GetSerializationSubclassOptionsKey() { return "Options"; }<br class="gmail_msg"></blockquote><div>More StringRef opportunities.  This makes it very convenient to do comparisons and searching on the return values without resorting to CRT functions.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br class="gmail_msg">
+  StructuredData::DictionarySP<br class="gmail_msg">
+  WrapOptionsDict(StructuredData::DictionarySP options_dict_sp);<br class="gmail_msg">
+<br class="gmail_msg">
+  //------------------------------------------------------------------<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
   /// An enumeration for keeping track of the concrete subclass that<br class="gmail_msg">
   /// is actually instantiated. Values of this enumeration are kept in the<br class="gmail_msg">
   /// BreakpointResolver's SubclassID field. They are used for concrete type<br class="gmail_msg">
   /// identification.<br class="gmail_msg">
   enum ResolverTy {<br class="gmail_msg">
-    FileLineResolver, // This is an instance of BreakpointResolverFileLine<br class="gmail_msg">
-    AddressResolver,  // This is an instance of BreakpointResolverAddress<br class="gmail_msg">
-    NameResolver,     // This is an instance of BreakpointResolverName<br class="gmail_msg">
+    FileLineResolver = 0, // This is an instance of BreakpointResolverFileLine<br class="gmail_msg">
+    AddressResolver,      // This is an instance of BreakpointResolverAddress<br class="gmail_msg">
+    NameResolver,         // This is an instance of BreakpointResolverName<br class="gmail_msg">
     FileRegexResolver,<br class="gmail_msg">
     ExceptionResolver,<br class="gmail_msg">
-    LastKnownResolverType = ExceptionResolver<br class="gmail_msg">
+    LastKnownResolverType = ExceptionResolver,<br class="gmail_msg">
+    UnknownResolver<br class="gmail_msg">
   };<br class="gmail_msg">
<br class="gmail_msg">
+  // Translate the Ty to name for serialization,<br class="gmail_msg">
+  // the "+2" is one for size vrs. index, and one for UnknownResolver.<br class="gmail_msg">
+  static const char *g_ty_to_name[LastKnownResolverType + 2];<br class="gmail_msg">
+<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
   /// getResolverID - Return an ID for the concrete type of this object.  This<br class="gmail_msg">
   /// is used to implement the LLVM classof checks.  This should not be used<br class="gmail_msg">
   /// for any other purpose, as the values may change as LLDB evolves.<br class="gmail_msg">
   unsigned getResolverID() const { return SubclassID; }<br class="gmail_msg">
<br class="gmail_msg">
+  enum ResolverTy GetResolverTy() {<br class="gmail_msg">
+    if (SubclassID > ResolverTy::LastKnownResolverType)<br class="gmail_msg">
+      return ResolverTy::UnknownResolver;<br class="gmail_msg">
+    else<br class="gmail_msg">
+      return (enum ResolverTy)SubclassID;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  const char *GetResolverName() { return ResolverTyToName(GetResolverTy()); }<br class="gmail_msg">
+<br class="gmail_msg">
+  static const char *ResolverTyToName(enum ResolverTy);<br class="gmail_msg">
+<br class="gmail_msg">
+  static ResolverTy NameToResolverTy(const char *name);<br class="gmail_msg">
+<br class="gmail_msg">
   virtual lldb::BreakpointResolverSP<br class="gmail_msg">
   CopyForBreakpoint(Breakpoint &breakpoint) = 0;<br class="gmail_msg">
<br class="gmail_msg">
 protected:<br class="gmail_msg">
+  // Used for serializing resolver options:<br class="gmail_msg">
+  // The options in this enum and the strings in the<br class="gmail_msg">
+  // g_option_names must be kept in sync.<br class="gmail_msg">
+  enum OptionNames {<br class="gmail_msg">
+    AddressOffset = 0,<br class="gmail_msg">
+    ExactMatch,<br class="gmail_msg">
+    FileName,<br class="gmail_msg">
+    Inlines,<br class="gmail_msg">
+    LanguageName,<br class="gmail_msg">
+    LineNumber,<br class="gmail_msg">
+    ModuleName,<br class="gmail_msg">
+    NameMaskArray,<br class="gmail_msg">
+    Offset,<br class="gmail_msg">
+    RegexString,<br class="gmail_msg">
+    SectionName,<br class="gmail_msg">
+    SkipPrologue,<br class="gmail_msg">
+    SymbolNameArray,<br class="gmail_msg">
+    LastOptionName<br class="gmail_msg">
+  };<br class="gmail_msg">
+  static const char *g_option_names[LastOptionName];<br class="gmail_msg">
+<br class="gmail_msg">
+public:<br class="gmail_msg">
+  static const char *GetKey(enum OptionNames enum_value) {<br class="gmail_msg">
+    return g_option_names[enum_value];<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+protected:<br class="gmail_msg">
   //------------------------------------------------------------------<br class="gmail_msg">
   /// SetSCMatchesByLine - Takes a symbol context list of matches which<br class="gmail_msg">
   /// supposedly represent the same file and<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointResolverAddress.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointResolverAddress.h?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointResolverAddress.h?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/include/lldb/Breakpoint/BreakpointResolverAddress.h (original)<br class="gmail_msg">
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointResolverAddress.h Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -36,6 +36,11 @@ public:<br class="gmail_msg">
<br class="gmail_msg">
   ~BreakpointResolverAddress() override;<br class="gmail_msg">
<br class="gmail_msg">
+  static BreakpointResolver *CreateFromStructuredData(<br class="gmail_msg">
+      Breakpoint *bkpt, StructuredData::Dictionary &options_dict, Error &error);<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::ObjectSP SerializeToStructuredData() override;<br class="gmail_msg">
+<br class="gmail_msg">
   void ResolveBreakpoint(SearchFilter &filter) override;<br class="gmail_msg">
<br class="gmail_msg">
   void ResolveBreakpointInModules(SearchFilter &filter,<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileLine.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileLine.h?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileLine.h?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileLine.h (original)<br class="gmail_msg">
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileLine.h Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -33,6 +33,12 @@ public:<br class="gmail_msg">
                              bool check_inlines, bool skip_prologue,<br class="gmail_msg">
                              bool exact_match);<br class="gmail_msg">
<br class="gmail_msg">
+  static BreakpointResolver *<br class="gmail_msg">
+  CreateFromStructuredData(Breakpoint *bkpt,<br class="gmail_msg">
+                           StructuredData::Dictionary &data_dict, Error &error);<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::ObjectSP SerializeToStructuredData() override;<br class="gmail_msg">
+<br class="gmail_msg">
   ~BreakpointResolverFileLine() override;<br class="gmail_msg">
<br class="gmail_msg">
   Searcher::CallbackReturn SearchCallback(SearchFilter &filter,<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h (original)<br class="gmail_msg">
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -35,6 +35,11 @@ public:<br class="gmail_msg">
       Breakpoint *bkpt, RegularExpression &regex,<br class="gmail_msg">
       const std::unordered_set<std::string> &func_name_set, bool exact_match);<br class="gmail_msg">
<br class="gmail_msg">
+  static BreakpointResolver *CreateFromStructuredData(<br class="gmail_msg">
+      Breakpoint *bkpt, StructuredData::Dictionary &options_dict, Error &error);<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::ObjectSP SerializeToStructuredData() override;<br class="gmail_msg">
+<br class="gmail_msg">
   ~BreakpointResolverFileRegex() override;<br class="gmail_msg">
<br class="gmail_msg">
   Searcher::CallbackReturn SearchCallback(SearchFilter &filter,<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointResolverName.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointResolverName.h?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointResolverName.h?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/include/lldb/Breakpoint/BreakpointResolverName.h (original)<br class="gmail_msg">
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointResolverName.h Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -54,9 +54,11 @@ public:<br class="gmail_msg">
                          lldb::LanguageType language, lldb::addr_t offset,<br class="gmail_msg">
                          bool skip_prologue);<br class="gmail_msg">
<br class="gmail_msg">
-  BreakpointResolverName(Breakpoint *bkpt, const char *class_name,<br class="gmail_msg">
-                         const char *method, Breakpoint::MatchType type,<br class="gmail_msg">
-                         lldb::addr_t offset, bool skip_prologue);<br class="gmail_msg">
+  static BreakpointResolver *<br class="gmail_msg">
+  CreateFromStructuredData(Breakpoint *bkpt,<br class="gmail_msg">
+                           StructuredData::Dictionary &data_dict, Error &error);<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::ObjectSP SerializeToStructuredData() override;<br class="gmail_msg">
<br class="gmail_msg">
   ~BreakpointResolverName() override;<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/include/lldb/Core/SearchFilter.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/SearchFilter.h?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/SearchFilter.h?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/include/lldb/Core/SearchFilter.h (original)<br class="gmail_msg">
+++ lldb/trunk/include/lldb/Core/SearchFilter.h Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -15,6 +15,7 @@<br class="gmail_msg">
 // Other libraries and framework includes<br class="gmail_msg">
 // Project includes<br class="gmail_msg">
 #include "lldb/Core/FileSpecList.h"<br class="gmail_msg">
+#include "lldb/Core/StructuredData.h"<br class="gmail_msg">
 #include "lldb/lldb-private.h"<br class="gmail_msg">
<br class="gmail_msg">
 namespace lldb_private {<br class="gmail_msg">
@@ -101,6 +102,8 @@ public:<br class="gmail_msg">
<br class="gmail_msg">
   SearchFilter(const SearchFilter &rhs);<br class="gmail_msg">
<br class="gmail_msg">
+  SearchFilter(const lldb::TargetSP &target_sp, unsigned char filterType);<br class="gmail_msg">
+<br class="gmail_msg">
   virtual ~SearchFilter();<br class="gmail_msg">
<br class="gmail_msg">
   SearchFilter &operator=(const SearchFilter &rhs);<br class="gmail_msg">
@@ -213,7 +216,60 @@ public:<br class="gmail_msg">
<br class="gmail_msg">
   lldb::SearchFilterSP CopyForBreakpoint(Breakpoint &breakpoint);<br class="gmail_msg">
<br class="gmail_msg">
+  static SearchFilter *<br class="gmail_msg">
+  CreateFromStructuredData(Target &target,<br class="gmail_msg">
+                           StructuredData::Dictionary &data_dict, Error &error);<br class="gmail_msg">
+<br class="gmail_msg">
+  virtual StructuredData::ObjectSP SerializeToStructuredData() {<br class="gmail_msg">
+    return StructuredData::ObjectSP();<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  static const char *GetSerializationKey() { return "SearchFilter"; }<br class="gmail_msg">
+<br class="gmail_msg">
+  static const char *GetSerializationSubclassKey() { return "Type"; }<br class="gmail_msg">
+<br class="gmail_msg">
+  static const char *GetSerializationSubclassOptionsKey() { return "Options"; }<br class="gmail_msg">
+<br class="gmail_msg">
+  enum FilterTy {<br class="gmail_msg">
+    Unconstrained = 0,<br class="gmail_msg">
+    Exception,<br class="gmail_msg">
+    ByModule,<br class="gmail_msg">
+    ByModules,<br class="gmail_msg">
+    ByModulesAndCU,<br class="gmail_msg">
+    LastKnownFilterType = ByModulesAndCU,<br class="gmail_msg">
+    UnknownFilter<br class="gmail_msg">
+  };<br class="gmail_msg">
+<br class="gmail_msg">
+  static const char *g_ty_to_name[LastKnownFilterType + 2];<br class="gmail_msg">
+<br class="gmail_msg">
+  enum FilterTy GetFilterTy() {<br class="gmail_msg">
+    if (SubclassID > FilterTy::LastKnownFilterType)<br class="gmail_msg">
+      return FilterTy::UnknownFilter;<br class="gmail_msg">
+    else<br class="gmail_msg">
+      return (enum FilterTy)SubclassID;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  const char *GetFilterName() { return FilterTyToName(GetFilterTy()); }<br class="gmail_msg">
+<br class="gmail_msg">
+  static const char *FilterTyToName(enum FilterTy);<br class="gmail_msg">
+<br class="gmail_msg">
+  static FilterTy NameToFilterTy(const char *name);<br class="gmail_msg">
+<br class="gmail_msg">
 protected:<br class="gmail_msg">
+  // Serialization of SearchFilter options:<br class="gmail_msg">
+  enum OptionNames { ModList = 0, CUList, LanguageName, LastOptionName };<br class="gmail_msg">
+  static const char *g_option_names[LastOptionName];<br class="gmail_msg">
+<br class="gmail_msg">
+  static const char *GetKey(enum OptionNames enum_value) {<br class="gmail_msg">
+    return g_option_names[enum_value];<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::DictionarySP<br class="gmail_msg">
+  WrapOptionsDict(StructuredData::DictionarySP options_dict_sp);<br class="gmail_msg">
+<br class="gmail_msg">
+  void SerializeFileSpecList(StructuredData::DictionarySP &options_dict_sp,<br class="gmail_msg">
+                             OptionNames name, FileSpecList &file_list);<br class="gmail_msg"></blockquote><div>A reference to a shared_ptr<> seems odd, is this intended?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br class="gmail_msg">
   // These are utility functions to assist with the search iteration.  They are<br class="gmail_msg">
   // used by the<br class="gmail_msg">
   // default Search method.<br class="gmail_msg">
@@ -239,6 +295,8 @@ protected:<br class="gmail_msg">
   lldb::TargetSP<br class="gmail_msg">
       m_target_sp; // Every filter has to be associated with a target for<br class="gmail_msg">
                    // now since you need a starting place for the search.<br class="gmail_msg">
+private:<br class="gmail_msg">
+  unsigned char SubclassID;<br class="gmail_msg"></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> };<br class="gmail_msg">
<br class="gmail_msg">
 //----------------------------------------------------------------------<br class="gmail_msg">
@@ -250,13 +308,20 @@ protected:<br class="gmail_msg">
 class SearchFilterForUnconstrainedSearches : public SearchFilter {<br class="gmail_msg">
 public:<br class="gmail_msg">
   SearchFilterForUnconstrainedSearches(const lldb::TargetSP &target_sp)<br class="gmail_msg">
-      : SearchFilter(target_sp) {}<br class="gmail_msg">
+      : SearchFilter(target_sp, FilterTy::Unconstrained) {}<br class="gmail_msg">
+<br class="gmail_msg">
   ~SearchFilterForUnconstrainedSearches() override = default;<br class="gmail_msg">
<br class="gmail_msg">
   bool ModulePasses(const FileSpec &module_spec) override;<br class="gmail_msg">
<br class="gmail_msg">
   bool ModulePasses(const lldb::ModuleSP &module_sp) override;<br class="gmail_msg">
<br class="gmail_msg">
+  static SearchFilter *<br class="gmail_msg">
+  CreateFromStructuredData(Target &target,<br class="gmail_msg">
+                           StructuredData::Dictionary &data_dict, Error &error);<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::ObjectSP SerializeToStructuredData() override;<br class="gmail_msg">
+<br class="gmail_msg">
 protected:<br class="gmail_msg">
   lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;<br class="gmail_msg">
 };<br class="gmail_msg">
@@ -304,6 +369,12 @@ public:<br class="gmail_msg">
<br class="gmail_msg">
   void Search(Searcher &searcher) override;<br class="gmail_msg">
<br class="gmail_msg">
+  static SearchFilter *<br class="gmail_msg">
+  CreateFromStructuredData(Target &target,<br class="gmail_msg">
+                           StructuredData::Dictionary &data_dict, Error &error);<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::ObjectSP SerializeToStructuredData() override;<br class="gmail_msg">
+<br class="gmail_msg">
 protected:<br class="gmail_msg">
   lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;<br class="gmail_msg">
<br class="gmail_msg">
@@ -326,6 +397,10 @@ public:<br class="gmail_msg">
   SearchFilterByModuleList(const lldb::TargetSP &targetSP,<br class="gmail_msg">
                            const FileSpecList &module_list);<br class="gmail_msg">
<br class="gmail_msg">
+  SearchFilterByModuleList(const lldb::TargetSP &targetSP,<br class="gmail_msg">
+                           const FileSpecList &module_list,<br class="gmail_msg">
+                           enum FilterTy filter_ty);<br class="gmail_msg">
+<br class="gmail_msg">
   SearchFilterByModuleList(const SearchFilterByModuleList &rhs);<br class="gmail_msg">
<br class="gmail_msg">
   ~SearchFilterByModuleList() override;<br class="gmail_msg">
@@ -350,6 +425,14 @@ public:<br class="gmail_msg">
<br class="gmail_msg">
   void Search(Searcher &searcher) override;<br class="gmail_msg">
<br class="gmail_msg">
+  static SearchFilter *<br class="gmail_msg">
+  CreateFromStructuredData(Target &target,<br class="gmail_msg">
+                           StructuredData::Dictionary &data_dict, Error &error);<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::ObjectSP SerializeToStructuredData() override;<br class="gmail_msg">
+<br class="gmail_msg">
+  void SerializeUnwrapped(StructuredData::DictionarySP &options_dict_sp);<br class="gmail_msg">
+<br class="gmail_msg">
 protected:<br class="gmail_msg">
   lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;<br class="gmail_msg">
<br class="gmail_msg">
@@ -394,6 +477,12 @@ public:<br class="gmail_msg">
<br class="gmail_msg">
   void Search(Searcher &searcher) override;<br class="gmail_msg">
<br class="gmail_msg">
+  static SearchFilter *<br class="gmail_msg">
+  CreateFromStructuredData(Target &target,<br class="gmail_msg">
+                           StructuredData::Dictionary &data_dict, Error &error);<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::ObjectSP SerializeToStructuredData() override;<br class="gmail_msg">
+<br class="gmail_msg">
 protected:<br class="gmail_msg">
   lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/include/lldb/Core/StructuredData.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/StructuredData.h?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/StructuredData.h?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/include/lldb/Core/StructuredData.h (original)<br class="gmail_msg">
+++ lldb/trunk/include/lldb/Core/StructuredData.h Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -390,6 +390,18 @@ public:<br class="gmail_msg">
       return value_sp;<br class="gmail_msg">
     }<br class="gmail_msg">
<br class="gmail_msg">
+    bool GetValueForKeyAsBoolean(llvm::StringRef key, bool &result) const {<br class="gmail_msg">
+      bool success = false;<br class="gmail_msg">
+      ObjectSP value_sp = GetValueForKey(key);<br class="gmail_msg">
+      if (value_sp.get()) {<br class="gmail_msg"></blockquote><div>Not a big deal since this is a short function, but LLVM style is to use early return on failure.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        Boolean *result_ptr = value_sp->GetAsBoolean();<br class="gmail_msg">
+        if (result_ptr) {<br class="gmail_msg">
+          result = result_ptr->GetValue();<br class="gmail_msg">
+          success = true;<br class="gmail_msg">
+        }<br class="gmail_msg">
+      }<br class="gmail_msg">
+      return success;<br class="gmail_msg">
+    }<br class="gmail_msg">
     template <class IntType><br class="gmail_msg">
     bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {<br class="gmail_msg">
       ObjectSP value_sp = GetValueForKey(key);<br class="gmail_msg">
@@ -539,6 +551,8 @@ public:<br class="gmail_msg">
   };<br class="gmail_msg">
<br class="gmail_msg">
   static ObjectSP ParseJSON(std::string json_text);<br class="gmail_msg">
+<br class="gmail_msg">
+  static ObjectSP ParseJSONFromFile(FileSpec &file, Error &error);<br class="gmail_msg"></blockquote><div>const FileSpec</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 };<br class="gmail_msg">
<br class="gmail_msg">
 } // namespace lldb_private<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/include/lldb/Target/LanguageRuntime.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/LanguageRuntime.h?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/LanguageRuntime.h?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/include/lldb/Target/LanguageRuntime.h (original)<br class="gmail_msg">
+++ lldb/trunk/include/lldb/Target/LanguageRuntime.h Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -1,5 +1,5 @@<br class="gmail_msg">
 //===-- LanguageRuntime.h ---------------------------------------------------*-<br class="gmail_msg">
-//C++ -*-===//<br class="gmail_msg">
+// C++ -*-===//<br class="gmail_msg">
 //<br class="gmail_msg">
 //                     The LLVM Compiler Infrastructure<br class="gmail_msg">
 //<br class="gmail_msg">
@@ -29,6 +29,38 @@<br class="gmail_msg">
<br class="gmail_msg">
 namespace lldb_private {<br class="gmail_msg">
<br class="gmail_msg">
+class ExceptionSearchFilter : public SearchFilter {<br class="gmail_msg">
+public:<br class="gmail_msg">
+  ExceptionSearchFilter(const lldb::TargetSP &target_sp,<br class="gmail_msg">
+                        lldb::LanguageType language,<br class="gmail_msg">
+                        bool update_module_list = true);<br class="gmail_msg">
+<br class="gmail_msg">
+  ~ExceptionSearchFilter() override = default;<br class="gmail_msg">
+<br class="gmail_msg">
+  bool ModulePasses(const lldb::ModuleSP &module_sp) override;<br class="gmail_msg"></blockquote><div>Another shared_ptr reference, shouldn't we just pass the shared_ptr by value or the value by reference?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br class="gmail_msg">
+  bool ModulePasses(const FileSpec &spec) override;<br class="gmail_msg">
+<br class="gmail_msg">
+  void Search(Searcher &searcher) override;<br class="gmail_msg">
+<br class="gmail_msg">
+  void GetDescription(Stream *s) override;<br class="gmail_msg">
+<br class="gmail_msg">
+  static SearchFilter *<br class="gmail_msg">
+  CreateFromStructuredData(Target &target,<br class="gmail_msg">
+                           StructuredData::Dictionary &data_dict, Error &error);<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::ObjectSP SerializeToStructuredData() override;<br class="gmail_msg">
+<br class="gmail_msg">
+protected:<br class="gmail_msg">
+  lldb::LanguageType m_language;<br class="gmail_msg">
+  LanguageRuntime *m_language_runtime;<br class="gmail_msg">
+  lldb::SearchFilterSP m_filter_sp;<br class="gmail_msg">
+<br class="gmail_msg">
+  lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;<br class="gmail_msg">
+<br class="gmail_msg">
+  void UpdateModuleListIfNeeded();<br class="gmail_msg">
+};<br class="gmail_msg">
+<br class="gmail_msg">
 class LanguageRuntime : public PluginInterface {<br class="gmail_msg">
 public:<br class="gmail_msg">
   ~LanguageRuntime() override;<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/source/Breakpoint/Breakpoint.cpp<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/Breakpoint.cpp?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/Breakpoint.cpp?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/source/Breakpoint/Breakpoint.cpp (original)<br class="gmail_msg">
+++ lldb/trunk/source/Breakpoint/Breakpoint.cpp Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -48,16 +48,17 @@ Breakpoint::Breakpoint(Target &target, S<br class="gmail_msg">
                        BreakpointResolverSP &resolver_sp, bool hardware,<br class="gmail_msg">
                        bool resolve_indirect_symbols)<br class="gmail_msg">
     : m_being_created(true), m_hardware(hardware), m_target(target),<br class="gmail_msg">
-      m_filter_sp(filter_sp), m_resolver_sp(resolver_sp), m_options(),<br class="gmail_msg">
-      m_locations(*this), m_resolve_indirect_symbols(resolve_indirect_symbols),<br class="gmail_msg">
-      m_hit_count(0) {<br class="gmail_msg">
+      m_filter_sp(filter_sp), m_resolver_sp(resolver_sp),<br class="gmail_msg">
+      m_options_up(new BreakpointOptions()), m_locations(*this),<br class="gmail_msg">
+      m_resolve_indirect_symbols(resolve_indirect_symbols), m_hit_count(0) {<br class="gmail_msg">
   m_being_created = false;<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 Breakpoint::Breakpoint(Target &new_target, Breakpoint &source_bp)<br class="gmail_msg">
     : m_being_created(true), m_hardware(source_bp.m_hardware),<br class="gmail_msg">
       m_target(new_target), m_name_list(source_bp.m_name_list),<br class="gmail_msg">
-      m_options(source_bp.m_options), m_locations(*this),<br class="gmail_msg">
+      m_options_up(new BreakpointOptions(*source_bp.m_options_up.get())),<br class="gmail_msg">
+      m_locations(*this),<br class="gmail_msg">
       m_resolve_indirect_symbols(source_bp.m_resolve_indirect_symbols),<br class="gmail_msg">
       m_hit_count(0) {<br class="gmail_msg">
   // Now go through and copy the filter & resolver:<br class="gmail_msg">
@@ -70,6 +71,115 @@ Breakpoint::Breakpoint(Target &new_targe<br class="gmail_msg">
 //----------------------------------------------------------------------<br class="gmail_msg">
 Breakpoint::~Breakpoint() = default;<br class="gmail_msg">
<br class="gmail_msg">
+//----------------------------------------------------------------------<br class="gmail_msg">
+// Serialization<br class="gmail_msg">
+//----------------------------------------------------------------------<br class="gmail_msg">
+StructuredData::ObjectSP Breakpoint::SerializeToStructuredData() {<br class="gmail_msg">
+  // Serialize the resolver:<br class="gmail_msg">
+  StructuredData::DictionarySP breakpoint_dict_sp(<br class="gmail_msg">
+      new StructuredData::Dictionary());<br class="gmail_msg">
+  StructuredData::DictionarySP breakpoint_contents_sp(<br class="gmail_msg">
+      new StructuredData::Dictionary());<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::ObjectSP resolver_dict_sp(<br class="gmail_msg">
+      m_resolver_sp->SerializeToStructuredData());<br class="gmail_msg">
+  if (!resolver_dict_sp)<br class="gmail_msg">
+    return StructuredData::ObjectSP();<br class="gmail_msg">
+<br class="gmail_msg">
+  breakpoint_contents_sp->AddItem(BreakpointResolver::GetSerializationKey(),<br class="gmail_msg">
+                                  resolver_dict_sp);<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::ObjectSP filter_dict_sp(<br class="gmail_msg">
+      m_filter_sp->SerializeToStructuredData());<br class="gmail_msg">
+  if (!filter_dict_sp)<br class="gmail_msg">
+    return StructuredData::ObjectSP();<br class="gmail_msg">
+<br class="gmail_msg">
+  breakpoint_contents_sp->AddItem(SearchFilter::GetSerializationKey(),<br class="gmail_msg">
+                                  filter_dict_sp);<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::ObjectSP options_dict_sp(<br class="gmail_msg">
+      m_options_up->SerializeToStructuredData());<br class="gmail_msg">
+  if (!options_dict_sp)<br class="gmail_msg">
+    return StructuredData::ObjectSP();<br class="gmail_msg">
+<br class="gmail_msg">
+  breakpoint_contents_sp->AddItem(BreakpointOptions::GetSerializationKey(),<br class="gmail_msg">
+                                  options_dict_sp);<br class="gmail_msg">
+<br class="gmail_msg">
+  breakpoint_dict_sp->AddItem(GetSerializationKey(), breakpoint_contents_sp);<br class="gmail_msg">
+  return breakpoint_dict_sp;<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+lldb::BreakpointSP Breakpoint::CreateFromStructuredData(<br class="gmail_msg">
+    Target &target, StructuredData::ObjectSP &object_data, Error &error) {<br class="gmail_msg">
+  BreakpointSP result_sp;<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::Dictionary *breakpoint_dict = object_data->GetAsDictionary();<br class="gmail_msg">
+<br class="gmail_msg">
+  if (!breakpoint_dict || !breakpoint_dict->IsValid()) {<br class="gmail_msg">
+    error.SetErrorString("Can't deserialize from an invalid data object.");<br class="gmail_msg">
+    return result_sp;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::Dictionary *resolver_dict;<br class="gmail_msg">
+  bool success = breakpoint_dict->GetValueForKeyAsDictionary(<br class="gmail_msg">
+      BreakpointResolver::GetSerializationKey(), resolver_dict);<br class="gmail_msg">
+  if (!success) {<br class="gmail_msg">
+    error.SetErrorStringWithFormat(<br class="gmail_msg">
+        "Breakpoint data missing toplevel resolver key");<br class="gmail_msg">
+    return result_sp;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  Error create_error;<br class="gmail_msg">
+  BreakpointResolverSP resolver_sp =<br class="gmail_msg">
+      BreakpointResolver::CreateFromStructuredData(*resolver_dict,<br class="gmail_msg">
+                                                   create_error);<br class="gmail_msg">
+  if (create_error.Fail()) {<br class="gmail_msg">
+    error.SetErrorStringWithFormat(<br class="gmail_msg">
+        "Error creating breakpoint resolver from data: %s.",<br class="gmail_msg">
+        create_error.AsCString());<br class="gmail_msg">
+    return result_sp;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::Dictionary *filter_dict;<br class="gmail_msg">
+  success = breakpoint_dict->GetValueForKeyAsDictionary(<br class="gmail_msg">
+      SearchFilter::GetSerializationKey(), filter_dict);<br class="gmail_msg">
+  SearchFilterSP filter_sp;<br class="gmail_msg">
+  if (!success)<br class="gmail_msg"></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">+    filter_sp.reset(<br class="gmail_msg">
+        new SearchFilterForUnconstrainedSearches(target.shared_from_this()));<br class="gmail_msg">
</blockquote><div>std::make_shared is preferable to this pattern.  There's a similar pattern for make_unique<>, but it's especially useful for shared_ptr's since it can allocate the object as well as the shared_ptr's control block with a single allocation.  As a general principle, it is also more resilient in the face of exceptions in the constructor, although this doesn't matter for us since we disable exceptions.</div><br class="inbox-inbox-Apple-interchange-newline"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">+  else {<br class="gmail_msg">
+    filter_sp.reset(SearchFilter::CreateFromStructuredData(target, *filter_dict,<br class="gmail_msg">
+                                                           create_error));<br class="gmail_msg">
+    if (create_error.Fail()) {<br class="gmail_msg">
+      error.SetErrorStringWithFormat(<br class="gmail_msg">
+          "Error creating breakpoint filter from data: %s.",<br class="gmail_msg">
+          create_error.AsCString());<br class="gmail_msg">
+      return result_sp;<br class="gmail_msg">
+    }<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  BreakpointOptions *options = nullptr;<br class="gmail_msg">
+  StructuredData::Dictionary *options_dict;<br class="gmail_msg">
+  success = breakpoint_dict->GetValueForKeyAsDictionary(<br class="gmail_msg">
+      BreakpointOptions::GetSerializationKey(), options_dict);<br class="gmail_msg">
+  if (success) {<br class="gmail_msg">
+    options = BreakpointOptions::CreateFromStructuredData(*options_dict,<br class="gmail_msg">
+                                                          create_error);<br class="gmail_msg">
+    if (create_error.Fail()) {<br class="gmail_msg">
+      error.SetErrorStringWithFormat(<br class="gmail_msg">
+          "Error creating breakpoint options from data: %s.",<br class="gmail_msg">
+          create_error.AsCString());<br class="gmail_msg">
+      return result_sp;<br class="gmail_msg">
+    }<br class="gmail_msg">
+  }<br class="gmail_msg">
+  result_sp =<br class="gmail_msg">
+      target.CreateBreakpoint(filter_sp, resolver_sp, false, false, true);<br class="gmail_msg">
+  if (result_sp && options) {<br class="gmail_msg">
+    result_sp->m_options_up.reset(options);<br class="gmail_msg">
+  }<br class="gmail_msg">
+  return result_sp;<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
 const lldb::TargetSP Breakpoint::GetTargetSP() {<br class="gmail_msg">
   return m_target.shared_from_this();<br class="gmail_msg">
 }<br class="gmail_msg">
@@ -111,10 +221,10 @@ void Breakpoint::RemoveInvalidLocations(<br class="gmail_msg">
 // up the individual settings.<br class="gmail_msg">
<br class="gmail_msg">
 void Breakpoint::SetEnabled(bool enable) {<br class="gmail_msg">
-  if (enable == m_options.IsEnabled())<br class="gmail_msg">
+  if (enable == m_options_up->IsEnabled())<br class="gmail_msg">
     return;<br class="gmail_msg">
<br class="gmail_msg">
-  m_options.SetEnabled(enable);<br class="gmail_msg">
+  m_options_up->SetEnabled(enable);<br class="gmail_msg">
   if (enable)<br class="gmail_msg">
     m_locations.ResolveAllBreakpointSites();<br class="gmail_msg">
   else<br class="gmail_msg">
@@ -124,24 +234,24 @@ void Breakpoint::SetEnabled(bool enable)<br class="gmail_msg">
                                     : eBreakpointEventTypeDisabled);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
-bool Breakpoint::IsEnabled() { return m_options.IsEnabled(); }<br class="gmail_msg">
+bool Breakpoint::IsEnabled() { return m_options_up->IsEnabled(); }<br class="gmail_msg"></blockquote><div>const member function?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br class="gmail_msg">
 void Breakpoint::SetIgnoreCount(uint32_t n) {<br class="gmail_msg">
-  if (m_options.GetIgnoreCount() == n)<br class="gmail_msg">
+  if (m_options_up->GetIgnoreCount() == n)<br class="gmail_msg">
     return;<br class="gmail_msg">
<br class="gmail_msg">
-  m_options.SetIgnoreCount(n);<br class="gmail_msg">
+  m_options_up->SetIgnoreCount(n);<br class="gmail_msg">
   SendBreakpointChangedEvent(eBreakpointEventTypeIgnoreChanged);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 void Breakpoint::DecrementIgnoreCount() {<br class="gmail_msg">
-  uint32_t ignore = m_options.GetIgnoreCount();<br class="gmail_msg">
+  uint32_t ignore = m_options_up->GetIgnoreCount();<br class="gmail_msg">
   if (ignore != 0)<br class="gmail_msg">
-    m_options.SetIgnoreCount(ignore - 1);<br class="gmail_msg">
+    m_options_up->SetIgnoreCount(ignore - 1);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 uint32_t Breakpoint::GetIgnoreCount() const {<br class="gmail_msg">
-  return m_options.GetIgnoreCount();<br class="gmail_msg">
+  return m_options_up->GetIgnoreCount();<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 bool Breakpoint::IgnoreCountShouldStop() {<br class="gmail_msg">
@@ -160,79 +270,81 @@ bool Breakpoint::IgnoreCountShouldStop()<br class="gmail_msg">
<br class="gmail_msg">
 uint32_t Breakpoint::GetHitCount() const { return m_hit_count; }<br class="gmail_msg">
<br class="gmail_msg">
-bool Breakpoint::IsOneShot() const { return m_options.IsOneShot(); }<br class="gmail_msg">
+bool Breakpoint::IsOneShot() const { return m_options_up->IsOneShot(); }<br class="gmail_msg">
<br class="gmail_msg">
-void Breakpoint::SetOneShot(bool one_shot) { m_options.SetOneShot(one_shot); }<br class="gmail_msg">
+void Breakpoint::SetOneShot(bool one_shot) {<br class="gmail_msg">
+  m_options_up->SetOneShot(one_shot);<br class="gmail_msg">
+}<br class="gmail_msg">
<br class="gmail_msg">
 void Breakpoint::SetThreadID(lldb::tid_t thread_id) {<br class="gmail_msg">
-  if (m_options.GetThreadSpec()->GetTID() == thread_id)<br class="gmail_msg">
+  if (m_options_up->GetThreadSpec()->GetTID() == thread_id)<br class="gmail_msg">
     return;<br class="gmail_msg">
<br class="gmail_msg">
-  m_options.GetThreadSpec()->SetTID(thread_id);<br class="gmail_msg">
+  m_options_up->GetThreadSpec()->SetTID(thread_id);<br class="gmail_msg">
   SendBreakpointChangedEvent(eBreakpointEventTypeThreadChanged);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 lldb::tid_t Breakpoint::GetThreadID() const {<br class="gmail_msg">
-  if (m_options.GetThreadSpecNoCreate() == nullptr)<br class="gmail_msg">
+  if (m_options_up->GetThreadSpecNoCreate() == nullptr)<br class="gmail_msg">
     return LLDB_INVALID_THREAD_ID;<br class="gmail_msg">
   else<br class="gmail_msg">
-    return m_options.GetThreadSpecNoCreate()->GetTID();<br class="gmail_msg">
+    return m_options_up->GetThreadSpecNoCreate()->GetTID();<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 void Breakpoint::SetThreadIndex(uint32_t index) {<br class="gmail_msg">
-  if (m_options.GetThreadSpec()->GetIndex() == index)<br class="gmail_msg">
+  if (m_options_up->GetThreadSpec()->GetIndex() == index)<br class="gmail_msg">
     return;<br class="gmail_msg">
<br class="gmail_msg">
-  m_options.GetThreadSpec()->SetIndex(index);<br class="gmail_msg">
+  m_options_up->GetThreadSpec()->SetIndex(index);<br class="gmail_msg">
   SendBreakpointChangedEvent(eBreakpointEventTypeThreadChanged);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 uint32_t Breakpoint::GetThreadIndex() const {<br class="gmail_msg">
-  if (m_options.GetThreadSpecNoCreate() == nullptr)<br class="gmail_msg">
+  if (m_options_up->GetThreadSpecNoCreate() == nullptr)<br class="gmail_msg">
     return 0;<br class="gmail_msg">
   else<br class="gmail_msg">
-    return m_options.GetThreadSpecNoCreate()->GetIndex();<br class="gmail_msg">
+    return m_options_up->GetThreadSpecNoCreate()->GetIndex();<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 void Breakpoint::SetThreadName(const char *thread_name) {<br class="gmail_msg">
-  if (m_options.GetThreadSpec()->GetName() != nullptr &&<br class="gmail_msg">
-      ::strcmp(m_options.GetThreadSpec()->GetName(), thread_name) == 0)<br class="gmail_msg">
+  if (m_options_up->GetThreadSpec()->GetName() != nullptr &&<br class="gmail_msg">
+      ::strcmp(m_options_up->GetThreadSpec()->GetName(), thread_name) == 0)<br class="gmail_msg">
     return;<br class="gmail_msg"></blockquote><div>Good opportunity to use a StringRef (for both the parameter as well as ThreadSpec::GetName())</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br class="gmail_msg">
-  m_options.GetThreadSpec()->SetName(thread_name);<br class="gmail_msg">
+  m_options_up->GetThreadSpec()->SetName(thread_name);<br class="gmail_msg">
   SendBreakpointChangedEvent(eBreakpointEventTypeThreadChanged);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 const char *Breakpoint::GetThreadName() const {<br class="gmail_msg">
-  if (m_options.GetThreadSpecNoCreate() == nullptr)<br class="gmail_msg">
+  if (m_options_up->GetThreadSpecNoCreate() == nullptr)<br class="gmail_msg">
     return nullptr;<br class="gmail_msg">
   else<br class="gmail_msg">
-    return m_options.GetThreadSpecNoCreate()->GetName();<br class="gmail_msg">
+    return m_options_up->GetThreadSpecNoCreate()->GetName();<br class="gmail_msg">
 }<br class="gmail_msg"></blockquote><div>StringRef.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br class="gmail_msg">
 void Breakpoint::SetQueueName(const char *queue_name) {<br class="gmail_msg"></blockquote><div>StringRef.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
-  if (m_options.GetThreadSpec()->GetQueueName() != nullptr &&<br class="gmail_msg">
-      ::strcmp(m_options.GetThreadSpec()->GetQueueName(), queue_name) == 0)<br class="gmail_msg">
+  if (m_options_up->GetThreadSpec()->GetQueueName() != nullptr &&<br class="gmail_msg">
+      ::strcmp(m_options_up->GetThreadSpec()->GetQueueName(), queue_name) == 0)<br class="gmail_msg">
     return;<br class="gmail_msg">
<br class="gmail_msg">
-  m_options.GetThreadSpec()->SetQueueName(queue_name);<br class="gmail_msg">
+  m_options_up->GetThreadSpec()->SetQueueName(queue_name);<br class="gmail_msg">
   SendBreakpointChangedEvent(eBreakpointEventTypeThreadChanged);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 const char *Breakpoint::GetQueueName() const {<br></blockquote><div>StringRef  </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br class="inbox-inbox-Apple-interchange-newline">-  if (m_options.GetThreadSpecNoCreate() == nullptr)<br class="gmail_msg">
+  if (m_options_up->GetThreadSpecNoCreate() == nullptr)<br class="gmail_msg">
     return nullptr;<br class="gmail_msg">
   else<br class="gmail_msg">
-    return m_options.GetThreadSpecNoCreate()->GetQueueName();<br class="gmail_msg">
+    return m_options_up->GetThreadSpecNoCreate()->GetQueueName();<br class="gmail_msg">
 }<br class="gmail_msg"></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br class="gmail_msg">
 void Breakpoint::SetCondition(const char *condition) {<br class="gmail_msg"></blockquote><div>StringRef.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
-  m_options.SetCondition(condition);<br class="gmail_msg">
+  m_options_up->SetCondition(condition);<br class="gmail_msg">
   SendBreakpointChangedEvent(eBreakpointEventTypeConditionChanged);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 const char *Breakpoint::GetConditionText() const {<br class="gmail_msg">
-  return m_options.GetConditionText();<br class="gmail_msg">
+  return m_options_up->GetConditionText();<br class="gmail_msg">
 }<br class="gmail_msg"></blockquote><div>StringRef.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br class="gmail_msg">
 // This function is used when "baton" doesn't need to be freed<br class="gmail_msg">
@@ -240,7 +352,8 @@ void Breakpoint::SetCallback(BreakpointH<br class="gmail_msg">
                              bool is_synchronous) {<br class="gmail_msg">
   // The default "Baton" class will keep a copy of "baton" and won't free<br class="gmail_msg">
   // or delete it when it goes goes out of scope.<br class="gmail_msg">
-  m_options.SetCallback(callback, BatonSP(new Baton(baton)), is_synchronous);<br class="gmail_msg">
+  m_options_up->SetCallback(callback, BatonSP(new Baton(baton)),<br class="gmail_msg">
+                            is_synchronous);<br class="gmail_msg">
<br class="gmail_msg">
   SendBreakpointChangedEvent(eBreakpointEventTypeCommandChanged);<br class="gmail_msg">
 }<br class="gmail_msg">
@@ -250,17 +363,17 @@ void Breakpoint::SetCallback(BreakpointH<br class="gmail_msg">
 void Breakpoint::SetCallback(BreakpointHitCallback callback,<br class="gmail_msg">
                              const BatonSP &callback_baton_sp,<br class="gmail_msg">
                              bool is_synchronous) {<br class="gmail_msg">
-  m_options.SetCallback(callback, callback_baton_sp, is_synchronous);<br class="gmail_msg">
+  m_options_up->SetCallback(callback, callback_baton_sp, is_synchronous);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
-void Breakpoint::ClearCallback() { m_options.ClearCallback(); }<br class="gmail_msg">
+void Breakpoint::ClearCallback() { m_options_up->ClearCallback(); }<br class="gmail_msg">
<br class="gmail_msg">
 bool Breakpoint::InvokeCallback(StoppointCallbackContext *context,<br class="gmail_msg">
                                 break_id_t bp_loc_id) {<br class="gmail_msg">
-  return m_options.InvokeCallback(context, GetID(), bp_loc_id);<br class="gmail_msg">
+  return m_options_up->InvokeCallback(context, GetID(), bp_loc_id);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
-BreakpointOptions *Breakpoint::GetOptions() { return &m_options; }<br class="gmail_msg">
+BreakpointOptions *Breakpoint::GetOptions() { return m_options_up.get(); }<br class="gmail_msg"></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br class="gmail_msg">
 void Breakpoint::ResolveBreakpoint() {<br class="gmail_msg">
   if (m_resolver_sp)<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/source/Breakpoint/BreakpointOptions.cpp<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointOptions.cpp?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointOptions.cpp?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/source/Breakpoint/BreakpointOptions.cpp (original)<br class="gmail_msg">
+++ lldb/trunk/source/Breakpoint/BreakpointOptions.cpp Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -17,6 +17,8 @@<br class="gmail_msg">
 #include "lldb/Core/Stream.h"<br class="gmail_msg">
 #include "lldb/Core/StringList.h"<br class="gmail_msg">
 #include "lldb/Core/Value.h"<br class="gmail_msg">
+#include "lldb/Interpreter/CommandInterpreter.h"<br class="gmail_msg">
+#include "lldb/Interpreter/CommandReturnObject.h"<br class="gmail_msg">
 #include "lldb/Target/Process.h"<br class="gmail_msg">
 #include "lldb/Target/Target.h"<br class="gmail_msg">
 #include "lldb/Target/ThreadSpec.h"<br class="gmail_msg">
@@ -24,6 +26,71 @@<br class="gmail_msg">
 using namespace lldb;<br class="gmail_msg">
 using namespace lldb_private;<br class="gmail_msg">
<br class="gmail_msg">
+const char *BreakpointOptions::CommandData::g_option_names<br class="gmail_msg">
+    [BreakpointOptions::CommandData::OptionNames::LastOptionName]{<br class="gmail_msg">
+        "UserSource", "ScriptSource", "StopOnError"};<br class="gmail_msg">
+<br class="gmail_msg">
+StructuredData::ObjectSP<br class="gmail_msg">
+BreakpointOptions::CommandData::SerializeToStructuredData() {<br class="gmail_msg">
+  size_t num_strings = user_source.GetSize();<br class="gmail_msg">
+  if (num_strings == 0 && script_source.empty()) {<br class="gmail_msg">
+    // We shouldn't serialize commands if there aren't any, return an empty sp<br class="gmail_msg">
+    // to indicate this.<br class="gmail_msg">
+    return StructuredData::ObjectSP();<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::DictionarySP options_dict_sp(<br class="gmail_msg">
+      new StructuredData::Dictionary());<br class="gmail_msg">
+  options_dict_sp->AddBooleanItem(GetKey(OptionNames::StopOnError),<br class="gmail_msg">
+                                  stop_on_error);<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::ArraySP user_source_sp(new StructuredData::Array());<br class="gmail_msg">
+  if (num_strings > 0) {<br class="gmail_msg"></blockquote><div>Is this necessary?  The loop just won't do anything if it's equal to 0.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    for (size_t i = 0; i < num_strings; i++) {<br class="gmail_msg">
+      StructuredData::StringSP item_sp(<br class="gmail_msg">
+          new StructuredData::String(user_source[i]));<br class="gmail_msg">
+      user_source_sp->AddItem(item_sp);<br class="gmail_msg">
+      options_dict_sp->AddItem(GetKey(OptionNames::UserSource), user_source_sp);<br class="gmail_msg">
+    }<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  if (!script_source.empty()) {<br class="gmail_msg">
+    StructuredData::StringSP item_sp(new StructuredData::String(script_source));<br class="gmail_msg">
+    options_dict_sp->AddItem(GetKey(OptionNames::ScriptSource), user_source_sp);<br class="gmail_msg">
+  }<br class="gmail_msg">
+  return options_dict_sp;<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+BreakpointOptions::CommandData *<br class="gmail_msg">
+BreakpointOptions::CommandData::CreateFromStructuredData(<br class="gmail_msg">
+    StructuredData::Dictionary &options_dict, Error &error) {<br class="gmail_msg">
+  std::string script_source;<br class="gmail_msg">
+  CommandData *data = new CommandData();<br class="gmail_msg">
+  bool success = options_dict.GetValueForKeyAsBoolean(<br class="gmail_msg">
+      GetKey(OptionNames::StopOnError), data->stop_on_error);<br class="gmail_msg">
+<br class="gmail_msg">
+  success = options_dict.GetValueForKeyAsString(<br class="gmail_msg">
+      GetKey(OptionNames::ScriptSource), data->script_source);<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::Array *user_source;<br class="gmail_msg">
+  success = options_dict.GetValueForKeyAsArray(GetKey(OptionNames::UserSource),<br class="gmail_msg">
+                                               user_source);<br class="gmail_msg">
+  if (success) {<br class="gmail_msg"></blockquote><div>Early return.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    size_t num_elems = user_source->GetSize();<br class="gmail_msg">
+    for (size_t i = 0; i < num_elems; i++) {<br class="gmail_msg">
+      std::string elem_string;<br class="gmail_msg">
+      success = user_source->GetItemAtIndexAsString(i, elem_string);<br class="gmail_msg">
+      if (success)<br class="gmail_msg">
+        data->user_source.AppendString(elem_string);<br class="gmail_msg">
+    }<br class="gmail_msg">
+  }<br class="gmail_msg">
+  return data;<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+const char *BreakpointOptions::g_option_names<br class="gmail_msg">
+    [BreakpointOptions::OptionNames::LastOptionName]{<br class="gmail_msg">
+        "ConditionText", "IgnoreCount", "EnabledState", "OneShotState"};<br class="gmail_msg">
+<br class="gmail_msg">
 bool BreakpointOptions::NullCallback(void *baton,<br class="gmail_msg">
                                      StoppointCallbackContext *context,<br class="gmail_msg">
                                      lldb::user_id_t break_id,<br class="gmail_msg">
@@ -36,15 +103,25 @@ bool BreakpointOptions::NullCallback(voi<br class="gmail_msg">
 //----------------------------------------------------------------------<br class="gmail_msg">
 BreakpointOptions::BreakpointOptions()<br class="gmail_msg">
     : m_callback(BreakpointOptions::NullCallback), m_callback_baton_sp(),<br class="gmail_msg">
-      m_callback_is_synchronous(false), m_enabled(true), m_one_shot(false),<br class="gmail_msg">
-      m_ignore_count(0), m_thread_spec_ap(), m_condition_text(),<br class="gmail_msg">
-      m_condition_text_hash(0) {}<br class="gmail_msg">
+      m_baton_is_command_baton(false), m_callback_is_synchronous(false),<br class="gmail_msg">
+      m_enabled(true), m_one_shot(false), m_ignore_count(0), m_thread_spec_ap(),<br class="gmail_msg">
+      m_condition_text(), m_condition_text_hash(0) {}<br class="gmail_msg">
+<br class="gmail_msg">
+BreakpointOptions::BreakpointOptions(const char *condition, bool enabled,<br class="gmail_msg">
+                                     int32_t ignore, bool one_shot)<br class="gmail_msg">
+    : m_callback(nullptr), m_baton_is_command_baton(false),<br class="gmail_msg">
+      m_callback_is_synchronous(false), m_enabled(enabled),<br class="gmail_msg">
+      m_one_shot(one_shot), m_ignore_count(ignore), m_condition_text(condition),<br class="gmail_msg">
+      m_condition_text_hash(0)<br class="gmail_msg">
+<br class="gmail_msg">
+{}<br class="gmail_msg">
<br class="gmail_msg">
 //----------------------------------------------------------------------<br class="gmail_msg">
 // BreakpointOptions copy constructor<br class="gmail_msg">
 //----------------------------------------------------------------------<br class="gmail_msg">
 BreakpointOptions::BreakpointOptions(const BreakpointOptions &rhs)<br class="gmail_msg">
     : m_callback(rhs.m_callback), m_callback_baton_sp(rhs.m_callback_baton_sp),<br class="gmail_msg">
+      m_baton_is_command_baton(rhs.m_baton_is_command_baton),<br class="gmail_msg">
       m_callback_is_synchronous(rhs.m_callback_is_synchronous),<br class="gmail_msg">
       m_enabled(rhs.m_enabled), m_one_shot(rhs.m_one_shot),<br class="gmail_msg">
       m_ignore_count(rhs.m_ignore_count), m_thread_spec_ap() {<br class="gmail_msg">
@@ -61,6 +138,7 @@ const BreakpointOptions &BreakpointOptio<br class="gmail_msg">
 operator=(const BreakpointOptions &rhs) {<br class="gmail_msg">
   m_callback = rhs.m_callback;<br class="gmail_msg">
   m_callback_baton_sp = rhs.m_callback_baton_sp;<br class="gmail_msg">
+  m_baton_is_command_baton = rhs.m_baton_is_command_baton;<br class="gmail_msg">
   m_callback_is_synchronous = rhs.m_callback_is_synchronous;<br class="gmail_msg">
   m_enabled = rhs.m_enabled;<br class="gmail_msg">
   m_one_shot = rhs.m_one_shot;<br class="gmail_msg">
@@ -91,21 +169,109 @@ BreakpointOptions::CopyOptionsNoCallback<br class="gmail_msg">
 //----------------------------------------------------------------------<br class="gmail_msg">
 BreakpointOptions::~BreakpointOptions() = default;<br class="gmail_msg">
<br class="gmail_msg">
+BreakpointOptions *BreakpointOptions::CreateFromStructuredData(<br class="gmail_msg">
+    StructuredData::Dictionary &options_dict, Error &error) {<br class="gmail_msg">
+  bool enabled = true;<br class="gmail_msg">
+  bool one_shot = false;<br class="gmail_msg">
+  int32_t ignore_count = 0;<br class="gmail_msg">
+  std::string condition_text;<br class="gmail_msg">
+<br class="gmail_msg">
+  bool success = options_dict.GetValueForKeyAsBoolean(<br class="gmail_msg">
+      GetKey(OptionNames::EnabledState), enabled);<br class="gmail_msg">
+  if (!success) {<br class="gmail_msg">
+    error.SetErrorStringWithFormat("%s key is not a boolean.",<br class="gmail_msg">
+                                   GetKey(OptionNames::EnabledState));<br class="gmail_msg">
+    return nullptr;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  success = options_dict.GetValueForKeyAsBoolean(<br class="gmail_msg">
+      GetKey(OptionNames::OneShotState), one_shot);<br class="gmail_msg">
+  if (!success) {<br class="gmail_msg">
+    error.SetErrorStringWithFormat("%s key is not a boolean.",<br class="gmail_msg">
+                                   GetKey(OptionNames::OneShotState));<br class="gmail_msg">
+    return nullptr;<br class="gmail_msg">
+  }<br class="gmail_msg">
+  success = options_dict.GetValueForKeyAsInteger(<br class="gmail_msg">
+      GetKey(OptionNames::IgnoreCount), ignore_count);<br class="gmail_msg">
+  if (!success) {<br class="gmail_msg">
+    error.SetErrorStringWithFormat("%s key is not an integer.",<br class="gmail_msg">
+                                   GetKey(OptionNames::IgnoreCount));<br class="gmail_msg">
+    return nullptr;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  BreakpointOptions::CommandData *cmd_data = nullptr;<br class="gmail_msg">
+  StructuredData::Dictionary *cmds_dict;<br class="gmail_msg">
+  success = options_dict.GetValueForKeyAsDictionary(<br class="gmail_msg">
+      CommandData::GetSerializationKey(), cmds_dict);<br class="gmail_msg">
+  if (success && cmds_dict) {<br class="gmail_msg">
+    Error cmds_error;<br class="gmail_msg">
+    cmd_data = CommandData::CreateFromStructuredData(*cmds_dict, cmds_error);<br class="gmail_msg">
+    if (cmds_error.Fail()) {<br class="gmail_msg">
+      error.SetErrorStringWithFormat(<br class="gmail_msg">
+          "Failed to deserialize breakpoint command options: %s.",<br class="gmail_msg">
+          cmds_error.AsCString());<br class="gmail_msg">
+      return nullptr;<br class="gmail_msg">
+    }<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  BreakpointOptions *bp_options = new BreakpointOptions(<br class="gmail_msg">
+      condition_text.c_str(), enabled, ignore_count, one_shot);<br class="gmail_msg">
+  if (cmd_data)<br class="gmail_msg">
+    bp_options->SetCommandDataCallback(cmd_data);<br class="gmail_msg">
+  return bp_options;<br class="gmail_msg">
+}<br class="gmail_msg"></blockquote><div>This should return a unique_ptr.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br class="gmail_msg">
+StructuredData::ObjectSP BreakpointOptions::SerializeToStructuredData() {<br class="gmail_msg">
+  StructuredData::DictionarySP options_dict_sp(<br class="gmail_msg">
+      new StructuredData::Dictionary());<br class="gmail_msg">
+  options_dict_sp->AddBooleanItem(GetKey(OptionNames::EnabledState), m_enabled);<br class="gmail_msg">
+  options_dict_sp->AddBooleanItem(GetKey(OptionNames::OneShotState),<br class="gmail_msg">
+                                  m_one_shot);<br class="gmail_msg">
+  options_dict_sp->AddIntegerItem(GetKey(OptionNames::IgnoreCount),<br class="gmail_msg">
+                                  m_ignore_count);<br class="gmail_msg">
+  options_dict_sp->AddStringItem(GetKey(OptionNames::ConditionText),<br class="gmail_msg">
+                                 m_condition_text);<br class="gmail_msg">
+  if (m_baton_is_command_baton) {<br class="gmail_msg">
+    CommandData *cmd_data =<br class="gmail_msg">
+        static_cast<CommandData *>(m_callback_baton_sp->m_data);<br class="gmail_msg">
+    StructuredData::ObjectSP commands_sp =<br class="gmail_msg">
+        cmd_data->SerializeToStructuredData();<br class="gmail_msg">
+    if (commands_sp) {<br class="gmail_msg">
+      options_dict_sp->AddItem(<br class="gmail_msg">
+          BreakpointOptions::CommandData::GetSerializationKey(), commands_sp);<br class="gmail_msg">
+    }<br class="gmail_msg">
+  }<br class="gmail_msg">
+  // FIXME: Need to serialize thread filter...<br class="gmail_msg">
+  return options_dict_sp;<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
 //------------------------------------------------------------------<br class="gmail_msg">
 // Callbacks<br class="gmail_msg">
 //------------------------------------------------------------------<br class="gmail_msg">
 void BreakpointOptions::SetCallback(BreakpointHitCallback callback,<br class="gmail_msg">
-                                    const BatonSP &callback_baton_sp,<br class="gmail_msg">
+                                    const lldb::BatonSP &callback_baton_sp,<br class="gmail_msg">
                                     bool callback_is_synchronous) {<br class="gmail_msg">
   m_callback_is_synchronous = callback_is_synchronous;<br class="gmail_msg">
   m_callback = callback;<br class="gmail_msg">
   m_callback_baton_sp = callback_baton_sp;<br class="gmail_msg">
+  m_baton_is_command_baton = false;<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+void BreakpointOptions::SetCallback(<br class="gmail_msg">
+    BreakpointHitCallback callback,<br class="gmail_msg">
+    const BreakpointOptions::CommandBatonSP &callback_baton_sp,<br class="gmail_msg">
+    bool callback_is_synchronous) {<br class="gmail_msg">
+  m_callback_is_synchronous = callback_is_synchronous;<br class="gmail_msg">
+  m_callback = callback;<br class="gmail_msg">
+  m_callback_baton_sp = callback_baton_sp;<br class="gmail_msg">
+  m_baton_is_command_baton = true;<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 void BreakpointOptions::ClearCallback() {<br class="gmail_msg">
   m_callback = BreakpointOptions::NullCallback;<br class="gmail_msg">
   m_callback_is_synchronous = false;<br class="gmail_msg">
   m_callback_baton_sp.reset();<br class="gmail_msg">
+  m_baton_is_command_baton = false;<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
 Baton *BreakpointOptions::GetBaton() { return m_callback_baton_sp.get(); }<br class="gmail_msg">
@@ -239,3 +405,49 @@ void BreakpointOptions::CommandBaton::Ge<br class="gmail_msg">
   s->IndentLess();<br class="gmail_msg">
   s->IndentLess();<br class="gmail_msg">
 }<br class="gmail_msg">
+<br class="gmail_msg">
+void BreakpointOptions::SetCommandDataCallback(CommandData *cmd_data) {<br class="gmail_msg">
+  CommandBatonSP baton_sp(new CommandBaton(cmd_data));<br class="gmail_msg">
+  SetCallback(BreakpointOptions::BreakpointOptionsCallbackFunction, baton_sp);<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+bool BreakpointOptions::BreakpointOptionsCallbackFunction(<br class="gmail_msg">
+    void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,<br class="gmail_msg">
+    lldb::user_id_t break_loc_id) {<br class="gmail_msg">
+  bool ret_value = true;<br class="gmail_msg">
+  if (baton == nullptr)<br class="gmail_msg">
+    return true;<br class="gmail_msg">
+<br class="gmail_msg">
+  CommandData *data = (CommandData *)baton;<br class="gmail_msg">
+  StringList &commands = data->user_source;<br class="gmail_msg">
+<br class="gmail_msg">
+  if (commands.GetSize() > 0) {<br class="gmail_msg">
+    ExecutionContext exe_ctx(context->exe_ctx_ref);<br class="gmail_msg">
+    Target *target = exe_ctx.GetTargetPtr();<br class="gmail_msg">
+    if (target) {<br class="gmail_msg">
+      CommandReturnObject result;<br class="gmail_msg">
+      Debugger &debugger = target->GetDebugger();<br class="gmail_msg">
+      // Rig up the results secondary output stream to the debugger's, so the<br class="gmail_msg">
+      // output will come out synchronously<br class="gmail_msg">
+      // if the debugger is set up that way.<br class="gmail_msg">
+<br class="gmail_msg">
+      StreamSP output_stream(debugger.GetAsyncOutputStream());<br class="gmail_msg">
+      StreamSP error_stream(debugger.GetAsyncErrorStream());<br class="gmail_msg">
+      result.SetImmediateOutputStream(output_stream);<br class="gmail_msg">
+      result.SetImmediateErrorStream(error_stream);<br class="gmail_msg">
+<br class="gmail_msg">
+      CommandInterpreterRunOptions options;<br class="gmail_msg">
+      options.SetStopOnContinue(true);<br class="gmail_msg">
+      options.SetStopOnError(data->stop_on_error);<br class="gmail_msg">
+      options.SetEchoCommands(true);<br class="gmail_msg">
+      options.SetPrintResults(true);<br class="gmail_msg">
+      options.SetAddToHistory(false);<br class="gmail_msg">
+<br class="gmail_msg">
+      debugger.GetCommandInterpreter().HandleCommands(commands, &exe_ctx,<br class="gmail_msg">
+                                                      options, result);<br class="gmail_msg">
+      result.GetImmediateOutputStream()->Flush();<br class="gmail_msg">
+      result.GetImmediateErrorStream()->Flush();<br class="gmail_msg">
+    }<br class="gmail_msg">
+  }<br class="gmail_msg">
+  return ret_value;<br class="gmail_msg">
+}<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/source/Breakpoint/BreakpointResolver.cpp<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolver.cpp?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolver.cpp?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/source/Breakpoint/BreakpointResolver.cpp (original)<br class="gmail_msg">
+++ lldb/trunk/source/Breakpoint/BreakpointResolver.cpp Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -15,6 +15,12 @@<br class="gmail_msg">
 // Project includes<br class="gmail_msg">
 #include "lldb/Breakpoint/Breakpoint.h"<br class="gmail_msg">
 #include "lldb/Breakpoint/BreakpointLocation.h"<br class="gmail_msg">
+// Have to include the other breakpoint resolver types here so the static create<br class="gmail_msg">
+// from StructuredData can call them.<br class="gmail_msg">
+#include "lldb/Breakpoint/BreakpointResolverAddress.h"<br class="gmail_msg">
+#include "lldb/Breakpoint/BreakpointResolverFileLine.h"<br class="gmail_msg">
+#include "lldb/Breakpoint/BreakpointResolverFileRegex.h"<br class="gmail_msg">
+#include "lldb/Breakpoint/BreakpointResolverName.h"<br class="gmail_msg">
 #include "lldb/Core/Address.h"<br class="gmail_msg">
 #include "lldb/Core/Log.h"<br class="gmail_msg">
 #include "lldb/Core/ModuleList.h"<br class="gmail_msg">
@@ -32,6 +38,32 @@ using namespace lldb;<br class="gmail_msg">
 //----------------------------------------------------------------------<br class="gmail_msg">
 // BreakpointResolver:<br class="gmail_msg">
 //----------------------------------------------------------------------<br class="gmail_msg">
+const char *BreakpointResolver::g_ty_to_name[] = {"FileAndLine", "Address",<br class="gmail_msg">
+                                                  "SymbolName",  "SourceRegex",<br class="gmail_msg">
+                                                  "Exception",   "Unknown"};<br class="gmail_msg">
+<br class="gmail_msg">
+const char *BreakpointResolver::g_option_names<br class="gmail_msg">
+    [BreakpointResolver::OptionNames::LastOptionName] = {<br class="gmail_msg">
+        "AddressOffset", "Exact",        "FileName",   "Inlines", "Language",<br class="gmail_msg">
+        "LineNumber",    "ModuleName",   "NameMask",   "Offset",  "Regex",<br class="gmail_msg">
+        "SectionName",   "SkipPrologue", "SymbolNames"};<br class="gmail_msg">
+<br class="gmail_msg">
+const char *BreakpointResolver::ResolverTyToName(enum ResolverTy type) {<br class="gmail_msg">
+  if (type > LastKnownResolverType)<br class="gmail_msg">
+    return g_ty_to_name[UnknownResolver];<br class="gmail_msg">
+<br class="gmail_msg">
+  return g_ty_to_name[type];<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+BreakpointResolver::ResolverTy<br class="gmail_msg">
+BreakpointResolver::NameToResolverTy(const char *name) {<br class="gmail_msg"></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">+  for (size_t i = 0; i < LastKnownResolverType; i++) {<br class="gmail_msg">
+    if (strcmp(name, g_ty_to_name[i]) == 0)<br class="gmail_msg"></blockquote><div>Function parameter should be StringRef so we can use operator==.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      return (ResolverTy)i;<br class="gmail_msg">
+  }<br class="gmail_msg">
+  return UnknownResolver;<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
 BreakpointResolver::BreakpointResolver(Breakpoint *bkpt,<br class="gmail_msg">
                                        const unsigned char resolverTy,<br class="gmail_msg">
                                        lldb::addr_t offset)<br class="gmail_msg">
@@ -39,6 +71,98 @@ BreakpointResolver::BreakpointResolver(B<br class="gmail_msg">
<br class="gmail_msg">
 BreakpointResolver::~BreakpointResolver() {}<br class="gmail_msg">
<br class="gmail_msg">
+BreakpointResolverSP BreakpointResolver::CreateFromStructuredData(<br class="gmail_msg">
+    StructuredData::Dictionary &resolver_dict, Error &error) {<br class="gmail_msg"></blockquote><div>const dictionary</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+  BreakpointResolverSP result_sp;<br class="gmail_msg">
+  if (!resolver_dict.IsValid()) {<br class="gmail_msg">
+    error.SetErrorString("Can't deserialize from an invalid data object.");<br class="gmail_msg">
+    return result_sp;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  std::string subclass_name;<br class="gmail_msg">
+<br class="gmail_msg">
+  bool success = resolver_dict.GetValueForKeyAsString(<br class="gmail_msg">
+      GetSerializationSubclassKey(), subclass_name);<br class="gmail_msg">
+<br class="gmail_msg">
+  if (!success) {<br class="gmail_msg">
+    error.SetErrorStringWithFormat(<br class="gmail_msg">
+        "Resolver data missing subclass resolver key");<br class="gmail_msg">
+    return result_sp;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  ResolverTy resolver_type = NameToResolverTy(subclass_name.c_str());<br class="gmail_msg">
+  if (resolver_type == UnknownResolver) {<br class="gmail_msg">
+    error.SetErrorStringWithFormat("Unknown resolver type: %s.",<br class="gmail_msg">
+                                   subclass_name.c_str());<br class="gmail_msg">
+    return result_sp;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::Dictionary *subclass_options = nullptr;<br class="gmail_msg">
+  success = resolver_dict.GetValueForKeyAsDictionary(<br class="gmail_msg">
+      GetSerializationSubclassOptionsKey(), subclass_options);<br class="gmail_msg">
+  if (!success || !subclass_options || !subclass_options->IsValid()) {<br class="gmail_msg">
+    error.SetErrorString("Resolver data missing subclass options key.");<br class="gmail_msg">
+    return result_sp;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  lldb::addr_t offset;<br class="gmail_msg">
+  success = subclass_options->GetValueForKeyAsInteger(<br class="gmail_msg">
+      GetKey(OptionNames::Offset), offset);<br class="gmail_msg">
+  if (!success) {<br class="gmail_msg">
+    error.SetErrorString("Resolver data missing offset options key.");<br class="gmail_msg">
+    return result_sp;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  BreakpointResolver *resolver;<br class="gmail_msg">
+<br class="gmail_msg">
+  switch (resolver_type) {<br class="gmail_msg">
+  case FileLineResolver:<br class="gmail_msg">
+    resolver = BreakpointResolverFileLine::CreateFromStructuredData(<br class="gmail_msg">
+        nullptr, *subclass_options, error);<br class="gmail_msg">
+    break;<br class="gmail_msg">
+  case AddressResolver:<br class="gmail_msg">
+    resolver = BreakpointResolverAddress::CreateFromStructuredData(<br class="gmail_msg">
+        nullptr, *subclass_options, error);<br class="gmail_msg">
+    break;<br class="gmail_msg">
+  case NameResolver:<br class="gmail_msg">
+    resolver = BreakpointResolverName::CreateFromStructuredData(<br class="gmail_msg">
+        nullptr, *subclass_options, error);<br class="gmail_msg">
+    break;<br class="gmail_msg">
+  case FileRegexResolver:<br class="gmail_msg">
+    resolver = BreakpointResolverFileRegex::CreateFromStructuredData(<br class="gmail_msg">
+        nullptr, *subclass_options, error);<br class="gmail_msg">
+    break;<br class="gmail_msg">
+  case ExceptionResolver:<br class="gmail_msg">
+    error.SetErrorString("Exception resolvers are hard.");<br class="gmail_msg">
+    break;<br class="gmail_msg">
+  default:<br class="gmail_msg">
+    llvm_unreachable("Should never get an unresolvable resolver type.");<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  if (!error.Success()) {<br class="gmail_msg">
+    return result_sp;<br class="gmail_msg">
+  } else {<br class="gmail_msg">
+    // Add on the global offset option:<br class="gmail_msg">
+    resolver->SetOffset(offset);<br class="gmail_msg">
+    return BreakpointResolverSP(resolver);<br class="gmail_msg">
+  }<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+StructuredData::DictionarySP BreakpointResolver::WrapOptionsDict(<br class="gmail_msg">
+    StructuredData::DictionarySP options_dict_sp) {<br class="gmail_msg">
+  if (!options_dict_sp || !options_dict_sp->IsValid())<br class="gmail_msg">
+    return StructuredData::DictionarySP();<br class="gmail_msg">
+<br class="gmail_msg">
+  StructuredData::DictionarySP type_dict_sp(new StructuredData::Dictionary());<br class="gmail_msg">
+  type_dict_sp->AddStringItem(GetSerializationSubclassKey(), GetResolverName());<br class="gmail_msg">
+  type_dict_sp->AddItem(GetSerializationSubclassOptionsKey(), options_dict_sp);<br class="gmail_msg">
+<br class="gmail_msg">
+  // Add the m_offset to the dictionary:<br class="gmail_msg">
+  options_dict_sp->AddIntegerItem(GetKey(OptionNames::Offset), m_offset);<br class="gmail_msg">
+<br class="gmail_msg">
+  return type_dict_sp;<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
 void BreakpointResolver::SetBreakpoint(Breakpoint *bkpt) {<br class="gmail_msg">
   m_breakpoint = bkpt;<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/source/Breakpoint/BreakpointResolverAddress.cpp<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolverAddress.cpp?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolverAddress.cpp?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/source/Breakpoint/BreakpointResolverAddress.cpp (original)<br class="gmail_msg">
+++ lldb/trunk/source/Breakpoint/BreakpointResolverAddress.cpp Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -17,6 +17,7 @@<br class="gmail_msg">
 #include "lldb/Breakpoint/BreakpointLocation.h"<br class="gmail_msg">
 #include "lldb/Core/Log.h"<br class="gmail_msg">
 #include "lldb/Core/Module.h"<br class="gmail_msg">
+#include "lldb/Core/Section.h"<br class="gmail_msg">
 #include "lldb/Core/StreamString.h"<br class="gmail_msg">
 #include "lldb/Target/Process.h"<br class="gmail_msg">
 #include "lldb/Target/Target.h"<br class="gmail_msg">
@@ -41,6 +42,62 @@ BreakpointResolverAddress::BreakpointRes<br class="gmail_msg">
<br class="gmail_msg">
 BreakpointResolverAddress::~BreakpointResolverAddress() {}<br class="gmail_msg">
<br class="gmail_msg">
+BreakpointResolver *BreakpointResolverAddress::CreateFromStructuredData(<br class="gmail_msg">
+    Breakpoint *bkpt, StructuredData::Dictionary &options_dict, Error &error) {<br class="gmail_msg">
+  std::string module_name;<br class="gmail_msg">
+  lldb::addr_t addr_offset;<br class="gmail_msg">
+  FileSpec module_filespec;<br class="gmail_msg">
+  bool success;<br class="gmail_msg">
+<br class="gmail_msg">
+  success = options_dict.GetValueForKeyAsInteger(<br class="gmail_msg">
+      GetKey(OptionNames::AddressOffset), addr_offset);<br class="gmail_msg">
+  if (!success) {<br class="gmail_msg">
+    error.SetErrorString("BRFL::CFSD: Couldn't find address offset entry.");<br class="gmail_msg">
+    return nullptr;<br class="gmail_msg">
+  }<br class="gmail_msg">
+  Address address(addr_offset);<br class="gmail_msg">
+<br class="gmail_msg">
+  success = options_dict.HasKey(GetKey(OptionNames::ModuleName));<br class="gmail_msg">
+  if (success) {<br class="gmail_msg">
+    success = options_dict.GetValueForKeyAsString(<br class="gmail_msg">
+        GetKey(OptionNames::ModuleName), module_name);<br class="gmail_msg">
+    if (!success) {<br class="gmail_msg">
+      error.SetErrorString("BRA::CFSD: Couldn't read module name entry.");<br class="gmail_msg">
+      return nullptr;<br class="gmail_msg">
+    }<br class="gmail_msg">
+    module_filespec.SetFile(module_name.c_str(), false);<br class="gmail_msg">
+  }<br class="gmail_msg">
+  return new BreakpointResolverAddress(bkpt, address, module_filespec);<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+StructuredData::ObjectSP<br class="gmail_msg">
+BreakpointResolverAddress::SerializeToStructuredData() {<br class="gmail_msg">
+  StructuredData::DictionarySP options_dict_sp(<br class="gmail_msg">
+      new StructuredData::Dictionary());<br class="gmail_msg">
+  SectionSP section_sp = m_addr.GetSection();<br class="gmail_msg">
+  if (section_sp) {<br class="gmail_msg">
+    ModuleSP module_sp = section_sp->GetModule();<br class="gmail_msg">
+    ConstString module_name;<br class="gmail_msg">
+    if (module_sp)<br class="gmail_msg">
+      module_name.SetCString(module_name.GetCString());<br class="gmail_msg">
+<br class="gmail_msg">
+    options_dict_sp->AddStringItem(GetKey(OptionNames::ModuleName),<br class="gmail_msg">
+                                   module_name.GetCString());<br class="gmail_msg">
+    options_dict_sp->AddIntegerItem(GetKey(OptionNames::AddressOffset),<br class="gmail_msg">
+                                    m_addr.GetOffset());<br class="gmail_msg">
+  } else {<br class="gmail_msg">
+    options_dict_sp->AddIntegerItem(GetKey(OptionNames::AddressOffset),<br class="gmail_msg">
+                                    m_addr.GetOffset());<br class="gmail_msg">
+    if (m_module_filespec) {<br class="gmail_msg">
+      options_dict_sp->AddStringItem(GetKey(OptionNames::ModuleName),<br class="gmail_msg">
+                                     m_module_filespec.GetPath());<br class="gmail_msg">
+    }<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  return WrapOptionsDict(options_dict_sp);<br class="gmail_msg">
+  return StructuredData::ObjectSP();<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
 void BreakpointResolverAddress::ResolveBreakpoint(SearchFilter &filter) {<br class="gmail_msg">
   // If the address is not section relative, then we should not try to<br class="gmail_msg">
   // re-resolve it, it is just some<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/source/Breakpoint/BreakpointResolverFileLine.cpp<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolverFileLine.cpp?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolverFileLine.cpp?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/source/Breakpoint/BreakpointResolverFileLine.cpp (original)<br class="gmail_msg">
+++ lldb/trunk/source/Breakpoint/BreakpointResolverFileLine.cpp Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -36,6 +36,77 @@ BreakpointResolverFileLine::BreakpointRe<br class="gmail_msg">
<br class="gmail_msg">
 BreakpointResolverFileLine::~BreakpointResolverFileLine() {}<br class="gmail_msg">
<br class="gmail_msg">
+BreakpointResolver *BreakpointResolverFileLine::CreateFromStructuredData(<br class="gmail_msg">
+    Breakpoint *bkpt, StructuredData::Dictionary &options_dict, Error &error) {<br class="gmail_msg">
+  std::string filename;<br class="gmail_msg">
+  uint32_t line_no;<br class="gmail_msg">
+  bool check_inlines;<br class="gmail_msg">
+  bool skip_prologue;<br class="gmail_msg">
+  bool exact_match;<br class="gmail_msg">
+  bool success;<br class="gmail_msg">
+<br class="gmail_msg">
+  lldb::addr_t offset = 0;<br class="gmail_msg">
+<br class="gmail_msg">
+  success = options_dict.GetValueForKeyAsString(GetKey(OptionNames::FileName),<br class="gmail_msg">
+                                                filename);<br class="gmail_msg">
+  if (!success) {<br class="gmail_msg">
+    error.SetErrorString("BRFL::CFSD: Couldn't find filename entry.");<br class="gmail_msg">
+    return nullptr;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  success = options_dict.GetValueForKeyAsInteger(<br class="gmail_msg">
+      GetKey(OptionNames::LineNumber), line_no);<br class="gmail_msg">
+  if (!success) {<br class="gmail_msg">
+    error.SetErrorString("BRFL::CFSD: Couldn't find line number entry.");<br class="gmail_msg">
+    return nullptr;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  success = options_dict.GetValueForKeyAsBoolean(GetKey(OptionNames::Inlines),<br class="gmail_msg">
+                                                 check_inlines);<br class="gmail_msg">
+  if (!success) {<br class="gmail_msg">
+    error.SetErrorString("BRFL::CFSD: Couldn't find check inlines entry.");<br class="gmail_msg">
+    return nullptr;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  success = options_dict.GetValueForKeyAsBoolean(<br class="gmail_msg">
+      GetKey(OptionNames::SkipPrologue), skip_prologue);<br class="gmail_msg">
+  if (!success) {<br class="gmail_msg">
+    error.SetErrorString("BRFL::CFSD: Couldn't find skip prologue entry.");<br class="gmail_msg">
+    return nullptr;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  success = options_dict.GetValueForKeyAsBoolean(<br class="gmail_msg">
+      GetKey(OptionNames::ExactMatch), exact_match);<br class="gmail_msg">
+  if (!success) {<br class="gmail_msg">
+    error.SetErrorString("BRFL::CFSD: Couldn't find exact match entry.");<br class="gmail_msg">
+    return nullptr;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  FileSpec file_spec(filename.c_str(), false);<br class="gmail_msg">
+<br class="gmail_msg">
+  return new BreakpointResolverFileLine(bkpt, file_spec, line_no, offset,<br class="gmail_msg">
+                                        check_inlines, skip_prologue,<br class="gmail_msg">
+                                        exact_match);<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+StructuredData::ObjectSP<br class="gmail_msg">
+BreakpointResolverFileLine::SerializeToStructuredData() {<br class="gmail_msg">
+  StructuredData::DictionarySP options_dict_sp(<br class="gmail_msg">
+      new StructuredData::Dictionary());<br class="gmail_msg">
+<br class="gmail_msg">
+  options_dict_sp->AddStringItem(GetKey(OptionNames::FileName),<br class="gmail_msg">
+                                 m_file_spec.GetPath());<br class="gmail_msg">
+  options_dict_sp->AddIntegerItem(GetKey(OptionNames::LineNumber),<br class="gmail_msg">
+                                  m_line_number);<br class="gmail_msg">
+  options_dict_sp->AddBooleanItem(GetKey(OptionNames::Inlines), m_inlines);<br class="gmail_msg">
+  options_dict_sp->AddBooleanItem(GetKey(OptionNames::SkipPrologue),<br class="gmail_msg">
+                                  m_skip_prologue);<br class="gmail_msg">
+  options_dict_sp->AddBooleanItem(GetKey(OptionNames::ExactMatch),<br class="gmail_msg">
+                                  m_exact_match);<br class="gmail_msg">
+<br class="gmail_msg">
+  return WrapOptionsDict(options_dict_sp);<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
 Searcher::CallbackReturn<br class="gmail_msg">
 BreakpointResolverFileLine::SearchCallback(SearchFilter &filter,<br class="gmail_msg">
                                            SymbolContext &context,<br class="gmail_msg">
<br class="gmail_msg">
Modified: lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp?rev=281273&r1=281272&r2=281273&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp?rev=281273&r1=281272&r2=281273&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp (original)<br class="gmail_msg">
+++ lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp Mon Sep 12 18:10:56 2016<br class="gmail_msg">
@@ -36,6 +36,70 @@ BreakpointResolverFileRegex::BreakpointR<br class="gmail_msg">
<br class="gmail_msg">
 BreakpointResolverFileRegex::~BreakpointResolverFileRegex() {}<br class="gmail_msg">
<br class="gmail_msg">
+BreakpointResolver *BreakpointResolverFileRegex::CreateFromStructuredData(<br class="gmail_msg">
+    Breakpoint *bkpt, StructuredData::Dictionary &options_dict, Error &error) {<br class="gmail_msg">
+  bool success;<br class="gmail_msg">
+<br class="gmail_msg">
+  std::string regex_string;<br class="gmail_msg">
+  success = options_dict.GetValueForKeyAsString(<br class="gmail_msg">
+      GetKey(OptionNames::RegexString), regex_string);<br class="gmail_msg">
+  if (!success) {<br class="gmail_msg">
+    error.SetErrorString("BRFR::CFSD: Couldn't find regex entry.");<br class="gmail_msg">
+    return nullptr;<br class="gmail_msg">
+  }<br class="gmail_msg">
+  RegularExpression regex(regex_string.c_str());<br class="gmail_msg">
+<br class="gmail_msg">
+  bool exact_match;<br class="gmail_msg">
+  success = options_dict.GetValueForKeyAsBoolean(<br class="gmail_msg">
+      GetKey(OptionNames::ExactMatch), exact_match);<br class="gmail_msg">
+  if (!success) {<br class="gmail_msg">
+    error.SetErrorString("BRFL::CFSD: Couldn't find exact match entry.");<br class="gmail_msg">
+    return nullptr;<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  // The names array is optional:<br class="gmail_msg">
+  std::unordered_set<std::string> names_set;<br class="gmail_msg">
+  StructuredData::Array *names_array;<br class="gmail_msg">
+  success = options_dict.GetValueForKeyAsArray(<br class="gmail_msg">
+      GetKey(OptionNames::SymbolNameArray), names_array);<br class="gmail_msg">
+  if (success && names_array) {<br class="gmail_msg">
+    size_t num_names = names_array->GetSize();<br class="gmail_msg">
+    for (size_t i = 0; i < num_names; i++) {<br class="gmail_msg">
+      std::string name;<br class="gmail_msg">
+      success = names_array->GetItemAtIndexAsString(i, name);<br class="gmail_msg">
+      if (!success) {<br class="gmail_msg">
+        error.SetErrorStringWithFormat(<br class="gmail_msg">
+            "BRFR::CFSD: Malformed element %zu in the names array.", i);<br class="gmail_msg">
+        return nullptr;<br class="gmail_msg">
+      }<br class="gmail_msg">
+      names_set.insert(name);<br class="gmail_msg">
+    }<br class="gmail_msg">
+  }<br class="gmail_msg">
+<br class="gmail_msg">
+  return new BreakpointResolverFileRegex(bkpt, regex, names_set, exact_match);<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
+StructuredData::ObjectSP<br class="gmail_msg">
+BreakpointResolverFileRegex::SerializeToStructuredData() {<</blockquote><div><br></div><div><br></div><div>Various comments inline.  </div><div><br></div><div>Also it would be nice if we could move towards submitting tests at the same time we submit functionality.  I'm not a fan of submitting tests at a later date, and I believe it's also against LLVM guidelines.</div></div></div>