We don't need to keep track of the packed alignment, just whether the struct is packe...
authorAnders Carlsson <andersca@mac.com>
Thu, 23 Jul 2009 17:24:40 +0000 (17:24 +0000)
committerAnders Carlsson <andersca@mac.com>
Thu, 23 Jul 2009 17:24:40 +0000 (17:24 +0000)
llvm-svn: 76884

clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
clang/lib/CodeGen/CGRecordLayoutBuilder.h
clang/test/CodeGen/pragma-pack-1.c [new file with mode: 0644]

index 5f6946d..2d10b1f 100644 (file)
@@ -33,16 +33,13 @@ void CGRecordLayoutBuilder::Layout(const RecordDecl *D) {
   }
   
   if (const PackedAttr* PA = D->getAttr<PackedAttr>())
-    StructPacking = PA->getAlignment();
+    Packed = PA->getAlignment();
 
   if (LayoutFields(D))
     return;
   
-  assert(!StructPacking && 
-         "FIXME: Were not able to lay out a struct with #pragma pack!");
-  
   // We weren't able to layout the struct. Try again with a packed struct
-  StructPacking = 1;
+  Packed = true;
   AlignmentAsLLVMStruct = 1;
   FieldTypes.clear();
   FieldInfos.clear();
@@ -99,21 +96,21 @@ void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D,
 
 bool CGRecordLayoutBuilder::LayoutField(const FieldDecl *D,
                                         uint64_t FieldOffset) {
-  unsigned FieldPacking = StructPacking;
+  bool FieldPacked = Packed;
   
   // FIXME: Should this override struct packing? Probably we want to
   // take the minimum?
   if (const PackedAttr *PA = D->getAttr<PackedAttr>())
-    FieldPacking = PA->getAlignment();
+    FieldPacked = PA->getAlignment();
 
   // If the field is packed, then we need a packed struct.
-  if (!StructPacking && FieldPacking)
+  if (!Packed && FieldPacked)
     return false;
 
   if (D->isBitField()) {
     // We must use packed structs for unnamed bit fields since they
     // don't affect the struct alignment.
-    if (!StructPacking && !D->getDeclName())
+    if (!Packed && !D->getDeclName())
       return false;
     
     LayoutBitField(D, FieldOffset);
@@ -126,7 +123,7 @@ bool CGRecordLayoutBuilder::LayoutField(const FieldDecl *D,
   if (const AlignedAttr *PA = D->getAttr<AlignedAttr>()) {
     unsigned FieldAlign = PA->getAlignment();
    
-    if (!StructPacking && getTypeAlignment(Ty) > FieldAlign)
+    if (!Packed && getTypeAlignment(Ty) > FieldAlign)
       return false;
   }
    
@@ -213,7 +210,7 @@ bool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
   for (RecordDecl::field_iterator Field = D->field_begin(), 
        FieldEnd = D->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
     if (!LayoutField(*Field, Layout.getFieldOffset(FieldNo))) {
-      assert(!StructPacking && 
+      assert(!Packed && 
              "Could not layout fields even with a packed LLVM struct!");
       return false;
     }
@@ -286,10 +283,8 @@ uint64_t CGRecordLayoutBuilder::getNextFieldOffsetInBytes() const {
 }
 
 unsigned CGRecordLayoutBuilder::getTypeAlignment(const llvm::Type *Ty) const {
-  if (StructPacking) {
-    assert(StructPacking == 1 && "FIXME: What if StructPacking is not 1 here");
+  if (Packed)
     return 1;
-  }
   
   return Types.getTargetData().getABITypeAlignment(Ty);
 }
@@ -310,7 +305,7 @@ CGRecordLayoutBuilder::ComputeLayout(CodeGenTypes &Types,
   
   // FIXME: Use a VMContext.
   const llvm::Type *Ty = llvm::StructType::get(Builder.FieldTypes,
-                                               Builder.StructPacking);
+                                               Builder.Packed);
   
   // Add all the field numbers.
   for (unsigned i = 0, e = Builder.LLVMFields.size(); i != e; ++i) {
index 2f212f8..197e420 100644 (file)
@@ -33,10 +33,8 @@ namespace CodeGen {
 class CGRecordLayoutBuilder {  
   CodeGenTypes &Types;
   
-  /// StructPacking - Will be 0 if this struct is not packed. If it is packed,
-  /// it will have the packing alignment in bits.
-  /// 
-  unsigned StructPacking;
+  /// Packed - Whether the resulting LLVM struct will be packed or not.
+  bool Packed;
 
   /// AlignmentAsLLVMStruct - Will contain the maximum alignment of all the
   /// LLVM types.
@@ -79,7 +77,7 @@ class CGRecordLayoutBuilder {
   llvm::SmallVector<LLVMBitFieldInfo, 16> LLVMBitFields;
   
   CGRecordLayoutBuilder(CodeGenTypes &Types) 
-    : Types(Types), StructPacking(0), AlignmentAsLLVMStruct(1)
+    : Types(Types), Packed(false), AlignmentAsLLVMStruct(1)
     , BitsAvailableInLastField(0) { }
 
   /// Layout - Will layout a RecordDecl.
diff --git a/clang/test/CodeGen/pragma-pack-1.c b/clang/test/CodeGen/pragma-pack-1.c
new file mode 100644 (file)
index 0000000..bcfcd5a
--- /dev/null
@@ -0,0 +1,7 @@
+// RUN: clang-cc -emit-llvm -o - 
+
+// PR4610
+#pragma pack(4)
+struct ref {
+        struct ref *next;
+} refs;