@@ -34,7 +34,7 @@ using namespace clang::interp;
34
34
35
35
// / Used to iterate over pointer fields.
36
36
using DataFunc = llvm::function_ref<bool (const Pointer &P, PrimType Ty,
37
- size_t BitOffset, bool PackedBools)>;
37
+ Bits BitOffset, bool PackedBools)>;
38
38
39
39
#define BITCAST_TYPE_SWITCH (Expr, B ) \
40
40
do { \
@@ -79,7 +79,7 @@ static void swapBytes(std::byte *M, size_t N) {
79
79
80
80
// / We use this to recursively iterate over all fields and elements of a pointer
81
81
// / 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,
83
83
DataFunc F) {
84
84
const Descriptor *FieldDesc = P.getFieldDesc ();
85
85
assert (FieldDesc);
@@ -124,15 +124,15 @@ static bool enumerateData(const Pointer &P, const Context &Ctx, size_t Offset,
124
124
125
125
for (const Record::Field &Fi : R->fields ()) {
126
126
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 () ));
129
129
Ok = Ok && enumerateData (Elem, Ctx, BitOffset, F);
130
130
}
131
131
for (const Record::Base &B : R->bases ()) {
132
132
Pointer Elem = P.atField (B.Offset );
133
133
CharUnits ByteOffset =
134
134
Layout.getBaseClassOffset (cast<CXXRecordDecl>(B.Decl ));
135
- size_t BitOffset = Offset + Ctx.getASTContext ().toBits (ByteOffset);
135
+ Bits BitOffset = Offset + Bits ( Ctx.getASTContext ().toBits (ByteOffset) );
136
136
Ok = Ok && enumerateData (Elem, Ctx, BitOffset, F);
137
137
}
138
138
@@ -144,7 +144,7 @@ static bool enumerateData(const Pointer &P, const Context &Ctx, size_t Offset,
144
144
145
145
static bool enumeratePointerFields (const Pointer &P, const Context &Ctx,
146
146
DataFunc F) {
147
- return enumerateData (P, Ctx, 0 , F);
147
+ return enumerateData (P, Ctx, Bits::zero () , F);
148
148
}
149
149
150
150
// 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,
223
223
224
224
return enumeratePointerFields (
225
225
FromPtr, Ctx,
226
- [&](const Pointer &P, PrimType T, size_t BitOffset,
226
+ [&](const Pointer &P, PrimType T, Bits BitOffset,
227
227
bool PackedBools) -> bool {
228
228
// if (!P.isInitialized()) {
229
229
// assert(false && "Implement uninitialized value tracking");
@@ -236,35 +236,36 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr,
236
236
assert (false && " Implement casting to pointer types" );
237
237
238
238
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;
241
241
auto Buff =
242
242
std::make_unique<std::byte[]>(ObjectReprChars.getQuantity ());
243
243
// Work around floating point types that contain unused padding bytes.
244
244
// This is really just `long double` on x86, which is the only
245
245
// fundamental type with padding bytes.
246
246
if (T == PT_Float) {
247
247
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 () );
252
252
F.bitcastToMemory (Buff.get ());
253
253
// Now, only (maybe) swap the actual size of the float, excluding the
254
254
// padding bits.
255
255
if (llvm::sys::IsBigEndianHost)
256
- swapBytes (Buff.get (), NumBits / 8 );
256
+ swapBytes (Buff.get (), NumBits. roundToBytes () );
257
257
258
258
} else {
259
259
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 ()));
261
262
else if (T == PT_Bool && PackedBools)
262
- BitWidth = 1 ;
263
+ BitWidth = Bits ( 1 ) ;
263
264
264
265
BITCAST_TYPE_SWITCH (T, { P.deref <T>().bitcastToMemory (Buff.get ()); });
265
266
266
267
if (llvm::sys::IsBigEndianHost)
267
- swapBytes (Buff.get (), FullBitWidth / 8 );
268
+ swapBytes (Buff.get (), FullBitWidth. roundToBytes () );
268
269
}
269
270
270
271
Buffer.pushData (Buff.get (), BitOffset, BitWidth, TargetEndianness);
@@ -279,7 +280,7 @@ bool clang::interp::DoBitCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
279
280
assert (Ptr.isBlockPointer ());
280
281
assert (Buff);
281
282
282
- size_t BitSize = BuffSize * 8 ;
283
+ Bits BitSize = Bytes ( BuffSize). toBits () ;
283
284
BitcastBuffer Buffer (BitSize);
284
285
if (!CheckBitcastType (S, OpPC, Ptr.getType (), /* IsToType=*/ false ))
285
286
return false ;
@@ -291,7 +292,7 @@ bool clang::interp::DoBitCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
291
292
const ASTContext &ASTCtx = S.getASTContext ();
292
293
Endian TargetEndianness =
293
294
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);
295
296
296
297
std::memcpy (Buff, B.get (), BuffSize);
297
298
@@ -318,7 +319,7 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
318
319
const ASTContext &ASTCtx = S.getASTContext ();
319
320
320
321
CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars (ToType);
321
- BitcastBuffer Buffer (ASTCtx.toBits (ObjectReprChars));
322
+ BitcastBuffer Buffer (Bits ( ASTCtx.toBits (ObjectReprChars) ));
322
323
readPointerToBuffer (S.getContext (), FromPtr, Buffer,
323
324
/* ReturnOnUninit=*/ false );
324
325
@@ -327,43 +328,44 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
327
328
ASTCtx.getTargetInfo ().isLittleEndian () ? Endian::Little : Endian::Big;
328
329
bool Success = enumeratePointerFields (
329
330
ToPtr, S.getContext (),
330
- [&](const Pointer &P, PrimType T, size_t BitOffset,
331
+ [&](const Pointer &P, PrimType T, Bits BitOffset,
331
332
bool PackedBools) -> bool {
332
333
CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars (P.getType ());
333
- unsigned FullBitWidth = ASTCtx.toBits (ObjectReprChars);
334
+ Bits FullBitWidth = Bits ( ASTCtx.toBits (ObjectReprChars) );
334
335
if (T == PT_Float) {
335
336
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 () );
339
340
auto M = Buffer.copyBits (BitOffset, NumBits, FullBitWidth,
340
341
TargetEndianness);
341
342
342
343
if (llvm::sys::IsBigEndianHost)
343
- swapBytes (M.get (), NumBits / 8 );
344
+ swapBytes (M.get (), NumBits. roundToBytes () );
344
345
345
346
P.deref <Floating>() = Floating::bitcastFromMemory (M.get (), Semantics);
346
347
P.initialize ();
347
348
return true ;
348
349
}
349
350
350
- unsigned BitWidth;
351
+ Bits BitWidth;
351
352
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 ()));
353
355
else if (T == PT_Bool && PackedBools)
354
- BitWidth = 1 ;
356
+ BitWidth = Bits ( 1 ) ;
355
357
else
356
- BitWidth = ASTCtx. toBits (ObjectReprChars) ;
358
+ BitWidth = FullBitWidth ;
357
359
358
360
auto Memory = Buffer.copyBits (BitOffset, BitWidth, FullBitWidth,
359
361
TargetEndianness);
360
362
if (llvm::sys::IsBigEndianHost)
361
- swapBytes (Memory.get (), FullBitWidth / 8 );
363
+ swapBytes (Memory.get (), FullBitWidth. roundToBytes () );
362
364
363
365
BITCAST_TYPE_SWITCH_FIXED_SIZE (T, {
364
- if (BitWidth > 0 )
366
+ if (BitWidth. nonZero () )
365
367
P.deref <T>() = T::bitcastFromMemory (Memory.get (), T::bitWidth ())
366
- .truncate (BitWidth);
368
+ .truncate (BitWidth. getQuantity () );
367
369
else
368
370
P.deref <T>() = T::zero ();
369
371
});
0 commit comments