Skip to content

Commit 980c977

Browse files
committed
Save FieldDecl BitWidth as a ConstantExpr
1 parent 14dcf82 commit 980c977

38 files changed

+96
-94
lines changed

clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ static MagnitudeBits calcMagnitudeBits(const ASTContext &Context,
124124
unsigned SignedBits = IntExprType->isUnsignedIntegerType() ? 0U : 1U;
125125

126126
if (const auto *BitField = IntExpr->getSourceBitField()) {
127-
unsigned BitFieldWidth = BitField->getBitWidthValue(Context);
127+
unsigned BitFieldWidth = BitField->getBitWidthValue();
128128
return {BitFieldWidth - SignedBits, BitFieldWidth};
129129
}
130130

clang-tools-extra/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ AST_MATCHER(FieldDecl, hasIntBitwidth) {
3838
assert(Node.isBitField());
3939
const ASTContext &Ctx = Node.getASTContext();
4040
unsigned IntBitWidth = Ctx.getIntWidth(Ctx.IntTy);
41-
unsigned CurrentBitWidth = Node.getBitWidthValue(Ctx);
41+
unsigned CurrentBitWidth = Node.getBitWidthValue();
4242
return IntBitWidth == CurrentBitWidth;
4343
}
4444

clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ void MultiwayPathsCoveredCheck::handleSwitchWithoutDefault(
160160
}
161161
if (const auto *BitfieldDecl =
162162
Result.Nodes.getNodeAs<FieldDecl>("bitfield")) {
163-
return twoPow(BitfieldDecl->getBitWidthValue(*Result.Context));
163+
return twoPow(BitfieldDecl->getBitWidthValue());
164164
}
165165

166166
return static_cast<std::size_t>(0);

clang-tools-extra/clangd/Hover.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,7 @@ void addLayoutInfo(const NamedDecl &ND, HoverInfo &HI) {
10181018
const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Record);
10191019
HI.Offset = Layout.getFieldOffset(FD->getFieldIndex());
10201020
if (FD->isBitField())
1021-
HI.Size = FD->getBitWidthValue(Ctx);
1021+
HI.Size = FD->getBitWidthValue();
10221022
else if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType()))
10231023
HI.Size = FD->isZeroSize(Ctx) ? 0 : Size->getQuantity() * 8;
10241024
if (HI.Size) {

clang/include/clang/AST/Decl.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3143,7 +3143,9 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
31433143

31443144
/// Computes the bit width of this field, if this is a bit field.
31453145
/// May not be called on non-bitfields.
3146-
unsigned getBitWidthValue(const ASTContext &Ctx) const;
3146+
/// Note that in order to successfully use this function, the bitwidth
3147+
/// expression must be a ConstantExpr with a valid integer result set.
3148+
unsigned getBitWidthValue() const;
31473149

31483150
/// Set the bit-field width for this member.
31493151
// Note: used by some clients (i.e., do not remove it).
@@ -3174,7 +3176,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
31743176
/// Is this a zero-length bit-field? Such bit-fields aren't really bit-fields
31753177
/// at all and instead act as a separator between contiguous runs of other
31763178
/// bit-fields.
3177-
bool isZeroLengthBitField(const ASTContext &Ctx) const;
3179+
bool isZeroLengthBitField() const;
31783180

31793181
/// Determine if this field is a subobject of zero size, that is, either a
31803182
/// zero-length bit-field or a field of empty class type with the

clang/include/clang/ASTMatchers/ASTMatchers.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -708,8 +708,7 @@ AST_MATCHER(FieldDecl, isBitField) {
708708
/// fieldDecl(hasBitWidth(2))
709709
/// matches 'int a;' and 'int c;' but not 'int b;'.
710710
AST_MATCHER_P(FieldDecl, hasBitWidth, unsigned, Width) {
711-
return Node.isBitField() &&
712-
Node.getBitWidthValue(Finder->getASTContext()) == Width;
711+
return Node.isBitField() && Node.getBitWidthValue() == Width;
713712
}
714713

715714
/// Matches non-static data members that have an in-class initializer.

clang/lib/AST/ASTContext.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2795,7 +2795,7 @@ getSubobjectSizeInBits(const FieldDecl *Field, const ASTContext &Context,
27952795
if (Field->isUnnamedBitField())
27962796
return 0;
27972797

2798-
int64_t BitfieldSize = Field->getBitWidthValue(Context);
2798+
int64_t BitfieldSize = Field->getBitWidthValue();
27992799
if (IsBitIntType) {
28002800
if ((unsigned)BitfieldSize >
28012801
cast<BitIntType>(Field->getType())->getNumBits())
@@ -7769,7 +7769,7 @@ QualType ASTContext::isPromotableBitField(Expr *E) const {
77697769

77707770
QualType FT = Field->getType();
77717771

7772-
uint64_t BitWidth = Field->getBitWidthValue(*this);
7772+
uint64_t BitWidth = Field->getBitWidthValue();
77737773
uint64_t IntSize = getTypeSize(IntTy);
77747774
// C++ [conv.prom]p5:
77757775
// 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,
87978797
S += getObjCEncodingForPrimitiveType(Ctx, BT);
87988798
}
87998799
}
8800-
S += llvm::utostr(FD->getBitWidthValue(*Ctx));
8800+
S += llvm::utostr(FD->getBitWidthValue());
88018801
}
88028802

88038803
// Helper function for determining whether the encoded type string would include
@@ -9223,7 +9223,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
92239223
}
92249224

92259225
for (FieldDecl *Field : RDecl->fields()) {
9226-
if (!Field->isZeroLengthBitField(*this) && Field->isZeroSize(*this))
9226+
if (!Field->isZeroLengthBitField() && Field->isZeroSize(*this))
92279227
continue;
92289228
uint64_t offs = layout.getFieldOffset(Field->getFieldIndex());
92299229
FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
@@ -9320,7 +9320,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
93209320
if (field->isBitField()) {
93219321
EncodeBitField(this, S, field->getType(), field);
93229322
#ifndef NDEBUG
9323-
CurOffs += field->getBitWidthValue(*this);
9323+
CurOffs += field->getBitWidthValue();
93249324
#endif
93259325
} else {
93269326
QualType qt = field->getType();

clang/lib/AST/ByteCode/Interp.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,8 +1483,7 @@ bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F,
14831483
return false;
14841484
const Pointer &Field = This.atField(FieldOffset);
14851485
const auto &Value = S.Stk.pop<T>();
1486-
Field.deref<T>() =
1487-
Value.truncate(F->Decl->getBitWidthValue(S.getASTContext()));
1486+
Field.deref<T>() = Value.truncate(F->Decl->getBitWidthValue());
14881487
Field.initialize();
14891488
return true;
14901489
}
@@ -1507,8 +1506,7 @@ bool InitBitField(InterpState &S, CodePtr OpPC, const Record::Field *F) {
15071506
assert(F->isBitField());
15081507
const T &Value = S.Stk.pop<T>();
15091508
const Pointer &Field = S.Stk.peek<Pointer>().atField(F->Offset);
1510-
Field.deref<T>() =
1511-
Value.truncate(F->Decl->getBitWidthValue(S.getASTContext()));
1509+
Field.deref<T>() = Value.truncate(F->Decl->getBitWidthValue());
15121510
Field.activate();
15131511
Field.initialize();
15141512
return true;
@@ -1815,7 +1813,7 @@ bool StoreBitField(InterpState &S, CodePtr OpPC) {
18151813
if (Ptr.canBeInitialized())
18161814
Ptr.initialize();
18171815
if (const auto *FD = Ptr.getField())
1818-
Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue(S.getASTContext()));
1816+
Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue());
18191817
else
18201818
Ptr.deref<T>() = Value;
18211819
return true;
@@ -1830,7 +1828,7 @@ bool StoreBitFieldPop(InterpState &S, CodePtr OpPC) {
18301828
if (Ptr.canBeInitialized())
18311829
Ptr.initialize();
18321830
if (const auto *FD = Ptr.getField())
1833-
Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue(S.getASTContext()));
1831+
Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue());
18341832
else
18351833
Ptr.deref<T>() = Value;
18361834
return true;

clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr,
272272
Bits BitWidth = FullBitWidth;
273273

274274
if (const FieldDecl *FD = P.getField(); FD && FD->isBitField())
275-
BitWidth = Bits(std::min(FD->getBitWidthValue(ASTCtx),
275+
BitWidth = Bits(std::min(FD->getBitWidthValue(),
276276
(unsigned)FullBitWidth.getQuantity()));
277277
else if (T == PT_Bool && PackedBools)
278278
BitWidth = Bits(1);
@@ -304,8 +304,8 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr,
304304
assert(NumBits.isFullByte());
305305
assert(NumBits.getQuantity() <= FullBitWidth.getQuantity());
306306
F.bitcastToMemory(Buff.get());
307-
// Now, only (maybe) swap the actual size of the float, excluding the
308-
// padding bits.
307+
// Now, only (maybe) swap the actual size of the float, excluding
308+
// the padding bits.
309309
if (llvm::sys::IsBigEndianHost)
310310
swapBytes(Buff.get(), NumBits.roundToBytes());
311311

@@ -409,7 +409,7 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
409409

410410
Bits BitWidth;
411411
if (const FieldDecl *FD = P.getField(); FD && FD->isBitField())
412-
BitWidth = Bits(std::min(FD->getBitWidthValue(ASTCtx),
412+
BitWidth = Bits(std::min(FD->getBitWidthValue(),
413413
(unsigned)FullBitWidth.getQuantity()));
414414
else if (T == PT_Bool && PackedBools)
415415
BitWidth = Bits(1);

clang/lib/AST/Decl.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4599,18 +4599,24 @@ void FieldDecl::setLazyInClassInitializer(LazyDeclStmtPtr NewInit) {
45994599
Init = NewInit;
46004600
}
46014601

4602-
unsigned FieldDecl::getBitWidthValue(const ASTContext &Ctx) const {
4602+
unsigned FieldDecl::getBitWidthValue() const {
46034603
assert(isBitField() && "not a bitfield");
4604-
return getBitWidth()->EvaluateKnownConstInt(Ctx).getZExtValue();
4604+
assert(isa<ConstantExpr>(getBitWidth()));
4605+
assert(cast<ConstantExpr>(getBitWidth())->hasAPValueResult());
4606+
assert(cast<ConstantExpr>(getBitWidth())->getAPValueResult().isInt());
4607+
return cast<ConstantExpr>(getBitWidth())
4608+
->getAPValueResult()
4609+
.getInt()
4610+
.getZExtValue();
46054611
}
46064612

4607-
bool FieldDecl::isZeroLengthBitField(const ASTContext &Ctx) const {
4613+
bool FieldDecl::isZeroLengthBitField() const {
46084614
return isUnnamedBitField() && !getBitWidth()->isValueDependent() &&
4609-
getBitWidthValue(Ctx) == 0;
4615+
getBitWidthValue() == 0;
46104616
}
46114617

46124618
bool FieldDecl::isZeroSize(const ASTContext &Ctx) const {
4613-
if (isZeroLengthBitField(Ctx))
4619+
if (isZeroLengthBitField())
46144620
return true;
46154621

46164622
// C++2a [intro.object]p7:

0 commit comments

Comments
 (0)