[clang] [clang] Avoid re-evaluating field bitwidth (PR #117732)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 26 08:10:42 PST 2024


https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/117732

None

>From d1d31ec6d00657786212660f657aac638366523f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Tue, 26 Nov 2024 13:10:33 +0100
Subject: [PATCH] [clang] Avoid re-evaluating field bitwidth

---
 clang/include/clang/AST/Decl.h            | 26 +++++--
 clang/include/clang/AST/DeclObjC.h        | 34 ++++++++--
 clang/include/clang/Sema/Sema.h           |  2 +-
 clang/lib/AST/ASTContext.cpp              | 83 ++++++++---------------
 clang/lib/AST/ASTImporter.cpp             |  2 +-
 clang/lib/AST/Decl.cpp                    | 23 +++++--
 clang/lib/AST/DeclObjC.cpp                | 34 ++++++----
 clang/lib/CodeGen/CGObjCMac.cpp           | 14 ++--
 clang/lib/CodeGen/CGOpenMPRuntime.cpp     |  3 +-
 clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp  |  6 +-
 clang/lib/CodeGen/CodeGenModule.cpp       | 12 ++--
 clang/lib/Sema/HLSLExternalSemaSource.cpp |  6 +-
 clang/lib/Sema/SemaDecl.cpp               | 71 +++++++++----------
 clang/lib/Sema/SemaDeclObjC.cpp           | 23 ++++---
 clang/lib/Sema/SemaLambda.cpp             |  2 +-
 15 files changed, 190 insertions(+), 151 deletions(-)

diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 8c39ef3d5a9fa6..db3c86a09bfb49 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -3089,17 +3089,27 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
     // Active member if ISK is ISK_CapturedVLAType.
     const VariableArrayType *CapturedVLAType;
   };
+  unsigned BitWidthValue = 0;
 
 protected:
   FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
             SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
-            TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
-            InClassInitStyle InitStyle)
+            TypeSourceInfo *TInfo, bool Mutable, InClassInitStyle InitStyle)
+      : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), BitField(false),
+        Mutable(Mutable), StorageKind((InitStorageKind)InitStyle),
+        CachedFieldIndex(0), Init() {}
+
+  FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
+            SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
+            TypeSourceInfo *TInfo, Expr *BW, unsigned BitWidthValue,
+            bool Mutable, InClassInitStyle InitStyle)
       : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), BitField(false),
         Mutable(Mutable), StorageKind((InitStorageKind)InitStyle),
         CachedFieldIndex(0), Init() {
-    if (BW)
+    if (BW) {
       setBitWidth(BW);
+      this->BitWidthValue = BitWidthValue;
+    }
   }
 
 public:
@@ -3109,7 +3119,15 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
   static FieldDecl *Create(const ASTContext &C, DeclContext *DC,
                            SourceLocation StartLoc, SourceLocation IdLoc,
                            const IdentifierInfo *Id, QualType T,
-                           TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
+                           TypeSourceInfo *TInfo, Expr *BW,
+                           unsigned BitWidthValue, bool Mutable,
+                           InClassInitStyle InitStyle);
+
+  /// For non-bit-fields.
+  static FieldDecl *Create(const ASTContext &C, DeclContext *DC,
+                           SourceLocation StartLoc, SourceLocation IdLoc,
+                           const IdentifierInfo *Id, QualType T,
+                           TypeSourceInfo *TInfo, bool Mutable,
                            InClassInitStyle InitStyle);
 
   static FieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h
index 4663603f797545..17bccfda784fed 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -1960,8 +1960,15 @@ class ObjCIvarDecl : public FieldDecl {
   ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
                SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
                TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
-               bool synthesized)
-      : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
+               unsigned BWValue, bool synthesized)
+      : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW, BWValue,
+                  /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
+        DeclAccess(ac), Synthesized(synthesized) {}
+
+  ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
+               SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
+               TypeSourceInfo *TInfo, AccessControl ac, bool synthesized)
+      : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo,
                   /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
         DeclAccess(ac), Synthesized(synthesized) {}
 
