]> granicus.if.org Git - clang/commitdiff
Add helper to determine if a field is a zero-length bitfield.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 2 Apr 2018 18:29:43 +0000 (18:29 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 2 Apr 2018 18:29:43 +0000 (18:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@328999 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Decl.h
lib/AST/Decl.cpp
lib/AST/DeclCXX.cpp
lib/CodeGen/CGCall.cpp
lib/CodeGen/CGRecordLayoutBuilder.cpp
lib/CodeGen/TargetInfo.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp

index da164c66a61989a40c44f3f4bebb60fcc1053fb2..f9f5cf858debd5568c04e6f54942ae3c0c60c252 100644 (file)
@@ -2635,6 +2635,11 @@ public:
     BitField = false;
   }
 
+  /// Is this a zero-length bit-field? Such bit-fields aren't really bit-fields
+  /// at all and instead act as a separator between contiguous runs of other
+  /// bit-fields.
+  bool isZeroLengthBitField(const ASTContext &Ctx) const;
+
   /// Get the kind of (C++11) default member initializer that this field has.
   InClassInitStyle getInClassInitStyle() const {
     InitStorageKind storageKind = InitStorage.getInt();
index 4fb687d0fdd6df817aae603f21aaf4ce77d2af44..b49fda08a7c19b739a309dfa28593dbe0026c258 100644 (file)
@@ -3691,6 +3691,11 @@ unsigned FieldDecl::getBitWidthValue(const ASTContext &Ctx) const {
   return getBitWidth()->EvaluateKnownConstInt(Ctx).getZExtValue();
 }
 
+bool FieldDecl::isZeroLengthBitField(const ASTContext &Ctx) const {
+  return isUnnamedBitfield() && !getBitWidth()->isValueDependent() &&
+         getBitWidthValue(Ctx) == 0;
+}
+
 unsigned FieldDecl::getFieldIndex() const {
   const FieldDecl *Canonical = getCanonicalDecl();
   if (Canonical != this)
index 1e1ee439d8daa40feb63ce671a650788e584d2bf..45ecc1b5b1f2a9443988201dc310c28f2ed84a94 100644 (file)
@@ -1085,10 +1085,7 @@ void CXXRecordDecl::addedMember(Decl *D) {
     //   T is a class type [...] with [...] no non-static data members other
     //   than bit-fields of length 0...
     if (data().Empty) {
-      if (!Field->isBitField() ||
-          (!Field->getBitWidth()->isTypeDependent() &&
-           !Field->getBitWidth()->isValueDependent() &&
-           Field->getBitWidthValue(Context) != 0))
+      if (!Field->isZeroLengthBitField(Context))
         data().Empty = false;
     }
   }
index 148a12eac84b9ab0f41bdaa295266d2a399fdbd7..d1daf5174d315c2e1640eb72df33632e5818c435 100644 (file)
@@ -906,8 +906,7 @@ getTypeExpansion(QualType Ty, const ASTContext &Context) {
       CharUnits UnionSize = CharUnits::Zero();
 
       for (const auto *FD : RD->fields()) {
-        // Skip zero length bitfields.
-        if (FD->isBitField() && FD->getBitWidthValue(Context) == 0)
+        if (FD->isZeroLengthBitField(Context))
           continue;
         assert(!FD->isBitField() &&
                "Cannot expand structure with bit-field members.");
@@ -928,8 +927,7 @@ getTypeExpansion(QualType Ty, const ASTContext &Context) {
       }
 
       for (const auto *FD : RD->fields()) {
-        // Skip zero length bitfields.
-        if (FD->isBitField() && FD->getBitWidthValue(Context) == 0)
+        if (FD->isZeroLengthBitField(Context))
           continue;
         assert(!FD->isBitField() &&
                "Cannot expand structure with bit-field members.");
index 7296da7d7e9e95c6ac77bcf39fc09595a2a98561..497c8aa48183a5fc1d8cfd0e2839eef56b3f2a43 100644 (file)
@@ -294,8 +294,7 @@ void CGRecordLowering::lowerUnion() {
   // been doing and cause lit tests to change.
   for (const auto *Field : D->fields()) {
     if (Field->isBitField()) {
-      // Skip 0 sized bitfields.
-      if (Field->getBitWidthValue(Context) == 0)
+      if (Field->isZeroLengthBitField(Context))
         continue;
       llvm::Type *FieldType = getStorageType(Field);
       if (LayoutSize < getSize(FieldType))
@@ -380,7 +379,7 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
     for (; Field != FieldEnd; ++Field) {
       uint64_t BitOffset = getFieldBitOffset(*Field);
       // Zero-width bitfields end runs.
-      if (Field->getBitWidthValue(Context) == 0) {
+      if (Field->isZeroLengthBitField(Context)) {
         Run = FieldEnd;
         continue;
       }
@@ -431,7 +430,7 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
       if (Field == FieldEnd)
         break;
       // Any non-zero-length bitfield can start a new run.
-      if (Field->getBitWidthValue(Context) != 0) {
+      if (!Field->isZeroLengthBitField(Context)) {
         Run = Field;
         StartBitOffset = getFieldBitOffset(*Field);
         Tail = StartBitOffset + Field->getBitWidthValue(Context);
@@ -452,7 +451,7 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
     // Otherwise, try to add bitfields to the run.
     if (!StartFieldAsSingleRun && Field != FieldEnd &&
         !IsBetterAsSingleFieldRun(Field) &&
-        (Field->getBitWidthValue(Context) != 0 ||
+        (!Field->isZeroLengthBitField(Context) ||
          (!Context.getTargetInfo().useZeroLengthBitfieldAlignment() &&
           !Context.getTargetInfo().useBitFieldTypeAlignment())) &&
         Tail == getFieldBitOffset(*Field)) {
@@ -811,7 +810,7 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D,
       continue;
 
     // Don't inspect zero-length bitfields.
-    if (FD->getBitWidthValue(getContext()) == 0)
+    if (FD->isZeroLengthBitField(getContext()))
       continue;
 
     const CGBitFieldInfo &Info = RL->getBitFieldInfo(FD);
index 02dd21483b45befa635e2a0c1ec59d4dcb96643a..68edb3258263705655a4c0e90b08b083c7e445b3 100644 (file)
@@ -4560,7 +4560,7 @@ bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base,
 
       // For compatibility with GCC, ignore empty bitfields in C++ mode.
       if (getContext().getLangOpts().CPlusPlus &&
-          FD->isBitField() && FD->getBitWidthValue(getContext()) == 0)
+          FD->isZeroLengthBitField(getContext()))
         continue;
 
       uint64_t FldMembers;
@@ -6406,7 +6406,7 @@ QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const {
       // Unlike isSingleElementStruct(), empty structure and array fields
       // do count.  So do anonymous bitfields that aren't zero-sized.
       if (getContext().getLangOpts().CPlusPlus &&
-          FD->isBitField() && FD->getBitWidthValue(getContext()) == 0)
+          FD->isZeroLengthBitField(getContext()))
         continue;
 
       // Unlike isSingleElementStruct(), arrays do not count.
index 8100b955da7b983b662cdbfcce8865885e7c11fd..295d89a40da28fee2da10e15dd130f3adcaf87ea 100644 (file)
@@ -15206,7 +15206,7 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc,
   Decl *ivarDecl = AllIvarDecls[AllIvarDecls.size()-1];
   ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(ivarDecl);
 
-  if (!Ivar->isBitField() || Ivar->getBitWidthValue(Context) == 0)
+  if (!Ivar->isBitField() || Ivar->isZeroLengthBitField(Context))
     return;
   ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CurContext);
   if (!ID) {
@@ -15588,7 +15588,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
            (NonBitFields == 0 || ZeroSize) && I != E; ++I) {
         IsEmpty = false;
         if (I->isUnnamedBitfield()) {
-          if (I->getBitWidthValue(Context) > 0)
+          if (!I->isZeroLengthBitField(Context))
             ZeroSize = false;
         } else {
           ++NonBitFields;
index f8a3d9444aac5ff458da634cd653779a42984012..55c7a9ae24d43e85137a5bc4bdfd2fbc22d1a256 100644 (file)
@@ -4335,7 +4335,7 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
     QualType ParamType = Param->getType().getNonReferenceType();
 
     // Suppress copying zero-width bitfields.
-    if (Field->isBitField() && Field->getBitWidthValue(SemaRef.Context) == 0)
+    if (Field->isZeroLengthBitField(SemaRef.Context))
       return false;
 
     Expr *MemberExprBase =
@@ -11740,7 +11740,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
     }
 
     // Suppress assigning zero-width bitfields.
-    if (Field->isBitField() && Field->getBitWidthValue(Context) == 0)
+    if (Field->isZeroLengthBitField(Context))
       continue;
 
     QualType FieldType = Field->getType().getNonReferenceType();
@@ -12107,7 +12107,7 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation,
     }
 
     // Suppress assigning zero-width bitfields.
-    if (Field->isBitField() && Field->getBitWidthValue(Context) == 0)
+    if (Field->isZeroLengthBitField(Context))
       continue;
 
     QualType FieldType = Field->getType().getNonReferenceType();