@@ -34,7 +34,7 @@ using namespace clang::interp;
3434
3535// / Used to iterate over pointer fields.
3636using DataFunc = llvm::function_ref<bool (const Pointer &P, PrimType Ty,
37- size_t BitOffset, bool PackedBools)>;
37+ Bits BitOffset, bool PackedBools)>;
3838
3939#define BITCAST_TYPE_SWITCH (Expr, B ) \
4040 do { \
@@ -79,7 +79,7 @@ static void swapBytes(std::byte *M, size_t N) {
7979
8080// / We use this to recursively iterate over all fields and elements of a pointer
8181// / and extract relevant data for a bitcast.
82- static bool enumerateData (const Pointer &P, const Context &Ctx, size_t Offset,
82+ static bool enumerateData (const Pointer &P, const Context &Ctx, Bits Offset,
8383 DataFunc F) {
8484 const Descriptor *FieldDesc = P.getFieldDesc ();
8585 assert (FieldDesc);
@@ -124,15 +124,15 @@ static bool enumerateData(const Pointer &P, const Context &Ctx, size_t Offset,
124124
125125 for (const Record::Field &Fi : R->fields ()) {
126126 Pointer Elem = P.atField (Fi.Offset );
127- size_t BitOffset =
128- Offset + Layout.getFieldOffset (Fi.Decl ->getFieldIndex ());
127+ Bits BitOffset =
128+ Offset + Bits ( Layout.getFieldOffset (Fi.Decl ->getFieldIndex () ));
129129 Ok = Ok && enumerateData (Elem, Ctx, BitOffset, F);
130130 }
131131 for (const Record::Base &B : R->bases ()) {
132132 Pointer Elem = P.atField (B.Offset );
133133 CharUnits ByteOffset =
134134 Layout.getBaseClassOffset (cast<CXXRecordDecl>(B.Decl ));
135- size_t BitOffset = Offset + Ctx.getASTContext ().toBits (ByteOffset);
135+ Bits BitOffset = Offset + Bits ( Ctx.getASTContext ().toBits (ByteOffset) );
136136 Ok = Ok && enumerateData (Elem, Ctx, BitOffset, F);
137137 }
138138
@@ -144,7 +144,7 @@ static bool enumerateData(const Pointer &P, const Context &Ctx, size_t Offset,
144144
145145static bool enumeratePointerFields (const Pointer &P, const Context &Ctx,
146146 DataFunc F) {
147- return enumerateData (P, Ctx, 0 , F);
147+ return enumerateData (P, Ctx, Bits::zero () , F);
148148}
149149
150150// This function is constexpr if and only if To, From, and the types of
@@ -223,7 +223,7 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr,
223223
224224 return enumeratePointerFields (
225225 FromPtr, Ctx,
226- [&](const Pointer &P, PrimType T, size_t BitOffset,
226+ [&](const Pointer &P, PrimType T, Bits BitOffset,
227227 bool PackedBools) -> bool {
228228 // if (!P.isInitialized()) {
229229 // assert(false && "Implement uninitialized value tracking");
@@ -236,35 +236,36 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr,
236236 assert (false && " Implement casting to pointer types" );
237237
238238 CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars (P.getType ());
239- unsigned BitWidth = ASTCtx.toBits (ObjectReprChars);
240- unsigned FullBitWidth = BitWidth;
239+ Bits BitWidth = Bits ( ASTCtx.toBits (ObjectReprChars) );
240+ Bits FullBitWidth = BitWidth;
241241 auto Buff =
242242 std::make_unique<std::byte[]>(ObjectReprChars.getQuantity ());
243243 // Work around floating point types that contain unused padding bytes.
244244 // This is really just `long double` on x86, which is the only
245245 // fundamental type with padding bytes.
246246 if (T == PT_Float) {
247247 const Floating &F = P.deref <Floating>();
248- unsigned NumBits =
249- llvm::APFloatBase::getSizeInBits (F.getAPFloat ().getSemantics ());
250- assert (fullByte ( NumBits));
251- assert (NumBits <= FullBitWidth);
248+ Bits NumBits = Bits (
249+ llvm::APFloatBase::getSizeInBits (F.getAPFloat ().getSemantics ())) ;
250+ assert (NumBits. isFullByte ( ));
251+ assert (NumBits. getQuantity () <= FullBitWidth. getQuantity () );
252252 F.bitcastToMemory (Buff.get ());
253253 // Now, only (maybe) swap the actual size of the float, excluding the
254254 // padding bits.
255255 if (llvm::sys::IsBigEndianHost)
256- swapBytes (Buff.get (), NumBits / 8 );
256+ swapBytes (Buff.get (), NumBits. roundToBytes () );
257257
258258 } else {
259259 if (const FieldDecl *FD = P.getField (); FD && FD->isBitField ())
260- BitWidth = std::min (FD->getBitWidthValue (ASTCtx), FullBitWidth);
260+ BitWidth = Bits (std::min (FD->getBitWidthValue (ASTCtx),
261+ (unsigned )FullBitWidth.getQuantity ()));
261262 else if (T == PT_Bool && PackedBools)
262- BitWidth = 1 ;
263+ BitWidth = Bits ( 1 ) ;
263264
264265 BITCAST_TYPE_SWITCH (T, { P.deref <T>().bitcastToMemory (Buff.get ()); });
265266
266267 if (llvm::sys::IsBigEndianHost)
267- swapBytes (Buff.get (), FullBitWidth / 8 );
268+ swapBytes (Buff.get (), FullBitWidth. roundToBytes () );
268269 }
269270
270271 Buffer.pushData (Buff.get (), BitOffset, BitWidth, TargetEndianness);
@@ -279,7 +280,7 @@ bool clang::interp::DoBitCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
279280 assert (Ptr.isBlockPointer ());
280281 assert (Buff);
281282
282- size_t BitSize = BuffSize * 8 ;
283+ Bits BitSize = Bytes ( BuffSize). toBits () ;
283284 BitcastBuffer Buffer (BitSize);
284285 if (!CheckBitcastType (S, OpPC, Ptr.getType (), /* IsToType=*/ false ))
285286 return false ;
@@ -291,7 +292,7 @@ bool clang::interp::DoBitCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
291292 const ASTContext &ASTCtx = S.getASTContext ();
292293 Endian TargetEndianness =
293294 ASTCtx.getTargetInfo ().isLittleEndian () ? Endian::Little : Endian::Big;
294- auto B = Buffer.copyBits (0 , BitSize, BitSize, TargetEndianness);
295+ auto B = Buffer.copyBits (Bits::zero () , BitSize, BitSize, TargetEndianness);
295296
296297 std::memcpy (Buff, B.get (), BuffSize);
297298
@@ -318,7 +319,7 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
318319 const ASTContext &ASTCtx = S.getASTContext ();
319320
320321 CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars (ToType);
321- BitcastBuffer Buffer (ASTCtx.toBits (ObjectReprChars));
322+ BitcastBuffer Buffer (Bits ( ASTCtx.toBits (ObjectReprChars) ));
322323 readPointerToBuffer (S.getContext (), FromPtr, Buffer,
323324 /* ReturnOnUninit=*/ false );
324325
@@ -327,43 +328,44 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
327328 ASTCtx.getTargetInfo ().isLittleEndian () ? Endian::Little : Endian::Big;
328329 bool Success = enumeratePointerFields (
329330 ToPtr, S.getContext (),
330- [&](const Pointer &P, PrimType T, size_t BitOffset,
331+ [&](const Pointer &P, PrimType T, Bits BitOffset,
331332 bool PackedBools) -> bool {
332333 CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars (P.getType ());
333- unsigned FullBitWidth = ASTCtx.toBits (ObjectReprChars);
334+ Bits FullBitWidth = Bits ( ASTCtx.toBits (ObjectReprChars) );
334335 if (T == PT_Float) {
335336 const auto &Semantics = ASTCtx.getFloatTypeSemantics (P.getType ());
336- unsigned NumBits = llvm::APFloatBase::getSizeInBits (Semantics);
337- assert (fullByte ( NumBits));
338- assert (NumBits <= FullBitWidth);
337+ Bits NumBits = Bits ( llvm::APFloatBase::getSizeInBits (Semantics) );
338+ assert (NumBits. isFullByte ( ));
339+ assert (NumBits. getQuantity () <= FullBitWidth. getQuantity () );
339340 auto M = Buffer.copyBits (BitOffset, NumBits, FullBitWidth,
340341 TargetEndianness);
341342
342343 if (llvm::sys::IsBigEndianHost)
343- swapBytes (M.get (), NumBits / 8 );
344+ swapBytes (M.get (), NumBits. roundToBytes () );
344345
345346 P.deref <Floating>() = Floating::bitcastFromMemory (M.get (), Semantics);
346347 P.initialize ();
347348 return true ;
348349 }
349350
350- unsigned BitWidth;
351+ Bits BitWidth;
351352 if (const FieldDecl *FD = P.getField (); FD && FD->isBitField ())
352- BitWidth = std::min (FD->getBitWidthValue (ASTCtx), FullBitWidth);
353+ BitWidth = Bits (std::min (FD->getBitWidthValue (ASTCtx),
354+ (unsigned )FullBitWidth.getQuantity ()));
353355 else if (T == PT_Bool && PackedBools)
354- BitWidth = 1 ;
356+ BitWidth = Bits ( 1 ) ;
355357 else
356- BitWidth = ASTCtx. toBits (ObjectReprChars) ;
358+ BitWidth = FullBitWidth ;
357359
358360 auto Memory = Buffer.copyBits (BitOffset, BitWidth, FullBitWidth,
359361 TargetEndianness);
360362 if (llvm::sys::IsBigEndianHost)
361- swapBytes (Memory.get (), FullBitWidth / 8 );
363+ swapBytes (Memory.get (), FullBitWidth. roundToBytes () );
362364
363365 BITCAST_TYPE_SWITCH_FIXED_SIZE (T, {
364- if (BitWidth > 0 )
366+ if (BitWidth. nonZero () )
365367 P.deref <T>() = T::bitcastFromMemory (Memory.get (), T::bitWidth ())
366- .truncate (BitWidth);
368+ .truncate (BitWidth. getQuantity () );
367369 else
368370 P.deref <T>() = T::zero ();
369371 });
0 commit comments