]> granicus.if.org Git - clang/commitdiff
Introduce a new PragmaPack attribute, and use it for #pragma pack. The PackedAttr...
authorAnders Carlsson <andersca@mac.com>
Sat, 8 Aug 2009 18:23:56 +0000 (18:23 +0000)
committerAnders Carlsson <andersca@mac.com>
Sat, 8 Aug 2009 18:23:56 +0000 (18:23 +0000)
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

include/clang/AST/Attr.h
lib/AST/RecordLayoutBuilder.cpp
lib/CodeGen/CGRecordLayoutBuilder.cpp
lib/Frontend/PCHReaderDecl.cpp
lib/Frontend/PCHWriter.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclAttr.cpp

index 7d3009b011293498f08e16f298ffd8b02f31ade9..581f8af2638c8ee8933b673c2573feb90c7222dc 100644 (file)
@@ -70,6 +70,7 @@ public:
     NSReturnsRetained,   // Clang/Checker-specific.
     Overloadable, // Clang-specific
     Packed,
+    PragmaPack,
     Pure,
     Regparm,
     ReqdWorkGroupSize,   // OpenCL-specific
@@ -146,24 +147,26 @@ public:                                                                 \
   static bool classof(const ATTR##Attr *A) { return true; }             \
 }
 
-class PackedAttr : public Attr {
+DEF_SIMPLE_ATTR(Packed);
+
+class PragmaPackAttr : public Attr {
   unsigned Alignment;
 
 public:
-  PackedAttr(unsigned alignment) : Attr(Packed), Alignment(alignment) {}
+  PragmaPackAttr(unsigned alignment) : Attr(PragmaPack), Alignment(alignment) {}
 
   /// getAlignment - The specified alignment in bits.
   unsigned getAlignment() const { return Alignment; }
 
   virtual Attr* clone(ASTContext &C) const { 
-    return ::new (C) PackedAttr(Alignment); 
+    return ::new (C) PragmaPackAttr(Alignment); 
   }
 
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Attr *A) {
-    return A->getKind() == Packed;
+    return A->getKind() == PragmaPack;
   }
-  static bool classof(const PackedAttr *A) { return true; }
+  static bool classof(const PragmaPackAttr *A) { return true; }
 };
   
 class AlignedAttr : public Attr {
index 1d96c1a20b7cbcc6f5b1ef0fe00830b4605e32a9..8a18197a5698e538b501aa5919ea1466ce58f7e1 100644 (file)
@@ -197,9 +197,11 @@ void ASTRecordLayoutBuilder::LayoutBaseNonVirtually(const CXXRecordDecl *RD) {
 
 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 @@ void ASTRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D,
     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 @@ void ASTRecordLayoutBuilder::LayoutField(const FieldDecl *D) {
   
   // 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!
index a119d4f3a40cc43946b030ffe42c5d012ed86fa2..d3699bb992d7e80d2d63fd3b700549a2b129792e 100644 (file)
@@ -31,9 +31,8 @@ void CGRecordLayoutBuilder::Layout(const RecordDecl *D) {
     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 @@ void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D,
 
 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()) {
index 65da7dc45174dbe7d7ab03659bb4e90508242a88..95163af111140c3343812bf1c87460eb78a2e132 100644 (file)
@@ -507,7 +507,8 @@ Attr *PCHReader::ReadAttributes() {
     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);
index 69247d3e859e39ce9921d780e2c6c484f7211cf1..0e570a61abb9c726546e9440ff18d6ba351b3bdf 100644 (file)
@@ -1698,10 +1698,13 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
     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;
 
index ed78ec0972db53030cbad780c8f89ec440a323f0..44e8b44d7a9e5b5b14bbd27ff25874b3d7e020d1 100644 (file)
@@ -4200,7 +4200,7 @@ CreateNewDecl:
     // 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) {
index 35230005904f565be582d547930048cd161f1902..6df8120786101cb397d3d0f30e54554606754580 100644 (file)
@@ -283,7 +283,7 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   }
 
   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 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
       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();
 }