23static void ctorTy(
Block *, std::byte *Ptr,
bool,
bool,
bool,
bool,
30 reinterpret_cast<T *
>(Ptr)->~
T();
34static void moveTy(
Block *,
const std::byte *Src, std::byte *Dst,
37 auto *SrcPtr =
reinterpret_cast<T *
>(
const_cast<std::byte *
>(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();
70 *
reinterpret_cast<InitMapPtr *
>(
const_cast<std::byte *
>(Src));
74 SrcIMP = std::nullopt;
78 for (
unsigned I = 0,
NE =
D->getNumElems(); I <
NE; ++I) {
79 auto *SrcPtr = &
reinterpret_cast<T *
>(
const_cast<std::byte *
>(Src))[I];
80 auto *DstPtr = &
reinterpret_cast<T *
>(Dst)[I];
81 new (DstPtr)
T(std::move(*SrcPtr));
86 bool IsMutable,
bool IsActive,
bool InUnion,
88 const unsigned NumElems =
D->getNumElems();
89 const unsigned ElemSize =
92 unsigned ElemOffset = 0;
93 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
94 auto *ElemPtr = Ptr + ElemOffset;
96 auto *ElemLoc =
reinterpret_cast<std::byte *
>(Desc + 1);
97 auto *SD =
D->ElemDesc;
101 Desc->IsInitialized =
true;
102 Desc->IsBase =
false;
103 Desc->IsActive = IsActive;
104 Desc->IsConst = IsConst ||
D->IsConst;
105 Desc->IsFieldMutable = IsMutable ||
D->IsMutable;
106 Desc->InUnion = InUnion;
108 if (
auto Fn =
D->ElemDesc->CtorFn)
109 Fn(B, ElemLoc, Desc->IsConst, Desc->IsFieldMutable, IsActive,
110 Desc->InUnion || SD->isUnion(),
D->ElemDesc);
115 const unsigned NumElems =
D->getNumElems();
116 const unsigned ElemSize =
119 unsigned ElemOffset = 0;
120 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
121 auto *ElemPtr = Ptr + ElemOffset;
123 auto *ElemLoc =
reinterpret_cast<std::byte *
>(Desc + 1);
124 if (
auto Fn =
D->ElemDesc->DtorFn)
125 Fn(B, ElemLoc,
D->ElemDesc);
131 const unsigned NumElems =
D->getNumElems();
132 const unsigned ElemSize =
135 unsigned ElemOffset = 0;
136 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
137 const auto *SrcPtr = Src + ElemOffset;
138 auto *DstPtr = Dst + ElemOffset;
141 const auto *SrcElemLoc =
reinterpret_cast<const std::byte *
>(SrcDesc + 1);
143 auto *DstElemLoc =
reinterpret_cast<std::byte *
>(DstDesc + 1);
146 if (
auto Fn =
D->ElemDesc->MoveFn)
147 Fn(B, SrcElemLoc, DstElemLoc,
D->ElemDesc);
152 bool IsActive,
bool IsUnionField,
bool InUnion,
155 Desc->
Offset = FieldOffset;
157 Desc->IsInitialized =
D->IsArray;
158 Desc->IsBase =
false;
159 Desc->IsActive = IsActive && !IsUnionField;
160 Desc->InUnion = InUnion;
161 Desc->IsConst = IsConst ||
D->IsConst;
162 Desc->IsFieldMutable = IsMutable ||
D->IsMutable;
164 if (
auto Fn =
D->CtorFn)
165 Fn(B, Ptr + FieldOffset, Desc->IsConst, Desc->IsFieldMutable,
166 Desc->IsActive, InUnion ||
D->isUnion(),
D);
171 unsigned FieldOffset,
bool IsVirtualBase) {
173 assert(
D->ElemRecord);
174 assert(!
D->ElemRecord->isUnion());
177 Desc->
Offset = FieldOffset;
179 Desc->IsInitialized =
D->IsArray;
181 Desc->IsVirtualBase = IsVirtualBase;
182 Desc->IsActive = IsActive && !InUnion;
183 Desc->IsConst = IsConst ||
D->IsConst;
184 Desc->IsFieldMutable = IsMutable ||
D->IsMutable;
185 Desc->InUnion = InUnion;
187 for (
const auto &
V :
D->ElemRecord->bases())
188 initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, InUnion,
189 V.Desc,
V.Offset,
false);
190 for (
const auto &F :
D->ElemRecord->fields())
191 initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, InUnion,
192 InUnion, F.Desc, F.Offset);
196 bool IsActive,
bool InUnion,
const Descriptor *
D) {
197 for (
const auto &
V :
D->ElemRecord->bases())
198 initBase(B, Ptr, IsConst, IsMutable, IsActive, InUnion,
V.Desc,
V.Offset,
200 for (
const auto &F :
D->ElemRecord->fields()) {
201 bool IsUnionField =
D->isUnion();
202 initField(B, Ptr, IsConst, IsMutable, IsActive, IsUnionField,
203 InUnion || IsUnionField, F.Desc, F.Offset);
205 for (
const auto &
V :
D->ElemRecord->virtual_bases())
206 initBase(B, Ptr, IsConst, IsMutable, IsActive, InUnion,
V.Desc,
V.Offset,
211 unsigned FieldOffset) {
212 if (
auto Fn =
D->DtorFn)
213 Fn(B, Ptr + FieldOffset,
D);
217 unsigned FieldOffset) {
219 assert(
D->ElemRecord);
221 for (
const auto &
V :
D->ElemRecord->bases())
223 for (
const auto &F :
D->ElemRecord->fields())
228 for (
const auto &F :
D->ElemRecord->bases())
230 for (
const auto &F :
D->ElemRecord->fields())
232 for (
const auto &F :
D->ElemRecord->virtual_bases())
239 assert(
D->ElemRecord);
243 for (
const auto &F :
D->ElemRecord->fields()) {
244 auto FieldOffset = F.Offset;
245 const auto *SrcDesc =
251 if (
auto Fn = F.Desc->MoveFn)
252 Fn(B, Src + FieldOffset, Dst + FieldOffset, F.Desc);
260 return ctorTy<PrimConv<PT_Float>::T>;
262 return ctorTy<PrimConv<PT_IntAP>::T>;
264 return ctorTy<PrimConv<PT_IntAPS>::T>;
266 return ctorTy<PrimConv<PT_MemberPtr>::T>;
275 return dtorTy<PrimConv<PT_Float>::T>;
277 return dtorTy<PrimConv<PT_IntAP>::T>;
279 return dtorTy<PrimConv<PT_IntAPS>::T>;
281 return dtorTy<PrimConv<PT_MemberPtr>::T>;
288 return moveTy<PrimConv<PT_Float>::T>;
290 return moveTy<PrimConv<PT_IntAP>::T>;
292 return moveTy<PrimConv<PT_IntAPS>::T>;
294 return moveTy<PrimConv<PT_MemberPtr>::T>;
300 llvm_unreachable(
"unknown Expr");
305 llvm_unreachable(
"unknown Expr");
310 llvm_unreachable(
"unknown Expr");
315 bool IsConst,
bool IsTemporary,
bool IsMutable)
317 MDSize(MD.value_or(0)), AllocSize(
align(Size + MDSize)), PrimT(
Type),
318 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
321 assert(AllocSize >= Size);
322 assert(Source &&
"Missing source");
327 size_t NumElems,
bool IsConst,
bool IsTemporary,
329 : Source(
D), ElemSize(
primSize(
Type)), Size(ElemSize * NumElems),
330 MDSize(MD.value_or(0)),
332 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
335 assert(Source &&
"Missing source");
342 : Source(
D), ElemSize(
primSize(
Type)), Size(UnknownSizeMark),
343 MDSize(MD.value_or(0)),
344 AllocSize(MDSize + sizeof(
InitMapPtr) + alignof(void *)), IsConst(
true),
345 IsMutable(
false), IsTemporary(IsTemporary), IsArray(
true),
348 assert(Source &&
"Missing source");
353 unsigned NumElems,
bool IsConst,
bool IsTemporary,
356 Size(ElemSize * NumElems), MDSize(MD.value_or(0)),
357 AllocSize(
std::
max<
size_t>(alignof(void *), Size) + MDSize),
358 ElemDesc(Elem), IsConst(IsConst), IsMutable(IsMutable),
361 assert(Source &&
"Missing source");
368 Size(UnknownSizeMark), MDSize(MD.value_or(0)),
369 AllocSize(MDSize + alignof(void *)), ElemDesc(Elem), IsConst(
true),
370 IsMutable(
false), IsTemporary(IsTemporary), IsArray(
true),
372 assert(Source &&
"Missing source");
377 bool IsConst,
bool IsTemporary,
bool IsMutable)
378 : Source(
D), ElemSize(
std::
max<
size_t>(alignof(void *), R->getFullSize())),
379 Size(ElemSize), MDSize(MD.value_or(0)), AllocSize(Size + MDSize),
380 ElemRecord(R), IsConst(IsConst), IsMutable(IsMutable),
383 assert(Source &&
"Missing source");
388 : Source(
D), ElemSize(1), Size(1), MDSize(0), AllocSize(MDSize),
389 ElemRecord(nullptr), IsConst(
true), IsMutable(
false), IsTemporary(
false),
391 assert(Source &&
"Missing source");
399 if (
const auto *
T = dyn_cast<TypeDecl>(
asDecl()))
401 llvm_unreachable(
"Invalid descriptor type");
408 return AT->getElementType();
410 return CT->getElementType();
412 return CT->getElementType();
413 llvm_unreachable(
"Array that's not an array/complex/vector type?");
417 if (
auto *
D = Source.dyn_cast<
const Decl *>())
419 if (
auto *
E = Source.dyn_cast<
const Expr *>())
421 llvm_unreachable(
"Invalid descriptor type");
427 : UninitFields(N),
Data(
std::make_unique<T[]>(numFields(N))) {
428 std::fill_n(data(), numFields(N), 0);
431bool InitMap::initializeElement(
unsigned I) {
432 unsigned Bucket = I / PER_FIELD;
433 T Mask = T(1) << (I % PER_FIELD);
434 if (!(data()[Bucket] & Mask)) {
435 data()[Bucket] |= Mask;
438 return UninitFields == 0;
441bool InitMap::isElementInitialized(
unsigned I)
const {
442 unsigned Bucket = I / PER_FIELD;
443 return data()[Bucket] & (T(1) << (I % PER_FIELD));
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, const std::byte *Src, std::byte *Dst, const Descriptor *D)
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 moveTy(Block *, const std::byte *Src, std::byte *Dst, const Descriptor *)
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, const 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 moveArrayTy(Block *, const std::byte *Src, std::byte *Dst, 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.
void(*)(Block *Storage, const std::byte *SrcFieldPtr, std::byte *DstFieldPtr, const Descriptor *FieldDesc) BlockMoveFn
Invoked when a block with pointers referencing it goes out of scope.
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
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.