]> granicus.if.org Git - clang/commitdiff
More rule enforcement of zero bitfields for ms_struct.
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 2 May 2011 17:20:56 +0000 (17:20 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 2 May 2011 17:20:56 +0000 (17:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130696 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
lib/AST/ASTContext.cpp
lib/AST/Decl.cpp
lib/AST/RecordLayoutBuilder.cpp
lib/CodeGen/CGDebugInfo.cpp
lib/CodeGen/CGExprConstant.cpp
lib/CodeGen/CGRecordLayoutBuilder.cpp
test/CodeGen/ms_struct-bitfield.c

index 3ca3c3b8a295c648c22469ea37b330a0bc68d693..28ec8cf88d52738bc5f275503d04748054ab606c 100644 (file)
@@ -402,6 +402,11 @@ public:
   bool ZeroBitfieldFollowsNonBitfield(const FieldDecl *FD, 
                                       const FieldDecl *LastFD) const;
 
+  /// ZeroBitfieldFollowsBitfield - return 'true" if 'FD' is a zero-length
+  /// bitfield which follows the bitfield 'LastFD'.
+  bool ZeroBitfieldFollowsBitfield(const FieldDecl *FD,
+                                   const FieldDecl *LastFD) const;
+
   // Access to the set of methods overridden by the given C++ method.
   typedef CXXMethodVector::iterator overridden_cxx_method_iterator;
   overridden_cxx_method_iterator
index 1f4d9a3718653ec63bcfa2e6d60d61940da39580..8316ea68e9e46cf1ac2a52957f7b05b69a5d35e2 100644 (file)
@@ -543,6 +543,13 @@ bool ASTContext::ZeroBitfieldFollowsNonBitfield(const FieldDecl *FD,
   
 }
 
+bool ASTContext::ZeroBitfieldFollowsBitfield(const FieldDecl *FD,
+                                             const FieldDecl *LastFD) const {
+  return (FD->isBitField() && LastFD && LastFD->isBitField() &&
+          FD->getBitWidth()-> EvaluateAsInt(*this).getZExtValue() == 0);
+
+}
+
 ASTContext::overridden_cxx_method_iterator
 ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const {
   llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos
index e336dd771a046504a17d21e304ac8c8c51666ccd..b21ba9a65e761a1b3a1e3ece04097e5039bdae6b 100644 (file)
@@ -2059,7 +2059,8 @@ unsigned FieldDecl::getFieldIndex() const {
 
     if (IsMsStruct) {
       // Zero-length bitfields following non-bitfield members are ignored.
-      if (getASTContext().ZeroBitfieldFollowsNonBitfield((*i), LastFD)) {
+      if (getASTContext().ZeroBitfieldFollowsNonBitfield((*i), LastFD) ||
+          getASTContext().ZeroBitfieldFollowsBitfield((*i), LastFD)) {
         ++i;
         continue;
       }
index 407655770dfc39c856d1262dd73e78e7e7d318a5..0770e1f151439d44bd83ecdac59c05e31ec12706 100644 (file)
@@ -582,6 +582,8 @@ protected:
   CharUnits NonVirtualSize;
   CharUnits NonVirtualAlignment;
 
+  CharUnits ZeroLengthBitfieldAlignment;
+
   /// PrimaryBase - the primary base class (if one exists) of the class
   /// we're laying out.
   const CXXRecordDecl *PrimaryBase;
@@ -618,7 +620,8 @@ protected:
       IsMac68kAlign(false), IsMsStruct(false),
       UnfilledBitsInLastByte(0), MaxFieldAlignment(CharUnits::Zero()), 
       DataSize(0), NonVirtualSize(CharUnits::Zero()), 
-      NonVirtualAlignment(CharUnits::One()), PrimaryBase(0), 
+      NonVirtualAlignment(CharUnits::One()), 
+      ZeroLengthBitfieldAlignment(CharUnits::Zero()), PrimaryBase(0), 
       PrimaryBaseIsVirtual(false), FirstNearlyEmptyVBase(0) { }
 
   void Layout(const RecordDecl *D);
@@ -1258,9 +1261,18 @@ void RecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
   for (RecordDecl::field_iterator Field = D->field_begin(),
        FieldEnd = D->field_end(); Field != FieldEnd; ++Field) {
     if (IsMsStruct) {
+      const FieldDecl *FD =  (*Field);
+      if (Context.ZeroBitfieldFollowsBitfield(FD, LastFD)) {
+        // FIXME. Multiple zero bitfields may follow a bitfield.
+        // set ZeroLengthBitfieldAlignment to max. of its
+        // currrent and alignment of 'FD'.
+        std::pair<CharUnits, CharUnits> FieldInfo = 
+          Context.getTypeInfoInChars(FD->getType());
+        ZeroLengthBitfieldAlignment = FieldInfo.second;
+        continue;
+      }
       // Zero-length bitfields following non-bitfield members are
       // ignored:
-      const FieldDecl *FD =  (*Field);
       if (Context.ZeroBitfieldFollowsNonBitfield(FD, LastFD))
         continue;
       LastFD = FD;
@@ -1443,6 +1455,9 @@ void RecordLayoutBuilder::LayoutField(const FieldDecl *D) {
       Context.getTypeInfoInChars(D->getType());
     FieldSize = FieldInfo.first;
     FieldAlign = FieldInfo.second;
+    if (ZeroLengthBitfieldAlignment > FieldAlign)
+      FieldAlign = ZeroLengthBitfieldAlignment;
+    ZeroLengthBitfieldAlignment = CharUnits::Zero();
 
     if (Context.getLangOptions().MSBitfields) {
       // If MS bitfield layout is required, figure out what type is being
index 6ce49b5f756e55b157c979ca199b121c0f151a5a..f2e1c024dd058ed48e1806b1609d1d45ebdddb9c 100644 (file)
@@ -628,7 +628,8 @@ CollectRecordFields(const RecordDecl *record, llvm::DIFile tunit,
     FieldDecl *field = *I;
     if (IsMsStruct) {
       // Zero-length bitfields following non-bitfield members are ignored
-      if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((field), LastFD)) {
+      if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((field), LastFD) ||
+          CGM.getContext().ZeroBitfieldFollowsBitfield((field), LastFD)) {
         --fieldNo;
         continue;
       }
index 8054d4b0372ce57e6d0f5263e3a6f62d6b541caa..463b913d9285ba4f291194e7bd4535ebb376e699 100644 (file)
@@ -352,7 +352,8 @@ bool ConstStructBuilder::Build(InitListExpr *ILE) {
     if (IsMsStruct) {
       // Zero-length bitfields following non-bitfield members are
       // ignored:
-      if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((*Field), LastFD)) {
+      if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((*Field), LastFD) ||
+          CGM.getContext().ZeroBitfieldFollowsBitfield((*Field), LastFD)) {
         --FieldNo;
         continue;
       }
index 3d9fd88613b793cf898c50639ab7ba2bb92ba506..a4ac390dd98c20f26ad694aabd75892d41023069 100644 (file)
@@ -753,7 +753,8 @@ bool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
       // Zero-length bitfields following non-bitfield members are
       // ignored:
       const FieldDecl *FD =  (*Field);
-      if (Types.getContext().ZeroBitfieldFollowsNonBitfield(FD, LastFD)) {
+      if (Types.getContext().ZeroBitfieldFollowsNonBitfield(FD, LastFD) ||
+          Types.getContext().ZeroBitfieldFollowsBitfield(FD, LastFD)) {
         --FieldNo;
         continue;
       }
@@ -996,7 +997,8 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {
     if (IsMsStruct) {
       // Zero-length bitfields following non-bitfield members are
       // ignored:
-      if (getContext().ZeroBitfieldFollowsNonBitfield(FD, LastFD)) {
+      if (getContext().ZeroBitfieldFollowsNonBitfield(FD, LastFD) ||
+          getContext().ZeroBitfieldFollowsBitfield(FD, LastFD)) {
         --i;
         continue;
       }
index e9bd1d3f31dd829522abc2b9725e365924f6926c..a8f4c91a49370b3c8d4040b7378bd0847fa94170 100644 (file)
@@ -107,6 +107,13 @@ struct
    char :4;
 } ATTR t9;
 
+struct
+{
+   char foo: 8;
+   long : 0;
+   char bar;
+} ATTR t10;
+
 static int arr1[(sizeof(t1) == 2) -1];
 static int arr2[(sizeof(t2) == 2) -1];
 static int arr3[(sizeof(t3) == 2) -1];
@@ -116,6 +123,7 @@ static int arr6[(sizeof(t6) == 1) -1];
 static int arr7[(sizeof(t7) == 9) -1];
 static int arr8[(sizeof(t8) == 0) -1];
 static int arr9[(sizeof(t9) == 28) -1];
+static int arr10[(sizeof(t10) == 16) -1];
 
 int main() {
   return 0;