[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