[cfe-commits] r89604 - in /cfe/trunk/lib/AST: RecordLayoutBuilder.cpp RecordLayoutBuilder.h

Anders Carlsson andersca at mac.com
Sun Nov 22 09:37:32 PST 2009


Author: andersca
Date: Sun Nov 22 11:37:31 2009
New Revision: 89604

URL: http://llvm.org/viewvc/llvm-project?rev=89604&view=rev
Log:
Move bit-field layout out into a separate function. No functionality change.

Modified:
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
    cfe/trunk/lib/AST/RecordLayoutBuilder.h

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=89604&r1=89603&r2=89604&view=diff

==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Sun Nov 22 11:37:31 2009
@@ -519,86 +519,103 @@
     LayoutField(*Field);
 }
 
+void ASTRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
+  bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
+  uint64_t FieldOffset = IsUnion ? 0 : DataSize;
+  uint64_t FieldSize = D->getBitWidth()->EvaluateAsInt(Ctx).getZExtValue();
+  
+  std::pair<uint64_t, unsigned> FieldInfo = Ctx.getTypeInfo(D->getType());
+  uint64_t TypeSize = FieldInfo.first;
+  unsigned FieldAlign = FieldInfo.second;
+  
+  if (FieldPacked)
+    FieldAlign = 1;
+  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
+    FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
+
+  // The maximum field alignment overrides the aligned attribute.
+  if (MaxFieldAlignment)
+    FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
+  
+  // Check if we need to add padding to give the field the correct
+  // alignment.
+  if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)
+    FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
+  
+  // Padding members don't affect overall alignment
+  if (!D->getIdentifier())
+    FieldAlign = 1;
+  
+  // Place this field at the current location.
+  FieldOffsets.push_back(FieldOffset);
+  
+  // Reserve space for this field.
+  if (IsUnion)
+    Size = std::max(Size, FieldSize);
+  else
+    Size = FieldOffset + FieldSize;
+  
+  // Update the data size.
+  DataSize = Size;
+  
+  // Remember max struct/class alignment.
+  UpdateAlignment(FieldAlign);
+}
+
 void ASTRecordLayoutBuilder::LayoutField(const FieldDecl *D) {
-  bool FieldPacked = Packed;
+  if (D->isBitField()) {
+    LayoutBitField(D);
+    return;
+  }
+
+  bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
   uint64_t FieldOffset = IsUnion ? 0 : DataSize;
   uint64_t FieldSize;
   unsigned FieldAlign;
-
-  FieldPacked |= D->hasAttr<PackedAttr>();
-
-  if (const Expr *BitWidthExpr = D->getBitWidth()) {
-    // TODO: Need to check this algorithm on other targets!
-    //       (tested on Linux-X86)
-    FieldSize = BitWidthExpr->EvaluateAsInt(Ctx).getZExtValue();
-
+  
+  if (D->getType()->isIncompleteArrayType()) {
+    // This is a flexible array member; we can't directly
+    // query getTypeInfo about these, so we figure it out here.
+    // Flexible array members don't have any size, but they
+    // have to be aligned appropriately for their element type.
+    FieldSize = 0;
+    const ArrayType* ATy = Ctx.getAsArrayType(D->getType());
+    FieldAlign = Ctx.getTypeAlign(ATy->getElementType());
+  } else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) {
+    unsigned AS = RT->getPointeeType().getAddressSpace();
+    FieldSize = Ctx.Target.getPointerWidth(AS);
+    FieldAlign = Ctx.Target.getPointerAlign(AS);
+  } else {
     std::pair<uint64_t, unsigned> FieldInfo = Ctx.getTypeInfo(D->getType());
-    uint64_t TypeSize = FieldInfo.first;
-
+    FieldSize = FieldInfo.first;
     FieldAlign = FieldInfo.second;
+  }
 
-    if (FieldPacked)
-      FieldAlign = 1;
-    if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) {
-      FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
-    }
-    // The maximum field alignment overrides the aligned attribute.
-    if (MaxFieldAlignment)
-      FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
-
-    // Check if we need to add padding to give the field the correct
-    // alignment.
-    if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)
-      FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
-
-    // Padding members don't affect overall alignment
-    if (!D->getIdentifier())
-      FieldAlign = 1;
-  } else {
-    if (D->getType()->isIncompleteArrayType()) {
-      // This is a flexible array member; we can't directly
-      // query getTypeInfo about these, so we figure it out here.
-      // Flexible array members don't have any size, but they
-      // have to be aligned appropriately for their element type.
-      FieldSize = 0;
-      const ArrayType* ATy = Ctx.getAsArrayType(D->getType());
-      FieldAlign = Ctx.getTypeAlign(ATy->getElementType());
-    } else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) {
-      unsigned AS = RT->getPointeeType().getAddressSpace();
-      FieldSize = Ctx.Target.getPointerWidth(AS);
-      FieldAlign = Ctx.Target.getPointerAlign(AS);
-    } else {
-      std::pair<uint64_t, unsigned> FieldInfo = Ctx.getTypeInfo(D->getType());
-      FieldSize = FieldInfo.first;
-      FieldAlign = FieldInfo.second;
-    }
-
-    if (FieldPacked)
-      FieldAlign = 8;
-    if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) {
-      FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
-    }
-    // The maximum field alignment overrides the aligned attribute.
-    if (MaxFieldAlignment)
-      FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
-
-    // Round up the current record size to the field's alignment boundary.
-    FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
-    
-    if (!IsUnion) {
-      while (true) {
-        // Check if we can place the field at this offset.
-        if (canPlaceFieldAtOffset(D, FieldOffset))
-          break;
-        
-        // We couldn't place the field at the offset. Try again at a new offset.
-        FieldOffset += FieldAlign;
-      }
+  if (FieldPacked)
+    FieldAlign = 8;
+  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
+    FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
+
+  // The maximum field alignment overrides the aligned attribute.
+  if (MaxFieldAlignment)
+    FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
+
+  // Round up the current record size to the field's alignment boundary.
+  FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
+  
+  if (!IsUnion) {
+    while (true) {
+      // Check if we can place the field at this offset.
+      if (canPlaceFieldAtOffset(D, FieldOffset))
+        break;
       
-      UpdateEmptyClassOffsets(D, FieldOffset);
+      // We couldn't place the field at the offset. Try again at a new offset.
+      FieldOffset += FieldAlign;
     }
+    
+    UpdateEmptyClassOffsets(D, FieldOffset);
   }
-
+  
   // Place this field at the current location.
   FieldOffsets.push_back(FieldOffset);
 
@@ -621,7 +638,7 @@
     Size = 8;
   // Finally, round the size of the record up to the alignment of the
   // record itself.
-  Size = (Size + (Alignment-1)) & ~(Alignment-1);
+  Size = llvm::RoundUpToAlignment(Size, Alignment);
 }
 
 void ASTRecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) {

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.h?rev=89604&r1=89603&r2=89604&view=diff

==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.h (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.h Sun Nov 22 11:37:31 2009
@@ -74,6 +74,7 @@
 
   void LayoutFields(const RecordDecl *D);
   void LayoutField(const FieldDecl *D);
+  void LayoutBitField(const FieldDecl *D);
 
   void SelectPrimaryBase(const CXXRecordDecl *RD);
   void SelectPrimaryVBase(const CXXRecordDecl *RD,





More information about the cfe-commits mailing list