30 reinterpret_cast<T *
>(Ptr)->~
T();
34static void moveTy(
Block *,
const std::byte *Src, std::byte *Dst,
36 const auto *SrcPtr =
reinterpret_cast<const 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();
69 *
reinterpret_cast<InitMapPtr *
>(
const_cast<std::byte *
>(Src));
73 SrcIMP = std::nullopt;
77 for (
unsigned I = 0,
NE =
D->getNumElems(); I <
NE; ++I) {
78 const auto *SrcPtr = &
reinterpret_cast<const T *
>(Src)[I];
79 auto *DstPtr = &
reinterpret_cast<T *
>(Dst)[I];
80 new (DstPtr)
T(std::move(*SrcPtr));
85 bool IsMutable,
bool IsActive,
const Descriptor *
D) {
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 if (
auto Fn =
D->ElemDesc->CtorFn)
105 Fn(B, ElemLoc, Desc->IsConst, Desc->IsFieldMutable, IsActive,
111 const unsigned NumElems =
D->getNumElems();
112 const unsigned ElemSize =
115 unsigned ElemOffset = 0;
116 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
117 auto *ElemPtr = Ptr + ElemOffset;
119 auto *ElemLoc =
reinterpret_cast<std::byte *
>(Desc + 1);
120 if (
auto Fn =
D->ElemDesc->DtorFn)
121 Fn(B, ElemLoc,
D->ElemDesc);
127 const unsigned NumElems =
D->getNumElems();
128 const unsigned ElemSize =
131 unsigned ElemOffset = 0;
132 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
133 const auto *SrcPtr = Src + ElemOffset;
134 auto *DstPtr = Dst + ElemOffset;
137 const auto *SrcElemLoc =
reinterpret_cast<const std::byte *
>(SrcDesc + 1);
139 auto *DstElemLoc =
reinterpret_cast<std::byte *
>(DstDesc + 1);
142 if (
auto Fn =
D->ElemDesc->MoveFn)
143 Fn(B, SrcElemLoc, DstElemLoc,
D->ElemDesc);
149 unsigned FieldOffset) {
151 Desc->
Offset = FieldOffset;
153 Desc->IsInitialized =
D->IsArray;
154 Desc->IsBase =
false;
155 Desc->IsActive = IsActive && !IsUnion;
156 Desc->IsConst = IsConst ||
D->IsConst;
157 Desc->IsFieldMutable = IsMutable ||
D->IsMutable;
159 if (
auto Fn =
D->CtorFn)
160 Fn(B, Ptr + FieldOffset, Desc->IsConst, Desc->IsFieldMutable,
165 bool IsActive,
const Descriptor *
D,
unsigned FieldOffset,
166 bool IsVirtualBase) {
168 assert(
D->ElemRecord);
170 bool IsUnion =
D->ElemRecord->isUnion();
172 Desc->
Offset = FieldOffset;
174 Desc->IsInitialized =
D->IsArray;
176 Desc->IsVirtualBase = IsVirtualBase;
177 Desc->IsActive = IsActive && !IsUnion;
178 Desc->IsConst = IsConst ||
D->IsConst;
179 Desc->IsFieldMutable = IsMutable ||
D->IsMutable;
181 for (
const auto &
V :
D->ElemRecord->bases())
182 initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive,
V.Desc,
184 for (
const auto &F :
D->ElemRecord->fields())
185 initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, IsUnion,
191 for (
const auto &
V :
D->ElemRecord->bases())
192 initBase(B, Ptr, IsConst, IsMutable, IsActive,
V.Desc,
V.Offset,
false);
193 for (
const auto &F :
D->ElemRecord->fields())
194 initField(B, Ptr, IsConst, IsMutable, IsActive,
D->ElemRecord->isUnion(), F.Desc, F.Offset);
195 for (
const auto &
V :
D->ElemRecord->virtual_bases())
196 initBase(B, Ptr, IsConst, IsMutable, IsActive,
V.Desc,
V.Offset,
true);
200 unsigned FieldOffset) {
201 if (
auto Fn =
D->DtorFn)
202 Fn(B, Ptr + FieldOffset,
D);
206 unsigned FieldOffset) {
208 assert(
D->ElemRecord);
210 for (
const auto &
V :
D->ElemRecord->bases())
212 for (
const auto &F :
D->ElemRecord->fields())
217 for (
const auto &F :
D->ElemRecord->bases())
219 for (
const auto &F :
D->ElemRecord->fields())
221 for (
const auto &F :
D->ElemRecord->virtual_bases())
227 for (
const auto &F :
D->ElemRecord->fields()) {
228 auto FieldOff = F.Offset;
229 auto *FieldDesc = F.Desc;
231 if (
auto Fn = FieldDesc->MoveFn)
232 Fn(B, Src + FieldOff, Dst + FieldOff, FieldDesc);
240 return ctorTy<PrimConv<PT_Float>::T>;
242 return ctorTy<PrimConv<PT_IntAP>::T>;
244 return ctorTy<PrimConv<PT_IntAPS>::T>;
246 return ctorTy<PrimConv<PT_MemberPtr>::T>;
255 return dtorTy<PrimConv<PT_Float>::T>;
257 return dtorTy<PrimConv<PT_IntAP>::T>;
259 return dtorTy<PrimConv<PT_IntAPS>::T>;
261 return dtorTy<PrimConv<PT_MemberPtr>::T>;
272 llvm_unreachable(
"unknown Expr");
277 llvm_unreachable(
"unknown Expr");
282 llvm_unreachable(
"unknown Expr");
287 bool IsConst,
bool IsTemporary,
bool IsMutable)
289 MDSize(MD.value_or(0)), AllocSize(
align(Size + MDSize)), PrimT(
Type),
290 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
293 assert(AllocSize >= Size);
294 assert(Source &&
"Missing source");
299 size_t NumElems,
bool IsConst,
bool IsTemporary,
301 : Source(
D), ElemSize(
primSize(
Type)), Size(ElemSize * NumElems),
302 MDSize(MD.value_or(0)),
304 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
307 assert(Source &&
"Missing source");
314 : Source(
D), ElemSize(
primSize(
Type)), Size(UnknownSizeMark),
315 MDSize(MD.value_or(0)),
316 AllocSize(MDSize + sizeof(
InitMapPtr) + alignof(void *)), IsConst(
true),
317 IsMutable(
false), IsTemporary(IsTemporary), IsArray(
true),
320 assert(Source &&
"Missing source");
325 unsigned NumElems,
bool IsConst,
bool IsTemporary,
328 Size(ElemSize * NumElems), MDSize(MD.value_or(0)),
329 AllocSize(
std::
max<
size_t>(alignof(void *), Size) + MDSize),
330 ElemDesc(Elem), IsConst(IsConst), IsMutable(IsMutable),
333 assert(Source &&
"Missing source");
340 Size(UnknownSizeMark), MDSize(MD.value_or(0)),
341 AllocSize(MDSize + alignof(void *)), ElemDesc(Elem), IsConst(
true),
342 IsMutable(
false), IsTemporary(IsTemporary), IsArray(
true),
344 assert(Source &&
"Missing source");
349 bool IsConst,
bool IsTemporary,
bool IsMutable)
350 : Source(
D), ElemSize(
std::
max<
size_t>(alignof(void *), R->getFullSize())),
351 Size(ElemSize), MDSize(MD.value_or(0)), AllocSize(Size + MDSize),
352 ElemRecord(R), IsConst(IsConst), IsMutable(IsMutable),
355 assert(Source &&
"Missing source");
360 : Source(
D), ElemSize(1), Size(1), MDSize(0), AllocSize(MDSize),
361 ElemRecord(nullptr), IsConst(
true), IsMutable(
false), IsTemporary(
false),
363 assert(Source &&
"Missing source");
371 if (
const auto *
T = dyn_cast<TypeDecl>(
asDecl()))
373 llvm_unreachable(
"Invalid descriptor type");
380 return AT->getElementType();
382 return CT->getElementType();
384 return CT->getElementType();
385 llvm_unreachable(
"Array that's not an array/complex/vector type?");
389 if (
auto *
D = Source.dyn_cast<
const Decl *>())
391 if (
auto *
E = Source.dyn_cast<
const Expr *>())
393 llvm_unreachable(
"Invalid descriptor type");
397 : UninitFields(N),
Data(
std::make_unique<T[]>(numFields(N))) {
398 std::fill_n(data(), numFields(N), 0);
401bool InitMap::initializeElement(
unsigned I) {
402 unsigned Bucket = I / PER_FIELD;
403 T Mask = T(1) << (I % PER_FIELD);
404 if (!(data()[Bucket] & Mask)) {
405 data()[Bucket] |= Mask;
408 return UninitFields == 0;
411bool InitMap::isElementInitialized(
unsigned I)
const {
412 unsigned Bucket = I / PER_FIELD;
413 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 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 ctorTy(Block *, std::byte *Ptr, bool, bool, bool, const Descriptor *)
static void initField(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, bool IsActive, bool IsUnion, const Descriptor *D, unsigned FieldOffset)
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 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 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)
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.
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.
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.
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.