<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Mon, Sep 12, 2016 at 5:31 PM Jim Ingham <<a href="mailto:jingham@apple.com">jingham@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br class="gmail_msg">
> On Sep 12, 2016, at 4:57 PM, Zachary Turner <<a href="mailto:zturner@google.com" class="gmail_msg" target="_blank">zturner@google.com</a>> wrote:<br class="gmail_msg">
><br class="gmail_msg">
><br class="gmail_msg">
><br class="gmail_msg">
> On Mon, Sep 12, 2016 at 4:19 PM Jim Ingham via lldb-commits <<a href="mailto:lldb-commits@lists.llvm.org" class="gmail_msg" target="_blank">lldb-commits@lists.llvm.org</a>> wrote:<br class="gmail_msg">
> 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"; }<br class="gmail_msg">
>    //------------------------------------------------------------------<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">
> This should probably return a unique_ptr to prevent memory leaks.  And the dictionary should be const.<br class="gmail_msg">
><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">
> +  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">
> 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><br class="gmail_msg">
<br class="gmail_msg">
I specifically overload the "Add baton" to make a distinction between CommandBatonSP's - which I know about and can serialize - and random pointer holding batons which will most likely be meaningless from run to run.  So I don't think I want this.<br class="gmail_msg">
<br class="gmail_msg">
><br class="gmail_msg">
>    //------------------------------------------------------------------<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">
> StringRef condition<br class="gmail_msg">
><br class="gmail_msg">
><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">
> unique_ptr<BreakpointOptions><br class="gmail_msg">
><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 "BKPTOptions"; }<br class="gmail_msg">
> StringRef GetSerializationKey<br class="gmail_msg">
><br class="gmail_msg">
> +<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">
> static StringRef GetKey().<br class="gmail_msg">
><br class="gmail_msg">
> Also this can be an enum class if you use llvm/ADT/BitmaskEnu.h<br class="gmail_msg">
><br class="gmail_msg">
> +<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">
> More StringRef opportunities.  This makes it very convenient to do comparisons and searching on the return values without resorting to CRT functions.<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">
> +  //------------------------------------------------------------------<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">
> A reference to a shared_ptr<> seems odd, is this intended?<br class="gmail_msg">
><br class="gmail_msg">
> +<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">
>  };<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">
> Not a big deal since this is a short function, but LLVM style is to use early return on failure.<br class="gmail_msg">
><br class="gmail_msg">
> +        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">
> const FileSpec<br class="gmail_msg">
><br class="gmail_msg">
>  };<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">
> Another shared_ptr reference, shouldn't we just pass the shared_ptr by value or the value by reference?<br class="gmail_msg">
><br class="gmail_msg">
> +<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">
> +    filter_sp.reset(<br class="gmail_msg">
> +        new SearchFilterForUnconstrainedSearches(target.shared_from_this()));<br class="gmail_msg">
> 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.<br class="gmail_msg">
<br class="gmail_msg">
We use this pattern in a bunch of places.  If we want to make a pass and change all of them, that's fine with me.  But doing it piecemeal seems less useful.<br class="gmail_msg">
<br class="gmail_msg">
><br class="gmail_msg">
><br class="gmail_msg">
> +  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">
> const member function?<br class="gmail_msg">
><br class="gmail_msg">
><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">
> Good opportunity to use a StringRef (for both the parameter as well as ThreadSpec::GetName())<br class="gmail_msg">
><br class="gmail_msg">
><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">
> StringRef.<br class="gmail_msg">
><br class="gmail_msg">
><br class="gmail_msg">
>  void Breakpoint::SetQueueName(const char *queue_name) {<br class="gmail_msg">
> StringRef.<br class="gmail_msg">
><br class="gmail_msg">
> -  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 class="gmail_msg">
> StringRef<br class="gmail_msg">
><br class="gmail_msg">
><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()->GetQueueName();<br class="gmail_msg">
> +    return m_options_up->GetThreadSpecNoCreate()->GetQueueName();<br class="gmail_msg">
>  }<br class="gmail_msg">
><br class="gmail_msg">
>  void Breakpoint::SetCondition(const char *condition) {<br class="gmail_msg">
> StringRef.<br class="gmail_msg">
><br class="gmail_msg">
> -  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">
> StringRef.<br class="gmail_msg">
><br class="gmail_msg">
><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">
><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">
> Is this necessary?  The loop just won't do anything if it's equal to 0.<br class="gmail_msg">
<br class="gmail_msg">
Thanks.  That was part of a previous implementation of not emitting anything when there were no commands.<br class="gmail_msg">
<br class="gmail_msg">
><br class="gmail_msg">
> +    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">
> Early return.<br class="gmail_msg">
><br class="gmail_msg">
> +    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">
> This should return a unique_ptr.<br class="gmail_msg">
><br class="gmail_msg">
> +<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">
> +  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">
> Function parameter should be StringRef so we can use operator==.<br class="gmail_msg">
<br class="gmail_msg">
That seems silly.  strcmp is a perfectly good function, and I know this is only ever going to get compared for equality.  What would I gain?<br class="gmail_msg"></blockquote><div>Immediately, very little.  A small amount of performance, since comparing StringRefs is faster than comparing null terminated stings, since the length is stored with the string it can use memcmp instead of strcmp.</div><div><br></div><div>From a big picture perspective, quite a lot IMO.  StringRef has numerous methods which are extremely useful and not easy to reproduce correctly.  Also, If you do the comparison many times, you only pay for the length computation once.  I've gone through and changed code that took 20 lines to code that took only 3 lines because I was able to utilize the member functions of StringRef.  I would flip the question around: If it can be a StringRef, why *not* make it one?  Why prefer unsafe C functions over safer, more modern counterparts?</div><div><br></div><div><span style="font-family:arial,sans-serif">> Thanks for the comments.</span><br style="font-family:arial,sans-serif"><span style="font-family:arial,sans-serif">><span class="inbox-inbox-Apple-converted-space"> </span></span>  <br style="font-family:arial,sans-serif"><span style="font-family:arial,sans-serif">><span class="inbox-inbox-Apple-converted-space"> </span></span>  <span style="font-family:arial,sans-serif">I don't see the benefit of using StringRef's to return all the key names.  I'm generally only ever going to pass them to the StructuredData API's, which makes them into StringRef's transparently on the way in.  How would building StringRefs help here?</span><br style="font-family:arial,sans-serif"><br style="font-family:arial,sans-serif"><span style="font-family:arial,sans-serif">><span class="inbox-inbox-Apple-converted-space"> </span></span>  <span style="font-family:arial,sans-serif">You also suggested changing a bunch of BreakpointOption API to return StringRef's.  OTOH this CL just mechanically changed from m_options to m_options_up, so changing the API was not part of the patches intent.  OTOH most of these options (condition, thread name, etc) can take and return NULL strings.  I didn't think StringRef's handled null strings well, was I wrong about that?  And again, what would I gain by making these StringRef's?  I'm just going to stash them away in some storage the object owns, and I'm not going to ever share the storage with the caller.  So least common denominator (const char *) seems a better choice here.  If the caller wants a StringRef they are welcome to make one.</span><br style="font-family:arial,sans-serif"><br></div><div>Right, but making the StringRef incurs a length computation.  That's not something you want to do over and over.  It's guaranteed someone somewhere is going to compute the length, so it's better to do it once upfront, and allow everyone else to never have to do it again.</div><div><br></div><div>On the other hand, using a StringRef gives you many advantages.  Unless you know every possible way in which these strings will ever be used, who knows what someone might want to do with it?  What if someone wants to take one of these strings, check if some other string starts with it, and chop it off if so?  You could either write:</div><div><br></div><div>if (strncmp(GetName(), str.c_str(), strlen(GetName()) == 0)</div><div>    str2 = str.substr(strlen(GetName()));</div><div><br></div><div>which there's a good chance will be either wrong or suboptimal, or you could write:</div><div><br></div><div>str.consume_front(GetName());</div><div><br></div><div>which is both easier to understand, obviously correct, and optimal from a performance standpoint.</div><div><br></div><div>const char* should almost never be used for anything unless you absolutely must interface with a C-api for which there is no good equivalent on StringRef (very rare).</div><div><br></div><div>Since we currently use const char* in many places, this sometimes makies interfacing difficult, but as more common classes move to StringRef, this will go away and almost all code will become faster and easier to understand.</div><div><br></div><div>You are right that StringRefs don't handle null strings, but they do handle empty strings, and it's not common that empty and null need to be treated as distinct values.</div></div></div>