diff options
author | Sean Callanan <scallanan@apple.com> | 2012-02-08 01:27:49 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2012-02-08 01:27:49 +0000 |
commit | 94a9a39ec450520ac97b1e065b337012fda0a81c (patch) | |
tree | 85941ffe8fae576fff03361389e60edd9fef8d38 /lldb/source/Expression/IRInterpreter.cpp | |
parent | a2a299e586bf3143480e1a75fbe20235d5fa33ff (diff) | |
download | bcm5719-llvm-94a9a39ec450520ac97b1e065b337012fda0a81c.tar.gz bcm5719-llvm-94a9a39ec450520ac97b1e065b337012fda0a81c.zip |
The IRInterpreter's constant evaluator wasn't
sufficiently general - it could only handle
literals and operations that didn't change the
data. Now the constant evaluator passes APInt
values around, and can handle GetElementPtr
constants.
llvm-svn: 150034
Diffstat (limited to 'lldb/source/Expression/IRInterpreter.cpp')
-rw-r--r-- | lldb/source/Expression/IRInterpreter.cpp | 62 |
1 files changed, 50 insertions, 12 deletions
diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp index 741f27ea329..b74251ef713 100644 --- a/lldb/source/Expression/IRInterpreter.cpp +++ b/lldb/source/Expression/IRInterpreter.cpp @@ -538,35 +538,73 @@ public: return true; } - bool ResolveConstant (Memory::Region ®ion, const Constant *constant) + bool ResolveConstantValue (APInt &value, const Constant *constant) { - size_t constant_size = m_target_data.getTypeStoreSize(constant->getType()); - if (const ConstantInt *constant_int = dyn_cast<ConstantInt>(constant)) { - const uint64_t *raw_data = constant_int->getValue().getRawData(); - return m_memory.Write(region.m_base, (const uint8_t*)raw_data, constant_size); + value = constant_int->getValue(); + return true; } else if (const ConstantFP *constant_fp = dyn_cast<ConstantFP>(constant)) { - const uint64_t *raw_data = constant_fp->getValueAPF().bitcastToAPInt().getRawData(); - return m_memory.Write(region.m_base, (const uint8_t*)raw_data, constant_size); + value = constant_fp->getValueAPF().bitcastToAPInt(); + return true; } else if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) { switch (constant_expr->getOpcode()) { - default: - return false; - case Instruction::IntToPtr: - case Instruction::BitCast: - return ResolveConstant(region, constant_expr->getOperand(0)); + default: + return false; + case Instruction::IntToPtr: + case Instruction::BitCast: + return ResolveConstantValue(value, constant_expr->getOperand(0)); + case Instruction::GetElementPtr: + { + ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin(); + ConstantExpr::const_op_iterator op_end = constant_expr->op_end(); + + Constant *base = dyn_cast<Constant>(*op_cursor); + + if (!base) + return false; + + if (!ResolveConstantValue(value, base)) + return false; + + op_cursor++; + + if (op_cursor == op_end) + return true; // no offset to apply! + + SmallVector <Value *, 8> indices (op_cursor, op_end); + + uint64_t offset = m_target_data.getIndexedOffset(base->getType(), indices); + + const bool is_signed = true; + value += APInt(value.getBitWidth(), offset, is_signed); + + return true; + } } } return false; } + bool ResolveConstant (Memory::Region ®ion, const Constant *constant) + { + APInt resolved_value; + + if (!ResolveConstantValue(resolved_value, constant)) + return false; + + const uint64_t *raw_data = resolved_value.getRawData(); + + size_t constant_size = m_target_data.getTypeStoreSize(constant->getType()); + return m_memory.Write(region.m_base, (const uint8_t*)raw_data, constant_size); + } + Memory::Region ResolveValue (const Value *value, Module &module) { ValueMap::iterator i = m_values.find(value); |