]> granicus.if.org Git - clang/commitdiff
IRgen: Move the bit-field access type into CGBitFieldInfo, and change bit-field LValu...
authorDaniel Dunbar <daniel@zuster.org>
Thu, 8 Apr 2010 02:59:45 +0000 (02:59 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 8 Apr 2010 02:59:45 +0000 (02:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100745 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGObjCMac.cpp
lib/CodeGen/CGRecordLayout.h
lib/CodeGen/CGRecordLayoutBuilder.cpp
lib/CodeGen/CGValue.h

index 0aa4438f4f47d35cae29dc0ec351547fcf8868c3..6fd18f395c4f007aa082c0a0c8895f388835fa98 100644 (file)
@@ -603,12 +603,27 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
   return EmitLoadOfKVCRefLValue(LV, ExprType);
 }
 
+static llvm::Value *getBitFieldAddr(LValue LV, CGBuilderTy &Builder) {
+  const CGBitFieldInfo &Info = LV.getBitFieldInfo();
+
+  llvm::Value *BaseValue = LV.getBitFieldBaseAddr();
+  const llvm::PointerType *BaseTy =
+    cast<llvm::PointerType>(BaseValue->getType());
+
+  // Cast to the type of the access we will perform.
+  llvm::Value *V = Builder.CreateBitCast(
+    BaseValue, llvm::PointerType::get(Info.FieldTy, BaseTy->getAddressSpace()));
+
+  // Offset by the access index.
+  return Builder.CreateConstGEP1_32(V, Info.FieldNo);
+}
+
 RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
                                                  QualType ExprType) {
   const CGBitFieldInfo &Info = LV.getBitFieldInfo();
   unsigned StartBit = Info.Start;
   unsigned BitfieldSize = Info.Size;
-  llvm::Value *Ptr = LV.getBitFieldAddr();
+  llvm::Value *Ptr = getBitFieldAddr(LV, Builder);
 
   const llvm::Type *EltTy =
     cast<llvm::PointerType>(Ptr->getType())->getElementType();
@@ -785,7 +800,7 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
   const CGBitFieldInfo &Info = Dst.getBitFieldInfo();
   unsigned StartBit = Info.Start;
   unsigned BitfieldSize = Info.Size;
-  llvm::Value *Ptr = Dst.getBitFieldAddr();
+  llvm::Value *Ptr = getBitFieldAddr(Dst, Builder);
 
   const llvm::Type *EltTy =
     cast<llvm::PointerType>(Ptr->getType())->getElementType();
@@ -1474,19 +1489,7 @@ LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue,
   const CGRecordLayout &RL =
     CGM.getTypes().getCGRecordLayout(Field->getParent());
   const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field);
-
-  // FIXME: CodeGenTypes should expose a method to get the appropriate type for
-  // FieldTy (the appropriate type is ABI-dependent).
-  const llvm::Type *FieldTy =
-    CGM.getTypes().ConvertTypeForMem(Field->getType());
-  const llvm::PointerType *BaseTy =
-  cast<llvm::PointerType>(BaseValue->getType());
-  unsigned AS = BaseTy->getAddressSpace();
-  BaseValue = Builder.CreateBitCast(BaseValue,
-                                    llvm::PointerType::get(FieldTy, AS));
-  llvm::Value *V = Builder.CreateConstGEP1_32(BaseValue, Info.FieldNo);
-
-  return LValue::MakeBitfield(V, Info,
+  return LValue::MakeBitfield(BaseValue, Info,
                              Field->getType().getCVRQualifiers()|CVRQualifiers);
 }
 
index ac8fa057a0e75f1a717854cdd1f6f8128e17ad57..be17e59d972ef7a01027dd569ecb92dbaa27a16c 100644 (file)
@@ -126,8 +126,8 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
   // objects.
   unsigned FieldNo = 0; // This value is unused.
   CGBitFieldInfo *Info =
-    new (CGF.CGM.getContext()) CGBitFieldInfo(FieldNo, BitOffset, BitFieldSize,
-                                              IvarTy->isSignedIntegerType());
+    new (CGF.CGM.getContext()) CGBitFieldInfo(
+      LTy, FieldNo, BitOffset, BitFieldSize, IvarTy->isSignedIntegerType());
 
   // FIXME: We need to set a very conservative alignment on this, or make sure
   // that the runtime is doing the right thing.
