summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2016-03-25 01:57:14 +0000
committerJim Ingham <jingham@apple.com>2016-03-25 01:57:14 +0000
commita1e541bf9fe0253541e6460ed8866f1a4ce0c9dd (patch)
treecabc44445df6df157522ea33af070393120e295e /lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
parent68f56243563417be95e7ef6936f7b7fc9dedf580 (diff)
downloadbcm5719-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.cpp45
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())
{
OpenPOWER on IntegriCloud