@@ -1970,7 +1977,8 @@ class ObjCIvarDecl : public FieldDecl {
                               SourceLocation StartLoc, SourceLocation IdLoc,
                               const IdentifierInfo *Id, QualType T,
                               TypeSourceInfo *TInfo, AccessControl ac,
-                              Expr *BW = nullptr, bool synthesized = false);
+                              Expr *BW = nullptr, unsigned BWValue = 0,
+                              bool synthesized = false);
 
   static ObjCIvarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
 
@@ -2028,11 +2036,19 @@ class ObjCIvarDecl : public FieldDecl {
 /// Represents a field declaration created by an \@defs(...).
 class ObjCAtDefsFieldDecl : public FieldDecl {
   ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
-                      SourceLocation IdLoc, IdentifierInfo *Id,
-                      QualType T, Expr *BW)
+                      SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
+                      Expr *BW, unsigned BWValue)
+      : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
+                  /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
+                  BW, BWValue, /*Mutable=*/false,
+                  /*HasInit=*/ICIS_NoInit) {}
+
+  ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
+                      SourceLocation IdLoc, IdentifierInfo *Id, QualType T)
       : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
                   /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
-                  BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
+                  /*Mutable=*/false,
+                  /*HasInit=*/ICIS_NoInit) {}
 
   void anchor() override;
 
