summaryrefslogtreecommitdiffstats
path: root/lldb/source/Expression/IRInterpreter.cpp
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2012-02-08 01:27:49 +0000
committerSean Callanan <scallanan@apple.com>2012-02-08 01:27:49 +0000
commit94a9a39ec450520ac97b1e065b337012fda0a81c (patch)
tree85941ffe8fae576fff03361389e60edd9fef8d38 /lldb/source/Expression/IRInterpreter.cpp
parenta2a299e586bf3143480e1a75fbe20235d5fa33ff (diff)
downloadbcm5719-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.cpp62
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 &region, 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 &region, 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);
OpenPOWER on IntegriCloud