diff options
author | Sean Callanan <scallanan@apple.com> | 2016-03-22 21:05:51 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2016-03-22 21:05:51 +0000 |
commit | 00294b34a3c99f3540214a148c0bd15e68f9d7fd (patch) | |
tree | a6892887ee99bed68154d36a82a975d01ec566a1 /lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp | |
parent | e32368fc6edd4f1c284a9ba0cbdd6b8931dbe925 (diff) | |
download | bcm5719-llvm-00294b34a3c99f3540214a148c0bd15e68f9d7fd.tar.gz bcm5719-llvm-00294b34a3c99f3540214a148c0bd15e68f9d7fd.zip |
Backend support for top-level Clang epxressions
This patch adds a new ExecutionPolicy, eExecutionPolicyTopLevel, which
tells the expression parser that the expression should be JITted as top
level code but nothing (except static initializers) should be run. I
have modified the Clang expression parser to recognize this execution
policy. On top of the existing patches that support storing IR and
maintaining a map of arbitrary Decls, this is mainly just patching up a
few places in the expression parser.
I intend to submit a patch for review that exposes this functionality
through the "expression" command and through the SB API. That patch
also includes a testcase for all of this.
<rdar://problem/22864976>
llvm-svn: 264095
Diffstat (limited to 'lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp')
-rw-r--r-- | lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp | 72 |
1 files changed, 47 insertions, 25 deletions
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index e9159653bf9..114764ba685 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -652,6 +652,11 @@ ClangExpressionParser::Parse(DiagnosticManager &diagnostic_manager) } } + if (!num_errors) + { + type_system_helper->CommitPersistentDecls(); + } + adapter->ResetManager(); return num_errors; @@ -697,24 +702,27 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr, return err; } - // Find the actual name of the function (it's often mangled somehow) - ConstString function_name; - if (!FindFunctionInModule(function_name, llvm_module_ap.get(), m_expr.FunctionName())) + if (execution_policy != eExecutionPolicyTopLevel) { - err.SetErrorToGenericError(); - err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName()); - return err; - } - else - { - if (log) - log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName()); + // Find the actual name of the function (it's often mangled somehow) + + if (!FindFunctionInModule(function_name, llvm_module_ap.get(), m_expr.FunctionName())) + { + err.SetErrorToGenericError(); + err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName()); + return err; + } + else + { + if (log) + log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName()); + } } - + SymbolContext sc; - + if (lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP()) { sc = frame_sp->GetSymbolContext(lldb::eSymbolContextEverything); @@ -741,20 +749,28 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr, if (target) error_stream = target->GetDebugger().GetErrorFile().get(); - IRForTarget ir_for_target(decl_map, - m_expr.NeedsVariableResolution(), - *execution_unit_sp, - error_stream, + IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(), *execution_unit_sp, error_stream, function_name.AsCString()); bool ir_can_run = ir_for_target.runOnModule(*execution_unit_sp->GetModule()); - Error interpret_error; Process *process = exe_ctx.GetProcessPtr(); - bool interpret_function_calls = !process ? false : process->CanInterpretFunctionCalls(); - can_interpret = IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), interpret_error, interpret_function_calls); + if (execution_policy != eExecutionPolicyAlways && execution_policy != eExecutionPolicyTopLevel) + { + Error interpret_error; + + bool interpret_function_calls = !process ? false : process->CanInterpretFunctionCalls(); + can_interpret = + IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), + interpret_error, interpret_function_calls); + if (!can_interpret && execution_policy == eExecutionPolicyNever) + { + err.SetErrorStringWithFormat("Can't run the expression locally: %s", interpret_error.AsCString()); + return err; + } + } if (!ir_can_run) { @@ -762,19 +778,21 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr, return err; } - if (!can_interpret && execution_policy == eExecutionPolicyNever) + if (!process && execution_policy == eExecutionPolicyAlways) { - err.SetErrorStringWithFormat("Can't run the expression locally: %s", interpret_error.AsCString()); + err.SetErrorString("Expression needed to run in the target, but the target can't be run"); return err; } - if (!process && execution_policy == eExecutionPolicyAlways) + if (!process && execution_policy == eExecutionPolicyTopLevel) { - err.SetErrorString("Expression needed to run in the target, but the target can't be run"); + err.SetErrorString( + "Top-level code needs to be inserted into a runnable target, but the target can't be run"); return err; } - if (execution_policy == eExecutionPolicyAlways || !can_interpret) + if (execution_policy == eExecutionPolicyAlways || + (execution_policy != eExecutionPolicyTopLevel && !can_interpret)) { if (m_expr.NeedsValidation() && process) { @@ -809,7 +827,11 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr, return err; } } + } + if (execution_policy == eExecutionPolicyAlways || execution_policy == eExecutionPolicyTopLevel || + !can_interpret) + { execution_unit_sp->GetRunnableInfo(err, func_addr, func_end); } } |