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>

llvm-svn: 264379
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index 7bf94ed..fa2be2c 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -61,6 +61,7 @@
     { 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 @@
         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 @@
     debug = false;
     language = eLanguageTypeUnknown;
     m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
+    auto_apply_fixits = eLazyBoolCalculate;
 }
 
 const OptionDefinition*
@@ -294,6 +307,14 @@
         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