[Lldb-commits] [lldb] r264379 - Use Clang's FixItHints to correct expressions with "trivial" mistakes (e.g. "." for "->".)

Jim Ingham via lldb-commits lldb-commits at lists.llvm.org
Fri Mar 25 10:22:17 PDT 2016


Quoting from the original submission notes below:

> This feature is controlled by an expression command option, a target property and the
> > SBExpressionOptions setting.

To be more explicit, if you don't want this behavior, put:

settings set target.auto-apply-fixits no

in your .lldbinit, or replace your print alias with  "expr -X 0 --".  The test suite test I added shows how to do this from the Python side. 

And:

>  At present the fixits are applied silently.  The next step
> > is to tell the user about the applied fixit.

Once I figure out how to tell the user about the applied fixit, I'll add an option to just tell about it (and put the fixed expression in the history buffer.)  But to do that I have to separate the user's expression out of all the goo we wrap it in, which isn't something we've done before.

Jim


> On Mar 24, 2016, at 7:48 PM, Zachary Turner <zturner at google.com> wrote:
> 
> I can see how it would be useful, but i do think it should be possible to disable and/or warn about 
> On Thu, Mar 24, 2016 at 7:40 PM Jason Molenda <jmolenda at apple.com> wrote:
> The specific example Jim gave (./->) is a very common complaint of people coming from gdb.
> 
> gdb's hand-rolled parser would realize that when you -> on an object, that doesn't make sense and silently correct it to . for you.  In practice, when you're examining local variables, you often don't remember whether something is an object or a pointer to an object - especially when you are dereferencing down a few levels (e.g. "p myvar->subelem.valcontainer->value").
> 
> Because lldb uses clang, we have to follow the rules of the language (for the most part) - this is likely the only way we could accomplish something similar in lldb.
> 
> 
> > On Mar 24, 2016, at 7:23 PM, Zachary Turner via lldb-commits <lldb-commits at lists.llvm.org> wrote:
> >
> > This seems like an odd thing to do by default. Is there going to be a setting to turn this off? Seems to me like off should be default
> >
> > An enumerated setting would be even nicer, where one option is "report" that just doesn't apply any FixIts, but prints a message saying "did you mean Foo->bar()?"
> > On Thu, Mar 24, 2016 at 7:02 PM Jim Ingham via lldb-commits <lldb-commits at lists.llvm.org> wrote:
> > Author: jingham
> > Date: Thu Mar 24 20:57:14 2016
> > New Revision: 264379
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=264379&view=rev
> > Log:
> > Use Clang's FixItHints to correct expressions with "trivial" mistakes (e.g. "." for "->".)
> > This feature is controlled by an expression command option, a target property and the
> > SBExpressionOptions setting.  FixIt's are only applied to UserExpressions, not UtilityFunctions,
> > those you have to get right when you make them.
> >
> > This is just a first stage.  At present the fixits are applied silently.  The next step
> > is to tell the user about the applied fixit.
> >
> > <rdar://problem/25351938>
> >
> > Added:
> >     lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/
> >     lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/Makefile
> >     lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/TestFixIts.py
> >     lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/main.cpp
> >     lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
> > Modified:
> >     lldb/trunk/include/lldb/API/SBExpressionOptions.h
> >     lldb/trunk/include/lldb/Expression/DiagnosticManager.h
> >     lldb/trunk/include/lldb/Expression/ExpressionParser.h
> >     lldb/trunk/include/lldb/Target/Target.h
> >     lldb/trunk/lldb.xcodeproj/project.pbxproj
> >     lldb/trunk/scripts/interface/SBExpressionOptions.i
> >     lldb/trunk/source/API/SBExpressionOptions.cpp
> >     lldb/trunk/source/Commands/CommandObjectExpression.cpp
> >     lldb/trunk/source/Commands/CommandObjectExpression.h
> >     lldb/trunk/source/Expression/DiagnosticManager.cpp
> >     lldb/trunk/source/Expression/UserExpression.cpp
> >     lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
> >     lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
> >     lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
> >     lldb/trunk/source/Target/Target.cpp
> >
> > Modified: lldb/trunk/include/lldb/API/SBExpressionOptions.h
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBExpressionOptions.h?rev=264379&r1=264378&r2=264379&view=diff
> > ==============================================================================
> > --- lldb/trunk/include/lldb/API/SBExpressionOptions.h (original)
> > +++ lldb/trunk/include/lldb/API/SBExpressionOptions.h Thu Mar 24 20:57:14 2016
> > @@ -110,6 +110,12 @@ public:
> >
> >      void
> >      SetPrefix (const char *prefix);
> > +
> > +    void
> > +    SetAutoApplyFixIts(bool b = true);
> > +
> > +    bool
> > +    GetAutoApplyFixIts();
> >
> >  protected:
> >
> >
> > Modified: lldb/trunk/include/lldb/Expression/DiagnosticManager.h
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/DiagnosticManager.h?rev=264379&r1=264378&r2=264379&view=diff
> > ==============================================================================
> > --- lldb/trunk/include/lldb/Expression/DiagnosticManager.h (original)
> > +++ lldb/trunk/include/lldb/Expression/DiagnosticManager.h Thu Mar 24 20:57:14 2016
> > @@ -38,15 +38,82 @@ enum DiagnosticSeverity
> >
> >  const uint32_t LLDB_INVALID_COMPILER_ID = UINT32_MAX;
> >
> > -struct Diagnostic
> > +class Diagnostic
> >  {
> > -    std::string message;
> > -    uint32_t compiler_id; // Compiler-specific diagnostic ID
> > -    DiagnosticSeverity severity;
> > -    DiagnosticOrigin origin;
> > +friend class DiagnosticManager;
> > +
> > +public:
> > +    DiagnosticOrigin getKind() const { return m_origin; }
> > +
> > +    static bool classof(const Diagnostic *diag)
> > +    {
> > +        DiagnosticOrigin kind =  diag->getKind();
> > +        switch (kind)
> > +        {
> > +            case eDiagnosticOriginUnknown:
> > +            case eDiagnosticOriginLLDB:
> > +            case eDiagnosticOriginGo:
> > +            case eDiagnosticOriginLLVM:
> > +                return true;
> > +            case eDiagnosticOriginClang:
> > +            case eDiagnosticOriginSwift:
> > +                return false;
> > +        }
> > +    }
> > +
> > +    Diagnostic(const char *message, DiagnosticSeverity severity, DiagnosticOrigin origin, uint32_t compiler_id) :
> > +            m_message(message),
> > +            m_severity(severity),
> > +            m_origin(origin),
> > +            m_compiler_id(compiler_id)
> > +    {
> > +    }
> > +
> > +    Diagnostic(const Diagnostic &rhs) :
> > +        m_message(rhs.m_message),
> > +        m_severity(rhs.m_severity),
> > +        m_origin(rhs.m_origin),
> > +        m_compiler_id(rhs.m_compiler_id)
> > +    {
> > +    }
> > +
> > +    virtual ~Diagnostic() = default;
> > +
> > +    virtual bool HasFixIts () const { return false; }
> > +
> > +    DiagnosticSeverity
> > +    GetSeverity() const
> > +    {
> > +        return m_severity;
> > +    }
> > +
> > +    uint32_t
> > +    GetCompilerID() const
> > +    {
> > +        return m_compiler_id;
> > +    }
> > +
> > +    const char *
> > +    GetMessage() const
> > +    {
> > +        return m_message.c_str();
> > +    }
> > +
> > +    void AppendMessage(const char *message, bool precede_with_newline = true)
> > +    {
> > +        if (precede_with_newline)
> > +            m_message.push_back('\n');
> > +        m_message.append(message);
> > +    }
> > +
> > +protected:
> > +    std::string m_message;
> > +    DiagnosticSeverity m_severity;
> > +    DiagnosticOrigin m_origin;
> > +    uint32_t m_compiler_id; // Compiler-specific diagnostic ID
> >  };
> >
> > -typedef std::vector<Diagnostic> DiagnosticList;
> > +typedef std::vector<Diagnostic *> DiagnosticList;
> >
> >  class DiagnosticManager
> >  {
> > @@ -55,19 +122,47 @@ public:
> >      Clear()
> >      {
> >          m_diagnostics.clear();
> > +        m_auto_apply_fixits = true;
> > +        m_fixed_expression.clear();
> >      }
> >
> > +    // The diagnostic manager holds a list of diagnostics, which are owned by the manager.
> >      const DiagnosticList &
> >      Diagnostics()
> >      {
> >          return m_diagnostics;
> >      }
> > -
> > +
> > +    ~DiagnosticManager()
> > +    {
> > +        for (Diagnostic *diag : m_diagnostics)
> > +        {
> > +            delete diag;
> > +        }
> > +    }
> > +
> > +    bool
> > +    HasFixIts()
> > +    {
> > +        for (Diagnostic *diag : m_diagnostics)
> > +        {
> > +            if (diag->HasFixIts())
> > +                return true;
> > +        }
> > +        return false;
> > +    }
> > +
> >      void
> >      AddDiagnostic(const char *message, DiagnosticSeverity severity, DiagnosticOrigin origin,
> >                    uint32_t compiler_id = LLDB_INVALID_COMPILER_ID)
> >      {
> > -        m_diagnostics.push_back({std::string(message), compiler_id, severity, origin});
> > +        m_diagnostics.push_back(new Diagnostic(message, severity, origin, compiler_id));
> > +    }
> > +
> > +    void
> > +    AddDiagnostic(Diagnostic *diagnostic)
> > +    {
> > +        m_diagnostics.push_back(diagnostic);
> >      }
> >
> >      size_t
> > @@ -80,11 +175,10 @@ public:
> >      {
> >          if (m_diagnostics.size())
> >          {
> > -            m_diagnostics.back().message.push_back('\n');
> > -            m_diagnostics.back().message.append(cstr);
> > +            m_diagnostics.back()->AppendMessage(cstr);
> >          }
> >      }
> > -
> > +
> >      // Returns a string containing errors in this format:
> >      //
> >      // "error: error text\n
> > @@ -95,9 +189,36 @@ public:
> >
> >      void
> >      Dump(Log *log);
> > +
> > +    const std::string &
> > +    GetFixedExpression()
> > +    {
> > +        return m_fixed_expression;
> > +    }
> > +
> > +    // Moves fixed_expression to the internal storage.
> > +    void
> > +    SetFixedExpression(std::string fixed_expression)
> > +    {
> > +        m_fixed_expression = std::move(fixed_expression);
> > +        fixed_expression.clear();
> > +    }
> > +
> > +    void
> > +    SetAutoApplyFixIts(bool auto_apply)
> > +    {
> > +        m_auto_apply_fixits = auto_apply;
> > +    }
> > +
> > +    bool ShouldAutoApplyFixIts()
> > +    {
> > +        return m_auto_apply_fixits;
> > +    }
> >
> > -private:
> > +protected:
> >      DiagnosticList m_diagnostics;
> > +    std::string m_fixed_expression;
> > +    bool m_auto_apply_fixits = true;
> >  };
> >  }
> >
> >
> > Modified: lldb/trunk/include/lldb/Expression/ExpressionParser.h
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ExpressionParser.h?rev=264379&r1=264378&r2=264379&view=diff
> > ==============================================================================
> > --- lldb/trunk/include/lldb/Expression/ExpressionParser.h (original)
> > +++ lldb/trunk/include/lldb/Expression/ExpressionParser.h Thu Mar 24 20:57:14 2016
> > @@ -58,7 +58,7 @@ public:
> >      /// wrap the expression in anything at all.
> >      ///
> >      /// @param[in] diagnostic_manager
> > -    ///     The stream to print errors to.
> > +    ///     The diagnostic manager in which to store the errors and warnings.
> >      ///
> >      /// @return
> >      ///     The number of errors encountered during parsing.  0 means
> > @@ -66,6 +66,23 @@ public:
> >      //------------------------------------------------------------------
> >      virtual unsigned
> >      Parse(DiagnosticManager &diagnostic_manager) = 0;
> > +
> > +    //------------------------------------------------------------------
> > +    /// Try to use the FixIts in the diagnostic_manager to rewrite the
> > +    /// expression.  If successful, the rewritten expression is stored
> > +    /// in the diagnostic_manager, get it out with GetFixedExpression.
> > +    ///
> > +    /// @param[in] diagnostic_manager
> > +    ///     The diagnostic manager containing fixit's to apply.
> > +    ///
> > +    /// @return
> > +    ///     \b true if the rewrite was successful, \b false otherwise.
> > +    //------------------------------------------------------------------
> > +    virtual bool
> > +    RewriteExpression(DiagnosticManager &diagnostic_manager)
> > +    {
> > +        return false;
> > +    }
> >
> >      //------------------------------------------------------------------
> >      /// Ready an already-parsed expression for execution, possibly
> >
> > Modified: lldb/trunk/include/lldb/Target/Target.h
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=264379&r1=264378&r2=264379&view=diff
> > ==============================================================================
> > --- lldb/trunk/include/lldb/Target/Target.h (original)
> > +++ lldb/trunk/include/lldb/Target/Target.h Thu Mar 24 20:57:14 2016
> > @@ -149,6 +149,9 @@ public:
> >      GetEnableAutoImportClangModules () const;
> >
> >      bool
> > +    GetEnableAutoApplyFixIts () const;
> > +
> > +    bool
> >      GetEnableSyntheticValue () const;
> >
> >      uint32_t
> > @@ -271,6 +274,7 @@ public:
> >          m_trap_exceptions (true),
> >          m_generate_debug_info (false),
> >          m_result_is_internal (false),
> > +        m_auto_apply_fixits (true),
> >          m_use_dynamic (lldb::eNoDynamicValues),
> >          m_timeout_usec (default_timeout),
> >          m_one_thread_timeout_usec (0),
> > @@ -541,6 +545,18 @@ public:
> >      {
> >          return m_result_is_internal;
> >      }
> > +
> > +    void
> > +    SetAutoApplyFixIts(bool b)
> > +    {
> > +        m_auto_apply_fixits = b;
> > +    }
> > +
> > +    bool
> > +    GetAutoApplyFixIts() const
> > +    {
> > +        return m_auto_apply_fixits;
> > +    }
> >
> >  private:
> >      ExecutionPolicy m_execution_policy;
> > @@ -558,6 +574,7 @@ private:
> >      bool m_generate_debug_info;
> >      bool m_ansi_color_errors;
> >      bool m_result_is_internal;
> > +    bool m_auto_apply_fixits;
> >      lldb::DynamicValueType m_use_dynamic;
> >      uint32_t m_timeout_usec;
> >      uint32_t m_one_thread_timeout_usec;
> >
> > Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=264379&r1=264378&r2=264379&view=diff
> > ==============================================================================
> > --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
> > +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Thu Mar 24 20:57:14 2016
> > @@ -2347,6 +2347,7 @@
> >                 4C2479BE1BA39843009C9A7B /* ExpressionParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ExpressionParser.h; path = include/lldb/Expression/ExpressionParser.h; sourceTree = "<group>"; };
> >                 4C29E77D1BA2403F00DFF855 /* ExpressionTypeSystemHelper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = ExpressionTypeSystemHelper.h; path = include/lldb/Expression/ExpressionTypeSystemHelper.h; sourceTree = "<group>"; };
> >                 4C2FAE2E135E3A70001EDE44 /* SharedCluster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SharedCluster.h; path = include/lldb/Utility/SharedCluster.h; sourceTree = "<group>"; };
> > +               4C3DA2301CA0BFB800CEB1D4 /* ClangDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangDiagnostic.h; path = ExpressionParser/Clang/ClangDiagnostic.h; sourceTree = "<group>"; };
> >                 4C43DEF9110641F300E55CBF /* ThreadPlanShouldStopHere.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanShouldStopHere.h; path = include/lldb/Target/ThreadPlanShouldStopHere.h; sourceTree = "<group>"; };
> >                 4C43DEFA110641F300E55CBF /* ThreadPlanShouldStopHere.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanShouldStopHere.cpp; path = source/Target/ThreadPlanShouldStopHere.cpp; sourceTree = "<group>"; };
> >                 4C43DF8511069BFD00E55CBF /* ThreadPlanStepInRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanStepInRange.h; path = include/lldb/Target/ThreadPlanStepInRange.h; sourceTree = "<group>"; };
> > @@ -5288,6 +5289,7 @@
> >                 4984BA0C1B97620B008658D4 /* Clang */ = {
> >                         isa = PBXGroup;
> >                         children = (
> > +                               4C3DA2301CA0BFB800CEB1D4 /* ClangDiagnostic.h */,
> >                                 4C98D3E0118FB98F00E575D0 /* ClangFunctionCaller.h */,
> >                                 4C98D3DA118FB96F00E575D0 /* ClangFunctionCaller.cpp */,
> >                                 26BC7DC010F1B79500F91463 /* ClangExpressionHelper.h */,
> >
> > Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/Makefile
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/Makefile?rev=264379&view=auto
> > ==============================================================================
> > --- lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/Makefile (added)
> > +++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/Makefile Thu Mar 24 20:57:14 2016
> > @@ -0,0 +1,12 @@
> > +LEVEL = ../../make
> > +
> > +CXX_SOURCES := main.cpp
> > +
> > +# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD
> > +# targets.  Other targets do not, which causes this test to fail.
> > +# This flag enables FullDebugInfo for all targets.
> > +ifneq (,$(findstring clang,$(CC)))
> > +  CFLAGS_EXTRAS += -fno-limit-debug-info
> > +endif
> > +
> > +include $(LEVEL)/Makefile.rules
> >
> > Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/TestFixIts.py
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/TestFixIts.py?rev=264379&view=auto
> > ==============================================================================
> > --- lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/TestFixIts.py (added)
> > +++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/TestFixIts.py Thu Mar 24 20:57:14 2016
> > @@ -0,0 +1,77 @@
> > +"""
> > +Test calling an expression with errors that a FixIt can fix.
> > +"""
> > +
> > +from __future__ import print_function
> > +
> > +
> > +
> > +import lldb
> > +from lldbsuite.test.decorators import *
> > +from lldbsuite.test.lldbtest import *
> > +from lldbsuite.test import lldbutil
> > +
> > +class ExprCommandWithFixits(TestBase):
> > +
> > +    mydir = TestBase.compute_mydir(__file__)
> > +
> > +    def setUp(self):
> > +        # Call super's setUp().
> > +        TestBase.setUp(self)
> > +
> > +        self.main_source = "main.cpp"
> > +        self.main_source_spec = lldb.SBFileSpec (self.main_source)
> > +
> > +    @skipUnlessDarwin
> > +    def test(self):
> > +        """Test calling a function that throws and ObjC exception."""
> > +        self.build()
> > +        self.try_expressions()
> > +
> > +    def try_expressions(self):
> > +        """Test calling expressions with errors that can be fixed by the FixIts."""
> > +        exe_name = "a.out"
> > +        exe = os.path.join(os.getcwd(), exe_name)
> > +
> > +        target = self.dbg.CreateTarget(exe)
> > +        self.assertTrue(target, VALID_TARGET)
> > +
> > +        breakpoint = target.BreakpointCreateBySourceRegex('Stop here to evaluate expressions',self.main_source_spec)
> > +        self.assertTrue(breakpoint.GetNumLocations() > 0, VALID_BREAKPOINT)
> > +
> > +        # Launch the process, and do not stop at the entry point.
> > +        process = target.LaunchSimple (None, None, self.get_process_working_directory())
> > +
> > +        self.assertTrue(process, PROCESS_IS_VALID)
> > +
> > +        # Frame #0 should be at our breakpoint.
> > +        threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint)
> > +
> > +        self.assertTrue(len(threads) == 1)
> > +        self.thread = threads[0]
> > +
> > +        options = lldb.SBExpressionOptions()
> > +        options.SetAutoApplyFixIts(True)
> > +
> > +        frame = self.thread.GetFrameAtIndex(0)
> > +
> > +        # Try with one error:
> > +        value = frame.EvaluateExpression("my_pointer.first", options)
> > +        self.assertTrue(value.IsValid())
> > +        self.assertTrue(value.GetError().Success())
> > +        self.assertTrue(value.GetValueAsUnsigned() == 10)
> > +
> > +        # Try with two errors:
> > +        two_error_expression = "my_pointer.second->a"
> > +        value = frame.EvaluateExpression(two_error_expression, options)
> > +        self.assertTrue(value.IsValid())
> > +        self.assertTrue(value.GetError().Success())
> > +        self.assertTrue(value.GetValueAsUnsigned() == 20)
> > +
> > +        # Now turn off the fixits, and the expression should fail:
> > +        options.SetAutoApplyFixIts(False)
> > +        value = frame.EvaluateExpression("two_error_expression", options)
> > +        self.assertTrue(value.IsValid())
> > +        self.assertTrue(value.GetError().Fail())
> > +
> > +
> >
> > Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/main.cpp
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/main.cpp?rev=264379&view=auto
> > ==============================================================================
> > --- lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/main.cpp (added)
> > +++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/fixits/main.cpp Thu Mar 24 20:57:14 2016
> > @@ -0,0 +1,25 @@
> > +#include <stdio.h>
> > +
> > +struct SubStruct
> > +{
> > +  int a;
> > +  int b;
> > +};
> > +
> > +struct MyStruct
> > +{
> > +  int first;
> > +  struct SubStruct second;
> > +};
> > +
> > +int
> > +main()
> > +{
> > +  struct MyStruct my_struct = {10, {20, 30}};
> > +  struct MyStruct *my_pointer = &my_struct;
> > +  printf ("Stop here to evaluate expressions: %d %d %p\n", my_pointer->first, my_pointer->second.a, my_pointer);
> > +  return 0;
> > +}
> > +
> > +
> > +
> >
> > Modified: lldb/trunk/scripts/interface/SBExpressionOptions.i
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBExpressionOptions.i?rev=264379&r1=264378&r2=264379&view=diff
> > ==============================================================================
> > --- lldb/trunk/scripts/interface/SBExpressionOptions.i (original)
> > +++ lldb/trunk/scripts/interface/SBExpressionOptions.i Thu Mar 24 20:57:14 2016
> > @@ -118,6 +118,15 @@ public:
> >      %feature("docstring", "Sets the prefix to use for this expression. This prefix gets inserted after the 'target.expr-prefix' prefix contents, but before the wrapped expression function body.") SetPrefix;
> >      void
> >      SetPrefix (const char *prefix);
> > +
> > +    %feature("docstring", "Sets whether to auto-apply FixIt hints to the expression being evaluated.") SetAutoApplyFixIts;
> > +    void
> > +    SetAutoApplyFixIts(bool b = true);
> > +
> > +    %feature("docstring", "Gets whether to auto-apply FixIt hints to an expression.") GetAutoApplyFixIts;
> > +    bool
> > +    GetAutoApplyFixIts();
> > +
> >
> >  protected:
> >
> >
> > Modified: lldb/trunk/source/API/SBExpressionOptions.cpp
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBExpressionOptions.cpp?rev=264379&r1=264378&r2=264379&view=diff
> > ==============================================================================
> > --- lldb/trunk/source/API/SBExpressionOptions.cpp (original)
> > +++ lldb/trunk/source/API/SBExpressionOptions.cpp Thu Mar 24 20:57:14 2016
> > @@ -197,6 +197,18 @@ SBExpressionOptions::SetPrefix (const ch
> >      return m_opaque_ap->SetPrefix(prefix);
> >  }
> >
> > +bool
> > +SBExpressionOptions::GetAutoApplyFixIts ()
> > +{
> > +    return m_opaque_ap->GetAutoApplyFixIts ();
> > +}
> > +
> > +void
> > +SBExpressionOptions::SetAutoApplyFixIts (bool b)
> > +{
> > +    return m_opaque_ap->SetAutoApplyFixIts (b);
> > +}
> > +
> >  EvaluateExpressionOptions *
> >  SBExpressionOptions::get() const
> >  {
> >
> > Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=264379&r1=264378&r2=264379&view=diff
> > ==============================================================================
> > --- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
> > +++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Thu Mar 24 20:57:14 2016
> > @@ -61,6 +61,7 @@ CommandObjectExpression::CommandOptions:
> >      { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error",    'u', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,    "Clean up program state if the expression causes a crash, or raises a signal.  Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."},
> >      { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug",              'g', OptionParser::eNoArgument      , nullptr, nullptr, 0, eArgTypeNone,       "When specified, debug the JIT code by setting a breakpoint on the first instruction and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."},
> >      { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language",           'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage,   "Specifies the Language to use when parsing the expression.  If not set the target.language setting is used." },
> > +    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "apply-fixits",       'X', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage,   "If true, simple FixIt hints will be automatically applied to the expression." },
> >      { LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, nullptr, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity,        "How verbose should the output of this expression be, if the object description is asked for."},
> >  };
> >
> > @@ -149,6 +150,17 @@ CommandObjectExpression::CommandOptions:
> >          ignore_breakpoints = false;
> >          break;
> >
> > +    case 'X':
> > +        {
> > +            bool success;
> > +            bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
> > +            if (success)
> > +                auto_apply_fixits = tmp_value ? eLazyBoolYes : eLazyBoolNo;
> > +            else
> > +                error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
> > +            break;
> > +        }
> > +
> >      default:
> >          error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
> >          break;
> > @@ -178,6 +190,7 @@ CommandObjectExpression::CommandOptions:
> >      debug = false;
> >      language = eLanguageTypeUnknown;
> >      m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
> > +    auto_apply_fixits = eLazyBoolCalculate;
> >  }
> >
> >  const OptionDefinition*
> > @@ -294,6 +307,14 @@ CommandObjectExpression::EvaluateExpress
> >          options.SetTryAllThreads(m_command_options.try_all_threads);
> >          options.SetDebug(m_command_options.debug);
> >          options.SetLanguage(m_command_options.language);
> > +
> > +        bool auto_apply_fixits;
> > +        if (m_command_options.auto_apply_fixits == eLazyBoolCalculate)
> > +            auto_apply_fixits = target->GetEnableAutoApplyFixIts();
> > +        else
> > +            auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes ? true : false;
> > +
> > +        options.SetAutoApplyFixIts(auto_apply_fixits);
> >
> >          // If there is any chance we are going to stop and want to see
> >          // what went wrong with our expression, we should generate debug info
> >
> > Modified: lldb/trunk/source/Commands/CommandObjectExpression.h
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.h?rev=264379&r1=264378&r2=264379&view=diff
> > ==============================================================================
> > --- lldb/trunk/source/Commands/CommandObjectExpression.h (original)
> > +++ lldb/trunk/source/Commands/CommandObjectExpression.h Thu Mar 24 20:57:14 2016
> > @@ -14,13 +14,13 @@
> >  // C++ Includes
> >  // Other libraries and framework includes
> >  // Project includes
> > +#include "lldb/lldb-private-enumerations.h"
> >  #include "lldb/Core/IOHandler.h"
> >  #include "lldb/Interpreter/CommandObject.h"
> >  #include "lldb/Interpreter/OptionGroupBoolean.h"
> >  #include "lldb/Interpreter/OptionGroupFormat.h"
> >  #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
> >  #include "lldb/Target/ExecutionContext.h"
> > -
> >  namespace lldb_private {
> >
> >  class CommandObjectExpression :
> > @@ -63,6 +63,7 @@ public:
> >          bool        try_all_threads;
> >          lldb::LanguageType language;
> >          LanguageRuntimeDescriptionDisplayVerbosity m_verbosity;
> > +        LazyBool        auto_apply_fixits;
> >      };
> >
> >      CommandObjectExpression (CommandInterpreter &interpreter);
> >
> > Modified: lldb/trunk/source/Expression/DiagnosticManager.cpp
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/DiagnosticManager.cpp?rev=264379&r1=264378&r2=264379&view=diff
> > ==============================================================================
> > --- lldb/trunk/source/Expression/DiagnosticManager.cpp (original)
> > +++ lldb/trunk/source/Expression/DiagnosticManager.cpp Thu Mar 24 20:57:14 2016
> > @@ -52,10 +52,10 @@ DiagnosticManager::GetString(char separa
> >  {
> >      std::string ret;
> >
> > -    for (const Diagnostic &diagnostic : Diagnostics())
> > +    for (const Diagnostic *diagnostic : Diagnostics())
> >      {
> > -        ret.append(StringForSeverity(diagnostic.severity));
> > -        ret.append(diagnostic.message);
> > +        ret.append(StringForSeverity(diagnostic->GetSeverity()));
> > +        ret.append(diagnostic->GetMessage());
> >          ret.push_back(separator);
> >      }
> >
> >
> > Modified: lldb/trunk/source/Expression/UserExpression.cpp
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/UserExpression.cpp?rev=264379&r1=264378&r2=264379&view=diff
> > ==============================================================================
> > --- lldb/trunk/source/Expression/UserExpression.cpp (original)
> > +++ lldb/trunk/source/Expression/UserExpression.cpp Thu Mar 24 20:57:14 2016
> > @@ -253,6 +253,7 @@ UserExpression::Evaluate (ExecutionConte
> >      }
> >
> >      DiagnosticManager diagnostic_manager;
> > +    diagnostic_manager.SetAutoApplyFixIts(options.GetAutoApplyFixIts());
> >
> >      if (!user_expression_sp->Parse(diagnostic_manager, exe_ctx, execution_policy, keep_expression_in_memory,
> >                                     generate_debug_info))
> >
> > Added: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h?rev=264379&view=auto
> > ==============================================================================
> > --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h (added)
> > +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangDiagnostic.h Thu Mar 24 20:57:14 2016
> > @@ -0,0 +1,59 @@
> > +//===-- DiagnosticManager.h -------------------------------------*- C++ -*-===//
> > +//
> > +//                     The LLVM Compiler Infrastructure
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> > +//===----------------------------------------------------------------------===//
> > +
> > +#ifndef lldb_ClangDiagnostic_h
> > +#define lldb_ClangDiagnostic_h
> > +
> > +#include <vector>
> > +
> > +#include "clang/Basic/Diagnostic.h"
> > +
> > +#include "lldb/lldb-defines.h"
> > +#include "lldb/lldb-types.h"
> > +
> > +#include "lldb/Expression/DiagnosticManager.h"
> > +
> > +namespace lldb_private
> > +{
> > +
> > +typedef std::vector<clang::FixItHint> FixItList;
> > +
> > +class ClangDiagnostic : public Diagnostic
> > +{
> > +public:
> > +    static inline bool classof(const ClangDiagnostic *) { return true; }
> > +    static inline bool classof(const Diagnostic *diag) {
> > +        return diag->getKind() == eDiagnosticOriginClang;
> > +    }
> > +
> > +    ClangDiagnostic(const char *message, DiagnosticSeverity severity, uint32_t compiler_id) :
> > +        Diagnostic(message, severity, eDiagnosticOriginClang, compiler_id)
> > +    {
> > +    }
> > +
> > +    virtual ~ClangDiagnostic() = default;
> > +
> > +    bool HasFixIts () const override { return !m_fixit_vec.empty(); }
> > +
> > +    void
> > +    AddFixitHint (const clang::FixItHint &fixit)
> > +    {
> > +        m_fixit_vec.push_back(fixit);
> > +    }
> > +
> > +    const FixItList &
> > +    FixIts() const
> > +    {
> > +        return m_fixit_vec;
> > +    }
> > +    FixItList m_fixit_vec;
> > +};
> > +
> > +}  // namespace lldb_private
> > +#endif /* lldb_ClangDiagnostic_h */
> >
> > Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp?rev=264379&r1=264378&r2=264379&view=diff
> > ==============================================================================
> > --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (original)
> > +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp Thu Mar 24 20:57:14 2016
> > @@ -17,9 +17,12 @@
> >  #include "clang/Basic/FileManager.h"
> >  #include "clang/Basic/SourceLocation.h"
> >  #include "clang/Basic/TargetInfo.h"
> > -#include "clang/Basic/Version.h"
> > +#include "clang/Basic/Version.h"
> >  #include "clang/CodeGen/CodeGenAction.h"
> >  #include "clang/CodeGen/ModuleBuilder.h"
> > +#include "clang/Edit/Commit.h"
> > +#include "clang/Edit/EditsReceiver.h"
> > +#include "clang/Edit/EditedSource.h"
> >  #include "clang/Frontend/CompilerInstance.h"
> >  #include "clang/Frontend/CompilerInvocation.h"
> >  #include "clang/Frontend/FrontendActions.h"
> > @@ -30,6 +33,7 @@
> >  #include "clang/Lex/Preprocessor.h"
> >  #include "clang/Parse/ParseAST.h"
> >  #include "clang/Rewrite/Frontend/FrontendActions.h"
> > +#include "clang/Rewrite/Core/Rewriter.h"
> >  #include "clang/Sema/SemaConsumer.h"
> >  #include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
> >
> > @@ -54,6 +58,7 @@
> >
> >  // Project includes
> >  #include "ClangExpressionParser.h"
> > +#include "ClangDiagnostic.h"
> >
> >  #include "ClangASTSource.h"
> >  #include "ClangExpressionHelper.h"
> > @@ -175,24 +180,48 @@ public:
> >              diag_str.push_back('\0');
> >              const char *data = diag_str.data();
> >
> > +            DiagnosticSeverity severity;
> > +            bool make_new_diagnostic = true;
> > +
> >              switch (DiagLevel)
> >              {
> >                  case DiagnosticsEngine::Level::Fatal:
> >                  case DiagnosticsEngine::Level::Error:
> > -                    m_manager->AddDiagnostic(data, eDiagnosticSeverityError, eDiagnosticOriginClang, Info.getID());
> > +                    severity = eDiagnosticSeverityError;
> >                      break;
> >                  case DiagnosticsEngine::Level::Warning:
> > -                    m_manager->AddDiagnostic(data, eDiagnosticSeverityWarning, eDiagnosticOriginClang, Info.getID());
> > +                    severity = eDiagnosticSeverityWarning;
> >                      break;
> >                  case DiagnosticsEngine::Level::Remark:
> >                  case DiagnosticsEngine::Level::Ignored:
> > -                    m_manager->AddDiagnostic(data, eDiagnosticSeverityRemark, eDiagnosticOriginClang, Info.getID());
> > +                    severity = eDiagnosticSeverityRemark;
> >                      break;
> >                  case DiagnosticsEngine::Level::Note:
> >                      m_manager->AppendMessageToDiagnostic(data);
> > +                    make_new_diagnostic = false;
> > +            }
> > +            if (make_new_diagnostic)
> > +            {
> > +                ClangDiagnostic *new_diagnostic = new ClangDiagnostic(data, severity, Info.getID());
> > +                m_manager->AddDiagnostic(new_diagnostic);
> > +
> > +                // Don't store away warning fixits, since the compiler doesn't have enough
> > +                // context in an expression for the warning to be useful.
> > +                // FIXME: Should we try to filter out FixIts that apply to our generated
> > +                // code, and not the user's expression?
> > +                if (severity == eDiagnosticSeverityError)
> > +                {
> > +                    size_t num_fixit_hints = Info.getNumFixItHints();
> > +                    for (int i = 0; i < num_fixit_hints; i++)
> > +                    {
> > +                        const clang::FixItHint &fixit = Info.getFixItHint(i);
> > +                        if (!fixit.isNull())
> > +                            new_diagnostic->AddFixitHint(fixit);
> > +                    }
> > +                }
> >              }
> >          }
> > -
> > +
> >          m_passthrough->HandleDiagnostic(DiagLevel, Info);
> >      }
> >
> > @@ -666,6 +695,87 @@ ClangExpressionParser::Parse(DiagnosticM
> >      return num_errors;
> >  }
> >
> > +bool
> > +ClangExpressionParser::RewriteExpression(DiagnosticManager &diagnostic_manager)
> > +{
> > +    clang::SourceManager &source_manager = m_compiler->getSourceManager();
> > +    clang::edit::EditedSource editor(source_manager, m_compiler->getLangOpts(), nullptr);
> > +    clang::edit::Commit commit(editor);
> > +    clang::Rewriter rewriter(source_manager, m_compiler->getLangOpts());
> > +
> > +    class RewritesReceiver : public edit::EditsReceiver {
> > +      Rewriter &rewrite;
> > +
> > +    public:
> > +      RewritesReceiver(Rewriter &in_rewrite) : rewrite(in_rewrite) { }
> > +
> > +      void insert(SourceLocation loc, StringRef text) override {
> > +        rewrite.InsertText(loc, text);
> > +      }
> > +      void replace(CharSourceRange range, StringRef text) override {
> > +        rewrite.ReplaceText(range.getBegin(), rewrite.getRangeSize(range), text);
> > +      }
> > +    };
> > +
> > +    RewritesReceiver rewrites_receiver(rewriter);
> > +
> > +    const DiagnosticList &diagnostics = diagnostic_manager.Diagnostics();
> > +    size_t num_diags = diagnostics.size();
> > +    if (num_diags == 0)
> > +        return false;
> > +
> > +    for (const Diagnostic *diag : diagnostic_manager.Diagnostics())
> > +    {
> > +        const ClangDiagnostic *diagnostic = llvm::dyn_cast<ClangDiagnostic>(diag);
> > +        if (diagnostic && diagnostic->HasFixIts())
> > +        {
> > +             for (const FixItHint &fixit : diagnostic->FixIts())
> > +             {
> > +                // This is cobbed from clang::Rewrite::FixItRewriter.
> > +                if (fixit.CodeToInsert.empty())
> > +                {
> > +                  if (fixit.InsertFromRange.isValid())
> > +                  {
> > +                      commit.insertFromRange(fixit.RemoveRange.getBegin(),
> > +                                             fixit.InsertFromRange, /*afterToken=*/false,
> > +                                             fixit.BeforePreviousInsertions);
> > +                  }
> > +                  else
> > +                    commit.remove(fixit.RemoveRange);
> > +                }
> > +                else
> > +                {
> > +                  if (fixit.RemoveRange.isTokenRange() ||
> > +                      fixit.RemoveRange.getBegin() != fixit.RemoveRange.getEnd())
> > +                    commit.replace(fixit.RemoveRange, fixit.CodeToInsert);
> > +                  else
> > +                    commit.insert(fixit.RemoveRange.getBegin(), fixit.CodeToInsert,
> > +                                /*afterToken=*/false, fixit.BeforePreviousInsertions);
> > +                }
> > +            }
> > +        }
> > +    }
> > +
> > +    // FIXME - do we want to try to propagate specific errors here?
> > +    if (!commit.isCommitable())
> > +        return false;
> > +    else if (!editor.commit(commit))
> > +        return false;
> > +
> > +    // Now play all the edits, and stash the result in the diagnostic manager.
> > +    editor.applyRewrites(rewrites_receiver);
> > +    RewriteBuffer &main_file_buffer = rewriter.getEditBuffer(source_manager.getMainFileID());
> > +
> > +    std::string fixed_expression;
> > +    llvm::raw_string_ostream out_stream(fixed_expression);
> > +
> > +    main_file_buffer.write(out_stream);
> > +    out_stream.flush();
> > +    diagnostic_manager.SetFixedExpression(fixed_expression);
> > +
> > +    return true;
> > +}
> > +
> >  static bool FindFunctionInModule (ConstString &mangled_name,
> >                                    llvm::Module *module,
> >                                    const char *orig_name)
> >
> > Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h?rev=264379&r1=264378&r2=264379&view=diff
> > ==============================================================================
> > --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h (original)
> > +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h Thu Mar 24 20:57:14 2016
> > @@ -73,6 +73,9 @@ public:
> >      //------------------------------------------------------------------
> >      unsigned
> >      Parse(DiagnosticManager &diagnostic_manager) override;
> > +
> > +    bool
> > +    RewriteExpression(DiagnosticManager &diagnostic_manager) override;
> >
> >      //------------------------------------------------------------------
> >      /// Ready an already-parsed expression for execution, possibly
> >
> > Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp?rev=264379&r1=264378&r2=264379&view=diff
> > ==============================================================================
> > --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp (original)
> > +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp Thu Mar 24 20:57:14 2016
> > @@ -23,6 +23,7 @@
> >  #include "ClangExpressionParser.h"
> >  #include "ClangModulesDeclVendor.h"
> >  #include "ClangPersistentVariables.h"
> > +#include "ClangDiagnostic.h"
> >
> >  #include "lldb/Core/ConstString.h"
> >  #include "lldb/Core/Log.h"
> > @@ -358,8 +359,6 @@ ClangUserExpression::Parse(DiagnosticMan
> >          diagnostic_manager.PutCString(eDiagnosticSeverityWarning, err.AsCString());
> >      }
> >
> > -    StreamString m_transformed_stream;
> > -
> >      ////////////////////////////////////
> >      // Generate the expression
> >      //
> > @@ -489,10 +488,38 @@ ClangUserExpression::Parse(DiagnosticMan
> >      if (!exe_scope)
> >          exe_scope = exe_ctx.GetTargetPtr();
> >
> > -    ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
> > +    // We use a shared pointer here so we can use the original parser - if it succeeds
> > +    // or the rewrite parser we might make if it fails.  But the parser_sp will never be empty.
> > +
> > +    std::shared_ptr<ClangExpressionParser> parser_sp(new ClangExpressionParser(exe_scope, *this, generate_debug_info));
> >
> > -    unsigned num_errors = parser.Parse(diagnostic_manager);
> > +    unsigned num_errors = parser_sp->Parse(diagnostic_manager);
> >
> > +    // Check here for FixItHints.  If there are any try fixing the source and re-parsing...
> > +    if (num_errors && diagnostic_manager.HasFixIts() && diagnostic_manager.ShouldAutoApplyFixIts())
> > +    {
> > +        if (parser_sp->RewriteExpression(diagnostic_manager))
> > +        {
> > +            std::string backup_source = std::move(m_transformed_text);
> > +            m_transformed_text = diagnostic_manager.GetFixedExpression();
> > +            // Make a new diagnostic manager and parser, and try again with the rewritten expression:
> > +            // FIXME: It would be nice to reuse the parser we have but that doesn't seem to be possible.
> > +            DiagnosticManager rewrite_manager;
> > +            std::shared_ptr<ClangExpressionParser> rewrite_parser_sp(new ClangExpressionParser(exe_scope, *this, generate_debug_info));
> > +            unsigned rewrite_errors = rewrite_parser_sp->Parse(rewrite_manager);
> > +            if (rewrite_errors == 0)
> > +            {
> > +                diagnostic_manager.Clear();
> > +                parser_sp = rewrite_parser_sp;
> > +                num_errors = 0;
> > +            }
> > +            else
> > +            {
> > +                m_transformed_text = std::move(backup_source);
> > +            }
> > +        }
> > +    }
> > +
> >      if (num_errors)
> >      {
> >          diagnostic_manager.Printf(eDiagnosticSeverityError, "%u error%s parsing expression", num_errors,
> > @@ -508,8 +535,12 @@ ClangUserExpression::Parse(DiagnosticMan
> >      //
> >
> >      {
> > -        Error jit_error = parser.PrepareForExecution(m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx,
> > -                                                     m_can_interpret, execution_policy);
> > +        Error jit_error = parser_sp->PrepareForExecution(m_jit_start_addr,
> > +                                                         m_jit_end_addr,
> > +                                                         m_execution_unit_sp,
> > +                                                         exe_ctx,
> > +                                                         m_can_interpret,
> > +                                                         execution_policy);
> >
> >          if (!jit_error.Success())
> >          {
> > @@ -524,7 +555,7 @@ ClangUserExpression::Parse(DiagnosticMan
> >
> >      if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel)
> >      {
> > -        Error static_init_error = parser.RunStaticInitializers(m_execution_unit_sp, exe_ctx);
> > +        Error static_init_error = parser_sp->RunStaticInitializers(m_execution_unit_sp, exe_ctx);
> >
> >          if (!static_init_error.Success())
> >          {
> >
> > Modified: lldb/trunk/source/Target/Target.cpp
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=264379&r1=264378&r2=264379&view=diff
> > ==============================================================================
> > --- lldb/trunk/source/Target/Target.cpp (original)
> > +++ lldb/trunk/source/Target/Target.cpp Thu Mar 24 20:57:14 2016
> > @@ -3425,6 +3425,7 @@ g_properties[] =
> >      { "debug-file-search-paths"            , OptionValue::eTypeFileSpecList, false, 0                       , nullptr, nullptr, "List of directories to be searched when locating debug symbol files." },
> >      { "clang-module-search-paths"          , OptionValue::eTypeFileSpecList, false, 0                       , nullptr, nullptr, "List of directories to be searched when locating modules for Clang." },
> >      { "auto-import-clang-modules"          , OptionValue::eTypeBoolean   , false, true                      , nullptr, nullptr, "Automatically load Clang modules referred to by the program." },
> > +    { "auto-apply-fixits"                  , OptionValue::eTypeBoolean   , false, true                      , nullptr, nullptr, "Automatically apply fixit hints to expressions." },
> >      { "max-children-count"                 , OptionValue::eTypeSInt64    , false, 256                       , nullptr, nullptr, "Maximum number of children to expand in any level of depth." },
> >      { "max-string-summary-length"          , OptionValue::eTypeSInt64    , false, 1024                      , nullptr, nullptr, "Maximum number of characters to show when using %s in summary strings." },
> >      { "max-memory-read-size"               , OptionValue::eTypeSInt64    , false, 1024                      , nullptr, nullptr, "Maximum number of bytes that 'memory read' will fetch before --force must be specified." },
> > @@ -3481,6 +3482,7 @@ enum
> >      ePropertyDebugFileSearchPaths,
> >      ePropertyClangModuleSearchPaths,
> >      ePropertyAutoImportClangModules,
> > +    ePropertyAutoApplyFixIts,
> >      ePropertyMaxChildrenCount,
> >      ePropertyMaxSummaryLength,
> >      ePropertyMaxMemReadSize,
> > @@ -3853,6 +3855,13 @@ TargetProperties::GetEnableAutoImportCla
> >      return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
> >  }
> >
> > +bool
> > +TargetProperties::GetEnableAutoApplyFixIts() const
> > +{
> > +    const uint32_t idx = ePropertyAutoApplyFixIts;
> > +    return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
> > +}
> > +
> >  bool
> >  TargetProperties::GetEnableSyntheticValue () const
> >  {
> >
> >
> > _______________________________________________
> > lldb-commits mailing list
> > lldb-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
> > _______________________________________________
> > lldb-commits mailing list
> > lldb-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
> 



More information about the lldb-commits mailing list