@@ -33,8 +33,9 @@ using namespace clang::interp;
33
33
// bytes to/from the buffer.
34
34
35
35
// / Used to iterate over pointer fields.
36
- using DataFunc = llvm::function_ref<bool (const Pointer &P, PrimType Ty,
37
- Bits BitOffset, bool PackedBools)>;
36
+ using DataFunc =
37
+ llvm::function_ref<bool (const Pointer &P, PrimType Ty, Bits BitOffset,
38
+ Bits FullBitWidth, bool PackedBools)>;
38
39
39
40
#define BITCAST_TYPE_SWITCH (Expr, B ) \
40
41
do { \
@@ -85,21 +86,25 @@ static bool enumerateData(const Pointer &P, const Context &Ctx, Bits Offset,
85
86
assert (FieldDesc);
86
87
87
88
// Primitives.
88
- if (FieldDesc->isPrimitive ())
89
- return F (P, FieldDesc->getPrimType (), Offset, /* PackedBools=*/ false );
89
+ if (FieldDesc->isPrimitive ()) {
90
+ Bits FullBitWidth =
91
+ Bits (Ctx.getASTContext ().getTypeSize (FieldDesc->getType ()));
92
+ return F (P, FieldDesc->getPrimType (), Offset, FullBitWidth,
93
+ /* PackedBools=*/ false );
94
+ }
90
95
91
96
// Primitive arrays.
92
97
if (FieldDesc->isPrimitiveArray ()) {
93
98
QualType ElemType = FieldDesc->getElemQualType ();
94
- size_t ElemSizeInBits = Ctx.getASTContext ().getTypeSize (ElemType);
99
+ Bits ElemSize = Bits ( Ctx.getASTContext ().getTypeSize (ElemType) );
95
100
PrimType ElemT = *Ctx.classify (ElemType);
96
101
// Special case, since the bools here are packed.
97
102
bool PackedBools = FieldDesc->getType ()->isExtVectorBoolType ();
98
103
unsigned NumElems = FieldDesc->getNumElems ();
99
104
bool Ok = true ;
100
105
for (unsigned I = P.getIndex (); I != NumElems; ++I) {
101
- Ok = Ok && F (P.atIndex (I), ElemT, Offset, PackedBools);
102
- Offset += PackedBools ? 1 : ElemSizeInBits ;
106
+ Ok = Ok && F (P.atIndex (I), ElemT, Offset, ElemSize, PackedBools);
107
+ Offset += PackedBools ? Bits ( 1 ) : ElemSize ;
103
108
if (Offset >= BitsToRead)
104
109
break ;
105
110
}
@@ -109,10 +114,10 @@ static bool enumerateData(const Pointer &P, const Context &Ctx, Bits Offset,
109
114
// Composite arrays.
110
115
if (FieldDesc->isCompositeArray ()) {
111
116
QualType ElemType = FieldDesc->getElemQualType ();
112
- size_t ElemSizeInBits = Ctx.getASTContext ().getTypeSize (ElemType);
117
+ Bits ElemSize = Bits ( Ctx.getASTContext ().getTypeSize (ElemType) );
113
118
for (unsigned I = 0 ; I != FieldDesc->getNumElems (); ++I) {
114
119
enumerateData (P.atIndex (I).narrow (), Ctx, Offset, BitsToRead, F);
115
- Offset += ElemSizeInBits ;
120
+ Offset += ElemSize ;
116
121
if (Offset >= BitsToRead)
117
122
break ;
118
123
}
@@ -262,16 +267,14 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr,
262
267
263
268
return enumeratePointerFields (
264
269
FromPtr, Ctx, Buffer.size (),
265
- [&](const Pointer &P, PrimType T, Bits BitOffset,
270
+ [&](const Pointer &P, PrimType T, Bits BitOffset, Bits FullBitWidth,
266
271
bool PackedBools) -> bool {
267
- CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars (P.getType ());
268
- Bits BitWidth = Bits (ASTCtx.toBits (ObjectReprChars));
269
- Bits FullBitWidth = BitWidth;
272
+ Bits BitWidth = FullBitWidth;
270
273
271
- if (const FieldDecl *FD = P.getField (); FD && FD->isBitField ()) {
274
+ if (const FieldDecl *FD = P.getField (); FD && FD->isBitField ())
272
275
BitWidth = Bits (std::min (FD->getBitWidthValue (ASTCtx),
273
276
(unsigned )FullBitWidth.getQuantity ()));
274
- } else if (T == PT_Bool && PackedBools)
277
+ else if (T == PT_Bool && PackedBools)
275
278
BitWidth = Bits (1 );
276
279
277
280
if (BitWidth.isZero ())
@@ -290,8 +293,7 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr,
290
293
}
291
294
292
295
assert (P.isInitialized ());
293
- auto Buff =
294
- std::make_unique<std::byte[]>(ObjectReprChars.getQuantity ());
296
+ auto Buff = std::make_unique<std::byte[]>(FullBitWidth.roundToBytes ());
295
297
// Work around floating point types that contain unused padding bytes.
296
298
// This is really just `long double` on x86, which is the only
297
299
// fundamental type with padding bytes.
@@ -386,11 +388,9 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
386
388
ASTCtx.getTargetInfo ().isLittleEndian () ? Endian::Little : Endian::Big;
387
389
bool Success = enumeratePointerFields (
388
390
ToPtr, S.getContext (), Buffer.size (),
389
- [&](const Pointer &P, PrimType T, Bits BitOffset,
391
+ [&](const Pointer &P, PrimType T, Bits BitOffset, Bits FullBitWidth,
390
392
bool PackedBools) -> bool {
391
393
QualType PtrType = P.getType ();
392
- CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars (PtrType);
393
- Bits FullBitWidth = Bits (ASTCtx.toBits (ObjectReprChars));
394
394
if (T == PT_Float) {
395
395
const auto &Semantics = ASTCtx.getFloatTypeSemantics (PtrType);
396
396
Bits NumBits = Bits (llvm::APFloatBase::getSizeInBits (Semantics));
0 commit comments