diff options
author | Sean Callanan <scallanan@apple.com> | 2016-02-12 21:16:58 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2016-02-12 21:16:58 +0000 |
commit | 8c62daf250020c76a78c54c2efc321d61c84f411 (patch) | |
tree | c5a46e269b9de4e8aec37ad7cd64b8c0f3fc17d4 /lldb/source/Expression/IRInterpreter.cpp | |
parent | b281480203663a1add8248f400947b8d23db9509 (diff) | |
download | bcm5719-llvm-8c62daf250020c76a78c54c2efc321d61c84f411.tar.gz bcm5719-llvm-8c62daf250020c76a78c54c2efc321d61c84f411.zip |
IRInterpreter now recognizes expressions with constants it doesn't handle.
If an instruction has a constant that IRInterpreter doesn't know how to deal
with (say, an array constant, because we can't materialize it to APInt) then we
used to ignore that and only fail during expression execution. This is annoying
because if IRInterpreter had just returned false from CanInterpret(), the JIT
would have been used.
Now the IRInterpreter checks constants as part of CanInterpret(), so this should
hopefully no longer be an issue.
llvm-svn: 260735
Diffstat (limited to 'lldb/source/Expression/IRInterpreter.cpp')
-rw-r--r-- | lldb/source/Expression/IRInterpreter.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp index 29c6742fa87..2b9bb7c53c7 100644 --- a/lldb/source/Expression/IRInterpreter.cpp +++ b/lldb/source/Expression/IRInterpreter.cpp @@ -465,6 +465,45 @@ static const char *memory_read_error = "Interpreter couldn't read static const char *infinite_loop_error = "Interpreter ran for too many cycles"; //static const char *bad_result_error = "Result of expression is in bad memory"; +static bool +CanResolveConstant (llvm::Constant *constant) +{ + switch (constant->getValueID()) + { + default: + return false; + case Value::ConstantIntVal: + case Value::ConstantFPVal: + return true; + case Value::ConstantExprVal: + if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) + { + switch (constant_expr->getOpcode()) + { + default: + return false; + case Instruction::IntToPtr: + case Instruction::PtrToInt: + case Instruction::BitCast: + return CanResolveConstant(constant_expr->getOperand(0)); + case Instruction::GetElementPtr: + { + ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin(); + Constant *base = dyn_cast<Constant>(*op_cursor); + if (!base) + return false; + + return CanResolveConstant(base); + } + } + } else { + return false; + } + case Value::ConstantPointerNullVal: + return true; + } +} + bool IRInterpreter::CanInterpret (llvm::Module &module, llvm::Function &function, @@ -611,6 +650,17 @@ IRInterpreter::CanInterpret (llvm::Module &module, return false; } } + + if (Constant *constant = llvm::dyn_cast<Constant>(operand)) + { + if (!CanResolveConstant(constant)) + { + if (log) + log->Printf("Unsupported constant: %s", PrintValue(constant).c_str()); + error.SetErrorString(unsupported_operand_error); + return false; + } + } } } |