23static void ctorTy(
Block *, std::byte *Ptr,
bool,
bool,
bool,
bool,
30 reinterpret_cast<T *
>(Ptr)->~
T();
36 auto *SrcPtr =
reinterpret_cast<T *
>(Src);
37 auto *DstPtr =
reinterpret_cast<T *
>(Dst);
38 new (DstPtr)
T(std::move(*SrcPtr));
47 for (
unsigned I = 0,
NE =
D->getNumElems(); I <
NE; ++I) {
48 new (&
reinterpret_cast<T *
>(Ptr)[I])
T();
59 for (
unsigned I = 0,
NE =
D->getNumElems(); I <
NE; ++I) {
60 reinterpret_cast<T *
>(Ptr)[I].~
T();
71 SrcIMP = std::nullopt;
75 for (
unsigned I = 0,
NE =
D->getNumElems(); I <
NE; ++I) {
76 auto *SrcPtr = &
reinterpret_cast<T *
>(Src)[I];
77 auto *DstPtr = &
reinterpret_cast<T *
>(Dst)[I];
78 new (DstPtr)
T(std::move(*SrcPtr));
83 bool IsMutable,
bool IsActive,
bool InUnion,
85 const unsigned NumElems =
D->getNumElems();
86 const unsigned ElemSize =
89 unsigned ElemOffset = 0;
90 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
91 auto *ElemPtr = Ptr + ElemOffset;
93 auto *ElemLoc =
reinterpret_cast<std::byte *
>(Desc + 1);
94 auto *SD =
D->ElemDesc;
98 Desc->IsInitialized =
true;
100 Desc->IsActive = IsActive;
101 Desc->IsConst = IsConst ||
D->IsConst;
102 Desc->IsFieldMutable = IsMutable ||
D->IsMutable;
103 Desc->InUnion = InUnion;
105 if (
auto Fn =
D->ElemDesc->CtorFn)
106 Fn(B, ElemLoc, Desc->IsConst, Desc->IsFieldMutable, IsActive,
107 Desc->InUnion || SD->isUnion(),
D->ElemDesc);
112 const unsigned NumElems =
D->getNumElems();
113 const unsigned ElemSize =
116 unsigned ElemOffset = 0;
117 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
118 auto *ElemPtr = Ptr + ElemOffset;
120 auto *ElemLoc =
reinterpret_cast<std::byte *
>(Desc + 1);
121 if (
auto Fn =
D->ElemDesc->DtorFn)
122 Fn(B, ElemLoc,
D->ElemDesc);
128 const unsigned NumElems =
D->getNumElems();
129 const unsigned ElemSize =
132 unsigned ElemOffset = 0;
133 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
134 auto *SrcPtr = Src + ElemOffset;
135 auto *DstPtr = Dst + ElemOffset;
138 auto *SrcElemLoc =
reinterpret_cast<std::byte *
>(SrcDesc + 1);
140 auto *DstElemLoc =
reinterpret_cast<std::byte *
>(DstDesc + 1);
143 if (
auto Fn =
D->ElemDesc->MoveFn)
144 Fn(B, SrcElemLoc, DstElemLoc,
D->ElemDesc);
149 bool IsActive,
bool IsUnionField,
bool InUnion,
152 Desc->
Offset = FieldOffset;
154 Desc->IsInitialized =
D->IsArray;
155 Desc->IsBase =
false;
156 Desc->IsActive = IsActive && !IsUnionField;
157 Desc->InUnion = InUnion;
158 Desc->IsConst = IsConst ||
D->IsConst;
159 Desc->IsFieldMutable = IsMutable ||
D->IsMutable;
161 if (
auto Fn =
D->CtorFn)
162 Fn(B, Ptr + FieldOffset, Desc->IsConst, Desc->IsFieldMutable,
163 Desc->IsActive, InUnion ||
D->isUnion(),
D);
168 unsigned FieldOffset,
bool IsVirtualBase) {
170 assert(
D->ElemRecord);
171 assert(!
D->ElemRecord->isUnion());
174 Desc->
Offset = FieldOffset;
176 Desc->IsInitialized =
D->IsArray;
178 Desc->IsVirtualBase = IsVirtualBase;
179 Desc->IsActive = IsActive && !InUnion;
180 Desc->IsConst = IsConst ||
D->IsConst;
181 Desc->IsFieldMutable = IsMutable ||
D->IsMutable;
182 Desc->InUnion = InUnion;
184 for (
const auto &
V :
D->ElemRecord->bases())
185 initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, InUnion,
186 V.Desc,
V.Offset,
false);
187 for (
const auto &F :
D->ElemRecord->fields())
188 initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, InUnion,
189 InUnion, F.Desc, F.Offset);
193 bool IsActive,
bool InUnion,
const Descriptor *
D) {
194 for (
const auto &
V :
D->ElemRecord->bases())
195 initBase(B, Ptr, IsConst, IsMutable, IsActive, InUnion,
V.Desc,
V.Offset,
197 for (
const auto &F :
D->ElemRecord->fields()) {
198 bool IsUnionField =
D->isUnion();
199 initField(B, Ptr, IsConst, IsMutable, IsActive, IsUnionField,
200 InUnion || IsUnionField, F.Desc, F.Offset);
202 for (
const auto &
V :
D->ElemRecord->virtual_bases())
203 initBase(B, Ptr, IsConst, IsMutable, IsActive, InUnion,
V.Desc,
V.Offset,
208 unsigned FieldOffset) {
209 if (
auto Fn =
D->DtorFn)
210 Fn(B, Ptr + FieldOffset,
D);
214 unsigned FieldOffset) {
216 assert(
D->ElemRecord);
218 for (
const auto &
V :
D->ElemRecord->bases())
220 for (
const auto &F :
D->ElemRecord->fields())
225 for (
const auto &F :
D->ElemRecord->bases())
227 for (
const auto &F :
D->ElemRecord->fields())
229 for (
const auto &F :
D->ElemRecord->virtual_bases())
236 assert(
D->ElemRecord);
240 for (
const auto &F :
D->ElemRecord->fields()) {
241 auto FieldOffset = F.Offset;
242 const auto *SrcDesc =
248 if (
auto Fn = F.Desc->MoveFn)
249 Fn(B, Src + FieldOffset, Dst + FieldOffset, F.Desc);
257 return ctorTy<PrimConv<PT_Float>::T>;
259 return ctorTy<PrimConv<PT_IntAP>::T>;
261 return ctorTy<PrimConv<PT_IntAPS>::T>;
263 return ctorTy<PrimConv<PT_MemberPtr>::T>;
272 return dtorTy<PrimConv<PT_Float>::T>;
274 return dtorTy<PrimConv<PT_IntAP>::T>;
276 return dtorTy<PrimConv<PT_IntAPS>::T>;
278 return dtorTy<PrimConv<PT_MemberPtr>::T>;
285 return moveTy<PrimConv<PT_Float>::T>;
287 return moveTy<PrimConv<PT_IntAP>::T>;
289 return moveTy<PrimConv<PT_IntAPS>::T>;
291 return moveTy<PrimConv<PT_MemberPtr>::T>;
297 llvm_unreachable(
"unknown Expr");
302 llvm_unreachable(
"unknown Expr");
307 llvm_unreachable(
"unknown Expr");
312 bool IsConst,
bool IsTemporary,
bool IsMutable)
314 MDSize(MD.value_or(0)), AllocSize(
align(Size + MDSize)), PrimT(
Type),
315 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
318 assert(AllocSize >= Size);
319 assert(Source &&
"Missing source");
324 size_t NumElems,
bool IsConst,
bool IsTemporary,
326 : Source(
D), ElemSize(
primSize(
Type)), Size(ElemSize * NumElems),
327 MDSize(MD.value_or(0)),
329 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
332 assert(Source &&
"Missing source");
339 : Source(
D), ElemSize(
primSize(
Type)), Size(UnknownSizeMark),
340 MDSize(MD.value_or(0)),
341 AllocSize(MDSize + sizeof(
InitMapPtr) + alignof(void *)), IsConst(
true),
342 IsMutable(
false), IsTemporary(IsTemporary), IsArray(
true),
345 assert(Source &&
"Missing source");
350 unsigned NumElems,
bool IsConst,
bool IsTemporary,
353 Size(ElemSize * NumElems), MDSize(MD.value_or(0)),
354 AllocSize(
std::
max<
size_t>(alignof(void *), Size) + MDSize),
355 ElemDesc(Elem), IsConst(IsConst), IsMutable(IsMutable),
358 assert(Source &&
"Missing source");
365 Size(UnknownSizeMark), MDSize(MD.value_or(0)),
366 AllocSize(MDSize + alignof(void *)), ElemDesc(Elem), IsConst(
true),
367 IsMutable(
false), IsTemporary(IsTemporary), IsArray(
true),
369 assert(Source &&
"Missing source");
374 bool IsConst,
bool IsTemporary,
bool IsMutable)
375 : Source(
D), ElemSize(
std::
max<
size_t>(alignof(void *), R->getFullSize())),
376 Size(ElemSize), MDSize(MD.value_or(0)), AllocSize(Size + MDSize),
377 ElemRecord(R), IsConst(IsConst), IsMutable(IsMutable),
380 assert(Source &&
"Missing source");
385 : Source(
D), ElemSize(1), Size(1), MDSize(0), AllocSize(MDSize),
386 ElemRecord(nullptr), IsConst(
true), IsMutable(
false), IsTemporary(
false),
388 assert(Source &&
"Missing source");
396 if (
const auto *
T = dyn_cast<TypeDecl>(
asDecl()))
398 llvm_unreachable(
"Invalid descriptor type");
405 return AT->getElementType();
407 return CT->getElementType();
409 return CT->getElementType();
410 llvm_unreachable(
"Array that's not an array/complex/vector type?");
414 if (
auto *
D = Source.dyn_cast<
const Decl *>())
416 if (
auto *
E = Source.dyn_cast<
const Expr *>())
418 llvm_unreachable(
"Invalid descriptor type");
424 : UninitFields(N),
Data(
std::make_unique<T[]>(numFields(N))) {
425 std::fill_n(data(), numFields(N), 0);
428bool InitMap::initializeElement(
unsigned I) {
429 unsigned Bucket = I / PER_FIELD;
430 T Mask = T(1) << (I % PER_FIELD);
431 if (!(data()[Bucket] & Mask)) {
432 data()[Bucket] |= Mask;
435 return UninitFields == 0;
438bool InitMap::isElementInitialized(
unsigned I)
const {
439 unsigned Bucket = I / PER_FIELD;
440 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)
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.
The base class of the type hierarchy.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
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.
bool isUnion() const
Checks if the record is a union.
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
SourceLocation getLocation() const
std::optional< unsigned > MetadataSize
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.