[cfe-commits] r51966 - in /cfe/trunk: include/clang/AST/RecordLayout.h lib/AST/ASTContext.cpp

Devang Patel dpatel at apple.com
Wed Jun 4 14:22:18 PDT 2008


Author: dpatel
Date: Wed Jun  4 16:22:16 2008
New Revision: 51966

URL: http://llvm.org/viewvc/llvm-project?rev=51966&view=rev
Log:
Refactoring. 
Move field layout code in a ASTRecordLayout member fn.

Modified:
    cfe/trunk/include/clang/AST/RecordLayout.h
    cfe/trunk/lib/AST/ASTContext.cpp

Modified: cfe/trunk/include/clang/AST/RecordLayout.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecordLayout.h?rev=51966&r1=51965&r2=51966&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/RecordLayout.h (original)
+++ cfe/trunk/include/clang/AST/RecordLayout.h Wed Jun  4 16:22:16 2008
@@ -29,15 +29,29 @@
   uint64_t *FieldOffsets;
   friend class ASTContext;
   
-  ASTRecordLayout() {}
+  ASTRecordLayout() : Size(0), Alignment(8) {}
   ~ASTRecordLayout() {
     delete [] FieldOffsets;
   }
+
+  /// Initialize record layout. N is the number of fields in this record.
+  void InitializeLayout(unsigned N) {
+    FieldOffsets = new uint64_t[N];
+  }
   
-  void SetLayout(uint64_t size, unsigned alignment, uint64_t *fieldOffsets) {
-    Size = size; Alignment = alignment;
-    FieldOffsets = fieldOffsets;
+  /// Finalize record layout. Adjust record size based on the alignment.
+  void FinalizeLayout() {
+    // Finally, round the size of the record up to the alignment of the
+    // record itself.
+    Size = (Size + (Alignment-1)) & ~(Alignment-1);
   }
+
+  void SetAlignment(unsigned A) {  Alignment = A; }
+
+  /// LayoutField - Field layout.
+  void LayoutField(const FieldDecl *FD, unsigned FieldNo,
+                   bool IsUnion, bool StructIsPacked,
+                   ASTContext &Context);
   
   ASTRecordLayout(const ASTRecordLayout&);   // DO NOT IMPLEMENT
   void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT

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

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Jun  4 16:22:16 2008
@@ -311,6 +311,81 @@
   return std::make_pair(Width, Align);
 }
 
+/// LayoutField - Field layout.
+void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo,
+                                  bool IsUnion, bool StructIsPacked,
+                                  ASTContext &Context) {
+  bool FieldIsPacked = StructIsPacked || FD->getAttr<PackedAttr>();
+  uint64_t FieldOffset = IsUnion ? 0 : Size;
+  uint64_t FieldSize;
+  unsigned FieldAlign;
+  
+  if (const Expr *BitWidthExpr = FD->getBitWidth()) {
+    // TODO: Need to check this algorithm on other targets!
+    //       (tested on Linux-X86)
+    llvm::APSInt I(32);
+    bool BitWidthIsICE = 
+      BitWidthExpr->isIntegerConstantExpr(I, Context);
+    assert (BitWidthIsICE  && "Invalid BitField size expression");
+    FieldSize = I.getZExtValue();
+    
+    std::pair<uint64_t, unsigned> FieldInfo = 
+      Context.getTypeInfo(FD->getType());
+    uint64_t TypeSize = FieldInfo.first;
+    
+    FieldAlign = FieldInfo.second;
+    if (FieldIsPacked)
+      FieldAlign = 1;
+    if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
+      FieldAlign = std::max(FieldAlign, AA->getAlignment());
+    
+    // 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 (!FD->getIdentifier())
+      FieldAlign = 1;
+  } else {
+    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.
+      FieldSize = 0;
+      const ArrayType* ATy = FD->getType()->getAsArrayType();
+      FieldAlign = Context.getTypeAlign(ATy->getElementType());
+    } else {
+      std::pair<uint64_t, unsigned> FieldInfo = 
+        Context.getTypeInfo(FD->getType());
+      FieldSize = FieldInfo.first;
+      FieldAlign = FieldInfo.second;
+    }
+    
+    if (FieldIsPacked)
+      FieldAlign = 8;
+    if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
+      FieldAlign = std::max(FieldAlign, AA->getAlignment());
+    
+    // Round up the current record size to the field's alignment boundary.
+    FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
+  }
+  
+  // Place this field at the current location.
+  FieldOffsets[FieldNo] = FieldOffset;
+  
+  // Reserve space for this field.
+  if (IsUnion) {
+    Size = std::max(Size, FieldSize);
+  } else {
+    Size = FieldOffset + FieldSize;
+  }
+  
+  // Remember max struct/class alignment.
+  Alignment = std::max(Alignment, FieldAlign);
+}
+
 /// getASTRecordLayout - Get or compute information about the layout of the
 /// specified record (struct/union/class), which indicates its size and field
 /// position information.
