Handle packed attribute correctly

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47197 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index 8f1085c..f4f7c3f 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -1242,6 +1242,7 @@
     S->AddDecl(New);
   }
   
+  HandleDeclAttributes(New, Attr, 0);
   return New;
 }
 
@@ -1300,6 +1301,9 @@
   else
     assert(0 && "Sema::ActOnField(): Unknown TagDecl");
     
+  HandleDeclAttributes(NewFD, D.getDeclSpec().getAttributes(),
+                       D.getAttributes());
+
   if (D.getInvalidType() || InvalidDecl)
     NewFD->setInvalidDecl();
   return NewFD;
@@ -1772,10 +1776,11 @@
       if (!newType.isNull()) // install the new addr spaced  type into the decl
         vDecl->setType(newType);
     }
-  } else if (attrLen == 7 && !memcmp(attrName, "aligned", 7)) {
-      HandleAlignedAttribute(New, rawAttr);
-  }
-  
+  } else if (attrLen == 7 && !memcmp(attrName, "aligned", 7))
+    HandleAlignedAttribute(New, rawAttr);
+  else if (attrLen == 6 && !memcmp(attrName, "packed", 6))
+    HandlePackedAttribute(New, rawAttr);
+
   // FIXME: add other attributes...
 }
 
@@ -1920,6 +1925,32 @@
   return Context.getVectorType(curType, vectorSize/typeSize);
 }
 
+void Sema::HandlePackedAttribute(Decl *d, AttributeList *rawAttr)
+{
+  // check the attribute arguments.
+  if (rawAttr->getNumArgs() > 0) {
+    Diag(rawAttr->getAttributeLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("0"));
+    return;
+  }
+  
+  if (TagDecl *TD = dyn_cast<TagDecl>(d))
+    TD->addAttr(new 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.
+    if (Context.getTypeAlign(FD->getType(), SourceLocation()) <= 8)
+      Diag(rawAttr->getAttributeLoc(), 
+           diag::warn_attribute_ignored_for_field_of_type,
+           rawAttr->getAttributeName()->getName(),
+           FD->getType().getAsString());
+    else
+      TD->addAttr(new PackedAttr);
+  } else
+    Diag(rawAttr->getAttributeLoc(), diag::warn_attribute_ignored,
+         rawAttr->getAttributeName()->getName());
+}
+  
 void Sema::HandleAlignedAttribute(Decl *d, AttributeList *rawAttr)
 {
   // check the attribute arguments.