Revert "[clang] Avoid re-evaluating field bitwidth (#117732)"
This reverts commit 81fc3add1e627c23b7270fe2739cdacc09063e54. This breaks some LLDB tests, e.g. SymbolFile/DWARF/x86/no_unique_address-with-bitfields.cpp: lldb: ../llvm-project/clang/lib/AST/Decl.cpp:4604: unsigned int clang::FieldDecl::getBitWidthValue() const: Assertion `isa<ConstantExpr>(getBitWidth())' failed.
This commit is contained in:
parent
346fad5c2c
commit
59bdea24b0
@ -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();
|
||||
unsigned CurrentBitWidth = Node.getBitWidthValue(Ctx);
|
||||
return IntBitWidth == CurrentBitWidth;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
unsigned BitFieldWidth = BitField->getBitWidthValue(Context);
|
||||
return {BitFieldWidth - SignedBits, BitFieldWidth};
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,7 @@ void MultiwayPathsCoveredCheck::handleSwitchWithoutDefault(
|
||||
}
|
||||
if (const auto *BitfieldDecl =
|
||||
Result.Nodes.getNodeAs<FieldDecl>("bitfield")) {
|
||||
return twoPow(BitfieldDecl->getBitWidthValue());
|
||||
return twoPow(BitfieldDecl->getBitWidthValue(*Result.Context));
|
||||
}
|
||||
|
||||
return static_cast<std::size_t>(0);
|
||||
|
@ -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();
|
||||
HI.Size = FD->getBitWidthValue(Ctx);
|
||||
else if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType()))
|
||||
HI.Size = FD->isZeroSize(Ctx) ? 0 : Size->getQuantity() * 8;
|
||||
if (HI.Size) {
|
||||
|
@ -3142,9 +3142,7 @@ public:
|
||||
|
||||
/// Computes the bit width of this field, if this is a bit field.
|
||||
/// May not be called on non-bitfields.
|
||||
/// Note that in order to successfully use this function, the bitwidth
|
||||
/// expression must be a ConstantExpr with a valid integer result set.
|
||||
unsigned getBitWidthValue() const;
|
||||
unsigned getBitWidthValue(const ASTContext &Ctx) const;
|
||||
|
||||
/// Set the bit-field width for this member.
|
||||
// Note: used by some clients (i.e., do not remove it).
|
||||
@ -3175,7 +3173,7 @@ public:
|
||||
/// 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;
|
||||
bool isZeroLengthBitField(const ASTContext &Ctx) 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
|
||||
|
@ -708,7 +708,8 @@ 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() == Width;
|
||||
return Node.isBitField() &&
|
||||
Node.getBitWidthValue(Finder->getASTContext()) == Width;
|
||||
}
|
||||
|
||||
/// Matches non-static data members that have an in-class initializer.
|
||||
|
@ -2795,7 +2795,7 @@ getSubobjectSizeInBits(const FieldDecl *Field, const ASTContext &Context,
|
||||
if (Field->isUnnamedBitField())
|
||||
return 0;
|
||||
|
||||
int64_t BitfieldSize = Field->getBitWidthValue();
|
||||
int64_t BitfieldSize = Field->getBitWidthValue(Context);
|
||||
if (IsBitIntType) {
|
||||
if ((unsigned)BitfieldSize >
|
||||
cast<BitIntType>(Field->getType())->getNumBits())
|
||||
@ -7769,7 +7769,7 @@ QualType ASTContext::isPromotableBitField(Expr *E) const {
|
||||
|
||||
QualType FT = Field->getType();
|
||||
|
||||
uint64_t BitWidth = Field->getBitWidthValue();
|
||||
uint64_t BitWidth = Field->getBitWidthValue(*this);
|
||||
uint64_t IntSize = getTypeSize(IntTy);
|
||||
// C++ [conv.prom]p5:
|
||||
// A prvalue for an integral bit-field can be converted to a prvalue of type
|
||||
@ -8797,7 +8797,7 @@ static void EncodeBitField(const ASTContext *Ctx, std::string& S,
|
||||
S += getObjCEncodingForPrimitiveType(Ctx, BT);
|
||||
}
|
||||
}
|
||||
S += llvm::utostr(FD->getBitWidthValue());
|
||||
S += llvm::utostr(FD->getBitWidthValue(*Ctx));
|
||||
}
|
||||
|
||||
// Helper function for determining whether the encoded type string would include
|
||||
@ -9223,7 +9223,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
|
||||
}
|
||||
|
||||
for (FieldDecl *Field : RDecl->fields()) {
|
||||
if (!Field->isZeroLengthBitField() && Field->isZeroSize(*this))
|
||||
if (!Field->isZeroLengthBitField(*this) && Field->isZeroSize(*this))
|
||||
continue;
|
||||
uint64_t offs = layout.getFieldOffset(Field->getFieldIndex());
|
||||
FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
|
||||
@ -9320,7 +9320,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
|
||||
if (field->isBitField()) {
|
||||
EncodeBitField(this, S, field->getType(), field);
|
||||
#ifndef NDEBUG
|
||||
CurOffs += field->getBitWidthValue();
|
||||
CurOffs += field->getBitWidthValue(*this);
|
||||
#endif
|
||||
} else {
|
||||
QualType qt = field->getType();
|
||||
|
@ -1471,7 +1471,8 @@ 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());
|
||||
Field.deref<T>() =
|
||||
Value.truncate(F->Decl->getBitWidthValue(S.getASTContext()));
|
||||
Field.initialize();
|
||||
return true;
|
||||
}
|
||||
@ -1494,7 +1495,8 @@ 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());
|
||||
Field.deref<T>() =
|
||||
Value.truncate(F->Decl->getBitWidthValue(S.getASTContext()));
|
||||
Field.activate();
|
||||
Field.initialize();
|
||||
return true;
|
||||
@ -1748,7 +1750,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());
|
||||
Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue(S.getASTContext()));
|
||||
else
|
||||
Ptr.deref<T>() = Value;
|
||||
return true;
|
||||
@ -1763,7 +1765,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());
|
||||
Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue(S.getASTContext()));
|
||||
else
|
||||
Ptr.deref<T>() = Value;
|
||||
return true;
|
||||
|
@ -269,7 +269,7 @@ bool clang::interp::readPointerToBuffer(const Context &Ctx,
|
||||
Bits BitWidth = FullBitWidth;
|
||||
|
||||
if (const FieldDecl *FD = P.getField(); FD && FD->isBitField())
|
||||
BitWidth = Bits(std::min(FD->getBitWidthValue(),
|
||||
BitWidth = Bits(std::min(FD->getBitWidthValue(ASTCtx),
|
||||
(unsigned)FullBitWidth.getQuantity()));
|
||||
else if (T == PT_Bool && PackedBools)
|
||||
BitWidth = Bits(1);
|
||||
@ -301,8 +301,8 @@ bool clang::interp::readPointerToBuffer(const Context &Ctx,
|
||||
assert(NumBits.isFullByte());
|
||||
assert(NumBits.getQuantity() <= FullBitWidth.getQuantity());
|
||||
F.bitcastToMemory(Buff.get());
|
||||
// Now, only (maybe) swap the actual size of the float, excluding
|
||||
// the padding bits.
|
||||
// Now, only (maybe) swap the actual size of the float, excluding the
|
||||
// padding bits.
|
||||
if (llvm::sys::IsBigEndianHost)
|
||||
swapBytes(Buff.get(), NumBits.roundToBytes());
|
||||
|
||||
@ -406,7 +406,7 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
|
||||
|
||||
Bits BitWidth;
|
||||
if (const FieldDecl *FD = P.getField(); FD && FD->isBitField())
|
||||
BitWidth = Bits(std::min(FD->getBitWidthValue(),
|
||||
BitWidth = Bits(std::min(FD->getBitWidthValue(ASTCtx),
|
||||
(unsigned)FullBitWidth.getQuantity()));
|
||||
else if (T == PT_Bool && PackedBools)
|
||||
BitWidth = Bits(1);
|
||||
|
@ -4599,24 +4599,18 @@ void FieldDecl::setLazyInClassInitializer(LazyDeclStmtPtr NewInit) {
|
||||
Init = NewInit;
|
||||
}
|
||||
|
||||
unsigned FieldDecl::getBitWidthValue() const {
|
||||
unsigned FieldDecl::getBitWidthValue(const ASTContext &Ctx) const {
|
||||
assert(isBitField() && "not a bitfield");
|
||||
assert(isa<ConstantExpr>(getBitWidth()));
|
||||
assert(cast<ConstantExpr>(getBitWidth())->hasAPValueResult());
|
||||
assert(cast<ConstantExpr>(getBitWidth())->getAPValueResult().isInt());
|
||||
return cast<ConstantExpr>(getBitWidth())
|
||||
->getAPValueResult()
|
||||
.getInt()
|
||||
.getZExtValue();
|
||||
return getBitWidth()->EvaluateKnownConstInt(Ctx).getZExtValue();
|
||||
}
|
||||
|
||||
bool FieldDecl::isZeroLengthBitField() const {
|
||||
bool FieldDecl::isZeroLengthBitField(const ASTContext &Ctx) const {
|
||||
return isUnnamedBitField() && !getBitWidth()->isValueDependent() &&
|
||||
getBitWidthValue() == 0;
|
||||
getBitWidthValue(Ctx) == 0;
|
||||
}
|
||||
|
||||
bool FieldDecl::isZeroSize(const ASTContext &Ctx) const {
|
||||
if (isZeroLengthBitField())
|
||||
if (isZeroLengthBitField(Ctx))
|
||||
return true;
|
||||
|
||||
// C++2a [intro.object]p7:
|
||||
|
@ -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() &&
|
||||
if (data().Empty && !Field->isZeroLengthBitField(Context) &&
|
||||
Context.getLangOpts().getClangABICompat() >
|
||||
LangOptions::ClangABI::Ver6)
|
||||
data().Empty = false;
|
||||
|
@ -196,7 +196,8 @@ bool Expr::isKnownToHaveBooleanValue(bool Semantic) const {
|
||||
|
||||
if (const FieldDecl *FD = E->getSourceBitField())
|
||||
if (!Semantic && FD->getType()->isUnsignedIntegerType() &&
|
||||
!FD->getBitWidth()->isValueDependent() && FD->getBitWidthValue() == 1)
|
||||
!FD->getBitWidth()->isValueDependent() &&
|
||||
FD->getBitWidthValue(FD->getASTContext()) == 1)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -2875,7 +2875,7 @@ static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E,
|
||||
|
||||
APSInt &Int = Value.getInt();
|
||||
unsigned OldBitWidth = Int.getBitWidth();
|
||||
unsigned NewBitWidth = FD->getBitWidthValue();
|
||||
unsigned NewBitWidth = FD->getBitWidthValue(Info.Ctx);
|
||||
if (NewBitWidth < OldBitWidth)
|
||||
Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
|
||||
return true;
|
||||
|
@ -91,7 +91,7 @@ void randomizeStructureLayoutImpl(const ASTContext &Context,
|
||||
auto FieldIter = FieldsOut.begin();
|
||||
FieldDecl *FD = *FieldIter;
|
||||
|
||||
if (FD->isBitField() && !FD->isZeroLengthBitField()) {
|
||||
if (FD->isBitField() && !FD->isZeroLengthBitField(Context)) {
|
||||
// Start a bitfield run if this is the first bitfield we have found.
|
||||
if (!CurrentBitfieldRun)
|
||||
CurrentBitfieldRun = std::make_unique<BitfieldRunBucket>();
|
||||
|
@ -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();
|
||||
uint64_t FieldSize = D->getBitWidthValue(Context);
|
||||
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();
|
||||
unsigned Width = FD->getBitWidthValue(Context);
|
||||
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();
|
||||
unsigned Width = Field.getBitWidthValue(C);
|
||||
PrintBitFieldOffset(OS, FieldOffset, Begin, Width, IndentLevel);
|
||||
} else {
|
||||
PrintOffset(OS, FieldOffset, IndentLevel);
|
||||
|
@ -106,7 +106,7 @@ bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base,
|
||||
continue;
|
||||
|
||||
if (isZeroLengthBitfieldPermittedInHomogeneousAggregate() &&
|
||||
FD->isZeroLengthBitField())
|
||||
FD->isZeroLengthBitField(getContext()))
|
||||
continue;
|
||||
|
||||
uint64_t FldMembers;
|
||||
|
@ -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())
|
||||
if (FD->isZeroLengthBitField(Context))
|
||||
return true;
|
||||
|
||||
if (FD->isUnnamedBitField())
|
||||
|
@ -954,7 +954,7 @@ getTypeExpansion(QualType Ty, const ASTContext &Context) {
|
||||
CharUnits UnionSize = CharUnits::Zero();
|
||||
|
||||
for (const auto *FD : RD->fields()) {
|
||||
if (FD->isZeroLengthBitField())
|
||||
if (FD->isZeroLengthBitField(Context))
|
||||
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())
|
||||
if (FD->isZeroLengthBitField(Context))
|
||||
continue;
|
||||
assert(!FD->isBitField() &&
|
||||
"Cannot expand structure with bit-field members.");
|
||||
@ -3682,7 +3682,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() ||
|
||||
if (F->isUnnamedBitField() || F->isZeroLengthBitField(Context) ||
|
||||
F->getType()->isIncompleteArrayType())
|
||||
continue;
|
||||
|
||||
|
@ -945,7 +945,7 @@ namespace {
|
||||
ASTContext &Ctx = CGF.getContext();
|
||||
unsigned LastFieldSize =
|
||||
LastField->isBitField()
|
||||
? LastField->getBitWidthValue()
|
||||
? LastField->getBitWidthValue(Ctx)
|
||||
: Ctx.toBits(
|
||||
Ctx.getTypeInfoDataSizeInChars(LastField->getType()).Width);
|
||||
uint64_t MemcpySizeBits = LastFieldOffset + LastFieldSize -
|
||||
|
@ -1721,7 +1721,8 @@ llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
|
||||
|
||||
assert(PreviousBitfield->isBitField());
|
||||
|
||||
if (!PreviousBitfield->isZeroLengthBitField())
|
||||
ASTContext &Context = CGM.getContext();
|
||||
if (!PreviousBitfield->isZeroLengthBitField(Context))
|
||||
return nullptr;
|
||||
|
||||
QualType Ty = PreviousBitfield->getType();
|
||||
@ -3213,8 +3214,9 @@ 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().getTypeSize(FType);
|
||||
FieldSize = Field->isBitField()
|
||||
? Field->getBitWidthValue(CGM.getContext())
|
||||
: CGM.getContext().getTypeSize(FType);
|
||||
FieldAlign = getTypeAlignIfRequired(FType, CGM.getContext());
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
return FD->getBitWidthValue(Ctx);
|
||||
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())
|
||||
if (FD && FD->isZeroLengthBitField(this->Ctx))
|
||||
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())
|
||||
if (FD->isZeroLengthBitField(this->CGF->getContext()))
|
||||
return;
|
||||
|
||||
QualType RT = QualType(FD->getParent()->getTypeForDecl(), 0);
|
||||
|
@ -2543,7 +2543,8 @@ 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();
|
||||
uint64_t BitFieldSize
|
||||
= LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
|
||||
unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
|
||||
((BitFieldSize % ByteSizeInBits) != 0);
|
||||
CharUnits Size = CharUnits::fromQuantity(UnsSize);
|
||||
|
@ -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();
|
||||
uint64_t BitFieldSize = Ivar->getBitWidthValue(CGF.getContext());
|
||||
CharUnits StorageSize = CGF.CGM.getContext().toCharUnitsFromBits(
|
||||
llvm::alignTo(BitOffset + BitFieldSize, AlignmentBits));
|
||||
CharUnits Alignment = CGF.CGM.getContext().toCharUnitsFromBits(AlignmentBits);
|
||||
|
@ -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(),
|
||||
(unsigned)Context.toBits(getSize(Type))));
|
||||
return getIntNType(std::min(FD->getBitWidthValue(Context),
|
||||
(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();
|
||||
Info.Size = FD->getBitWidthValue(Context);
|
||||
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())
|
||||
if (Field->isZeroLengthBitField(Context))
|
||||
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()) {
|
||||
if (Field->isZeroLengthBitField(Context)) {
|
||||
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())
|
||||
if (Field->isZeroLengthBitField(Context))
|
||||
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())
|
||||
if (!Begin->isZeroLengthBitField(Context))
|
||||
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();
|
||||
BitSizeSinceBegin += Field->getBitWidthValue(Context);
|
||||
++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())
|
||||
if (F->isBitField() && !F->isZeroLengthBitField(Context))
|
||||
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()) {
|
||||
if (F->isZeroLengthBitField(Context)) {
|
||||
if (End > FOffset && StorageOffset < FOffset) {
|
||||
Conflict = true;
|
||||
break;
|
||||
|
@ -186,7 +186,7 @@ void SwiftAggLowering::addBitFieldData(const FieldDecl *bitfield,
|
||||
uint64_t bitfieldBitBegin) {
|
||||
assert(bitfield->isBitField());
|
||||
auto &ctx = CGM.getContext();
|
||||
auto width = bitfield->getBitWidthValue();
|
||||
auto width = bitfield->getBitWidthValue(ctx);
|
||||
|
||||
// We can ignore zero-width bit-fields.
|
||||
if (width == 0) return;
|
||||
|
@ -192,7 +192,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper(
|
||||
for (const FieldDecl *FD : RD->fields()) {
|
||||
QualType QTy = FD->getType();
|
||||
if (FD->isBitField()) {
|
||||
unsigned BitWidth = FD->getBitWidthValue();
|
||||
unsigned BitWidth = FD->getBitWidthValue(getContext());
|
||||
// Zero-width bitfields are ignored.
|
||||
if (BitWidth == 0)
|
||||
continue;
|
||||
|
@ -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();
|
||||
unsigned BitWidth = FD->getBitWidthValue(getContext());
|
||||
// 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)
|
||||
|
@ -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();
|
||||
uint64_t Size = i->getBitWidthValue(getContext());
|
||||
|
||||
uint64_t EB_Lo = Offset / 64;
|
||||
uint64_t EB_Hi = (Offset + Size - 1) / 64;
|
||||
|
@ -343,7 +343,7 @@ static bool extractFieldType(SmallVectorImpl<FieldEncoding> &FE,
|
||||
if (Field->isBitField()) {
|
||||
Enc += "b(";
|
||||
llvm::raw_svector_ostream OS(Enc);
|
||||
OS << Field->getBitWidthValue();
|
||||
OS << Field->getBitWidthValue(CGM.getContext());
|
||||
Enc += ':';
|
||||
}
|
||||
if (!appendType(Enc, Field->getType(), CGM, TSC))
|
||||
|
@ -3699,8 +3699,7 @@ void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl,
|
||||
Type.getAsStringInternal(Name, Context->getPrintingPolicy());
|
||||
Result += Name;
|
||||
if (fieldDecl->isBitField()) {
|
||||
Result += " : ";
|
||||
Result += utostr(fieldDecl->getBitWidthValue());
|
||||
Result += " : "; Result += utostr(fieldDecl->getBitWidthValue(*Context));
|
||||
}
|
||||
else if (EleboratedType && Type->isArrayType()) {
|
||||
const ArrayType *AT = Context->getAsArrayType(Type);
|
||||
|
@ -658,7 +658,7 @@ struct BuiltinDumpStructGenerator {
|
||||
Format += ": %zu ";
|
||||
QualType SizeT = S.Context.getSizeType();
|
||||
llvm::APInt BitWidth(S.Context.getIntWidth(SizeT),
|
||||
FD->getBitWidthValue());
|
||||
FD->getBitWidthValue(S.Context));
|
||||
Args.push_back(IntegerLiteral::Create(S.Context, BitWidth, SizeT, Loc));
|
||||
}
|
||||
|
||||
@ -10027,7 +10027,7 @@ static std::optional<IntRange> TryGetExprRange(ASTContext &C, const Expr *E,
|
||||
Approximate);
|
||||
|
||||
if (const auto *BitField = E->getSourceBitField())
|
||||
return IntRange(BitField->getBitWidthValue(),
|
||||
return IntRange(BitField->getBitWidthValue(C),
|
||||
BitField->getType()->isUnsignedIntegerOrEnumerationType());
|
||||
|
||||
if (GetExprType(E)->isVoidType())
|
||||
@ -10580,7 +10580,7 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
|
||||
return false;
|
||||
|
||||
Expr *OriginalInit = Init->IgnoreParenImpCasts();
|
||||
unsigned FieldWidth = Bitfield->getBitWidthValue();
|
||||
unsigned FieldWidth = Bitfield->getBitWidthValue(S.Context);
|
||||
|
||||
Expr::EvalResult Result;
|
||||
if (!OriginalInit->EvaluateAsInt(Result, S.Context,
|
||||
@ -14044,8 +14044,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();
|
||||
unsigned Bits2 = Field2->getBitWidthValue();
|
||||
unsigned Bits1 = Field1->getBitWidthValue(C);
|
||||
unsigned Bits2 = Field2->getBitWidthValue(C);
|
||||
|
||||
if (Bits1 != Bits2)
|
||||
return false;
|
||||
|
@ -18376,9 +18376,7 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
|
||||
}
|
||||
}
|
||||
|
||||
if (isa<ConstantExpr>(BitWidth))
|
||||
return BitWidth;
|
||||
return ConstantExpr::Create(getASTContext(), BitWidth, APValue{Value});
|
||||
return BitWidth;
|
||||
}
|
||||
|
||||
Decl *Sema::ActOnField(Scope *S, Decl *TagD, SourceLocation DeclStart,
|
||||
@ -18753,7 +18751,7 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc,
|
||||
Decl *ivarDecl = AllIvarDecls[AllIvarDecls.size()-1];
|
||||
ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(ivarDecl);
|
||||
|
||||
if (!Ivar->isBitField() || Ivar->isZeroLengthBitField())
|
||||
if (!Ivar->isBitField() || Ivar->isZeroLengthBitField(Context))
|
||||
return;
|
||||
ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CurContext);
|
||||
if (!ID) {
|
||||
@ -18768,13 +18766,14 @@ 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, BitWidth, true);
|
||||
Ivar = ObjCIvarDecl::Create(Context, cast<ObjCContainerDecl>(CurContext),
|
||||
DeclLoc, DeclLoc, nullptr,
|
||||
Context.CharTy,
|
||||
Context.getTrivialTypeSourceInfo(Context.CharTy,
|
||||
DeclLoc),
|
||||
ObjCIvarDecl::Private, BW,
|
||||
true);
|
||||
AllIvarDecls.push_back(Ivar);
|
||||
}
|
||||
|
||||
@ -19404,7 +19403,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
|
||||
(NonBitFields == 0 || ZeroSize) && I != E; ++I) {
|
||||
IsEmpty = false;
|
||||
if (I->isUnnamedBitField()) {
|
||||
if (!I->isZeroLengthBitField())
|
||||
if (!I->isZeroLengthBitField(Context))
|
||||
ZeroSize = false;
|
||||
} else {
|
||||
++NonBitFields;
|
||||
|
@ -4877,7 +4877,7 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
|
||||
QualType ParamType = Param->getType().getNonReferenceType();
|
||||
|
||||
// Suppress copying zero-width bitfields.
|
||||
if (Field->isZeroLengthBitField())
|
||||
if (Field->isZeroLengthBitField(SemaRef.Context))
|
||||
return false;
|
||||
|
||||
Expr *MemberExprBase =
|
||||
@ -15041,7 +15041,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
|
||||
}
|
||||
|
||||
// Suppress assigning zero-width bitfields.
|
||||
if (Field->isZeroLengthBitField())
|
||||
if (Field->isZeroLengthBitField(Context))
|
||||
continue;
|
||||
|
||||
QualType FieldType = Field->getType().getNonReferenceType();
|
||||
@ -15428,7 +15428,7 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation,
|
||||
}
|
||||
|
||||
// Suppress assigning zero-width bitfields.
|
||||
if (Field->isZeroLengthBitField())
|
||||
if (Field->isZeroLengthBitField(Context))
|
||||
continue;
|
||||
|
||||
QualType FieldType = Field->getType().getNonReferenceType();
|
||||
|
@ -2210,7 +2210,8 @@ void SemaObjC::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
|
||||
<< ImplIvar->getType() << ClsIvar->getType();
|
||||
Diag(ClsIvar->getLocation(), diag::note_previous_definition);
|
||||
} else if (ImplIvar->isBitField() && ClsIvar->isBitField() &&
|
||||
ImplIvar->getBitWidthValue() != ClsIvar->getBitWidthValue()) {
|
||||
ImplIvar->getBitWidthValue(Context) !=
|
||||
ClsIvar->getBitWidthValue(Context)) {
|
||||
Diag(ImplIvar->getBitWidth()->getBeginLoc(),
|
||||
diag::err_conflicting_ivar_bitwidth)
|
||||
<< ImplIvar->getIdentifier();
|
||||
|
@ -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();
|
||||
else if (unsigned BitFieldWidth = BitField->getBitWidthValue(Ctx);
|
||||
BitFieldWidth < FromWidth) {
|
||||
if (CanRepresentAll(FromSigned, BitFieldWidth, ToSigned, ToWidth))
|
||||
return NK_Not_Narrowing;
|
||||
|
@ -931,7 +931,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();
|
||||
Length = FR->getDecl()->getBitWidthValue(SVB.getContext());
|
||||
}
|
||||
|
||||
for (const auto &StoreEntry : Cluster) {
|
||||
|
@ -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();
|
||||
return FD->getBitWidthValue(getCursorContext(C));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3392,12 +3392,12 @@ TEST_P(ASTImporterOptionSpecificTestBase, ImportBitfields) {
|
||||
FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl(hasName("x")));
|
||||
|
||||
ASSERT_TRUE(FromF->isBitField());
|
||||
ASSERT_EQ(3u, FromF->getBitWidthValue());
|
||||
ASSERT_EQ(3u, FromF->getBitWidthValue(FromTU->getASTContext()));
|
||||
auto *ToField = Import(FromF, Lang_CXX03);
|
||||
auto *ToTU = ToField->getTranslationUnitDecl();
|
||||
|
||||
EXPECT_TRUE(ToField->isBitField());
|
||||
EXPECT_EQ(3u, ToField->getBitWidthValue());
|
||||
EXPECT_EQ(3u, ToField->getBitWidthValue(ToTU->getASTContext()));
|
||||
|
||||
const auto *FromBT = FromF->getBitWidth()->getType()->getAs<BuiltinType>();
|
||||
const auto *ToBT = ToField->getBitWidth()->getType()->getAs<BuiltinType>();
|
||||
|
Loading…
x
Reference in New Issue
Block a user