24static void ctorTy(
Block *, std::byte *Ptr,
bool,
bool,
bool,
bool,
31 reinterpret_cast<T *
>(Ptr)->~
T();
37 auto *SrcPtr =
reinterpret_cast<T *
>(Src);
38 auto *DstPtr =
reinterpret_cast<T *
>(Dst);
39 new (DstPtr)
T(std::move(*SrcPtr));
48 for (
unsigned I = 0,
NE =
D->getNumElems(); I <
NE; ++I) {
49 new (&
reinterpret_cast<T *
>(Ptr)[I])
T();
60 for (
unsigned I = 0,
NE =
D->getNumElems(); I <
NE; ++I) {
61 reinterpret_cast<T *
>(Ptr)[I].~
T();
72 SrcIMP = std::nullopt;
76 for (
unsigned I = 0,
NE =
D->getNumElems(); I <
NE; ++I) {
77 auto *SrcPtr = &
reinterpret_cast<T *
>(Src)[I];
78 auto *DstPtr = &
reinterpret_cast<T *
>(Dst)[I];
79 new (DstPtr)
T(std::move(*SrcPtr));
84 bool IsMutable,
bool IsActive,
bool InUnion,
86 const unsigned NumElems =
D->getNumElems();
87 const unsigned ElemSize =
90 unsigned ElemOffset = 0;
91 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
92 auto *ElemPtr = Ptr + ElemOffset;
94 auto *ElemLoc =
reinterpret_cast<std::byte *
>(Desc + 1);
95 auto *SD =
D->ElemDesc;
99 Desc->IsInitialized =
true;
100 Desc->IsBase =
false;
101 Desc->IsActive = IsActive;
102 Desc->IsConst = IsConst ||
D->IsConst;
103 Desc->IsFieldMutable = IsMutable ||
D->IsMutable;
104 Desc->InUnion = InUnion;
105 Desc->IsArrayElement =
true;
107 if (
auto Fn =
D->ElemDesc->CtorFn)
108 Fn(B, ElemLoc, Desc->IsConst, Desc->IsFieldMutable, IsActive,
109 Desc->InUnion || SD->isUnion(),
D->ElemDesc);
114 const unsigned NumElems =
D->getNumElems();
115 const unsigned ElemSize =
118 unsigned ElemOffset = 0;
119 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
120 auto *ElemPtr = Ptr + ElemOffset;
122 auto *ElemLoc =
reinterpret_cast<std::byte *
>(Desc + 1);
123 if (
auto Fn =
D->ElemDesc->DtorFn)
124 Fn(B, ElemLoc,
D->ElemDesc);
130 const unsigned NumElems =
D->getNumElems();
131 const unsigned ElemSize =
134 unsigned ElemOffset = 0;
135 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
136 auto *SrcPtr = Src + ElemOffset;
137 auto *DstPtr = Dst + ElemOffset;
140 auto *SrcElemLoc =
reinterpret_cast<std::byte *
>(SrcDesc + 1);
142 auto *DstElemLoc =
reinterpret_cast<std::byte *
>(DstDesc + 1);
145 if (
auto Fn =
D->ElemDesc->MoveFn)
146 Fn(B, SrcElemLoc, DstElemLoc,
D->ElemDesc);
151 bool IsActive,
bool IsUnionField,
bool InUnion,
154 Desc->
Offset = FieldOffset;
156 Desc->IsInitialized =
D->IsArray;
157 Desc->IsBase =
false;
158 Desc->IsActive = IsActive && !IsUnionField;
159 Desc->InUnion = InUnion;
160 Desc->IsConst = IsConst ||
D->IsConst;
161 Desc->IsFieldMutable = IsMutable ||
D->IsMutable;
163 if (
auto Fn =
D->CtorFn)
164 Fn(B, Ptr + FieldOffset, Desc->IsConst, Desc->IsFieldMutable,
165 Desc->IsActive, InUnion ||
D->isUnion(),
D);
170 unsigned FieldOffset,
bool IsVirtualBase) {
172 assert(
D->ElemRecord);
173 assert(!
D->ElemRecord->isUnion());
176 Desc->
Offset = FieldOffset;
178 Desc->IsInitialized =
D->IsArray;
180 Desc->IsVirtualBase = IsVirtualBase;
181 Desc->IsActive = IsActive && !InUnion;
182 Desc->IsConst = IsConst ||
D->IsConst;
183 Desc->IsFieldMutable = IsMutable ||
D->IsMutable;
184 Desc->InUnion = InUnion;
186 for (
const auto &
V :
D->ElemRecord->bases())
187 initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, InUnion,
188 V.Desc,
V.Offset,
false);
189 for (
const auto &F :
D->ElemRecord->fields())
190 initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, InUnion,
191 InUnion, F.Desc, F.Offset);
195 bool IsActive,
bool InUnion,
const Descriptor *
D) {
196 for (
const auto &
V :
D->ElemRecord->bases())
197 initBase(B, Ptr, IsConst, IsMutable, IsActive, InUnion,
V.Desc,
V.Offset,
199 for (
const auto &F :
D->ElemRecord->fields()) {
200 bool IsUnionField =
D->isUnion();
201 initField(B, Ptr, IsConst, IsMutable, IsActive, IsUnionField,
202 InUnion || IsUnionField, F.Desc, F.Offset);
204 for (
const auto &
V :
D->ElemRecord->virtual_bases())
205 initBase(B, Ptr, IsConst, IsMutable, IsActive, InUnion,
V.Desc,
V.Offset,
210 unsigned FieldOffset) {
211 if (
auto Fn =
D->DtorFn)
212 Fn(B, Ptr + FieldOffset,
D);
216 unsigned FieldOffset) {
218 assert(
D->ElemRecord);
220 for (
const auto &
V :
D->ElemRecord->bases())
222 for (
const auto &F :
D->ElemRecord->fields())
227 for (
const auto &F :
D->ElemRecord->bases())
229 for (
const auto &F :
D->ElemRecord->fields())
231 for (
const auto &F :
D->ElemRecord->virtual_bases())
238 assert(
D->ElemRecord);
242 for (
const auto &F :
D->ElemRecord->fields()) {
243 auto FieldOffset = F.Offset;
244 const auto *SrcDesc =
250 if (
auto Fn = F.Desc->MoveFn)
251 Fn(B, Src + FieldOffset, Dst + FieldOffset, F.Desc);
259 return ctorTy<PrimConv<PT_Float>::T>;
261 return ctorTy<PrimConv<PT_IntAP>::T>;
263 return ctorTy<PrimConv<PT_IntAPS>::T>;
265 return ctorTy<PrimConv<PT_MemberPtr>::T>;
274 return dtorTy<PrimConv<PT_Float>::T>;
276 return dtorTy<PrimConv<PT_IntAP>::T>;
278 return dtorTy<PrimConv<PT_IntAPS>::T>;
280 return dtorTy<PrimConv<PT_MemberPtr>::T>;
287 return moveTy<PrimConv<PT_Float>::T>;
289 return moveTy<PrimConv<PT_IntAP>::T>;
291 return moveTy<PrimConv<PT_IntAPS>::T>;
293 return moveTy<PrimConv<PT_MemberPtr>::T>;
299 llvm_unreachable(
"unknown Expr");
304 llvm_unreachable(
"unknown Expr");
309 llvm_unreachable(
"unknown Expr");
314 bool IsConst,
bool IsTemporary,
bool IsMutable)
316 MDSize(MD.value_or(0)), AllocSize(
align(Size + MDSize)), PrimT(
Type),
317 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
320 assert(AllocSize >= Size);
321 assert(Source &&
"Missing source");
326 size_t NumElems,
bool IsConst,
bool IsTemporary,
328 : Source(
D), ElemSize(
primSize(
Type)), Size(ElemSize * NumElems),
329 MDSize(MD.value_or(0)),
331 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
334 assert(Source &&
"Missing source");
341 : Source(
D), ElemSize(
primSize(
Type)), Size(UnknownSizeMark),
342 MDSize(MD.value_or(0)),
343 AllocSize(MDSize + sizeof(
InitMapPtr) + alignof(void *)), IsConst(
true),
344 IsMutable(
false), IsTemporary(IsTemporary), IsArray(
true),
347 assert(Source &&
"Missing source");
352 unsigned NumElems,
bool IsConst,
bool IsTemporary,
355 Size(ElemSize * NumElems), MDSize(MD.value_or(0)),
356 AllocSize(
std::
max<
size_t>(alignof(void *), Size) + MDSize),
357 ElemDesc(Elem), IsConst(IsConst), IsMutable(IsMutable),
360 assert(Source &&
"Missing source");
367 Size(UnknownSizeMark), MDSize(MD.value_or(0)),
368 AllocSize(MDSize + alignof(void *)), ElemDesc(Elem), IsConst(
true),
369 IsMutable(
false), IsTemporary(IsTemporary), IsArray(
true),
371 assert(Source &&
"Missing source");
376 bool IsConst,
bool IsTemporary,
bool IsMutable)
377 : Source(
D), ElemSize(
std::
max<
size_t>(alignof(void *), R->getFullSize())),
378 Size(ElemSize), MDSize(MD.value_or(0)), AllocSize(Size + MDSize),
379 ElemRecord(R), IsConst(IsConst), IsMutable(IsMutable),
382 assert(Source &&
"Missing source");
387 : Source(
D), ElemSize(1), Size(1), MDSize(0), AllocSize(MDSize),
388 ElemRecord(nullptr), IsConst(
true), IsMutable(
false), IsTemporary(
false),
390 assert(Source &&
"Missing source");
396 if (
const auto *
T = dyn_cast_if_present<TypeDecl>(
asDecl()))
405 llvm_unreachable(
"Invalid descriptor type");
421 return AT->getElementType();
424 return CT->getElementType();
426 return CT->getElementType();
427 llvm_unreachable(
"Array that's not an array/complex/vector type?");
431 if (
auto *
D = Source.dyn_cast<
const Decl *>())
433 if (
auto *
E = Source.dyn_cast<
const Expr *>())
435 llvm_unreachable(
"Invalid descriptor type");
439 if (
const auto *
D = Source.dyn_cast<
const Decl *>())
441 if (
const auto *
E = Source.dyn_cast<
const Expr *>())
443 llvm_unreachable(
"Invalid descriptor type");
449 : UninitFields(N),
Data(
std::make_unique<T[]>(numFields(N))) {
450 std::fill_n(data(), numFields(N), 0);
453bool InitMap::initializeElement(
unsigned I) {
454 unsigned Bucket = I / PER_FIELD;
455 T Mask = T(1) << (I % PER_FIELD);
456 if (!(data()[Bucket] & Mask)) {
457 data()[Bucket] |= Mask;
460 return UninitFields == 0;
463bool InitMap::isElementInitialized(
unsigned I)
const {
464 unsigned Bucket = I / PER_FIELD;
465 return data()[Bucket] & (T(1) << (I % PER_FIELD));
static void moveArrayTy(Block *, std::byte *Src, std::byte *Dst, const Descriptor *D)
static void dtorTy(Block *, std::byte *Ptr, const Descriptor *)
static BlockCtorFn getCtorArrayPrim(PrimType Type)
static void initField(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, bool IsActive, bool IsUnionField, bool InUnion, const Descriptor *D, unsigned FieldOffset)
static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, bool IsActive, bool InUnion, const Descriptor *D, unsigned FieldOffset, bool IsVirtualBase)
static BlockMoveFn getMoveArrayPrim(PrimType Type)
static void destroyField(Block *B, std::byte *Ptr, const Descriptor *D, unsigned FieldOffset)
static void dtorArrayTy(Block *, std::byte *Ptr, const Descriptor *D)
static BlockMoveFn getMovePrim(PrimType Type)
static void moveRecord(Block *B, std::byte *Src, std::byte *Dst, const Descriptor *D)
static void moveTy(Block *, std::byte *Src, std::byte *Dst, const Descriptor *)
static void ctorArrayTy(Block *, std::byte *Ptr, bool, bool, bool, bool, const Descriptor *D)
static void destroyBase(Block *B, std::byte *Ptr, const Descriptor *D, unsigned FieldOffset)
static void dtorArrayDesc(Block *B, std::byte *Ptr, const Descriptor *D)
static void ctorTy(Block *, std::byte *Ptr, bool, bool, bool, bool, const Descriptor *)
static BlockDtorFn getDtorPrim(PrimType Type)
static BlockCtorFn getCtorPrim(PrimType Type)
static BlockDtorFn getDtorArrayPrim(PrimType Type)
static void moveArrayDesc(Block *B, std::byte *Src, std::byte *Dst, const Descriptor *D)
static void dtorRecord(Block *B, std::byte *Ptr, const Descriptor *D)
static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, bool IsActive, bool InUnion, const Descriptor *D)
static void ctorRecord(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, bool IsActive, bool InUnion, const Descriptor *D)
#define COMPOSITE_TYPE_SWITCH(Expr, B, D)
#define TYPE_SWITCH(Expr, B)
__DEVICE__ int max(int __a, int __b)
QualType getElementType() const
Complex values, per C99 6.2.5p11.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
A (possibly-)qualified type.
Encodes a location in the source.
const Type * getTypeForDecl() const
The base class of the type hierarchy.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isPointerOrReferenceType() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents a GCC generic vector type.
A memory block, either on the stack or in the heap.
Structure/Class descriptor.
const RecordDecl * getDecl() const
Returns the underlying declaration.
bool isUnion() const
Checks if the record is a union.
Describes the statement/declaration an opcode was generated from.
std::optional< std::pair< bool, std::shared_ptr< InitMap > > > InitMapPtr
void(*)(Block *Storage, std::byte *FieldPtr, bool IsConst, bool IsMutable, bool IsActive, bool InUnion, const Descriptor *FieldDesc) BlockCtorFn
Invoked whenever a block is created.
bool NE(InterpState &S, CodePtr OpPC)
void(*)(Block *Storage, std::byte *FieldPtr, const Descriptor *FieldDesc) BlockDtorFn
Invoked when a block is destroyed.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
PrimType
Enumeration of the primitive types of the VM.
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
void(*)(Block *Storage, std::byte *SrcFieldPtr, std::byte *DstFieldPtr, const Descriptor *FieldDesc) BlockMoveFn
Invoked when a block with pointers referencing it goes out of scope.
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
Token to denote structures of unknown size.
Describes a memory block created by an allocation site.
QualType getElemQualType() const
const ValueDecl * asValueDecl() const
static constexpr unsigned MaxArrayElemBytes
Maximum number of bytes to be used for array elements.
const Decl * asDecl() const
SourceInfo getLoc() const
SourceLocation getLocation() const
std::optional< unsigned > MetadataSize
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD, bool IsConst, bool IsTemporary, bool IsMutable)
Allocates a descriptor for a primitive.
bool isRecord() const
Checks if the descriptor is of a record.
const Record *const ElemRecord
Pointer to the record, if block contains records.
bool isUnion() const
Checks if the descriptor is of a union.
const Expr * asExpr() const
bool isArray() const
Checks if the descriptor is of an array.
InitMap(unsigned N)
Initializes the map with no fields set.
Inline descriptor embedded in structures and arrays.
unsigned Offset
Offset inside the structure/array.