@@ -2040,7 +2056,11 @@ class ObjCAtDefsFieldDecl : public FieldDecl {
   static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
                                      SourceLocation StartLoc,
                                      SourceLocation IdLoc, IdentifierInfo *Id,
-                                     QualType T, Expr *BW);
+                                     QualType T, Expr *BW, unsigned BWValue);
+  static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
+                                     SourceLocation StartLoc,
+                                     SourceLocation IdLoc, IdentifierInfo *Id,
+                                     QualType T);
 
   static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C,
                                                  GlobalDeclID ID);
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 24abd5d95dd844..5c82a75f491e37 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4277,7 +4277,7 @@ class Sema final : public SemaBase {
   /// Returns false on success.
   ExprResult VerifyBitField(SourceLocation FieldLoc,
                             const IdentifierInfo *FieldName, QualType FieldTy,
-                            bool IsMsStruct, Expr *BitWidth);
+                            bool IsMsStruct, Expr *BitWidth, unsigned &BWV);
 
   /// IsValueInFlagEnum - Determine if a value is allowed as part of a flag
   /// enum. If AllowMask is true, then we also allow the complement of a valid
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 80e8c5b9df58e7..26631f9a5c7f9b 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -7969,11 +7969,10 @@ TypedefDecl *ASTContext::getCFConstantStringDecl() const {
 
   // Create fields
   for (unsigned i = 0; i < Count; ++i) {
-    FieldDecl *Field =
-        FieldDecl::Create(*this, CFConstantStringTagDecl, SourceLocation(),
-                          SourceLocation(), &Idents.get(Fields[i].Name),
-                          Fields[i].Type, /*TInfo=*/nullptr,
-                          /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit);
+    FieldDecl *Field = FieldDecl::Create(
+        *this, CFConstantStringTagDecl, SourceLocation(), SourceLocation(),
+        &Idents.get(Fields[i].Name), Fields[i].Type, /*TInfo=*/nullptr,
+        /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     CFConstantStringTagDecl->addDecl(Field);
   }
@@ -8039,7 +8038,7 @@ QualType ASTContext::getBlockDescriptorType() const {
     FieldDecl *Field = FieldDecl::Create(
         *this, RD, SourceLocation(), SourceLocation(),
         &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
-        /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit);
+        /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     RD->addDecl(Field);
   }
@@ -8078,7 +8077,6 @@ QualType ASTContext::getBlockDescriptorExtendedType() const {
     FieldDecl *Field = FieldDecl::Create(
         *this, RD, SourceLocation(), SourceLocation(),
         &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
-        /*BitWidth=*/nullptr,
         /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     RD->addDecl(Field);
@@ -9436,15 +9434,11 @@ CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) {
 
   // Create fields
   for (unsigned i = 0; i < NumFields; ++i) {
-    FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),
-                                         VaListTagDecl,
-                                         SourceLocation(),
-                                         SourceLocation(),
-                                         &Context->Idents.get(FieldNames[i]),
-                                         FieldTypes[i], /*TInfo=*/nullptr,
-                                         /*BitWidth=*/nullptr,
-                                         /*Mutable=*/false,
-                                         ICIS_NoInit);
+    FieldDecl *Field = FieldDecl::Create(
+        const_cast<ASTContext &>(*Context), VaListTagDecl, SourceLocation(),
+        SourceLocation(), &Context->Idents.get(FieldNames[i]), FieldTypes[i],
+        /*TInfo=*/nullptr,
+        /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     VaListTagDecl->addDecl(Field);
   }
@@ -9489,14 +9483,10 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
 
   // Create fields
   for (unsigned i = 0; i < NumFields; ++i) {
-    FieldDecl *Field = FieldDecl::Create(*Context, VaListTagDecl,
-                                         SourceLocation(),
-                                         SourceLocation(),
-                                         &Context->Idents.get(FieldNames[i]),
-                                         FieldTypes[i], /*TInfo=*/nullptr,
-                                         /*BitWidth=*/nullptr,
-                                         /*Mutable=*/false,
-                                         ICIS_NoInit);
+    FieldDecl *Field = FieldDecl::Create(
+        *Context, VaListTagDecl, SourceLocation(), SourceLocation(),
+        &Context->Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
+        /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     VaListTagDecl->addDecl(Field);
   }
@@ -9547,15 +9537,11 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
 
   // Create fields
   for (unsigned i = 0; i < NumFields; ++i) {
-    FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),
-                                         VaListTagDecl,
-                                         SourceLocation(),
-                                         SourceLocation(),
-                                         &Context->Idents.get(FieldNames[i]),
-                                         FieldTypes[i], /*TInfo=*/nullptr,
-                                         /*BitWidth=*/nullptr,
-                                         /*Mutable=*/false,
-                                         ICIS_NoInit);
+    FieldDecl *Field = FieldDecl::Create(
+        const_cast<ASTContext &>(*Context), VaListTagDecl, SourceLocation(),
+        SourceLocation(), &Context->Idents.get(FieldNames[i]), FieldTypes[i],
+        /*TInfo=*/nullptr,
+        /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     VaListTagDecl->addDecl(Field);
   }
@@ -9599,16 +9585,12 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {
   VaListDecl->startDefinition();
 
   // void * __ap;
-  FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),
-                                       VaListDecl,
-                                       SourceLocation(),
-                                       SourceLocation(),
-                                       &Context->Idents.get("__ap"),
-                                       Context->getPointerType(Context->VoidTy),
-                                       /*TInfo=*/nullptr,
-                                       /*BitWidth=*/nullptr,
-                                       /*Mutable=*/false,
-                                       ICIS_NoInit);
+  FieldDecl *Field = FieldDecl::Create(
+      const_cast<ASTContext &>(*Context), VaListDecl, SourceLocation(),
+      SourceLocation(), &Context->Idents.get("__ap"),
+      Context->getPointerType(Context->VoidTy),
+      /*TInfo=*/nullptr,
+      /*Mutable=*/false, ICIS_NoInit);
   Field->setAccess(AS_public);
   VaListDecl->addDecl(Field);
 
@@ -9650,15 +9632,11 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
 
   // Create fields
   for (unsigned i = 0; i < NumFields; ++i) {
-    FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),
-                                         VaListTagDecl,
-                                         SourceLocation(),
-                                         SourceLocation(),
-                                         &Context->Idents.get(FieldNames[i]),
-                                         FieldTypes[i], /*TInfo=*/nullptr,
-                                         /*BitWidth=*/nullptr,
-                                         /*Mutable=*/false,
-                                         ICIS_NoInit);
+    FieldDecl *Field = FieldDecl::Create(
+        const_cast<ASTContext &>(*Context), VaListTagDecl, SourceLocation(),
+        SourceLocation(), &Context->Idents.get(FieldNames[i]), FieldTypes[i],
+        /*TInfo=*/nullptr,
+        /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     VaListTagDecl->addDecl(Field);
   }
@@ -9704,7 +9682,6 @@ static TypedefDecl *CreateHexagonBuiltinVaListDecl(const ASTContext *Context) {
         const_cast<ASTContext &>(*Context), VaListTagDecl, SourceLocation(),
         SourceLocation(), &Context->Idents.get(FieldNames[i]), FieldTypes[i],
         /*TInfo=*/nullptr,
-        /*BitWidth=*/nullptr,
         /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
     VaListTagDecl->addDecl(Field);
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index a0cd57e2e5ee0d..517d3332d07e07 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -4231,7 +4231,7 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
   FieldDecl *ToField;
   if (GetImportedOrCreateDecl(ToField, D, Importer.getToContext(), DC,
                               ToInnerLocStart, Loc, Name.getAsIdentifierInfo(),
-                              ToType, ToTInfo, ToBitWidth, D->isMutable(),
+                              ToType, ToTInfo, ToBitWidth, 0, D->isMutable(),
                               D->getInClassInitStyle()))
     return ToField;
 
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 741e908cf9bc56..e92cc00b23ed5c 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -4555,16 +4555,26 @@ unsigned FunctionDecl::getODRHash() {
 FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC,
                              SourceLocation StartLoc, SourceLocation IdLoc,
                              const IdentifierInfo *Id, QualType T,
-                             TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
+                             TypeSourceInfo *TInfo, Expr *BW,
+                             unsigned BitWidthValue, bool Mutable,
                              InClassInitStyle InitStyle) {
   return new (C, DC) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
-                               BW, Mutable, InitStyle);
+                               BW, BitWidthValue, Mutable, InitStyle);
+}
+
+FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC,
+                             SourceLocation StartLoc, SourceLocation IdLoc,
+                             const IdentifierInfo *Id, QualType T,
+                             TypeSourceInfo *TInfo, bool Mutable,
+                             InClassInitStyle InitStyle) {
+  return new (C, DC) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
+                               nullptr, 0, Mutable, InitStyle);
 }
 
 FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