index fd1775ea5e6cfe9c9ba813c7f86dd5432260c188..86c57d10c4ac3613fd3e631494e59bce89f832f6 100644 (file)
@@ -21,11 +21,14 @@ namespace CodeGen {
 
 class CGBitFieldInfo {
 public:
-  CGBitFieldInfo(unsigned FieldNo, unsigned Start, unsigned Size,
-                 bool IsSigned)
-    : FieldNo(FieldNo), Start(Start), Size(Size), IsSigned(IsSigned) {}
+  CGBitFieldInfo(const llvm::Type *FieldTy, unsigned FieldNo,
+                 unsigned Start, unsigned Size, bool IsSigned)
+    : FieldTy(FieldTy), FieldNo(FieldNo),
+      Start(Start), Size(Size), IsSigned(IsSigned) {}
 
+  const llvm::Type *FieldTy;
   unsigned FieldNo;
+
   unsigned Start;
   unsigned Size;
   bool IsSigned : 1;
index 4b9ec66e178c3f07a36e37667460b9287eea13dc..fdd8d059267439b5296b5dbda3b7a53d2b50ea86 100644 (file)
@@ -180,7 +180,7 @@ void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D,
 
   bool IsSigned = D->getType()->isSignedIntegerType();
   LLVMBitFields.push_back(LLVMBitFieldInfo(
-                            D, CGBitFieldInfo(FieldOffset / TypeSizeInBits,
+                            D, CGBitFieldInfo(Ty, FieldOffset / TypeSizeInBits,
                                               FieldOffset % TypeSizeInBits,
                                               FieldSize, IsSigned)));
 
@@ -270,6 +270,8 @@ void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) {
        FieldEnd = D->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
     assert(Layout.getFieldOffset(FieldNo) == 0 &&
           "Union field offset did not start at the beginning of record!");
+    const llvm::Type *FieldTy =
+      Types.ConvertTypeForMemRecursive(Field->getType());
 
     if (Field->isBitField()) {
       uint64_t FieldSize =
@@ -282,7 +284,7 @@ void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) {
       // Add the bit field info.
       bool IsSigned = Field->getType()->isSignedIntegerType();
       LLVMBitFields.push_back(LLVMBitFieldInfo(
-                                *Field, CGBitFieldInfo(0, 0, FieldSize,
+                                *Field, CGBitFieldInfo(FieldTy, 0, 0, FieldSize,
                                                        IsSigned)));
     } else {
       LLVMFields.push_back(LLVMFieldInfo(*Field, 0));
@@ -290,8 +292,6 @@ void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) {
 
     HasOnlyZeroSizedBitFields = false;
 
-    const llvm::Type *FieldTy =
-      Types.ConvertTypeForMemRecursive(Field->getType());
     unsigned FieldAlign = Types.getTargetData().getABITypeAlignment(FieldTy);
     uint64_t FieldSize = Types.getTargetData().getTypeAllocSize(FieldTy);
 
index 91fb714315fc4542105e2ebad25da02d064f4b62..e7343e2018441ba2b5fbb4633d3b03296746e5da 100644 (file)
@@ -220,7 +220,7 @@ public:
   }
 
   // bitfield lvalue
-  llvm::Value *getBitFieldAddr() const {
+  llvm::Value *getBitFieldBaseAddr() const {
     assert(isBitField());
     return V;
   }
@@ -269,11 +269,17 @@ public:
     return R;
   }
 
-  static LValue MakeBitfield(llvm::Value *V, const CGBitFieldInfo &Info,
+  /// \brief Create a new object to represent a bit-field access.
+  ///
+  /// \param BaseValue - The base address of the structure containing the
+  /// bit-field.
+  /// \param Info - The information describing how to perform the bit-field
+  /// access.
+  static LValue MakeBitfield(llvm::Value *BaseValue, const CGBitFieldInfo &Info,
                              unsigned CVR) {
     LValue R;
     R.LVType = BitField;
-    R.V = V;
+    R.V = BaseValue;
     R.BitFieldInfo = &Info;
     R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
     return R;