[Lldb-commits] [lldb] r150034 - /lldb/trunk/source/Expression/IRInterpreter.cpp

Sean Callanan scallanan at apple.com
Tue Feb 7 17:27:49 PST 2012


Author: spyffe
Date: Tue Feb  7 19:27:49 2012
New Revision: 150034

URL: http://llvm.org/viewvc/llvm-project?rev=150034&view=rev
Log:
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.

Modified:
    lldb/trunk/source/Expression/IRInterpreter.cpp

Modified: lldb/trunk/source/Expression/IRInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRInterpreter.cpp?rev=150034&r1=150033&r2=150034&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRInterpreter.cpp (original)
+++ lldb/trunk/source/Expression/IRInterpreter.cpp Tue Feb  7 19:27:49 2012
@@ -538,35 +538,73 @@
         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);





More information about the lldb-commits mailing list