@@ -33,8 +33,9 @@ using namespace clang::interp;
3333// bytes to/from the buffer.
3434
3535// / 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)>;
3839
3940#define BITCAST_TYPE_SWITCH (Expr, B ) \
4041 do { \
@@ -85,21 +86,25 @@ static bool enumerateData(const Pointer &P, const Context &Ctx, Bits Offset,
8586 assert (FieldDesc);
8687
8788 // 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+ }
9095
9196 // Primitive arrays.
9297 if (FieldDesc->isPrimitiveArray ()) {
9398 QualType ElemType = FieldDesc->getElemQualType ();
94- size_t ElemSizeInBits = Ctx.getASTContext ().getTypeSize (ElemType);
99+ Bits ElemSize = Bits ( Ctx.getASTContext ().getTypeSize (ElemType) );
95100 PrimType ElemT = *Ctx.classify (ElemType);
96101 // Special case, since the bools here are packed.
97102 bool PackedBools = FieldDesc->getType ()->isExtVectorBoolType ();
98103 unsigned NumElems = FieldDesc->getNumElems ();
99104 bool Ok = true ;
100105 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 ;
103108 if (Offset >= BitsToRead)
104109 break ;
105110 }
@@ -109,10 +114,10 @@ static bool enumerateData(const Pointer &P, const Context &Ctx, Bits Offset,
109114 // Composite arrays.
110115 if (FieldDesc->isCompositeArray ()) {
111116 QualType ElemType = FieldDesc->getElemQualType ();
112- size_t ElemSizeInBits = Ctx.getASTContext ().getTypeSize (ElemType);
117+ Bits ElemSize = Bits ( Ctx.getASTContext ().getTypeSize (ElemType) );
113118 for (unsigned I = 0 ; I != FieldDesc->getNumElems (); ++I) {
114119 enumerateData (P.atIndex (I).narrow (), Ctx, Offset, BitsToRead, F);
115- Offset += ElemSizeInBits ;
120+ Offset += ElemSize ;
116121 if (Offset >= BitsToRead)
117122 break ;
118123 }
@@ -262,16 +267,14 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr,
262267
263268 return enumeratePointerFields (
264269 FromPtr, Ctx, Buffer.size (),
265- [&](const Pointer &P, PrimType T, Bits BitOffset,
270+ [&](const Pointer &P, PrimType T, Bits BitOffset, Bits FullBitWidth,
266271 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;
270273
271- if (const FieldDecl *FD = P.getField (); FD && FD->isBitField ()) {
274+ if (const FieldDecl *FD = P.getField (); FD && FD->isBitField ())
272275 BitWidth = Bits (std::min (FD->getBitWidthValue (ASTCtx),
273276 (unsigned )FullBitWidth.getQuantity ()));
274- } else if (T == PT_Bool && PackedBools)
277+ else if (T == PT_Bool && PackedBools)
275278 BitWidth = Bits (1 );
276279
277280 if (BitWidth.isZero ())
@@ -290,8 +293,7 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr,
290293 }
291294
292295 assert (P.isInitialized ());
293- auto Buff =
294- std::make_unique<std::byte[]>(ObjectReprChars.getQuantity ());
296+ auto Buff = std::make_unique<std::byte[]>(FullBitWidth.roundToBytes ());
295297 // Work around floating point types that contain unused padding bytes.
296298 // This is really just `long double` on x86, which is the only
297299 // fundamental type with padding bytes.
@@ -386,11 +388,9 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
386388 ASTCtx.getTargetInfo ().isLittleEndian () ? Endian::Little : Endian::Big;
387389 bool Success = enumeratePointerFields (
388390 ToPtr, S.getContext (), Buffer.size (),
389- [&](const Pointer &P, PrimType T, Bits BitOffset,
391+ [&](const Pointer &P, PrimType T, Bits BitOffset, Bits FullBitWidth,
390392 bool PackedBools) -> bool {
391393 QualType PtrType = P.getType ();
392- CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars (PtrType);
393- Bits FullBitWidth = Bits (ASTCtx.toBits (ObjectReprChars));
394394 if (T == PT_Float) {
395395 const auto &Semantics = ASTCtx.getFloatTypeSemantics (PtrType);
396396 Bits NumBits = Bits (llvm::APFloatBase::getSizeInBits (Semantics));
0 commit comments