[llvm-commits] [124887] Fix component reference handling.

dpatel at apple.com dpatel at apple.com
Mon Mar 12 15:27:39 PDT 2007


Revision: 124887
Author:   dpatel
Date:     2007-03-12 15:27:39 -0700 (Mon, 12 Mar 2007)

Log Message:
-----------
Fix component reference handling. Patch by Duncan Sands.

Modified Paths:
--------------
    apple-local/branches/llvm/gcc/llvm-convert.cpp

Modified: apple-local/branches/llvm/gcc/llvm-convert.cpp
===================================================================
--- apple-local/branches/llvm/gcc/llvm-convert.cpp	2007-03-12 18:24:41 UTC (rev 124886)
+++ apple-local/branches/llvm/gcc/llvm-convert.cpp	2007-03-12 22:27:39 UTC (rev 124887)
@@ -4596,6 +4596,20 @@
   return Result;
 }
 
+/// getComponentRefOffsetInBits - Return the offset (in bits) of the field
+/// referenced in a COMPONENT_REF exp.
+static unsigned getComponentRefOffsetInBits(tree exp) {
+  assert(TREE_CODE(exp) == COMPONENT_REF && "not a COMPONENT_REF!");
+  tree field = TREE_OPERAND(exp, 1);
+  assert(TREE_CODE(field) == FIELD_DECL && "not a FIELD_DECL!");
+  tree field_offset = component_ref_field_offset (exp);
+  assert(DECL_FIELD_BIT_OFFSET(field) && field_offset);
+  unsigned Result = TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(field));
+  if (TREE_CODE(field_offset) == INTEGER_CST)
+    Result += TREE_INT_CST_LOW(field_offset)*8;
+  return Result;
+}
+
 LValue TreeToLLVM::EmitLV_COMPONENT_REF(tree exp) {
   LValue StructAddrLV = EmitLV(TREE_OPERAND(exp, 0));
   tree FieldDecl = TREE_OPERAND(exp, 1);
@@ -4618,11 +4632,12 @@
   
   // BitStart - This is the actual offset of the field from the start of the
   // struct, in bits.  For bitfields this may be on a non-byte boundary.
-  unsigned BitStart = getFieldOffsetInBits(FieldDecl);
+  unsigned BitStart = getComponentRefOffsetInBits(exp);
   Value *FieldPtr;
   
+  tree field_offset = component_ref_field_offset (exp);
   // If this is a normal field at a fixed offset from the start, handle it.
-  if (TREE_CODE(DECL_FIELD_OFFSET(FieldDecl)) == INTEGER_CST) {
+  if (TREE_CODE(field_offset) == INTEGER_CST) {
     assert(DECL_LLVM_SET_P(FieldDecl) && "Struct not laid out for LLVM?");
     ConstantInt *CI = cast<ConstantInt>(DECL_LLVM(FieldDecl));
     uint32_t MemberIndex = CI->getZExtValue();
@@ -4646,7 +4661,7 @@
     }
     
   } else {
-    Value *Offset = Emit(DECL_FIELD_OFFSET(FieldDecl), 0);
+    Value *Offset = Emit(field_offset, 0);
     Value *Ptr = CastToType(Instruction::PtrToInt, StructAddrLV.Ptr, 
                             Offset->getType());
     Ptr = BinaryOperator::createAdd(Ptr, Offset, "tmp", CurBB);
@@ -5663,13 +5678,14 @@
   
   // BitStart - This is the actual offset of the field from the start of the
   // struct, in bits.  For bitfields this may be on a non-byte boundary.
-  unsigned BitStart = getFieldOffsetInBits(FieldDecl);
+  unsigned BitStart = getComponentRefOffsetInBits(exp);
   unsigned BitSize  = 0;
   Constant *FieldPtr;
   const TargetData &TD = getTargetData();
-  
+
+  tree field_offset = component_ref_field_offset (exp);
   // If this is a normal field at a fixed offset from the start, handle it.
-  if (TREE_CODE(DECL_FIELD_OFFSET(FieldDecl)) == INTEGER_CST) {
+  if (TREE_CODE(field_offset) == INTEGER_CST) {
     assert(DECL_LLVM_SET_P(FieldDecl) && "Struct not laid out for LLVM?");
     ConstantInt *CI = cast<ConstantInt>(DECL_LLVM(FieldDecl));
     uint64_t MemberIndex = CI->getZExtValue();
@@ -5689,18 +5705,18 @@
       }
     } else {
       // We were unable to make a nice offset, emit an ugly one.
-      Constant *Offset = Convert(DECL_FIELD_OFFSET(FieldDecl));
+      Constant *Offset = Convert(field_offset);
       FieldPtr = ConstantExpr::getPtrToInt(StructAddrLV, Offset->getType());
       FieldPtr = ConstantExpr::getAdd(FieldPtr, Offset);
       FieldPtr = ConstantExpr::getIntToPtr(FieldPtr, PointerType::get(FieldTy));
       
       // Do horrible pointer arithmetic to get the address of the field.
-      unsigned ByteOffset = TREE_INT_CST_LOW(DECL_FIELD_OFFSET(FieldDecl));
+      unsigned ByteOffset = TREE_INT_CST_LOW(field_offset);
       BitStart -= ByteOffset * 8;
     }
     
   } else {
-    Constant *Offset = Convert(DECL_FIELD_OFFSET(FieldDecl));
+    Constant *Offset = Convert(field_offset);
     Constant *Ptr = ConstantExpr::getPtrToInt(StructAddrLV, Offset->getType());
     Ptr = ConstantExpr::getAdd(Ptr, Offset);
     FieldPtr = ConstantExpr::getIntToPtr(Ptr, PointerType::get(FieldTy));





More information about the llvm-commits mailing list