Introduce a new PragmaPack attribute, and use it for #pragma pack. The PackedAttr now only represents __attribute__((packed)).

This is necessary because #pragma pack and __attribute__((packed)) have different semantics. No functionality change yet, but this lays the groundwork for fixing a record layout bug.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78483 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 1d96c1a..8a18197 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -197,9 +197,11 @@
 
 void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
   IsUnion = D->isUnion();
-  
-  if (const PackedAttr* PA = D->getAttr<PackedAttr>())
-    StructPacking = PA->getAlignment();
+
+  if (D->hasAttr<PackedAttr>())
+    StructPacking = 1;
+  if (const PragmaPackAttr *PPA = D->getAttr<PragmaPackAttr>())
+    StructPacking = PPA->getAlignment();
   
   if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
     UpdateAlignment(AA->getAlignment());
@@ -240,8 +242,8 @@
     NextOffset = Size;
   }
   
-  if (const PackedAttr *PA = D->getAttr<PackedAttr>())
-    StructPacking = PA->getAlignment();
+  if (D->hasAttr<PackedAttr>())
+    StructPacking = 1;
   
   if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
     UpdateAlignment(AA->getAlignment());
@@ -273,8 +275,8 @@
   
   // FIXME: Should this override struct packing? Probably we want to
   // take the minimum?
-  if (const PackedAttr *PA = D->getAttr<PackedAttr>())
-    FieldPacking = PA->getAlignment();
+  if (D->hasAttr<PackedAttr>())
+    FieldPacking = 1;
   
   if (const Expr *BitWidthExpr = D->getBitWidth()) {
     // TODO: Need to check this algorithm on other targets!
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index a119d4f..d3699bb 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -31,9 +31,8 @@
     LayoutUnion(D);
     return;
   }
-  
-  if (const PackedAttr* PA = D->getAttr<PackedAttr>())
-    Packed = PA->getAlignment();
+
+  Packed = D->hasAttr<PackedAttr>();
 
   if (LayoutFields(D))
     return;
@@ -96,15 +95,8 @@
 
 bool CGRecordLayoutBuilder::LayoutField(const FieldDecl *D,
                                         uint64_t FieldOffset) {
-  bool FieldPacked = Packed;
-  
-  // FIXME: Should this override struct packing? Probably we want to
-  // take the minimum?
-  if (const PackedAttr *PA = D->getAttr<PackedAttr>())
-    FieldPacked = PA->getAlignment();
-
   // If the field is packed, then we need a packed struct.
-  if (!Packed && FieldPacked)
+  if (!Packed && D->hasAttr<PackedAttr>())
     return false;
 
   if (D->isBitField()) {
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index 65da7dc..95163af 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -507,7 +507,8 @@
     SIMPLE_ATTR(CFReturnsRetained);
     SIMPLE_ATTR(NSReturnsRetained);
     SIMPLE_ATTR(Overloadable);
-    UNSIGNED_ATTR(Packed);
+    SIMPLE_ATTR(Packed);
+    UNSIGNED_ATTR(PragmaPack);
     SIMPLE_ATTR(Pure);
     UNSIGNED_ATTR(Regparm);
     STRING_ATTR(Section);
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 69247d3..0e570a6 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -1698,10 +1698,13 @@
     case Attr::Overloadable:
       break;
 
-    case Attr::Packed:
-      Record.push_back(cast<PackedAttr>(Attr)->getAlignment());
+    case Attr::PragmaPack:
+      Record.push_back(cast<PragmaPackAttr>(Attr)->getAlignment());
       break;
 
+    case Attr::Packed:
+      break;
+    
     case Attr::Pure:
       break;
 
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index ed78ec0..44e8b44 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -4200,7 +4200,7 @@
     // the #pragma tokens are effectively skipped over during the
     // parsing of the struct).
     if (unsigned Alignment = getPragmaPackAlignment())
-      New->addAttr(::new (Context) PackedAttr(Alignment * 8));
+      New->addAttr(::new (Context) PragmaPackAttr(Alignment * 8));
   }
 
   if (getLangOptions().CPlusPlus && SS.isEmpty() && Name && !Invalid) {
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 3523000..6df8120 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -283,7 +283,7 @@
   }
 
   if (TagDecl *TD = dyn_cast<TagDecl>(d))
-    TD->addAttr(::new (S.Context) PackedAttr(1));
+    TD->addAttr(::new (S.Context) PackedAttr);
   else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
     // If the alignment is less than or equal to 8 bits, the packed attribute
     // has no effect.
@@ -292,7 +292,7 @@
       S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
         << Attr.getName() << FD->getType();
     else
-      FD->addAttr(::new (S.Context) PackedAttr(1));
+      FD->addAttr(::new (S.Context) PackedAttr);
   } else
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 }