-  return new (C, ID) FieldDecl(Field, nullptr, SourceLocation(),
-                               SourceLocation(), nullptr, QualType(), nullptr,
-                               nullptr, false, ICIS_NoInit);
+  return new (C, ID)
+      FieldDecl(Field, nullptr, SourceLocation(), SourceLocation(), nullptr,
+                QualType(), nullptr, false, ICIS_NoInit);
 }
 
 bool FieldDecl::isAnonymousStructOrUnion() const {
@@ -4601,6 +4611,9 @@ void FieldDecl::setLazyInClassInitializer(LazyDeclStmtPtr NewInit) {
 
 unsigned FieldDecl::getBitWidthValue(const ASTContext &Ctx) const {
   assert(isBitField() && "not a bitfield");
+  // FIXME: 0 might be the actual value of the bitwidth.
+  if (BitWidthValue != 0)
+    return BitWidthValue;
   return getBitWidth()->EvaluateKnownConstInt(Ctx).getZExtValue();
 }
 
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp
index 5c107325df30c6..a2ed670cd941ca 100644
--- a/clang/lib/AST/DeclObjC.cpp
+++ b/clang/lib/AST/DeclObjC.cpp
@@ -1833,7 +1833,8 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
                                    SourceLocation IdLoc,
                                    const IdentifierInfo *Id, QualType T,
                                    TypeSourceInfo *TInfo, AccessControl ac,
-                                   Expr *BW, bool synthesized) {
+                                   Expr *BW, unsigned BWValue,
+                                   bool synthesized) {
   if (DC) {
     // Ivar's can only appear in interfaces, implementations (via synthesized
     // properties), and class extensions (via direct declaration, or synthesized
@@ -1861,13 +1862,13 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
   }
 
   return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,
-                                  synthesized);
+                                  BWValue, synthesized);
 }
 
 ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
