Timm =?utf-8?q?Bäder?= <tbae...@redhat.com> Message-ID: In-Reply-To: <llvm.org/llvm/llvm-project/pull/117...@github.com>
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/117732 >From ca2184f07dbceda33ca429b3d63015d49fef3684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Wed, 27 Nov 2024 08:54:51 +0100 Subject: [PATCH 1/2] Save FieldDecl BitWidth as a ConstantExpr --- .../bugprone/TooSmallLoopVariableCheck.cpp | 2 +- .../NarrowingConversionsCheck.cpp | 2 +- .../hicpp/MultiwayPathsCoveredCheck.cpp | 2 +- clang-tools-extra/clangd/Hover.cpp | 2 +- clang/include/clang/AST/Decl.h | 4 ++-- clang/include/clang/ASTMatchers/ASTMatchers.h | 3 +-- clang/lib/AST/ASTContext.cpp | 10 ++++----- clang/lib/AST/ByteCode/Interp.h | 10 ++++----- .../lib/AST/ByteCode/InterpBuiltinBitCast.cpp | 2 +- clang/lib/AST/Decl.cpp | 13 +++++++----- clang/lib/AST/DeclCXX.cpp | 2 +- clang/lib/AST/Expr.cpp | 3 +-- clang/lib/AST/ExprConstant.cpp | 2 +- clang/lib/AST/Randstruct.cpp | 2 +- clang/lib/AST/RecordLayoutBuilder.cpp | 6 +++--- clang/lib/CodeGen/ABIInfo.cpp | 2 +- clang/lib/CodeGen/ABIInfoImpl.cpp | 2 +- clang/lib/CodeGen/CGCall.cpp | 6 +++--- clang/lib/CodeGen/CGClass.cpp | 2 +- clang/lib/CodeGen/CGDebugInfo.cpp | 8 +++---- clang/lib/CodeGen/CGNonTrivialStruct.cpp | 6 +++--- clang/lib/CodeGen/CGObjCMac.cpp | 3 +-- clang/lib/CodeGen/CGObjCRuntime.cpp | 2 +- clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 20 +++++++++--------- clang/lib/CodeGen/SwiftCallingConv.cpp | 2 +- clang/lib/CodeGen/Targets/LoongArch.cpp | 2 +- clang/lib/CodeGen/Targets/RISCV.cpp | 2 +- clang/lib/CodeGen/Targets/X86.cpp | 2 +- clang/lib/CodeGen/Targets/XCore.cpp | 2 +- .../Frontend/Rewrite/RewriteModernObjC.cpp | 3 ++- clang/lib/Sema/SemaChecking.cpp | 10 ++++----- clang/lib/Sema/SemaDecl.cpp | 21 ++++++++++--------- clang/lib/Sema/SemaDeclCXX.cpp | 6 +++--- clang/lib/Sema/SemaDeclObjC.cpp | 3 +-- clang/lib/Sema/SemaOverload.cpp | 2 +- clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 2 +- clang/tools/libclang/CXType.cpp | 2 +- clang/unittests/AST/ASTImporterTest.cpp | 4 ++-- 38 files changed, 88 insertions(+), 91 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp index a73d46f01d9b2d..4ceeefb78ee824 100644 --- a/clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp @@ -124,7 +124,7 @@ static MagnitudeBits calcMagnitudeBits(const ASTContext &Context, unsigned SignedBits = IntExprType->isUnsignedIntegerType() ? 0U : 1U; if (const auto *BitField = IntExpr->getSourceBitField()) { - unsigned BitFieldWidth = BitField->getBitWidthValue(Context); + unsigned BitFieldWidth = BitField->getBitWidthValue(); return {BitFieldWidth - SignedBits, BitFieldWidth}; } diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp index 45fef9471d5211..25931d57943de1 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp @@ -38,7 +38,7 @@ AST_MATCHER(FieldDecl, hasIntBitwidth) { assert(Node.isBitField()); const ASTContext &Ctx = Node.getASTContext(); unsigned IntBitWidth = Ctx.getIntWidth(Ctx.IntTy); - unsigned CurrentBitWidth = Node.getBitWidthValue(Ctx); + unsigned CurrentBitWidth = Node.getBitWidthValue(); return IntBitWidth == CurrentBitWidth; } diff --git a/clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp b/clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp index 47dafca2d03ff0..7028c3958f103e 100644 --- a/clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp +++ b/clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp @@ -160,7 +160,7 @@ void MultiwayPathsCoveredCheck::handleSwitchWithoutDefault( } if (const auto *BitfieldDecl = Result.Nodes.getNodeAs<FieldDecl>("bitfield")) { - return twoPow(BitfieldDecl->getBitWidthValue(*Result.Context)); + return twoPow(BitfieldDecl->getBitWidthValue()); } return static_cast<std::size_t>(0); diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp index 298fa79e3fd0ba..5e136d0e76ece7 100644 --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -1018,7 +1018,7 @@ void addLayoutInfo(const NamedDecl &ND, HoverInfo &HI) { const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Record); HI.Offset = Layout.getFieldOffset(FD->getFieldIndex()); if (FD->isBitField()) - HI.Size = FD->getBitWidthValue(Ctx); + HI.Size = FD->getBitWidthValue(); else if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType())) HI.Size = FD->isZeroSize(Ctx) ? 0 : Size->getQuantity() * 8; if (HI.Size) { diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 8c39ef3d5a9fa6..4ec0781377c5af 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -3143,7 +3143,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { /// Computes the bit width of this field, if this is a bit field. /// May not be called on non-bitfields. - unsigned getBitWidthValue(const ASTContext &Ctx) const; + unsigned getBitWidthValue() const; /// Set the bit-field width for this member. // Note: used by some clients (i.e., do not remove it). @@ -3174,7 +3174,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { /// 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; + bool isZeroLengthBitField() const; /// Determine if this field is a subobject of zero size, that is, either a /// zero-length bit-field or a field of empty class type with the diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 4bcaa953a61af2..4452e4406a70e3 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -708,8 +708,7 @@ AST_MATCHER(FieldDecl, isBitField) { /// fieldDecl(hasBitWidth(2)) /// matches 'int a;' and 'int c;' but not 'int b;'. AST_MATCHER_P(FieldDecl, hasBitWidth, unsigned, Width) { - return Node.isBitField() && - Node.getBitWidthValue(Finder->getASTContext()) == Width; + return Node.isBitField() && Node.getBitWidthValue() == Width; } /// Matches non-static data members that have an in-class initializer. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 80e8c5b9df58e7..ee9d4e4d716ce6 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2774,7 +2774,7 @@ getSubobjectSizeInBits(const FieldDecl *Field, const ASTContext &Context, if (Field->isUnnamedBitField()) return 0; - int64_t BitfieldSize = Field->getBitWidthValue(Context); + int64_t BitfieldSize = Field->getBitWidthValue(); if (IsBitIntType) { if ((unsigned)BitfieldSize > cast<BitIntType>(Field->getType())->getNumBits()) @@ -7745,7 +7745,7 @@ QualType ASTContext::isPromotableBitField(Expr *E) const { QualType FT = Field->getType(); - uint64_t BitWidth = Field->getBitWidthValue(*this); + uint64_t BitWidth = Field->getBitWidthValue(); uint64_t IntSize = getTypeSize(IntTy); // C++ [conv.prom]p5: // A prvalue for an integral bit-field can be converted to a prvalue of type @@ -8773,7 +8773,7 @@ static void EncodeBitField(const ASTContext *Ctx, std::string& S, S += getObjCEncodingForPrimitiveType(Ctx, BT); } } - S += llvm::utostr(FD->getBitWidthValue(*Ctx)); + S += llvm::utostr(FD->getBitWidthValue()); } // Helper function for determining whether the encoded type string would include @@ -9199,7 +9199,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, } for (FieldDecl *Field : RDecl->fields()) { - if (!Field->isZeroLengthBitField(*this) && Field->isZeroSize(*this)) + if (!Field->isZeroLengthBitField() && Field->isZeroSize(*this)) continue; uint64_t offs = layout.getFieldOffset(Field->getFieldIndex()); FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs), @@ -9296,7 +9296,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl, if (field->isBitField()) { EncodeBitField(this, S, field->getType(), field); #ifndef NDEBUG - CurOffs += field->getBitWidthValue(*this); + CurOffs += field->getBitWidthValue(); #endif } else { QualType qt = field->getType(); diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 47dcfca79f7356..782b6f2e13d52c 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -1489,8 +1489,7 @@ bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F, return false; const Pointer &Field = This.atField(FieldOffset); const auto &Value = S.Stk.pop<T>(); - Field.deref<T>() = - Value.truncate(F->Decl->getBitWidthValue(S.getASTContext())); + Field.deref<T>() = Value.truncate(F->Decl->getBitWidthValue()); Field.initialize(); return true; } @@ -1513,8 +1512,7 @@ bool InitBitField(InterpState &S, CodePtr OpPC, const Record::Field *F) { assert(F->isBitField()); const T &Value = S.Stk.pop<T>(); const Pointer &Field = S.Stk.peek<Pointer>().atField(F->Offset); - Field.deref<T>() = - Value.truncate(F->Decl->getBitWidthValue(S.getASTContext())); + Field.deref<T>() = Value.truncate(F->Decl->getBitWidthValue()); Field.activate(); Field.initialize(); return true; @@ -1821,7 +1819,7 @@ bool StoreBitField(InterpState &S, CodePtr OpPC) { if (Ptr.canBeInitialized()) Ptr.initialize(); if (const auto *FD = Ptr.getField()) - Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue(S.getASTContext())); + Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue()); else Ptr.deref<T>() = Value; return true; @@ -1836,7 +1834,7 @@ bool StoreBitFieldPop(InterpState &S, CodePtr OpPC) { if (Ptr.canBeInitialized()) Ptr.initialize(); if (const auto *FD = Ptr.getField()) - Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue(S.getASTContext())); + Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue()); else Ptr.deref<T>() = Value; return true; diff --git a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp index b1230f92ddf1d4..77c87a13d0a7f2 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp @@ -333,7 +333,7 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr, } else { if (const FieldDecl *FD = P.getField(); FD && FD->isBitField()) - BitWidth = FD->getBitWidthValue(ASTCtx); + BitWidth = FD->getBitWidthValue(); else if (T == PT_Bool && PackedBools) BitWidth = 1; diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 741e908cf9bc56..597fc9a163aa5e 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -4599,18 +4599,21 @@ void FieldDecl::setLazyInClassInitializer(LazyDeclStmtPtr NewInit) { Init = NewInit; } -unsigned FieldDecl::getBitWidthValue(const ASTContext &Ctx) const { +unsigned FieldDecl::getBitWidthValue() const { assert(isBitField() && "not a bitfield"); - return getBitWidth()->EvaluateKnownConstInt(Ctx).getZExtValue(); + return cast<ConstantExpr>(getBitWidth()) + ->getAPValueResult() + .getInt() + .getZExtValue(); } -bool FieldDecl::isZeroLengthBitField(const ASTContext &Ctx) const { +bool FieldDecl::isZeroLengthBitField() const { return isUnnamedBitField() && !getBitWidth()->isValueDependent() && - getBitWidthValue(Ctx) == 0; + getBitWidthValue() == 0; } bool FieldDecl::isZeroSize(const ASTContext &Ctx) const { - if (isZeroLengthBitField(Ctx)) + if (isZeroLengthBitField()) return true; // C++2a [intro.object]p7: diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 25560faae8672b..7d8bf509f03e20 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -993,7 +993,7 @@ void CXXRecordDecl::addedMember(Decl *D) { // C++ [meta.unary.prop]p4: [LWG2358] // T is a class type [...] with [...] no unnamed bit-fields of non-zero // length - if (data().Empty && !Field->isZeroLengthBitField(Context) && + if (data().Empty && !Field->isZeroLengthBitField() && Context.getLangOpts().getClangABICompat() > LangOptions::ClangABI::Ver6) data().Empty = false; diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index a4fb4d5a1f2ec4..3af62ff7c4440e 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -196,8 +196,7 @@ bool Expr::isKnownToHaveBooleanValue(bool Semantic) const { if (const FieldDecl *FD = E->getSourceBitField()) if (!Semantic && FD->getType()->isUnsignedIntegerType() && - !FD->getBitWidth()->isValueDependent() && - FD->getBitWidthValue(FD->getASTContext()) == 1) + !FD->getBitWidth()->isValueDependent() && FD->getBitWidthValue() == 1) return true; return false; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index c6d003073966f3..707ba0e08a4228 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2875,7 +2875,7 @@ static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APSInt &Int = Value.getInt(); unsigned OldBitWidth = Int.getBitWidth(); - unsigned NewBitWidth = FD->getBitWidthValue(Info.Ctx); + unsigned NewBitWidth = FD->getBitWidthValue(); if (NewBitWidth < OldBitWidth) Int = Int.trunc(NewBitWidth).extend(OldBitWidth); return true; diff --git a/clang/lib/AST/Randstruct.cpp b/clang/lib/AST/Randstruct.cpp index b484afa4997bbc..4537ba5309e0bc 100644 --- a/clang/lib/AST/Randstruct.cpp +++ b/clang/lib/AST/Randstruct.cpp @@ -91,7 +91,7 @@ void randomizeStructureLayoutImpl(const ASTContext &Context, auto FieldIter = FieldsOut.begin(); FieldDecl *FD = *FieldIter; - if (FD->isBitField() && !FD->isZeroLengthBitField(Context)) { + if (FD->isBitField() && !FD->isZeroLengthBitField()) { // Start a bitfield run if this is the first bitfield we have found. if (!CurrentBitfieldRun) CurrentBitfieldRun = std::make_unique<BitfieldRunBucket>(); diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index b1b13b66a5e504..1c4edf06908e3b 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -1542,7 +1542,7 @@ static bool isAIXLayout(const ASTContext &Context) { void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { bool FieldPacked = Packed || D->hasAttr<PackedAttr>(); - uint64_t FieldSize = D->getBitWidthValue(Context); + uint64_t FieldSize = D->getBitWidthValue(); TypeInfo FieldInfo = Context.getTypeInfo(D->getType()); uint64_t StorageUnitSize = FieldInfo.Width; unsigned FieldAlign = FieldInfo.Align; @@ -3022,7 +3022,7 @@ void MicrosoftRecordLayoutBuilder::layoutField(const FieldDecl *FD) { } void MicrosoftRecordLayoutBuilder::layoutBitField(const FieldDecl *FD) { - unsigned Width = FD->getBitWidthValue(Context); + unsigned Width = FD->getBitWidthValue(); if (Width == 0) { layoutZeroWidthBitField(FD); return; @@ -3692,7 +3692,7 @@ static void DumpRecordLayout(raw_ostream &OS, const RecordDecl *RD, if (Field.isBitField()) { uint64_t LocalFieldByteOffsetInBits = C.toBits(FieldOffset - Offset); unsigned Begin = LocalFieldOffsetInBits - LocalFieldByteOffsetInBits; - unsigned Width = Field.getBitWidthValue(C); + unsigned Width = Field.getBitWidthValue(); PrintBitFieldOffset(OS, FieldOffset, Begin, Width, IndentLevel); } else { PrintOffset(OS, FieldOffset, IndentLevel); diff --git a/clang/lib/CodeGen/ABIInfo.cpp b/clang/lib/CodeGen/ABIInfo.cpp index edd7146dc1ac76..6954314e6aebba 100644 --- a/clang/lib/CodeGen/ABIInfo.cpp +++ b/clang/lib/CodeGen/ABIInfo.cpp @@ -106,7 +106,7 @@ bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base, continue; if (isZeroLengthBitfieldPermittedInHomogeneousAggregate() && - FD->isZeroLengthBitField(getContext())) + FD->isZeroLengthBitField()) continue; uint64_t FldMembers; diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp index 79300df15d0e29..795874059bda71 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.cpp +++ b/clang/lib/CodeGen/ABIInfoImpl.cpp @@ -303,7 +303,7 @@ bool CodeGen::isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool CodeGen::isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD) { - if (FD->isZeroLengthBitField(Context)) + if (FD->isZeroLengthBitField()) return true; if (FD->isUnnamedBitField()) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 35d495d4dfab82..b90cd792b38ebe 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -954,7 +954,7 @@ getTypeExpansion(QualType Ty, const ASTContext &Context) { CharUnits UnionSize = CharUnits::Zero(); for (const auto *FD : RD->fields()) { - if (FD->isZeroLengthBitField(Context)) + if (FD->isZeroLengthBitField()) continue; assert(!FD->isBitField() && "Cannot expand structure with bit-field members."); @@ -974,7 +974,7 @@ getTypeExpansion(QualType Ty, const ASTContext &Context) { } for (const auto *FD : RD->fields()) { - if (FD->isZeroLengthBitField(Context)) + if (FD->isZeroLengthBitField()) continue; assert(!FD->isBitField() && "Cannot expand structure with bit-field members."); @@ -3698,7 +3698,7 @@ static void setUsedBits(CodeGenModule &CGM, const RecordType *RTy, int Offset, for (auto I = RD->field_begin(), E = RD->field_end(); I != E; ++I, ++Idx) { const FieldDecl *F = *I; - if (F->isUnnamedBitField() || F->isZeroLengthBitField(Context) || + if (F->isUnnamedBitField() || F->isZeroLengthBitField() || F->getType()->isIncompleteArrayType()) continue; diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index c45688bd1ed3ce..8c190732c8cdcf 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -945,7 +945,7 @@ namespace { ASTContext &Ctx = CGF.getContext(); unsigned LastFieldSize = LastField->isBitField() - ? LastField->getBitWidthValue(Ctx) + ? LastField->getBitWidthValue() : Ctx.toBits( Ctx.getTypeInfoDataSizeInChars(LastField->getType()).Width); uint64_t MemcpySizeBits = LastFieldOffset + LastFieldSize - diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 60f32f76109e9a..84cc6a4b5f1388 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1721,8 +1721,7 @@ llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded( assert(PreviousBitfield->isBitField()); - ASTContext &Context = CGM.getContext(); - if (!PreviousBitfield->isZeroLengthBitField(Context)) + if (!PreviousBitfield->isZeroLengthBitField()) return nullptr; QualType Ty = PreviousBitfield->getType(); @@ -3231,9 +3230,8 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty, if (!FType->isIncompleteArrayType()) { // Bit size, align and offset of the type. - FieldSize = Field->isBitField() - ? Field->getBitWidthValue(CGM.getContext()) - : CGM.getContext().getTypeSize(FType); + FieldSize = Field->isBitField() ? Field->getBitWidthValue() + : CGM.getContext().getTypeSize(FType); FieldAlign = getTypeAlignIfRequired(FType, CGM.getContext()); } diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp b/clang/lib/CodeGen/CGNonTrivialStruct.cpp index 6a02e4dbf84d14..d90c44d770d14b 100644 --- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp +++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp @@ -25,7 +25,7 @@ using namespace CodeGen; static uint64_t getFieldSize(const FieldDecl *FD, QualType FT, ASTContext &Ctx) { if (FD && FD->isBitField()) - return FD->getBitWidthValue(Ctx); + return FD->getBitWidthValue(); return Ctx.getTypeSize(FT); } @@ -255,7 +255,7 @@ struct GenBinaryFuncName : CopyStructVisitor<GenBinaryFuncName<IsMove>, IsMove>, void visitVolatileTrivial(QualType FT, const FieldDecl *FD, CharUnits CurStructOffset) { // Zero-length bit-fields don't need to be copied/assigned. - if (FD && FD->isZeroLengthBitField(this->Ctx)) + if (FD && FD->isZeroLengthBitField()) return; // Because volatile fields can be bit-fields and are individually copied, @@ -544,7 +544,7 @@ struct GenBinaryFunc : CopyStructVisitor<Derived, IsMove>, LValue DstLV, SrcLV; if (FD) { // No need to copy zero-length bit-fields. - if (FD->isZeroLengthBitField(this->CGF->getContext())) + if (FD->isZeroLengthBitField()) return; QualType RT = QualType(FD->getParent()->getTypeForDecl(), 0); diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 7b85dcc2c7984f..dd900f9b32fb78 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -2543,8 +2543,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, if (LastFieldBitfieldOrUnnamed) { if (LastFieldBitfieldOrUnnamed->isBitField()) { // Last field was a bitfield. Must update the info. - uint64_t BitFieldSize - = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext()); + uint64_t BitFieldSize = LastFieldBitfieldOrUnnamed->getBitWidthValue(); unsigned UnsSize = (BitFieldSize / ByteSizeInBits) + ((BitFieldSize % ByteSizeInBits) != 0); CharUnits Size = CharUnits::fromQuantity(UnsSize); diff --git a/clang/lib/CodeGen/CGObjCRuntime.cpp b/clang/lib/CodeGen/CGObjCRuntime.cpp index 01d0f35da19643..b438a92a4fd627 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.cpp +++ b/clang/lib/CodeGen/CGObjCRuntime.cpp @@ -89,7 +89,7 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, CGF.CGM.getContext().lookupFieldBitOffset(OID, nullptr, Ivar); uint64_t BitOffset = FieldBitOffset % CGF.CGM.getContext().getCharWidth(); uint64_t AlignmentBits = CGF.CGM.getTarget().getCharAlign(); - uint64_t BitFieldSize = Ivar->getBitWidthValue(CGF.getContext()); + uint64_t BitFieldSize = Ivar->getBitWidthValue(); CharUnits StorageSize = CGF.CGM.getContext().toCharUnitsFromBits( llvm::alignTo(BitOffset + BitFieldSize, AlignmentBits)); CharUnits Alignment = CGF.CGM.getContext().toCharUnitsFromBits(AlignmentBits); diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index ea44e6f21f3c86..4afcd9d6d32ccc 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -148,8 +148,8 @@ struct CGRecordLowering { llvm::Type *Type = Types.ConvertTypeForMem(FD->getType()); if (!FD->isBitField()) return Type; if (isDiscreteBitFieldABI()) return Type; - return getIntNType(std::min(FD->getBitWidthValue(Context), - (unsigned)Context.toBits(getSize(Type)))); + return getIntNType(std::min(FD->getBitWidthValue(), + (unsigned)Context.toBits(getSize(Type)))); } /// Gets the llvm Basesubobject type from a CXXRecordDecl. llvm::Type *getStorageType(const CXXRecordDecl *RD) const { @@ -242,7 +242,7 @@ void CGRecordLowering::setBitFieldInfo( CGBitFieldInfo &Info = BitFields[FD->getCanonicalDecl()]; Info.IsSigned = FD->getType()->isSignedIntegerOrEnumerationType(); Info.Offset = (unsigned)(getFieldBitOffset(FD) - Context.toBits(StartOffset)); - Info.Size = FD->getBitWidthValue(Context); + Info.Size = FD->getBitWidthValue(); Info.StorageSize = (unsigned)DataLayout.getTypeAllocSizeInBits(StorageType); Info.StorageOffset = StartOffset; if (Info.Size > Info.StorageSize) @@ -322,7 +322,7 @@ void CGRecordLowering::lowerUnion(bool isNoUniqueAddress) { // been doing and cause lit tests to change. for (const auto *Field : D->fields()) { if (Field->isBitField()) { - if (Field->isZeroLengthBitField(Context)) + if (Field->isZeroLengthBitField()) continue; llvm::Type *FieldType = getStorageType(Field); if (LayoutSize < getSize(FieldType)) @@ -423,7 +423,7 @@ CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType, uint64_t StartBitOffset, Tail = 0; for (; Field != FieldEnd && Field->isBitField(); ++Field) { // Zero-width bitfields end runs. - if (Field->isZeroLengthBitField(Context)) { + if (Field->isZeroLengthBitField()) { Run = FieldEnd; continue; } @@ -559,7 +559,7 @@ CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType, // Bitfield potentially begins a new span. This includes zero-length // bitfields on non-aligning targets that lie at character boundaries // (those are barriers to merging). - if (Field->isZeroLengthBitField(Context)) + if (Field->isZeroLengthBitField()) Barrier = true; AtAlignedBoundary = true; } @@ -697,7 +697,7 @@ CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType, } Members.push_back(StorageInfo(BeginOffset, Type)); for (; Begin != BestEnd; ++Begin) - if (!Begin->isZeroLengthBitField(Context)) + if (!Begin->isZeroLengthBitField()) Members.push_back( MemberInfo(BeginOffset, MemberInfo::Field, nullptr, *Begin)); } @@ -709,7 +709,7 @@ CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType, "Accumulating past end of bitfields"); assert(!Barrier && "Accumulating across barrier"); // Accumulate this bitfield into the current (potential) span. - BitSizeSinceBegin += Field->getBitWidthValue(Context); + BitSizeSinceBegin += Field->getBitWidthValue(); ++Field; } } @@ -813,7 +813,7 @@ void CGRecordLowering::computeVolatileBitfields() { bool Conflict = false; for (const auto *F : D->fields()) { // Allow sized bit-fields overlaps. - if (F->isBitField() && !F->isZeroLengthBitField(Context)) + if (F->isBitField() && !F->isZeroLengthBitField()) continue; const CharUnits FOffset = Context.toCharUnitsFromBits( @@ -823,7 +823,7 @@ void CGRecordLowering::computeVolatileBitfields() { // fields after and before it should be race condition free. // The AAPCS acknowledges it and imposes no restritions when the // natural container overlaps a zero-length bit-field. - if (F->isZeroLengthBitField(Context)) { + if (F->isZeroLengthBitField()) { if (End > FOffset && StorageOffset < FOffset) { Conflict = true; break; diff --git a/clang/lib/CodeGen/SwiftCallingConv.cpp b/clang/lib/CodeGen/SwiftCallingConv.cpp index 0873896df213e8..1ff4ece2811ec0 100644 --- a/clang/lib/CodeGen/SwiftCallingConv.cpp +++ b/clang/lib/CodeGen/SwiftCallingConv.cpp @@ -186,7 +186,7 @@ void SwiftAggLowering::addBitFieldData(const FieldDecl *bitfield, uint64_t bitfieldBitBegin) { assert(bitfield->isBitField()); auto &ctx = CGM.getContext(); - auto width = bitfield->getBitWidthValue(ctx); + auto width = bitfield->getBitWidthValue(); // We can ignore zero-width bit-fields. if (width == 0) return; diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp index 6af9375461f095..6c90e48a5ea417 100644 --- a/clang/lib/CodeGen/Targets/LoongArch.cpp +++ b/clang/lib/CodeGen/Targets/LoongArch.cpp @@ -192,7 +192,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper( for (const FieldDecl *FD : RD->fields()) { QualType QTy = FD->getType(); if (FD->isBitField()) { - unsigned BitWidth = FD->getBitWidthValue(getContext()); + unsigned BitWidth = FD->getBitWidthValue(); // Zero-width bitfields are ignored. if (BitWidth == 0) continue; diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index b04e436c665f52..67bd7c120d02f3 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -246,7 +246,7 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff, uint64_t FieldOffInBits = Layout.getFieldOffset(FD->getFieldIndex()); QualType QTy = FD->getType(); if (FD->isBitField()) { - unsigned BitWidth = FD->getBitWidthValue(getContext()); + unsigned BitWidth = FD->getBitWidthValue(); // Allow a bitfield with a type greater than XLen as long as the // bitwidth is XLen or less. if (getContext().getTypeSize(QTy) > XLen && BitWidth <= XLen) diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index 7f73bf2a65266e..5ee5179dd0f3e8 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -2130,7 +2130,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo, if (BitField) { assert(!i->isUnnamedBitField()); uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx); - uint64_t Size = i->getBitWidthValue(getContext()); + uint64_t Size = i->getBitWidthValue(); uint64_t EB_Lo = Offset / 64; uint64_t EB_Hi = (Offset + Size - 1) / 64; diff --git a/clang/lib/CodeGen/Targets/XCore.cpp b/clang/lib/CodeGen/Targets/XCore.cpp index f3e241171b8729..ced4981fd124f6 100644 --- a/clang/lib/CodeGen/Targets/XCore.cpp +++ b/clang/lib/CodeGen/Targets/XCore.cpp @@ -343,7 +343,7 @@ static bool extractFieldType(SmallVectorImpl<FieldEncoding> &FE, if (Field->isBitField()) { Enc += "b("; llvm::raw_svector_ostream OS(Enc); - OS << Field->getBitWidthValue(CGM.getContext()); + OS << Field->getBitWidthValue(); Enc += ':'; } if (!appendType(Enc, Field->getType(), CGM, TSC)) diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp index 8cdb463e2c99f2..fc65559e9d4a51 100644 --- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -3699,7 +3699,8 @@ void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl, Type.getAsStringInternal(Name, Context->getPrintingPolicy()); Result += Name; if (fieldDecl->isBitField()) { - Result += " : "; Result += utostr(fieldDecl->getBitWidthValue(*Context)); + Result += " : "; + Result += utostr(fieldDecl->getBitWidthValue()); } else if (EleboratedType && Type->isArrayType()) { const ArrayType *AT = Context->getAsArrayType(Type); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a49605e4867651..c9530a86ac89d3 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -657,7 +657,7 @@ struct BuiltinDumpStructGenerator { Format += ": %zu "; QualType SizeT = S.Context.getSizeType(); llvm::APInt BitWidth(S.Context.getIntWidth(SizeT), - FD->getBitWidthValue(S.Context)); + FD->getBitWidthValue()); Args.push_back(IntegerLiteral::Create(S.Context, BitWidth, SizeT, Loc)); } @@ -9970,7 +9970,7 @@ static std::optional<IntRange> TryGetExprRange(ASTContext &C, const Expr *E, Approximate); if (const auto *BitField = E->getSourceBitField()) - return IntRange(BitField->getBitWidthValue(C), + return IntRange(BitField->getBitWidthValue(), BitField->getType()->isUnsignedIntegerOrEnumerationType()); if (GetExprType(E)->isVoidType()) @@ -10523,7 +10523,7 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, return false; Expr *OriginalInit = Init->IgnoreParenImpCasts(); - unsigned FieldWidth = Bitfield->getBitWidthValue(S.Context); + unsigned FieldWidth = Bitfield->getBitWidthValue(); Expr::EvalResult Result; if (!OriginalInit->EvaluateAsInt(Result, S.Context, @@ -13987,8 +13987,8 @@ static bool isLayoutCompatible(const ASTContext &C, const FieldDecl *Field1, if (Field1->isBitField()) { // Make sure that the bit-fields are the same length. - unsigned Bits1 = Field1->getBitWidthValue(C); - unsigned Bits2 = Field2->getBitWidthValue(C); + unsigned Bits1 = Field1->getBitWidthValue(); + unsigned Bits2 = Field2->getBitWidthValue(); if (Bits1 != Bits2) return false; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 74b0e5ad23bd48..30d16639d1f934 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18349,7 +18349,9 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, } } - return BitWidth; + if (isa<ConstantExpr>(BitWidth)) + return BitWidth; + return ConstantExpr::Create(getASTContext(), BitWidth, APValue{Value}); } Decl *Sema::ActOnField(Scope *S, Decl *TagD, SourceLocation DeclStart, @@ -18724,7 +18726,7 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc, Decl *ivarDecl = AllIvarDecls[AllIvarDecls.size()-1]; ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(ivarDecl); - if (!Ivar->isBitField() || Ivar->isZeroLengthBitField(Context)) + if (!Ivar->isBitField() || Ivar->isZeroLengthBitField()) return; ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CurContext); if (!ID) { @@ -18739,14 +18741,13 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc, // All conditions are met. Add a new bitfield to the tail end of ivars. llvm::APInt Zero(Context.getTypeSize(Context.IntTy), 0); Expr * BW = IntegerLiteral::Create(Context, Zero, Context.IntTy, DeclLoc); + Expr *BitWidth = + ConstantExpr::Create(Context, BW, APValue(llvm::APSInt(Zero))); - Ivar = ObjCIvarDecl::Create(Context, cast<ObjCContainerDecl>(CurContext), - DeclLoc, DeclLoc, nullptr, - Context.CharTy, - Context.getTrivialTypeSourceInfo(Context.CharTy, - DeclLoc), - ObjCIvarDecl::Private, BW, - true); + Ivar = ObjCIvarDecl::Create( + Context, cast<ObjCContainerDecl>(CurContext), DeclLoc, DeclLoc, nullptr, + Context.CharTy, Context.getTrivialTypeSourceInfo(Context.CharTy, DeclLoc), + ObjCIvarDecl::Private, BitWidth, true); AllIvarDecls.push_back(Ivar); } @@ -19376,7 +19377,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, (NonBitFields == 0 || ZeroSize) && I != E; ++I) { IsEmpty = false; if (I->isUnnamedBitField()) { - if (!I->isZeroLengthBitField(Context)) + if (!I->isZeroLengthBitField()) ZeroSize = false; } else { ++NonBitFields; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 26041e53de5061..4a81074664a3a7 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4873,7 +4873,7 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, QualType ParamType = Param->getType().getNonReferenceType(); // Suppress copying zero-width bitfields. - if (Field->isZeroLengthBitField(SemaRef.Context)) + if (Field->isZeroLengthBitField()) return false; Expr *MemberExprBase = @@ -15030,7 +15030,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, } // Suppress assigning zero-width bitfields. - if (Field->isZeroLengthBitField(Context)) + if (Field->isZeroLengthBitField()) continue; QualType FieldType = Field->getType().getNonReferenceType(); @@ -15417,7 +15417,7 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation, } // Suppress assigning zero-width bitfields. - if (Field->isZeroLengthBitField(Context)) + if (Field->isZeroLengthBitField()) continue; QualType FieldType = Field->getType().getNonReferenceType(); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index ad1a02cf098b1e..fedc0c36891799 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -2210,8 +2210,7 @@ void SemaObjC::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, << ImplIvar->getType() << ClsIvar->getType(); Diag(ClsIvar->getLocation(), diag::note_previous_definition); } else if (ImplIvar->isBitField() && ClsIvar->isBitField() && - ImplIvar->getBitWidthValue(Context) != - ClsIvar->getBitWidthValue(Context)) { + ImplIvar->getBitWidthValue() != ClsIvar->getBitWidthValue()) { Diag(ImplIvar->getBitWidth()->getBeginLoc(), diag::err_conflicting_ivar_bitwidth) << ImplIvar->getIdentifier(); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index e4bf9aa521224b..b81820d26a570c 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -516,7 +516,7 @@ NarrowingKind StandardConversionSequence::getNarrowingKind( if (const FieldDecl *BitField = Initializer->getSourceBitField()) { if (BitField->getBitWidth()->isValueDependent()) DependentBitField = true; - else if (unsigned BitFieldWidth = BitField->getBitWidthValue(Ctx); + else if (unsigned BitFieldWidth = BitField->getBitWidthValue(); BitFieldWidth < FromWidth) { if (CanRepresentAll(FromSigned, BitFieldWidth, ToSigned, ToWidth)) return NK_Not_Narrowing; diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 46e294a1741cfe..9553e6221ed331 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -929,7 +929,7 @@ collectSubRegionBindings(SmallVectorImpl<BindingPair> &Bindings, Length = ExtentInt.getLimitedValue() * SVB.getContext().getCharWidth(); } else if (const FieldRegion *FR = dyn_cast<FieldRegion>(Top)) { if (FR->getDecl()->isBitField()) - Length = FR->getDecl()->getBitWidthValue(SVB.getContext()); + Length = FR->getDecl()->getBitWidthValue(); } for (const auto &StoreEntry : Cluster) { diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp index b4df12405cf356..990daadd322dc3 100644 --- a/clang/tools/libclang/CXType.cpp +++ b/clang/tools/libclang/CXType.cpp @@ -381,7 +381,7 @@ int clang_getFieldDeclBitWidth(CXCursor C) { if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) { if (FD->isBitField() && !FD->getBitWidth()->isValueDependent()) - return FD->getBitWidthValue(getCursorContext(C)); + return FD->getBitWidthValue(); } } diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index bf7313f882e455..236e4b3770fb2f 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -3402,12 +3402,12 @@ TEST_P(ASTImporterOptionSpecificTestBase, ImportBitfields) { FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl(hasName("x"))); ASSERT_TRUE(FromF->isBitField()); - ASSERT_EQ(3u, FromF->getBitWidthValue(FromTU->getASTContext())); + ASSERT_EQ(3u, FromF->getBitWidthValue()); auto *ToField = Import(FromF, Lang_CXX03); auto *ToTU = ToField->getTranslationUnitDecl(); EXPECT_TRUE(ToField->isBitField()); - EXPECT_EQ(3u, ToField->getBitWidthValue(ToTU->getASTContext())); + EXPECT_EQ(3u, ToField->getBitWidthValue()); const auto *FromBT = FromF->getBitWidth()->getType()->getAs<BuiltinType>(); const auto *ToBT = ToField->getBitWidth()->getType()->getAs<BuiltinType>(); >From 5516ef958946322ee15ec2933603fae149ca0fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Wed, 27 Nov 2024 12:50:08 +0100 Subject: [PATCH 2/2] Save BitWidth as ConstantExpr --- clang/include/clang/AST/Decl.h | 22 ++++++++++++++-------- clang/include/clang/AST/DeclObjC.h | 11 ++++++----- clang/lib/AST/Decl.cpp | 9 +++------ clang/lib/AST/DeclObjC.cpp | 11 ++++++----- clang/lib/Sema/SemaDecl.cpp | 7 +++++-- clang/lib/Sema/SemaDeclObjC.cpp | 6 +++++- clang/lib/Sema/SemaObjCProperty.cpp | 9 ++++----- clang/lib/Serialization/ASTReaderDecl.cpp | 2 +- 8 files changed, 44 insertions(+), 33 deletions(-) diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 4ec0781377c5af..424213ebe3aad8 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -58,6 +58,7 @@ class CompoundStmt; class DependentFunctionTemplateSpecializationInfo; class EnumDecl; class Expr; +class ConstantExpr; // : Expr; class FunctionTemplateDecl; class FunctionTemplateSpecializationInfo; class FunctionTypeLoc; @@ -3030,6 +3031,11 @@ class FunctionDecl : public DeclaratorDecl, } }; +// class ConstantExpr : public Expr; +// class ConstantExpr final +// : public FullExpr, +// private llvm::TrailingObjects<ConstantExpr, APValue, uint64_t>; + /// Represents a member of a struct/union/class. class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { /// The kinds of value we can store in StorageKind. @@ -3067,7 +3073,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { /// structure is used to represent the two expressions. struct InitAndBitWidthStorage { LazyDeclStmtPtr Init; - Expr *BitWidth; + ConstantExpr *BitWidth; }; /// Storage for either the bit-width, the in-class initializer, or @@ -3083,7 +3089,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { // Active member if ISK is not ISK_CapturedVLAType and BitField is false. LazyDeclStmtPtr Init; // Active member if ISK is ISK_NoInit and BitField is true. - Expr *BitWidth; + ConstantExpr *BitWidth; // Active member if ISK is ISK_InClass*Init and BitField is true. InitAndBitWidthStorage *InitAndBitWidth; // Active member if ISK is ISK_CapturedVLAType. @@ -3093,7 +3099,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { protected: FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, - TypeSourceInfo *TInfo, Expr *BW, bool Mutable, + TypeSourceInfo *TInfo, ConstantExpr *BW, bool Mutable, InClassInitStyle InitStyle) : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), BitField(false), Mutable(Mutable), StorageKind((InitStorageKind)InitStyle), @@ -3109,8 +3115,8 @@ 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, - InClassInitStyle InitStyle); + TypeSourceInfo *TInfo, ConstantExpr *BW, + bool Mutable, InClassInitStyle InitStyle); static FieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); @@ -3135,7 +3141,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { /// Returns the expression that represents the bit width, if this field /// is a bit field. For non-bitfields, this returns \c nullptr. - Expr *getBitWidth() const { + ConstantExpr *getBitWidth() const { if (!BitField) return nullptr; return hasInClassInitializer() ? InitAndBitWidth->BitWidth : BitWidth; @@ -3147,7 +3153,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { /// Set the bit-field width for this member. // Note: used by some clients (i.e., do not remove it). - void setBitWidth(Expr *Width) { + void setBitWidth(ConstantExpr *Width) { assert(!hasCapturedVLAType() && !BitField && "bit width or captured type already set"); assert(Width && "no bit width specified"); @@ -3224,7 +3230,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { StorageKind = ISK_NoInit; if (BitField) { // Read the bit width before we change the active union member. - Expr *ExistingBitWidth = InitAndBitWidth->BitWidth; + ConstantExpr *ExistingBitWidth = InitAndBitWidth->BitWidth; BitWidth = ExistingBitWidth; } } diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index 4663603f797545..dcda9915c0a98b 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -1959,7 +1959,7 @@ class ObjCIvarDecl : public FieldDecl { private: ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, - TypeSourceInfo *TInfo, AccessControl ac, Expr *BW, + TypeSourceInfo *TInfo, AccessControl ac, ConstantExpr *BW, bool synthesized) : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit), @@ -1970,7 +1970,8 @@ class ObjCIvarDecl : public FieldDecl { SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, AccessControl ac, - Expr *BW = nullptr, bool synthesized = false); + ConstantExpr *BW = nullptr, + bool synthesized = false); static ObjCIvarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); @@ -2028,8 +2029,8 @@ 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, + ConstantExpr *BW) : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T, /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ? BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {} @@ -2040,7 +2041,7 @@ class ObjCAtDefsFieldDecl : public FieldDecl { static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, - QualType T, Expr *BW); + QualType T, ConstantExpr *BW); static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 597fc9a163aa5e..885cf94b7fab60 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -4555,8 +4555,8 @@ 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, - InClassInitStyle InitStyle) { + TypeSourceInfo *TInfo, ConstantExpr *BW, + bool Mutable, InClassInitStyle InitStyle) { return new (C, DC) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo, BW, Mutable, InitStyle); } @@ -4601,10 +4601,7 @@ void FieldDecl::setLazyInClassInitializer(LazyDeclStmtPtr NewInit) { unsigned FieldDecl::getBitWidthValue() const { assert(isBitField() && "not a bitfield"); - return cast<ConstantExpr>(getBitWidth()) - ->getAPValueResult() - .getInt() - .getZExtValue(); + return getBitWidth()->getAPValueResult().getInt().getZExtValue(); } bool FieldDecl::isZeroLengthBitField() const { diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 5c107325df30c6..40c0f3760bf50d 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -1833,7 +1833,7 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, AccessControl ac, - Expr *BW, bool synthesized) { + ConstantExpr *BW, bool synthesized) { if (DC) { // Ivar's can only appear in interfaces, implementations (via synthesized // properties), and class extensions (via direct declaration, or synthesized @@ -1905,10 +1905,11 @@ 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) { +ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, + SourceLocation IdLoc, + IdentifierInfo *Id, QualType T, + ConstantExpr *BW) { return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW); } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 30d16639d1f934..764658591241a4 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18547,12 +18547,15 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, if (InvalidDecl) BitWidth = nullptr; // If this is declared as a bit-field, check the bit-field. + ConstantExpr *ConstantBW = nullptr; if (BitWidth) { BitWidth = VerifyBitField(Loc, II, T, Record->isMsStruct(Context), BitWidth).get(); if (!BitWidth) { InvalidDecl = true; BitWidth = nullptr; + } else if (!BitWidth->isValueDependent() && !BitWidth->isTypeDependent()) { + ConstantBW = cast<ConstantExpr>(BitWidth); } } @@ -18584,7 +18587,7 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, checkDuplicateDefaultInit(*this, cast<CXXRecordDecl>(Record), Loc); FieldDecl *NewFD = FieldDecl::Create(Context, Record, TSSL, Loc, II, T, TInfo, - BitWidth, Mutable, InitStyle); + ConstantBW, Mutable, InitStyle); if (InvalidDecl) NewFD->setInvalidDecl(); @@ -18741,7 +18744,7 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc, // All conditions are met. Add a new bitfield to the tail end of ivars. llvm::APInt Zero(Context.getTypeSize(Context.IntTy), 0); Expr * BW = IntegerLiteral::Create(Context, Zero, Context.IntTy, DeclLoc); - Expr *BitWidth = + ConstantExpr *BitWidth = ConstantExpr::Create(Context, BW, APValue(llvm::APSInt(Zero))); Ivar = ObjCIvarDecl::Create( diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index fedc0c36891799..ed715509a9a3ae 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -5577,6 +5577,7 @@ Decl *SemaObjC::ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D, TypeSourceInfo *TInfo = SemaRef.GetTypeForDeclarator(D); QualType T = TInfo->getType(); + ConstantExpr *ConstantBW = nullptr; if (BitWidth) { // 6.7.2.1p3, 6.7.2.1p4 BitWidth = @@ -5584,6 +5585,9 @@ Decl *SemaObjC::ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D, .get(); if (!BitWidth) D.setInvalidType(); + else + ConstantBW = cast<ConstantExpr>(BitWidth); + } else { // Not a bitfield. @@ -5633,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, ConstantBW); if (T->containsErrors()) NewID->setInvalidDecl(); diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index 93a17e84598115..731e56b34f4102 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -1295,11 +1295,10 @@ Decl *SemaObjC::ActOnPropertyImplDecl( } } - Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, - PropertyIvarLoc,PropertyIvarLoc, PropertyIvar, - PropertyIvarType, /*TInfo=*/nullptr, - ObjCIvarDecl::Private, - (Expr *)nullptr, true); + Ivar = ObjCIvarDecl::Create( + Context, ClassImpDecl, PropertyIvarLoc, PropertyIvarLoc, PropertyIvar, + PropertyIvarType, /*TInfo=*/nullptr, ObjCIvarDecl::Private, + (ConstantExpr *)nullptr, true); if (SemaRef.RequireNonAbstractType(PropertyIvarLoc, PropertyIvarType, diag::err_abstract_type_in_decl, Sema::AbstractSynthesizedIvarType)) { diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 6ece3ba7af9f4b..75707cf29f76a6 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1545,7 +1545,7 @@ void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) { FD->CapturedVLAType = cast<VariableArrayType>(Record.readType().getTypePtr()); else if (Bits & 1) - FD->setBitWidth(Record.readExpr()); + FD->setBitWidth(cast<ConstantExpr>(Record.readExpr())); if (!FD->getDeclName() || FD->isPlaceholderVar(Reader.getContext().getLangOpts())) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits