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);
142 auto CtorSub = [=](
unsigned SubOff,
const Descriptor *F,
bool IsBase) {
146 Desc->IsInitialized = F->IsArray && !IsBase;
147 Desc->IsBase = IsBase;
148 Desc->IsActive = IsActive && !IsUnion;
149 Desc->IsConst = IsConst || F->IsConst;
150 Desc->IsFieldMutable = IsMutable || F->IsMutable;
151 if (
auto Fn = F->CtorFn)
152 Fn(B, Ptr + SubOff, Desc->IsConst, Desc->IsFieldMutable, Desc->IsActive,
156 CtorSub(B.Offset, B.
Desc,
true);
158 CtorSub(F.Offset, F.Desc,
false);
160 CtorSub(
V.Offset,
V.Desc,
true);
164 auto DtorSub = [=](
unsigned SubOff,
const Descriptor *F) {
165 if (
auto Fn = F->DtorFn)
166 Fn(B, Ptr + SubOff, F);
169 DtorSub(F.Offset, F.Desc);
171 DtorSub(F.Offset, F.Desc);
173 DtorSub(F.Offset, F.Desc);
179 auto FieldOff = F.Offset;
180 auto *FieldDesc = F.Desc;
182 if (
auto Fn = FieldDesc->MoveFn)
183 Fn(B, Src + FieldOff, Dst + FieldOff, FieldDesc);
191 return ctorTy<PrimConv<PT_Float>::T>;
193 return ctorTy<PrimConv<PT_IntAP>::T>;
195 return ctorTy<PrimConv<PT_IntAPS>::T>;
204 return dtorTy<PrimConv<PT_Float>::T>;
206 return dtorTy<PrimConv<PT_IntAP>::T>;
208 return dtorTy<PrimConv<PT_IntAPS>::T>;
219 llvm_unreachable(
"unknown Expr");
224 llvm_unreachable(
"unknown Expr");
229 llvm_unreachable(
"unknown Expr");
234 bool IsConst,
bool IsTemporary,
bool IsMutable)
236 MDSize(MD.value_or(0)), AllocSize(
align(Size + MDSize)), PrimT(
Type),
237 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
240 assert(AllocSize >= Size);
241 assert(Source &&
"Missing source");
246 size_t NumElems,
bool IsConst,
bool IsTemporary,
248 : Source(D), ElemSize(
primSize(
Type)), Size(ElemSize * NumElems),
249 MDSize(MD.value_or(0)),
251 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
254 assert(Source &&
"Missing source");
260 : Source(D), ElemSize(
primSize(
Type)), Size(UnknownSizeMark),
261 MDSize(MD.value_or(0)),
262 AllocSize(MDSize + sizeof(
InitMapPtr) + alignof(void *)), IsConst(
true),
263 IsMutable(
false), IsTemporary(IsTemporary), IsArray(
true),
266 assert(Source &&
"Missing source");
271 unsigned NumElems,
bool IsConst,
bool IsTemporary,
274 Size(ElemSize * NumElems), MDSize(MD.value_or(0)),
275 AllocSize(
std::
max<
size_t>(alignof(void *), Size) + MDSize),
276 ElemDesc(Elem), IsConst(IsConst), IsMutable(IsMutable),
279 assert(Source &&
"Missing source");
286 Size(UnknownSizeMark), MDSize(MD.value_or(0)),
287 AllocSize(MDSize + alignof(void *)), ElemDesc(Elem), IsConst(
true),
288 IsMutable(
false), IsTemporary(IsTemporary), IsArray(
true),
290 assert(Source &&
"Missing source");
295 bool IsConst,
bool IsTemporary,
bool IsMutable)
296 : Source(D), ElemSize(
std::
max<
size_t>(alignof(void *), R->getFullSize())),
297 Size(ElemSize), MDSize(MD.value_or(0)), AllocSize(Size + MDSize),
298 ElemRecord(R), IsConst(IsConst), IsMutable(IsMutable),
301 assert(Source &&
"Missing source");
306 : Source(D), ElemSize(1), Size(1), MDSize(0), AllocSize(MDSize),
307 ElemRecord(nullptr), IsConst(
true), IsMutable(
false), IsTemporary(
false),
309 assert(Source &&
"Missing source");
314 : Source(D), ElemSize(1), Size(UnknownSizeMark), MDSize(0),
315 AllocSize(MDSize), ElemRecord(nullptr), IsConst(
true), IsMutable(
false),
317 assert(Source &&
"Missing source");
325 if (
auto *T = dyn_cast<TypeDecl>(
asDecl()))
326 return QualType(T->getTypeForDecl(), 0);
327 llvm_unreachable(
"Invalid descriptor type");
332 const auto *AT = cast<ArrayType>(
getType());
333 return AT->getElementType();
337 if (
auto *D = Source.dyn_cast<
const Decl *>())
338 return D->getLocation();
339 if (
auto *E = Source.dyn_cast<
const Expr *>())
340 return E->getExprLoc();
341 llvm_unreachable(
"Invalid descriptor type");
345 : UninitFields(N),
Data(
std::make_unique<T[]>(numFields(N))) {
346 std::fill_n(data(), numFields(N), 0);
349bool InitMap::initializeElement(
unsigned I) {
350 unsigned Bucket = I / PER_FIELD;
351 T Mask = T(1) << (I % PER_FIELD);
352 if (!(data()[Bucket] & Mask)) {
353 data()[Bucket] |= Mask;
356 return UninitFields == 0;
359bool InitMap::isElementInitialized(
unsigned I)
const {
360 unsigned Bucket = I / PER_FIELD;
361 return data()[Bucket] & (T(1) << (I % PER_FIELD));
static void dtorTy(Block *, std::byte *Ptr, const Descriptor *)
static BlockCtorFn getCtorArrayPrim(PrimType Type)
static BlockMoveFn getMoveArrayPrim(PrimType Type)
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.
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
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.