-  return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(),
-                                  nullptr, QualType(), nullptr,
-                                  ObjCIvarDecl::None, nullptr, false);
+  return new (C, ID)
+      ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
+                   QualType(), nullptr, ObjCIvarDecl::None, false);
 }
 
 ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() {
@@ -1905,18 +1906,27 @@ QualType ObjCIvarDecl::getUsageType(QualType objectType) const {
 
 void ObjCAtDefsFieldDecl::anchor() {}
 
-ObjCAtDefsFieldDecl
-*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
-                             SourceLocation StartLoc,  SourceLocation IdLoc,
-                             IdentifierInfo *Id, QualType T, Expr *BW) {
-  return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
+ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
+                                                 SourceLocation StartLoc,
+                                                 SourceLocation IdLoc,
+                                                 IdentifierInfo *Id, QualType T,
+                                                 Expr *BW, unsigned BWValue) {
+  return new (C, DC)
+      ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW, BWValue);
+}
+
+ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
+                                                 SourceLocation StartLoc,
+                                                 SourceLocation IdLoc,
+                                                 IdentifierInfo *Id,
+                                                 QualType T) {
+  return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T);
 }
 
 ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
                                                              GlobalDeclID ID) {
   return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(),
-                                         SourceLocation(), nullptr, QualType(),
-                                         nullptr);
+                                         SourceLocation(), nullptr, QualType());
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 7b85dcc2c7984f..8b2e2e590579d4 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -5751,11 +5751,11 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
       Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
       SourceLocation(), &Ctx.Idents.get("_objc_super"));
   RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
-                                nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
-                                false, ICIS_NoInit));
+                                nullptr, Ctx.getObjCIdType(), nullptr, false,
+                                ICIS_NoInit));
   RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
-                                nullptr, Ctx.getObjCClassType(), nullptr,
-                                nullptr, false, ICIS_NoInit));
+                                nullptr, Ctx.getObjCClassType(), nullptr, false,
+                                ICIS_NoInit));
   RD->completeDefinition();
 
   SuperCTy = Ctx.getTagDeclType(RD);
@@ -6098,11 +6098,11 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
       Ctx, TagTypeKind::Struct, Ctx.getTranslationUnitDecl(), SourceLocation(),
       SourceLocation(), &Ctx.Idents.get("_message_ref_t"));
   RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
-                                nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
+                                nullptr, Ctx.VoidPtrTy, nullptr, false,
                                 ICIS_NoInit));
   RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
-                                nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
-                                false, ICIS_NoInit));
+                                nullptr, Ctx.getObjCSelType(), nullptr, false,
+                                ICIS_NoInit));
   RD->completeDefinition();
 
   MessageRefCTy = Ctx.getTagDeclType(RD);
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index cc389974e04081..de2d93acd04c3d 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -1022,7 +1022,8 @@ static FieldDecl *addFieldToRecordDecl(ASTContext &C, DeclContext *DC,
   auto *Field = FieldDecl::Create(
       C, DC, SourceLocation(), SourceLocation(), /*Id=*/nullptr, FieldTy,
       C.getTrivialTypeSourceInfo(FieldTy, SourceLocation()),
-      /*BW=*/nullptr, /*Mutable=*/false, /*InitStyle=*/ICIS_NoInit);
+      /*Mutable=*/false,
+      /*InitStyle=*/ICIS_NoInit);
   Field->setAccess(AS_public);
   DC->addDecl(Field);
   return Field;
diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
index 756f0482b8ea72..7c8d6a7e0c6ac0 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
@@ -142,7 +142,7 @@ static RecordDecl *buildRecordForGlobalizedVars(
       Field = FieldDecl::Create(
           C, GlobalizedRD, Loc, Loc, VD->getIdentifier(), Type,
           C.getTrivialTypeSourceInfo(Type, SourceLocation()),
-          /*BW=*/nullptr, /*Mutable=*/false,
+          /*Mutable=*/false,
           /*InitStyle=*/ICIS_NoInit);
       Field->setAccess(AS_public);
       if (VD->hasAttrs()) {
@@ -160,7 +160,7 @@ static RecordDecl *buildRecordForGlobalizedVars(
       Field = FieldDecl::Create(
           C, GlobalizedRD, Loc, Loc, VD->getIdentifier(), Type,
           C.getTrivialTypeSourceInfo(Type, SourceLocation()),
-          /*BW=*/nullptr, /*Mutable=*/false,
+          /*Mutable=*/false,
           /*InitStyle=*/ICIS_NoInit);
       Field->setAccess(AS_public);
       llvm::APInt Align(32, Pair.first.getQuantity());
@@ -772,7 +772,7 @@ void CGOpenMPRuntimeGPU::emitKernelDeinit(CodeGenFunction &CGF,
     auto *Field = FieldDecl::Create(
         C, StaticRD, SourceLocation(), SourceLocation(), nullptr, RecTy,
         C.getTrivialTypeSourceInfo(RecTy, SourceLocation()),
-        /*BW=*/nullptr, /*Mutable=*/false,
+        /*Mutable=*/false,
         /*InitStyle=*/ICIS_NoInit);
     Field->setAccess(AS_public);
     StaticRD->addDecl(Field);
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index b854eeb62a80ce..f6097ee03e718a 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -6500,14 +6500,10 @@ QualType CodeGenModule::getObjCFastEnumerationStateType() {
                                      nullptr, ArraySizeModifier::Normal, 0)};
 
     for (size_t i = 0; i < 4; ++i) {
-      FieldDecl *Field = FieldDecl::Create(Context,
-                                           D,
-                                           SourceLocation(),
-                                           SourceLocation(), nullptr,
-                                           FieldTypes[i], /*TInfo=*/nullptr,
-                                           /*BitWidth=*/nullptr,
-                                           /*Mutable=*/false,
-                                           ICIS_NoInit);
+      FieldDecl *Field =
+          FieldDecl::Create(Context, D, SourceLocation(), SourceLocation(),
+                            nullptr, FieldTypes[i], /*TInfo=*/nullptr,
+                            /*Mutable=*/false, ICIS_NoInit);
       Field->setAccess(AS_public);
       D->addDecl(Field);
     }
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index 0f37738b217c6d..6cbe29288756a3 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -93,9 +93,9 @@ struct BuiltinTypeDeclBuilder {
     IdentifierInfo &II = AST.Idents.get(Name, tok::TokenKind::identifier);
     TypeSourceInfo *MemTySource =
         AST.getTrivialTypeSourceInfo(Type, SourceLocation());
-    auto *Field = FieldDecl::Create(
-        AST, Record, SourceLocation(), SourceLocation(), &II, Type, MemTySource,
-        nullptr, false, InClassInitStyle::ICIS_NoInit);
+    auto *Field = FieldDecl::Create(AST, Record, SourceLocation(),
+                                    SourceLocation(), &II, Type, MemTySource,
+                                    false, InClassInitStyle::ICIS_NoInit);
     Field->setAccess(Access);
     Field->setImplicit(true);
     for (Attr *A : Attrs) {
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 74b0e5ad23bd48..e7528c5fea08d6 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -5665,7 +5665,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
     Anon = FieldDecl::Create(
         Context, OwningClass, DS.getBeginLoc(), Record->getLocation(),
         /*IdentifierInfo=*/nullptr, Context.getTypeDeclType(Record), TInfo,
-        /*BitWidth=*/nullptr, /*Mutable=*/false,
+        /*Mutable=*/false,
         /*InitStyle=*/ICIS_NoInit);
     Anon->setAccess(AS);
     ProcessDeclAttributes(S, Anon, Dc);
@@ -5753,7 +5753,7 @@ Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,
   NamedDecl *Anon =
       FieldDecl::Create(Context, ParentDecl, DS.getBeginLoc(), DS.getBeginLoc(),
                         /*IdentifierInfo=*/nullptr, RecTy, TInfo,
-                        /*BitWidth=*/nullptr, /*Mutable=*/false,
+                        /*Mutable=*/false,
                         /*InitStyle=*/ICIS_NoInit);
   Anon->setImplicit();
 
@@ -18267,7 +18267,7 @@ void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) {
 ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
                                 const IdentifierInfo *FieldName,
                                 QualType FieldTy, bool IsMsStruct,
-                                Expr *BitWidth) {
+                                Expr *BitWidth, unsigned &BWV) {
   assert(BitWidth);
   if (BitWidth->containsErrors())
     return ExprError();
@@ -18298,6 +18298,7 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
   if (ICE.isInvalid())
     return ICE;
   BitWidth = ICE.get();
+  BWV = Value.getZExtValue();
 
   // Zero-width bitfield is ok for anonymous field.
   if (Value == 0 && FieldName)
@@ -18545,12 +18546,15 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
   if (InvalidDecl)
     BitWidth = nullptr;
   // If this is declared as a bit-field, check the bit-field.
+  unsigned BitWidthValue = 0;
   if (BitWidth) {
-    BitWidth =
-        VerifyBitField(Loc, II, T, Record->isMsStruct(Context), BitWidth).get();
+    BitWidth = VerifyBitField(Loc, II, T, Record->isMsStruct(Context), BitWidth,
+                              BitWidthValue)
+                   .get();
     if (!BitWidth) {
       InvalidDecl = true;
       BitWidth = nullptr;
+      BitWidthValue = 0;
     }
   }
 
@@ -18581,8 +18585,9 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
   if (InitStyle != ICIS_NoInit)
     checkDuplicateDefaultInit(*this, cast<CXXRecordDecl>(Record), Loc);
 
-  FieldDecl *NewFD = FieldDecl::Create(Context, Record, TSSL, Loc, II, T, TInfo,
-                                       BitWidth, Mutable, InitStyle);
+  FieldDecl *NewFD =
+      FieldDecl::Create(Context, Record, TSSL, Loc, II, T, TInfo, BitWidth,
+                        BitWidthValue, Mutable, InitStyle);
   if (InvalidDecl)
     NewFD->setInvalidDecl();
 
@@ -18593,36 +18598,32 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
     NewFD->setInvalidDecl();
   }
 
-  if (!InvalidDecl && getLangOpts().CPlusPlus) {
-    if (Record->isUnion()) {
-      if (const RecordType *RT = EltTy->getAs<RecordType>()) {
-        CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
-        if (RDecl->getDefinition()) {
-          // C++ [class.union]p1: An object of a class with a non-trivial
-          // constructor, a non-trivial copy constructor, a non-trivial
-          // destructor, or a non-trivial copy assignment operator
-          // cannot be a member of a union, nor can an array of such
-          // objects.
-          if (CheckNontrivialField(NewFD))
-            NewFD->setInvalidDecl();
-        }
-      }
+  if (!InvalidDecl && getLangOpts().CPlusPlus && Record->isUnion()) {
+    if (const auto *RT = EltTy->getAs<RecordType>();
+        RT && cast<CXXRecordDecl>(RT->getDecl())->getDefinition()) {
+      // C++ [class.union]p1: An object of a class with a non-trivial
+      // constructor, a non-trivial copy constructor, a non-trivial
+      // destructor, or a non-trivial copy assignment operator
+      // cannot be a member of a union, nor can an array of such
+      // objects.
+      if (CheckNontrivialField(NewFD))
+        NewFD->setInvalidDecl();
+    }
 
-      // C++ [class.union]p1: If a union contains a member of reference type,
-      // the program is ill-formed, except when compiling with MSVC extensions
-      // enabled.
-      if (EltTy->isReferenceType()) {
-        const bool HaveMSExt =
-            getLangOpts().MicrosoftExt &&
-            !getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015);
+    // C++ [class.union]p1: If a union contains a member of reference type,
+    // the program is ill-formed, except when compiling with MSVC extensions
+    // enabled.
+    if (EltTy->isReferenceType()) {
+      const bool HaveMSExt =
+          getLangOpts().MicrosoftExt &&
+          !getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015);
 
-        Diag(NewFD->getLocation(),
-             HaveMSExt ? diag::ext_union_member_of_reference_type
-                       : diag::err_union_member_of_reference_type)
-            << NewFD->getDeclName() << EltTy;
-        if (!HaveMSExt)
-          NewFD->setInvalidDecl();
-      }
+      Diag(NewFD->getLocation(), HaveMSExt
+                                     ? diag::ext_union_member_of_reference_type
+                                     : diag::err_union_member_of_reference_type)
+          << NewFD->getDeclName() << EltTy;
+      if (!HaveMSExt)
+        NewFD->setInvalidDecl();
     }
   }
 
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index ad1a02cf098b1e..0aa200cf6dba40 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -5128,11 +5128,10 @@ void SemaObjC::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart,
   for (unsigned i = 0; i < Ivars.size(); i++) {
     const FieldDecl* ID = Ivars[i];
     RecordDecl *Record = dyn_cast<RecordDecl>(TagD);
-    Decl *FD = ObjCAtDefsFieldDecl::Create(Context, Record,
-                                           /*FIXME: StartL=*/ID->getLocation(),
-                                           ID->getLocation(),
-                                           ID->getIdentifier(), ID->getType(),
-                                           ID->getBitWidth());
+    Decl *FD = ObjCAtDefsFieldDecl::Create(
+        Context, Record,
+        /*FIXME: StartL=*/ID->getLocation(), ID->getLocation(),
+        ID->getIdentifier(), ID->getType(), ID->getBitWidth(), 0);
     Decls.push_back(FD);
   }
 
@@ -5578,13 +5577,17 @@ Decl *SemaObjC::ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D,
   TypeSourceInfo *TInfo = SemaRef.GetTypeForDeclarator(D);
   QualType T = TInfo->getType();
 
+  unsigned BitWidthValue = 0;
   if (BitWidth) {
     // 6.7.2.1p3, 6.7.2.1p4
-    BitWidth =
-        SemaRef.VerifyBitField(Loc, II, T, /*IsMsStruct*/ false, BitWidth)
-            .get();
-    if (!BitWidth)
+    BitWidth = SemaRef
+                   .VerifyBitField(Loc, II, T, /*IsMsStruct*/ false, BitWidth,
+                                   BitWidthValue)
+                   .get();
+    if (!BitWidth) {
       D.setInvalidType();
+      BitWidthValue = 0;
+    }
   } else {
     // Not a bitfield.
 
@@ -5634,7 +5637,7 @@ Decl *SemaObjC::ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D,
   // Construct the decl.
   ObjCIvarDecl *NewID =
       ObjCIvarDecl::Create(getASTContext(), EnclosingContext, DeclStart, Loc,
-                           II, T, TInfo, ac, BitWidth);
+                           II, T, TInfo, ac, BitWidth, BitWidthValue);
 
   if (T->containsErrors())
     NewID->setInvalidDecl();
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index a67c0b2b367d1a..3f1f2c68737f4c 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -2040,7 +2040,7 @@ FieldDecl *Sema::BuildCaptureField(RecordDecl *RD,
   // Build the non-static data member.
   FieldDecl *Field =
       FieldDecl::Create(Context, RD, /*StartLoc=*/Loc, /*IdLoc=*/Loc,
-                        /*Id=*/nullptr, FieldType, TSI, /*BW=*/nullptr,
+                        /*Id=*/nullptr, FieldType, TSI,
                         /*Mutable=*/false, ICIS_NoInit);
   // If the variable being captured has an invalid type, mark the class as
   // invalid as well.



More information about the cfe-commits mailing list