summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2016-03-22 21:05:51 +0000
committerSean Callanan <scallanan@apple.com>2016-03-22 21:05:51 +0000
commit00294b34a3c99f3540214a148c0bd15e68f9d7fd (patch)
treea6892887ee99bed68154d36a82a975d01ec566a1 /lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
parente32368fc6edd4f1c284a9ba0cbdd6b8931dbe925 (diff)
downloadbcm5719-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.cpp72
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);
}
}
OpenPOWER on IntegriCloud