;
38 BitsFullBitWidth,
boolPackedBools)>;
40#define BITCAST_TYPE_SWITCH(Expr, B) \ 43 TYPE_SWITCH_CASE(PT_Sint8, B) \ 44 TYPE_SWITCH_CASE(PT_Uint8, B) \ 45 TYPE_SWITCH_CASE(PT_Sint16, B) \ 46 TYPE_SWITCH_CASE(PT_Uint16, B) \ 47 TYPE_SWITCH_CASE(PT_Sint32, B) \ 48 TYPE_SWITCH_CASE(PT_Uint32, B) \ 49 TYPE_SWITCH_CASE(PT_Sint64, B) \ 50 TYPE_SWITCH_CASE(PT_Uint64, B) \ 51 TYPE_SWITCH_CASE(PT_IntAP, B) \ 52 TYPE_SWITCH_CASE(PT_IntAPS, B) \ 53 TYPE_SWITCH_CASE(PT_Bool, B) \ 55 llvm_unreachable("Unhandled bitcast type"); \
59#define BITCAST_TYPE_SWITCH_FIXED_SIZE(Expr, B) \ 62 TYPE_SWITCH_CASE(PT_Sint8, B) \ 63 TYPE_SWITCH_CASE(PT_Uint8, B) \ 64 TYPE_SWITCH_CASE(PT_Sint16, B) \ 65 TYPE_SWITCH_CASE(PT_Uint16, B) \ 66 TYPE_SWITCH_CASE(PT_Sint32, B) \ 67 TYPE_SWITCH_CASE(PT_Uint32, B) \ 68 TYPE_SWITCH_CASE(PT_Sint64, B) \ 69 TYPE_SWITCH_CASE(PT_Uint64, B) \ 70 TYPE_SWITCH_CASE(PT_Bool, B) \ 72 llvm_unreachable("Unhandled bitcast type"); \
87 returnF(
P, FieldDesc->
getPrimType(), Offset, FullBitWidth,
95 PrimTypeElemT = *Ctx.classify(ElemType);
100 for(
unsignedI =
P.getIndex(); I != NumElems; ++I) {
101 Ok=
Ok&& F(
P.atIndex(I), ElemT, Offset, ElemSize, PackedBools);
102Offset += PackedBools ?
Bits(1) : ElemSize;
103 if(Offset >= BitsToRead)
113 for(
unsignedI =
P.getIndex(); I != FieldDesc->
getNumElems(); ++I) {
114 enumerateData(
P.atIndex(I).narrow(), Ctx, Offset, BitsToRead, F);
116 if(Offset >= BitsToRead)
129 for(
constRecord::Field &Fi : R->
fields()) {
130 if(Fi.isUnnamedBitField())
132 PointerElem =
P.atField(Fi.Offset);
137 for(
constRecord::Base &B : R->
bases()) {
138 PointerElem =
P.atField(B.Offset);
141 BitsBitOffset = Offset +
Bits(Ctx.getASTContext().
toBits(ByteOffset));
152llvm_unreachable(
"Unhandled data type");
179 enum{ C_Member, C_Base };
181 autodiag = [&](
intReason) ->
bool{
182 const Expr*
E= S.Current->getExpr(OpPC);
183S.FFDiag(
E, diag::note_constexpr_bit_cast_invalid_type)
184<<
static_cast<int>(IsToType) << (Reason == E_Reference) << Reason
189S.Note(NoteRange.getBegin(), diag::note_constexpr_bit_cast_invalid_subtype)
190<< NoteType << Construct <<
T.getUnqualifiedType() << NoteRange;
194 T=
T.getCanonicalType();
197 returndiag(E_Union);
199 returndiag(E_Pointer);
201 returndiag(E_MemberPointer);
202 if(
T.isVolatileQualified())
203 returndiag(E_Volatile);
206 if(
const auto*CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
209 returnnote(C_Base, BS.getType(), BS.getBeginLoc());
212 for(
const FieldDecl*FD : RD->fields()) {
213 if(FD->getType()->isReferenceType())
214 returndiag(E_Reference);
216 returnnote(C_Member, FD->getType(), FD->getSourceRange());
227 QualTypeEltTy = VT->getElementType();
228 unsignedNElts = VT->getNumElements();
237 const Expr*
E= S.Current->getExpr(OpPC);
238S.FFDiag(
E, diag::note_constexpr_bit_cast_invalid_vector)
248 const Expr*
E= S.Current->getExpr(OpPC);
249S.FFDiag(
E, diag::note_constexpr_bit_cast_unsupported_type) << EltTy;
260 boolReturnOnUninit) {
261 const ASTContext&ASTCtx = Ctx.getASTContext();
266FromPtr, Ctx, Buffer.
size(),
268 boolPackedBools) ->
bool{
269Bits BitWidth = FullBitWidth;
271if (const FieldDecl *FD = P.getField(); FD && FD->isBitField())
272BitWidth = Bits(std::min(FD->getBitWidthValue(),
273(unsigned)FullBitWidth.getQuantity()));
274else if (T == PT_Bool && PackedBools)
277if (BitWidth.isZero())
281if (!P.isInitialized())
285assert(P.getType()->isNullPtrType());
292assert(
P.isInitialized());
293 autoBuff = std::make_unique<std::byte[]>(FullBitWidth.
roundToBytes());
300llvm::APFloatBase::getSizeInBits(F.
getAPFloat().getSemantics()));
301assert(NumBits.isFullByte());
302assert(NumBits.getQuantity() <= FullBitWidth.
getQuantity());
306 if(llvm::sys::IsBigEndianHost)
307 swapBytes(Buff.get(), NumBits.roundToBytes());
313 if(llvm::sys::IsBigEndianHost)
318Buffer.
pushData(Buff.get(), BitOffset, BitWidth, TargetEndianness);
324std::byte *Buff,
BitsBitWidth,
BitsFullBitWidth,
325 bool&HasIndeterminateBits) {
329assert(BitWidth <= FullBitWidth);
348std::memcpy(Buff, B.get(), BuffSize);
350 if(llvm::sys::IsBigEndianHost)
366assert(FromPtr.
isLive());
387ToPtr, S.getContext(), Buffer.
size(),
389 boolPackedBools) ->
bool{
390QualType PtrType = P.getType();
392const auto &Semantics = ASTCtx.getFloatTypeSemantics(PtrType);
393Bits NumBits = Bits(llvm::APFloatBase::getSizeInBits(Semantics));
394assert(NumBits.isFullByte());
395assert(NumBits.getQuantity() <= FullBitWidth.getQuantity());
396auto M = Buffer.copyBits(BitOffset, NumBits, FullBitWidth,
399if (llvm::sys::IsBigEndianHost)
400swapBytes(M.get(), NumBits.roundToBytes());
402P.deref<Floating>() = Floating::bitcastFromMemory(M.get(), Semantics);
408 if(
const FieldDecl*FD =
P.getField(); FD && FD->isBitField())
409BitWidth =
Bits(std::min(FD->getBitWidthValue(),
414BitWidth = FullBitWidth;
420 if(!PtrType->isStdByteType() &&
421!PtrType->isSpecificBuiltinType(BuiltinType::UChar) &&
422!PtrType->isSpecificBuiltinType(BuiltinType::Char_U)) {
423const Expr *E = S.Current->getExpr(OpPC);
424S.FFDiag(E, diag::note_constexpr_bit_cast_indet_dest)
425<< PtrType << S.getLangOpts().CharIsSigned
426<< E->getSourceRange();
433 autoMemory = Buffer.
copyBits(BitOffset, BitWidth, FullBitWidth,
435 if(llvm::sys::IsBigEndianHost)
439 if(BitWidth.nonZero())
440 P.deref<
T>() = T::bitcastFromMemory(Memory.get(), T::bitWidth())
441.truncate(BitWidth.getQuantity());
443 P.deref<
T>() = T::zero();
463 BitsFullBitWidth,
boolPackedBools) ->
bool{
464unsigned SrcOffsetDiff =
465P.getByteOffset() - SrcStartOffset;
468Pointer(DestPtr.asBlockPointer().Pointee,
469DestPtr.asBlockPointer().Base,
470DestStartOffset + SrcOffsetDiff);
473DestP.deref<T>() = P.deref<T>();
Defines the clang::ASTContext interface.
#define BITCAST_TYPE_SWITCH_FIXED_SIZE(Expr, B)
llvm::function_ref< bool(const Pointer &P, PrimType Ty, Bits BitOffset, Bits FullBitWidth, bool PackedBools)> DataFunc
Implement __builtin_bit_cast and related operations.
#define BITCAST_TYPE_SWITCH(Expr, B)
static bool CheckBitcastType(InterpState &S, CodePtr OpPC, QualType T, bool IsToType)
static bool enumeratePointerFields(const Pointer &P, const Context &Ctx, Bits BitsToRead, DataFunc F)
static bool enumerateData(const Pointer &P, const Context &Ctx, Bits Offset, Bits BitsToRead, DataFunc F)
We use this to recursively iterate over all fields and elements of a pointer and extract relevant dat...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const TargetInfo & getTargetInfo() const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Represents a base class of a C++ class.
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
This represents one expression.
Represents a member of a struct/union/class.
A (possibly-)qualified type.
Represents a struct/union/class.
ASTContext & getASTContext() const
A trivial tuple used to represent a source range.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
bool isLittleEndian() const
bool isPointerType() const
bool isExtVectorBoolType() const
bool isMemberPointerType() const
bool isRealFloatingType() const
Floating point categories.
const T * getAs() const
Member-template getAs<specific type>'.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Represents a GCC generic vector type.
Pointer into the code segment.
Holds all information required to evaluate constexpr code in a module.
const APFloat & getAPFloat() const
void bitcastToMemory(std::byte *Buff) const
A pointer to a memory block, live or dead.
QualType getType() const
Returns the type of the innermost field.
bool isLive() const
Checks if the pointer is live.
uint64_t getByteOffset() const
Returns the byte offset from the start.
bool isBlockPointer() const
void initialize() const
Initializes a field.
Structure/Class descriptor.
const RecordDecl * getDecl() const
Returns the underlying declaration.
llvm::iterator_range< const_base_iter > bases() const
llvm::iterator_range< const_field_iter > fields() const
Defines the clang::TargetInfo interface.
bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr, BitcastBuffer &Buffer, bool ReturnOnUninit)
bool DoBitCastPtr(InterpState &S, CodePtr OpPC, const Pointer &FromPtr, Pointer &ToPtr)
PrimType
Enumeration of the primitive types of the VM.
bool DoMemcpy(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest)
Copy the contents of Src into Dest.
bool DoBitCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr, std::byte *Buff, Bits BitWidth, Bits FullBitWidth, bool &HasIndeterminateBits)
static void swapBytes(std::byte *M, size_t N)
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
const FunctionProtoType * T
@ Success
Template argument deduction was successful.
Track what bits have been initialized to known values and which ones have indeterminate value.
std::unique_ptr< std::byte[]> copyBits(Bits BitOffset, Bits BitWidth, Bits FullBitWidth, Endian TargetEndianness) const
Copy BitWidth bits at offset BitOffset from the buffer.
void markInitialized(Bits Start, Bits Length)
Marks the bits in the given range as initialized.
bool rangeInitialized(Bits Offset, Bits Length) const
Bits size() const
Returns the buffer size in bits.
void pushData(const std::byte *In, Bits BitOffset, Bits BitWidth, Endian TargetEndianness)
Push BitWidth bits at BitOffset from In into the buffer.
size_t roundToBytes() const
size_t getQuantity() const
Describes a memory block created by an allocation site.
unsigned getNumElems() const
Returns the number of elements stored in the block.
bool isPrimitive() const
Checks if the descriptor is of a primitive.
QualType getElemQualType() const
bool isCompositeArray() const
Checks if the descriptor is of an array of composites.
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
PrimType getPrimType() const
bool isRecord() const
Checks if the descriptor is of a record.
const Record *const ElemRecord
Pointer to the record, if block contains records.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4