diff options
author | Jim Ingham <jingham@apple.com> | 2016-03-25 01:57:14 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2016-03-25 01:57:14 +0000 |
commit | a1e541bf9fe0253541e6460ed8866f1a4ce0c9dd (patch) | |
tree | cabc44445df6df157522ea33af070393120e295e /lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp | |
parent | 68f56243563417be95e7ef6936f7b7fc9dedf580 (diff) | |
download | bcm5719-llvm-a1e541bf9fe0253541e6460ed8866f1a4ce0c9dd.tar.gz bcm5719-llvm-a1e541bf9fe0253541e6460ed8866f1a4ce0c9dd.zip |
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
Diffstat (limited to 'lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp')
-rw-r--r-- | lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp index 3066384a1a5..9bf8cd5f295 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -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(DiagnosticManager &diagnostic_manager, ExecutionConte diagnostic_manager.PutCString(eDiagnosticSeverityWarning, err.AsCString()); } - StreamString m_transformed_stream; - //////////////////////////////////// // Generate the expression // @@ -489,10 +488,38 @@ ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, ExecutionConte 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(DiagnosticManager &diagnostic_manager, ExecutionConte // { - 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(DiagnosticManager &diagnostic_manager, ExecutionConte 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()) { |