@@ -326,93 +401,24 @@
   ASTRecordLayout *NewEntry = new ASTRecordLayout();
   Entry = NewEntry;
 
-  uint64_t *FieldOffsets = new uint64_t[D->getNumMembers()];
-  uint64_t RecordSize = 0;
-  unsigned RecordAlign = 8;  // Default alignment = 1 byte = 8 bits.
+  NewEntry->InitializeLayout(D->getNumMembers());
   bool StructIsPacked = D->getAttr<PackedAttr>();
   bool IsUnion = (D->getKind() == Decl::Union);
 
   if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
-    RecordAlign = std::max(RecordAlign, AA->getAlignment());
+    NewEntry->SetAlignment(std::max(NewEntry->getAlignment(), 
+                                    AA->getAlignment()));
 
   // Layout each field, for now, just sequentially, respecting alignment.  In
   // the future, this will need to be tweakable by targets.
   for (unsigned i = 0, e = D->getNumMembers(); i != e; ++i) {
     const FieldDecl *FD = D->getMember(i);
-    bool FieldIsPacked = StructIsPacked || FD->getAttr<PackedAttr>();
-    uint64_t FieldOffset = IsUnion ? 0 : RecordSize;
-    uint64_t FieldSize;
-    unsigned FieldAlign;
-
-    if (const Expr *BitWidthExpr = FD->getBitWidth()) {
-      // TODO: Need to check this algorithm on other targets!
-      //       (tested on Linux-X86)
-      llvm::APSInt I(32);
-      bool BitWidthIsICE = 
-        BitWidthExpr->isIntegerConstantExpr(I, *this);
-      assert (BitWidthIsICE  && "Invalid BitField size expression");
-      FieldSize = I.getZExtValue();
-
-      std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType());
-      uint64_t TypeSize = FieldInfo.first;
-
-      FieldAlign = FieldInfo.second;
-      if (FieldIsPacked)
-        FieldAlign = 1;
-      if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
-        FieldAlign = std::max(FieldAlign, AA->getAlignment());
-
-      // 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 (!FD->getIdentifier())
-        FieldAlign = 1;
-    } else {
-      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.
-        FieldSize = 0;
-        const ArrayType* ATy = FD->getType()->getAsArrayType();
-        FieldAlign = getTypeAlign(ATy->getElementType());
-      } else {
-        std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType());
-        FieldSize = FieldInfo.first;
-        FieldAlign = FieldInfo.second;
-      }
-
-      if (FieldIsPacked)
-        FieldAlign = 8;
-      if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
-        FieldAlign = std::max(FieldAlign, AA->getAlignment());
-
-      // Round up the current record size to the field's alignment boundary.
-      FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
-    }
-
-    // Place this field at the current location.
-    FieldOffsets[i] = FieldOffset;
-
-    // Reserve space for this field.
-    if (IsUnion) {
-      RecordSize = std::max(RecordSize, FieldSize);
-    } else {
-      RecordSize = FieldOffset + FieldSize;
-    }
-
-    // Remember max struct/class alignment.
-    RecordAlign = std::max(RecordAlign, FieldAlign);
+    NewEntry->LayoutField(FD, i, IsUnion, StructIsPacked, *this);
   }
 
   // Finally, round the size of the total struct up to the alignment of the
   // struct itself.
-  RecordSize = (RecordSize + (RecordAlign-1)) & ~(RecordAlign-1);
-
-  NewEntry->SetLayout(RecordSize, RecordAlign, FieldOffsets);
+  NewEntry->FinalizeLayout();
   return *NewEntry;
 }
 





More information about the cfe-commits mailing list