diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2011-05-02 17:20:56 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2011-05-02 17:20:56 +0000 |
commit | 340fa242130c2d8d74c83edca0952e771aebe0e6 (patch) | |
tree | dea1131fbdb6341aeebc382316a1a741262a982f | |
parent | 0f0cdab31a4f71914b7f654501d69d96e9f378da (diff) |
More rule enforcement of zero bitfields for ms_struct.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130696 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/ASTContext.h | 5 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 7 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 3 | ||||
-rw-r--r-- | lib/AST/RecordLayoutBuilder.cpp | 19 | ||||
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/CGRecordLayoutBuilder.cpp | 6 | ||||
-rw-r--r-- | test/CodeGen/ms_struct-bitfield.c | 8 |
8 files changed, 47 insertions, 7 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 3ca3c3b8a2..28ec8cf88d 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -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 diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 1f4d9a3718..8316ea68e9 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -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 diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index e336dd771a..b21ba9a65e 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -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; } diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 407655770d..0770e1f151 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -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 diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 6ce49b5f75..f2e1c024dd 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -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; } diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 8054d4b037..463b913d92 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -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; } diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index 3d9fd88613..a4ac390dd9 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -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; } diff --git a/test/CodeGen/ms_struct-bitfield.c b/test/CodeGen/ms_struct-bitfield.c index e9bd1d3f31..a8f4c91a49 100644 --- a/test/CodeGen/ms_struct-bitfield.c +++ b/test/CodeGen/ms_struct-bitfield.c @@ -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; |