diff options
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()) { |