[cfe-commits] r47260 - /cfe/trunk/AST/ASTContext.cpp

Anders Carlsson andersca at mac.com
Sun Feb 17 23:13:10 PST 2008


Author: andersca
Date: Mon Feb 18 01:13:09 2008
New Revision: 47260

URL: http://llvm.org/viewvc/llvm-project?rev=47260&view=rev
Log:
More bitfield improvements.

Modified:
    cfe/trunk/AST/ASTContext.cpp

Modified: cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/ASTContext.cpp?rev=47260&r1=47259&r2=47260&view=diff

==============================================================================
--- cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/trunk/AST/ASTContext.cpp Mon Feb 18 01:13:09 2008
@@ -331,35 +331,65 @@
       bool FieldIsPacked = StructIsPacked || FD->getAttr<PackedAttr>();
       uint64_t FieldSize;
       unsigned FieldAlign;
-      if (FD->getType()->isIncompleteType()) {
-        // This must be 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.
+      
+      if (const Expr *BitWidthExpr = FD->getBitWidth()) {
+        llvm::APSInt I(32);
+        bool BitWidthIsICE = 
+          BitWidthExpr->isIntegerConstantExpr(I, *this);
+        assert (BitWidthIsICE  && "Invalid BitField size expression");
+        FieldSize = I.getZExtValue();
+
+        std::pair<uint64_t, unsigned> TypeInfo = getTypeInfo(FD->getType(), L);
+        uint64_t TypeSize = TypeInfo.first;
         
         if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
           FieldAlign = AA->getAlignment();
         else if (FieldIsPacked)
           FieldAlign = 8;
         else {
-          const ArrayType* ATy = FD->getType()->getAsArrayType();
-          FieldAlign = getTypeAlign(ATy->getElementType(), L);
+          // FIXME: This is X86 specific, use 32-bit alignment for long long.
+          if (FD->getType()->isIntegerType() && TypeInfo.second > 32)
+            FieldAlign = 32;
+          else
+            FieldAlign = TypeInfo.second;
         }
-        FieldSize = 0;
+
+        // Check if we need to add padding to give the field the correct
+        // alignment.
+        if (RecordSize % FieldAlign + FieldSize > TypeSize)
+          RecordSize = (RecordSize+FieldAlign-1) & ~(FieldAlign-1);
+
       } else {
-        std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType(), L);
-        FieldSize = FieldInfo.first;
+        if (FD->getType()->isIncompleteType()) {
+          // This must be 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.
         
-        if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
-          FieldAlign = AA->getAlignment();
-        else if (FieldIsPacked)
-          FieldAlign = 8;
-        else
-          FieldAlign = FieldInfo.second;
-      }
+          if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
+            FieldAlign = AA->getAlignment();
+          else if (FieldIsPacked)
+            FieldAlign = 8;
+          else {
+            const ArrayType* ATy = FD->getType()->getAsArrayType();
+            FieldAlign = getTypeAlign(ATy->getElementType(), L);
+          }
+          FieldSize = 0;
+        } else {
+          std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType(), L);
+          FieldSize = FieldInfo.first;
+        
+          if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
+            FieldAlign = AA->getAlignment();
+          else if (FieldIsPacked)
+            FieldAlign = 8;
+          else
+            FieldAlign = FieldInfo.second;
+        }
 
-      // Round up the current record size to the field's alignment boundary.
-      RecordSize = (RecordSize+FieldAlign-1) & ~(FieldAlign-1);
+        // Round up the current record size to the field's alignment boundary.
+        RecordSize = (RecordSize+FieldAlign-1) & ~(FieldAlign-1);
+      }
       
       // Place this field at the current location.
       FieldOffsets[i] = RecordSize;
@@ -382,6 +412,10 @@
       uint64_t FieldSize = FieldInfo.first;
       unsigned FieldAlign = FieldInfo.second;
       
+      // FIXME: This is X86 specific, use 32-bit alignment for long long.
+      if (FD->getType()->isIntegerType() && FieldAlign > 32)
+        FieldAlign = 32;
+
       // Round up the current record size to the field's alignment boundary.
       RecordSize = std::max(RecordSize, FieldSize);
       





More information about the cfe-commits mailing list