29 reinterpret_cast<T *
>(Ptr)->~
T();
33static void moveTy(
Block *,
const std::byte *Src, std::byte *Dst,
35 const auto *SrcPtr =
reinterpret_cast<const T *
>(Src);
36 auto *DstPtr =
reinterpret_cast<T *
>(Dst);
37 new (DstPtr)
T(std::move(*SrcPtr));
47 new (&
reinterpret_cast<T *
>(Ptr)[I])
T();
59 reinterpret_cast<T *
>(Ptr)[I].~
T();
70 const auto *SrcPtr = &
reinterpret_cast<const T *
>(Src)[I];
71 auto *DstPtr = &
reinterpret_cast<T *
>(Dst)[I];
72 new (DstPtr)
T(std::move(*SrcPtr));
77 bool IsMutable,
bool IsActive,
const Descriptor *D) {
79 const unsigned ElemSize =
82 unsigned ElemOffset = 0;
83 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
84 auto *ElemPtr = Ptr + ElemOffset;
86 auto *ElemLoc =
reinterpret_cast<std::byte *
>(Desc + 1);
91 Desc->IsInitialized =
true;
93 Desc->IsActive = IsActive;
95 Desc->IsFieldMutable = IsMutable || D->
IsMutable;
97 Fn(B, ElemLoc, Desc->IsConst, Desc->IsFieldMutable, IsActive,
104 const unsigned ElemSize =
107 unsigned ElemOffset = 0;
108 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
109 auto *ElemPtr = Ptr + ElemOffset;
111 auto *ElemLoc =
reinterpret_cast<std::byte *
>(Desc + 1);
120 const unsigned ElemSize =
123 unsigned ElemOffset = 0;
124 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
125 const auto *SrcPtr = Src + ElemOffset;
126 auto *DstPtr = Dst + ElemOffset;
129 const auto *SrcElemLoc =
reinterpret_cast<const std::byte *
>(SrcDesc + 1);
131 auto *DstElemLoc =
reinterpret_cast<std::byte *
>(DstDesc + 1);
135 Fn(B, SrcElemLoc, DstElemLoc, D->
ElemDesc);
141 unsigned FieldOffset) {
142 bool IsUnion =
false;
144 Desc->
Offset = FieldOffset;
146 Desc->IsInitialized = D->
IsArray;
147 Desc->IsBase =
false;
148 Desc->IsActive = IsActive && !IsUnion;
149 Desc->IsConst = IsConst || D->
IsConst;
150 Desc->IsFieldMutable = IsMutable || D->
IsMutable;
153 Fn(B, Ptr + FieldOffset, Desc->IsConst, Desc->IsFieldMutable,
158 bool IsActive,
const Descriptor *D,
unsigned FieldOffset,
159 bool IsVirtualBase) {
165 Desc->
Offset = FieldOffset;
167 Desc->IsInitialized = D->
IsArray;
169 Desc->IsActive = IsActive && !IsUnion;
170 Desc->IsConst = IsConst || D->
IsConst;
171 Desc->IsFieldMutable = IsMutable || D->
IsMutable;
174 initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive,
V.Desc,
177 initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, F.Desc,
187 initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive,
V.Desc,
194 initBase(B, Ptr, IsConst, IsMutable, IsActive,
V.Desc,
V.Offset,
false);
196 initField(B, Ptr, IsConst, IsMutable, IsActive, F.
Desc, F.Offset);
198 initBase(B, Ptr, IsConst, IsMutable, IsActive,
V.Desc,
V.Offset,
true);
202 auto DtorSub = [=](
unsigned SubOff,
const Descriptor *F) {
203 if (
auto Fn = F->DtorFn)
204 Fn(B, Ptr + SubOff, F);
207 DtorSub(F.Offset, F.Desc);
209 DtorSub(F.Offset, F.Desc);
211 DtorSub(F.Offset, F.Desc);
217 auto FieldOff = F.Offset;
218 auto *FieldDesc = F.Desc;
220 if (
auto Fn = FieldDesc->MoveFn)
221 Fn(B, Src + FieldOff, Dst + FieldOff, FieldDesc);
229 return ctorTy<PrimConv<PT_Float>::T>;
231 return ctorTy<PrimConv<PT_IntAP>::T>;
233 return ctorTy<PrimConv<PT_IntAPS>::T>;
242 return dtorTy<PrimConv<PT_Float>::T>;
244 return dtorTy<PrimConv<PT_IntAP>::T>;
246 return dtorTy<PrimConv<PT_IntAPS>::T>;
257 llvm_unreachable(
"unknown Expr");
262 llvm_unreachable(
"unknown Expr");
267 llvm_unreachable(
"unknown Expr");
272 bool IsConst,
bool IsTemporary,
bool IsMutable)
274 MDSize(MD.value_or(0)), AllocSize(
align(Size + MDSize)), PrimT(
Type),
275 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
278 assert(AllocSize >= Size);
279 assert(Source &&
"Missing source");
284 size_t NumElems,
bool IsConst,
bool IsTemporary,
286 : Source(D), ElemSize(
primSize(
Type)), Size(ElemSize * NumElems),
287 MDSize(MD.value_or(0)),
289 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
292 assert(Source &&
"Missing source");
298 : Source(D), ElemSize(
primSize(
Type)), Size(UnknownSizeMark),
299 MDSize(MD.value_or(0)),
300 AllocSize(MDSize + sizeof(
InitMapPtr) + alignof(void *)), IsConst(
true),
301 IsMutable(
false), IsTemporary(IsTemporary), IsArray(
true),
304 assert(Source &&
"Missing source");
309 unsigned NumElems,
bool IsConst,
bool IsTemporary,
312 Size(ElemSize * NumElems), MDSize(MD.value_or(0)),
313 AllocSize(
std::
max<
size_t>(alignof(void *), Size) + MDSize),
314 ElemDesc(Elem), IsConst(IsConst), IsMutable(IsMutable),
317 assert(Source &&
"Missing source");
324 Size(UnknownSizeMark), MDSize(MD.value_or(0)),
325 AllocSize(MDSize + alignof(void *)), ElemDesc(Elem), IsConst(
true),
326 IsMutable(
false), IsTemporary(IsTemporary), IsArray(
true),
328 assert(Source &&
"Missing source");
333 bool IsConst,
bool IsTemporary,
bool IsMutable)
334 : Source(D), ElemSize(
std::
max<
size_t>(alignof(void *), R->getFullSize())),
335 Size(ElemSize), MDSize(MD.value_or(0)), AllocSize(Size + MDSize),
336 ElemRecord(R), IsConst(IsConst), IsMutable(IsMutable),
339 assert(Source &&
"Missing source");
344 : Source(D), ElemSize(1), Size(1), MDSize(0), AllocSize(MDSize),
345 ElemRecord(nullptr), IsConst(
true), IsMutable(
false), IsTemporary(
false),
347 assert(Source &&
"Missing source");
355 if (
auto *
T = dyn_cast<TypeDecl>(
asDecl()))
357 llvm_unreachable(
"Invalid descriptor type");
362 const auto *AT = cast<ArrayType>(
getType());
363 return AT->getElementType();
367 if (
auto *D = Source.dyn_cast<
const Decl *>())
368 return D->getLocation();
369 if (
auto *E = Source.dyn_cast<
const Expr *>())
370 return E->getExprLoc();
371 llvm_unreachable(
"Invalid descriptor type");
375 : UninitFields(N),
Data(
std::make_unique<T[]>(numFields(N))) {
376 std::fill_n(data(), numFields(N), 0);
379bool InitMap::initializeElement(
unsigned I) {
380 unsigned Bucket = I / PER_FIELD;
381 T Mask = T(1) << (I % PER_FIELD);
382 if (!(data()[Bucket] & Mask)) {
383 data()[Bucket] |= Mask;
386 return UninitFields == 0;
389bool InitMap::isElementInitialized(
unsigned I)
const {
390 unsigned Bucket = I / PER_FIELD;
391 return data()[Bucket] & (T(1) << (I % PER_FIELD));
static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, bool IsActive, const Descriptor *D, unsigned FieldOffset, bool IsVirtualBase)
static void dtorTy(Block *, std::byte *Ptr, const Descriptor *)
static BlockCtorFn getCtorArrayPrim(PrimType Type)
static BlockMoveFn getMoveArrayPrim(PrimType Type)
static void initField(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, bool IsActive, const Descriptor *D, unsigned FieldOffset)
static void dtorArrayTy(Block *, std::byte *Ptr, const Descriptor *D)
static BlockMoveFn getMovePrim(PrimType Type)
static void ctorTy(Block *, std::byte *Ptr, bool, bool, bool, const Descriptor *)
static void ctorArrayTy(Block *, std::byte *Ptr, bool, bool, bool, const Descriptor *D)
static void moveRecord(Block *B, const std::byte *Src, std::byte *Dst, const Descriptor *D)
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 BlockDtorFn getDtorPrim(PrimType Type)
static BlockCtorFn getCtorPrim(PrimType Type)
static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, bool IsActive, const Descriptor *D)
static BlockDtorFn getDtorArrayPrim(PrimType Type)
static void moveArrayDesc(Block *B, const std::byte *Src, std::byte *Dst, const Descriptor *D)
static void ctorRecord(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, bool IsActive, const Descriptor *D)
static void dtorRecord(Block *B, std::byte *Ptr, const Descriptor *D)
static void moveArrayTy(Block *, const std::byte *Src, std::byte *Dst, const Descriptor *D)
#define COMPOSITE_TYPE_SWITCH(Expr, B, D)
#define TYPE_SWITCH(Expr, B)
__DEVICE__ int max(int __a, int __b)
Decl - This represents one declaration (or definition), e.g.
This represents one expression.
A (possibly-)qualified type.
Encodes a location in the source.
The base class of the type hierarchy.
A memory block, either on the stack or in the heap.
const Descriptor * Desc
Pointer to the stack slot descriptor.
Structure/Class descriptor.
bool isUnion() const
Checks if the record is a union.
llvm::iterator_range< const_virtual_iter > virtual_bases() const
llvm::iterator_range< const_base_iter > bases() const
llvm::iterator_range< const_field_iter > fields() const
std::optional< std::pair< bool, std::shared_ptr< InitMap > > > InitMapPtr
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.
void(*)(Block *Storage, std::byte *FieldPtr, bool IsConst, bool IsMutable, bool IsActive, const Descriptor *FieldDesc) BlockCtorFn
Invoked whenever a block is created.
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.
const bool IsConst
Flag indicating if the block is mutable.
unsigned getAllocSize() const
Returns the allocated size, including metadata.
unsigned getNumElems() const
Returns the number of elements stored in the block.
QualType getElemQualType() const
const ValueDecl * asValueDecl() const
const BlockCtorFn CtorFn
Storage management methods.
const Decl * asDecl() const
const Descriptor *const ElemDesc
Descriptor of the array element.
SourceLocation getLocation() const
const bool IsMutable
Flag indicating if a field is mutable.
std::optional< unsigned > MetadataSize
const bool IsArray
Flag indicating if the block is an array.
Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD, bool IsConst, bool IsTemporary, bool IsMutable)
Allocates a descriptor for a primitive.
const Record *const ElemRecord
Pointer to the record, if block contains records.
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.