]> granicus.if.org Git - clang/commitdiff
Move the LLVM field number for bit fields into the BitFieldInfo structure, since...
authorAnders Carlsson <andersca@mac.com>
Thu, 23 Jul 2009 17:01:21 +0000 (17:01 +0000)
committerAnders Carlsson <andersca@mac.com>
Thu, 23 Jul 2009 17:01:21 +0000 (17:01 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76882 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprConstant.cpp
lib/CodeGen/CGRecordLayoutBuilder.cpp
lib/CodeGen/CGRecordLayoutBuilder.h
lib/CodeGen/CodeGenTypes.cpp
lib/CodeGen/CodeGenTypes.h

index de44e697211d423e0c245c6163b0519d3f07972d..9b5b68d3f66e2886543eeabb5b4d51073b8c8c41 100644 (file)
@@ -1026,7 +1026,8 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
 LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue,
                                               FieldDecl* Field,
                                               unsigned CVRQualifiers) {
-   unsigned idx = CGM.getTypes().getLLVMFieldNo(Field);
+  CodeGenTypes::BitFieldInfo Info = CGM.getTypes().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 = 
@@ -1037,13 +1038,12 @@ LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue,
   BaseValue = Builder.CreateBitCast(BaseValue,
                                     VMContext.getPointerType(FieldTy, AS),
                                     "tmp");
-  llvm::Value *V = Builder.CreateGEP(BaseValue,
-                            VMContext.getConstantInt(llvm::Type::Int32Ty, idx),
-                              "tmp");
   
-  CodeGenTypes::BitFieldInfo bitFieldInfo = 
-    CGM.getTypes().getBitFieldInfo(Field);
-  return LValue::MakeBitfield(V, bitFieldInfo.Begin, bitFieldInfo.Size,
+  llvm::Value *Idx = 
+    VMContext.getConstantInt(llvm::Type::Int32Ty, Info.FieldNo);
+  llvm::Value *V = Builder.CreateGEP(BaseValue, Idx, "tmp");
+  
+  return LValue::MakeBitfield(V, Info.Start, Info.Size,
                               Field->getType()->isSignedIntegerType(),
                             Field->getType().getCVRQualifiers()|CVRQualifiers);
 }
index 43284b517307296c951fe08baebf317a8e3cf636..61b217bc66619327796ad37026684378fbd22a70 100644 (file)
@@ -139,16 +139,16 @@ public:
     const llvm::Type* Ty = CI->getType();
     const llvm::TargetData &TD = CGM.getTypes().getTargetData();
     unsigned size = TD.getTypeAllocSizeInBits(Ty);
-    unsigned fieldOffset = CGM.getTypes().getLLVMFieldNo(Field) * size;
-    CodeGenTypes::BitFieldInfo bitFieldInfo =
-        CGM.getTypes().getBitFieldInfo(Field);
-    fieldOffset += bitFieldInfo.Begin;
+    CodeGenTypes::BitFieldInfo Info = CGM.getTypes().getBitFieldInfo(Field);
+    unsigned FieldOffset = Info.FieldNo * size;
+        
+    FieldOffset += Info.Start;
 
     // Find where to start the insertion
     // FIXME: This is O(n^2) in the number of bit-fields!
     // FIXME: This won't work if the struct isn't completely packed!
     unsigned offset = 0, i = 0;
-    while (offset < (fieldOffset & -8))
+    while (offset < (FieldOffset & -8))
       offset += TD.getTypeAllocSizeInBits(Elts[i++]->getType());
 
     // Advance over 0 sized elements (must terminate in bounds since
@@ -160,15 +160,15 @@ public:
     // FIXME: This should never occur, but currently it can because initializer
     // constants are cast to bool, and because clang is not enforcing bitfield
     // width limits.
-    if (bitFieldInfo.Size > V.getBitWidth())
-      V.zext(bitFieldInfo.Size);
+    if (Info.Size > V.getBitWidth())
+      V.zext(Info.Size);
 
     // Insert the bits into the struct
     // FIXME: This algorthm is only correct on X86!
     // FIXME: THis algorthm assumes bit-fields only have byte-size elements!
-    unsigned bitsToInsert = bitFieldInfo.Size;
-    unsigned curBits = std::min(8 - (fieldOffset & 7), bitsToInsert);
-    unsigned byte = V.getLoBits(curBits).getZExtValue() << (fieldOffset & 7);
+    unsigned bitsToInsert = Info.Size;
+    unsigned curBits = std::min(8 - (FieldOffset & 7), bitsToInsert);
+    unsigned byte = V.getLoBits(curBits).getZExtValue() << (FieldOffset & 7);
     do {
       llvm::Constant* byteC =
         VMContext.getConstantInt(llvm::Type::Int8Ty, byte);
index fa096bd63067dc9b08876eea82a268c23cede987..5f6946db6ba9e4c75dc2533a08e705cc37407755 100644 (file)
@@ -85,8 +85,8 @@ void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D,
   const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(D->getType());
   uint64_t TypeSizeInBits = getTypeSizeInBytes(Ty) * 8;
   
-  LLVMFields.push_back(LLVMFieldInfo(D, FieldOffset / TypeSizeInBits));
-  LLVMBitFields.push_back(LLVMBitFieldInfo(D, FieldOffset % TypeSizeInBits, 
+  LLVMBitFields.push_back(LLVMBitFieldInfo(D, FieldOffset / TypeSizeInBits,
+                                           FieldOffset % TypeSizeInBits, 
                                            FieldSize));
   
   AppendBytes(NumBytesToAppend);
@@ -190,13 +190,13 @@ void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) {
   // Now add our field.
   if (FD) {
     AppendField(0, Size, Ty);
-    Types.addFieldInfo(FD, 0);
     
     if (FD->isBitField()) {
       uint64_t FieldSize = 
         FD->getBitWidth()->EvaluateAsInt(Types.getContext()).getZExtValue();
-      Types.addBitFieldInfo(FD, 0, FieldSize);
-    }
+      Types.addBitFieldInfo(FD, 0, 0, FieldSize);
+    } else
+      Types.addFieldInfo(FD, 0);
   }
   
   // Append tail padding.
@@ -324,7 +324,7 @@ CGRecordLayoutBuilder::ComputeLayout(CodeGenTypes &Types,
   for (unsigned i = 0, e = Builder.LLVMBitFields.size(); i != e; ++i) {
     const LLVMBitFieldInfo &Info = Builder.LLVMBitFields[i];
     
-    Types.addBitFieldInfo(Info.FD, Info.Start, Info.Size);
+    Types.addBitFieldInfo(Info.FD, Info.FieldNo, Info.Start, Info.Size);
   }
   
   return new CGRecordLayout(Ty, llvm::SmallSet<unsigned, 8>());
index c1ba6056d78c1ddd385dfe5c53840979725a4c92..2f212f86c022b9197f36f333675bd0a4e8e13e49 100644 (file)
@@ -66,11 +66,13 @@ class CGRecordLayoutBuilder {
 
   /// LLVMBitFieldInfo - Holds location and size information about a bit field.
   struct LLVMBitFieldInfo {
-    LLVMBitFieldInfo(const FieldDecl *FD, unsigned Start, unsigned Size)
-      : FD(FD), Start(Start), Size(Size) { }
+    LLVMBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, unsigned Start, 
+                     unsigned Size)
+      : FD(FD), FieldNo(FieldNo), Start(Start), Size(Size) { }
     
     const FieldDecl *FD;
     
+    unsigned FieldNo;
     unsigned Start;
     unsigned Size;
   };
index 59463fa24ffe7a2f98b8109b45104544fd0b2ec8..0869b2d11c05b623efce248184b8764ab8d78346 100644 (file)
@@ -494,6 +494,8 @@ const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) {
 /// getLLVMFieldNo - Return llvm::StructType element number
 /// that corresponds to the field FD.
 unsigned CodeGenTypes::getLLVMFieldNo(const FieldDecl *FD) {
+  assert(!FD->isBitField() && "Don't use getLLVMFieldNo on bit fields!");
+  
   llvm::DenseMap<const FieldDecl*, unsigned>::iterator I = FieldInfo.find(FD);
   assert (I != FieldInfo.end()  && "Unable to find field info");
   return I->second;
@@ -513,9 +515,9 @@ CodeGenTypes::BitFieldInfo CodeGenTypes::getBitFieldInfo(const FieldDecl *FD) {
 }
 
 /// addBitFieldInfo - Assign a start bit and a size to field FD.
-void CodeGenTypes::addBitFieldInfo(const FieldDecl *FD, unsigned Begin,
-                                   unsigned Size) {
-  BitFields.insert(std::make_pair(FD, BitFieldInfo(Begin, Size)));
+void CodeGenTypes::addBitFieldInfo(const FieldDecl *FD, unsigned FieldNo,
+                                   unsigned Start, unsigned Size) {
+  BitFields.insert(std::make_pair(FD, BitFieldInfo(FieldNo, Start, Size)));
 }
 
 /// getCGRecordLayout - Return record layout info for the given llvm::Type.
@@ -559,8 +561,7 @@ void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) {
       // Bitfield field info is different from other field info;
       // it actually ignores the underlying LLVM struct because
       // there isn't any convenient mapping.
-      CGT.addFieldInfo(*Field, offset / size);
-      CGT.addBitFieldInfo(*Field, offset % size, BitFieldSize);
+      CGT.addBitFieldInfo(*Field, offset / size, offset % size, BitFieldSize);
     } else {
       // Put the element into the struct. This would be simpler
       // if we didn't bother, but it seems a bit too strange to
@@ -603,8 +604,7 @@ void RecordOrganizer::layoutUnionFields(const ASTRecordLayout &RL) {
       uint64_t BitFieldSize =  
         BitWidth->EvaluateAsInt(CGT.getContext()).getZExtValue();
 
-      CGT.addFieldInfo(*Field, 0);
-      CGT.addBitFieldInfo(*Field, offset, BitFieldSize);
+      CGT.addBitFieldInfo(*Field, 0, offset, BitFieldSize);
     } else {
       CGT.addFieldInfo(*Field, 0);
     }
index 925b933fca01c4e4e266c59b6830d2f7f9913b9b..0f6e51d1d3ec93b9fe1601906dbdc96df1f9ada7 100644 (file)
@@ -113,13 +113,15 @@ class CodeGenTypes {
   llvm::FoldingSet<CGFunctionInfo> FunctionInfos;
 
 public:
-  class BitFieldInfo {
-  public:
-    explicit BitFieldInfo(unsigned short B, unsigned short S)
-      : Begin(B), Size(S) {}
-
-    unsigned short Begin;
-    unsigned short Size;
+  struct BitFieldInfo {
+    BitFieldInfo(unsigned FieldNo, 
+                 unsigned Start, 
+                 unsigned Size)
+      : FieldNo(FieldNo), Start(Start), Size(Size) {}
+
+    unsigned FieldNo;
+    unsigned Start;
+    unsigned Size;
   };
 
 private:
@@ -188,10 +190,11 @@ public:
   
 public:  // These are internal details of CGT that shouldn't be used externally.
   /// addFieldInfo - Assign field number to field FD.
-  void addFieldInfo(const FieldDecl *FD, unsigned No);
+  void addFieldInfo(const FieldDecl *FD, unsigned FieldNo);
 
   /// addBitFieldInfo - Assign a start bit and a size to field FD.
-  void addBitFieldInfo(const FieldDecl *FD, unsigned Begin, unsigned Size);
+  void addBitFieldInfo(const FieldDecl *FD, unsigned FieldNo,
+                       unsigned Start, unsigned Size);
 
   /// getBitFieldInfo - Return the BitFieldInfo  that corresponds to the field
   /// FD.