25 reinterpret_cast<T *
>(Ptr)->~T();
30 auto *SrcPtr =
reinterpret_cast<T *
>(Src);
31 auto *DstPtr =
reinterpret_cast<T *
>(Dst);
32 new (DstPtr) T(std::move(*SrcPtr));
38 new (&
reinterpret_cast<T *
>(Ptr)[I]) T();
50 reinterpret_cast<T *
>(Ptr)[I].~T();
57 auto *SrcPtr = &
reinterpret_cast<T *
>(Src)[I];
58 auto *DstPtr = &
reinterpret_cast<T *
>(Dst)[I];
59 new (DstPtr) T(std::move(*SrcPtr));
66 const unsigned ElemSize =
69 unsigned ElemOffset = 0;
70 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
71 auto *ElemPtr = Ptr + ElemOffset;
73 auto *ElemLoc =
reinterpret_cast<char *
>(Desc + 1);
78 Desc->IsInitialized =
true;
80 Desc->IsActive = IsActive;
82 Desc->IsFieldMutable = IsMutable || D->
IsMutable;
84 Fn(B, ElemLoc, Desc->IsConst, Desc->IsFieldMutable, IsActive,
91 const unsigned ElemSize =
94 unsigned ElemOffset = 0;
95 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
96 auto *ElemPtr = Ptr + ElemOffset;
98 auto *ElemLoc =
reinterpret_cast<char *
>(Desc + 1);
106 const unsigned ElemSize =
109 unsigned ElemOffset = 0;
110 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
111 auto *SrcPtr = Src + ElemOffset;
112 auto *DstPtr = Dst + ElemOffset;
115 auto *SrcElemLoc =
reinterpret_cast<char *
>(SrcDesc + 1);
117 auto *DstElemLoc =
reinterpret_cast<char *
>(DstDesc + 1);
121 Fn(B, SrcElemLoc, DstElemLoc, D->
ElemDesc);
128 auto CtorSub = [=](
unsigned SubOff,
Descriptor *F,
bool IsBase) {
132 Desc->IsInitialized = F->IsArray && !IsBase;
133 Desc->IsBase = IsBase;
134 Desc->IsActive = IsActive && !IsUnion;
135 Desc->IsConst = IsConst || F->IsConst;
136 Desc->IsFieldMutable = IsMutable || F->IsMutable;
137 if (
auto Fn = F->CtorFn)
138 Fn(B, Ptr + SubOff, Desc->IsConst, Desc->IsFieldMutable, Desc->IsActive,
142 CtorSub(B.Offset, B.
Desc,
true);
144 CtorSub(F.Offset, F.Desc,
false);
146 CtorSub(
V.Offset,
V.Desc,
true);
150 auto DtorSub = [=](
unsigned SubOff,
Descriptor *F) {
151 if (
auto Fn = F->DtorFn)
152 Fn(B, Ptr + SubOff, F);
155 DtorSub(F.Offset, F.Desc);
157 DtorSub(F.Offset, F.Desc);
159 DtorSub(F.Offset, F.Desc);
164 auto FieldOff = F.Offset;
165 auto FieldDesc = F.Desc;
167 *(
reinterpret_cast<Descriptor **
>(Dst + FieldOff) - 1) = FieldDesc;
168 if (
auto Fn = FieldDesc->MoveFn)
169 Fn(B, Src + FieldOff, Dst + FieldOff, FieldDesc);
177 return ctorTy<PrimConv<PT_Float>::T>;
196 llvm_unreachable(
"unknown Expr");
204 bool IsConst,
bool IsTemporary,
bool IsMutable)
206 MDSize(MD.value_or(0)), AllocSize(
align(Size + MDSize)), IsConst(IsConst),
207 IsMutable(IsMutable), IsTemporary(IsTemporary), CtorFn(
getCtorPrim(
Type)),
209 assert(AllocSize >= Size);
210 assert(Source &&
"Missing source");
214 size_t NumElems,
bool IsConst,
bool IsTemporary,
216 : Source(D), ElemSize(
primSize(
Type)), Size(ElemSize * NumElems),
217 MDSize(MD.value_or(0)),
218 AllocSize(
align(Size) + sizeof(
InitMap *) + MDSize), IsConst(IsConst),
219 IsMutable(IsMutable), IsTemporary(IsTemporary), IsArray(
true),
222 assert(Source &&
"Missing source");
227 : Source(D), ElemSize(
primSize(
Type)), Size(UnknownSizeMark), MDSize(0),
231 assert(Source &&
"Missing source");
235 unsigned NumElems,
bool IsConst,
bool IsTemporary,
238 Size(ElemSize * NumElems), MDSize(MD.value_or(0)),
240 ElemDesc(Elem), IsConst(IsConst), IsMutable(IsMutable),
243 assert(Source &&
"Missing source");
249 Size(UnknownSizeMark), MDSize(0), AllocSize(
alignof(void *)),
250 ElemDesc(Elem), IsConst(
true), IsMutable(
false), IsTemporary(IsTemporary),
253 assert(Source &&
"Missing source");
257 bool IsConst,
bool IsTemporary,
bool IsMutable)
259 Size(ElemSize), MDSize(MD.value_or(0)), AllocSize(Size + MDSize),
260 ElemRecord(R), IsConst(IsConst), IsMutable(IsMutable),
263 assert(Source &&
"Missing source");
271 llvm_unreachable(
"Invalid descriptor type");
275 if (
auto *D = Source.dyn_cast<
const Decl *>())
276 return D->getLocation();
277 if (
auto *E = Source.dyn_cast<
const Expr *>())
278 return E->getExprLoc();
279 llvm_unreachable(
"Invalid descriptor type");
282InitMap::InitMap(
unsigned N) : UninitFields(N) {
283 std::fill_n(data(), (N + PER_FIELD - 1) / PER_FIELD, 0);
286InitMap::T *InitMap::data() {
287 auto *Start =
reinterpret_cast<char *
>(
this) +
align(
sizeof(
InitMap));
288 return reinterpret_cast<T *
>(Start);
291const InitMap::T *InitMap::data()
const {
292 auto *Start =
reinterpret_cast<const char *
>(
this) +
align(
sizeof(
InitMap));
293 return reinterpret_cast<const T *
>(Start);
297 unsigned Bucket = I / PER_FIELD;
298 T Mask = T(1) << (I % PER_FIELD);
299 if (!(data()[Bucket] & Mask)) {
300 data()[Bucket] |= Mask;
303 return UninitFields == 0;
307 unsigned Bucket = I / PER_FIELD;
308 return data()[Bucket] & (T(1) << (I % PER_FIELD));
312 const size_t NumFields = ((N + PER_FIELD - 1) / PER_FIELD);
313 const size_t Size =
align(
sizeof(
InitMap)) + NumFields * PER_FIELD;
314 return new (malloc(Size))
InitMap(N);
static void ctorArrayTy(Block *, char *Ptr, bool, bool, bool, Descriptor *D)
static BlockCtorFn getCtorArrayPrim(PrimType Type)
static BlockMoveFn getMoveArrayPrim(PrimType Type)
static void ctorTy(Block *, char *Ptr, bool, bool, bool, Descriptor *)
static BlockMoveFn getMovePrim(PrimType Type)
static void ctorArrayDesc(Block *B, char *Ptr, bool IsConst, bool IsMutable, bool IsActive, Descriptor *D)
static void moveTy(Block *, char *Src, char *Dst, Descriptor *)
static void moveRecord(Block *B, char *Src, char *Dst, Descriptor *D)
static void dtorRecord(Block *B, char *Ptr, Descriptor *D)
static void dtorTy(Block *, char *Ptr, Descriptor *)
static BlockDtorFn getDtorPrim(PrimType Type)
static BlockCtorFn getCtorPrim(PrimType Type)
static BlockDtorFn getDtorArrayPrim(PrimType Type)
static void ctorRecord(Block *B, char *Ptr, bool IsConst, bool IsMutable, bool IsActive, Descriptor *D)
static void moveArrayTy(Block *, char *Src, char *Dst, Descriptor *D)
static void dtorArrayDesc(Block *B, char *Ptr, Descriptor *D)
static void moveArrayDesc(Block *B, char *Src, char *Dst, Descriptor *D)
static void dtorArrayTy(Block *, char *Ptr, 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.
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
void(*)(Block *Storage, char *FieldPtr, bool IsConst, bool IsMutable, bool IsActive, Descriptor *FieldDesc) BlockCtorFn
Invoked whenever a block is created.
bool NE(InterpState &S, CodePtr OpPC)
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, char *SrcFieldPtr, char *DstFieldPtr, Descriptor *FieldDesc) BlockMoveFn
Invoked when a block with pointers referencing it goes out of scope.
void(*)(Block *Storage, char *FieldPtr, Descriptor *FieldDesc) BlockDtorFn
Invoked when a block is destroyed.
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
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.
const ValueDecl * asValueDecl() const
const BlockCtorFn CtorFn
Storage management methods.
SourceLocation getLocation() const
const bool IsMutable
Flag indicating if a field is mutable.
std::optional< unsigned > MetadataSize
Descriptor *const ElemDesc
Descriptor of the array element.
Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD, bool IsConst, bool IsTemporary, bool IsMutable)
Allocates a descriptor for a primitive.
const Expr * asExpr() const
Record *const ElemRecord
Pointer to the record, if block contains records.
Bitfield tracking the initialisation status of elements of primitive arrays.
static InitMap * allocate(unsigned N)
Allocates a map holding N elements.
bool isInitialized(unsigned I) const
Checks if an element was initialized.
bool initialize(unsigned I)
Initializes an element. Returns true when object if fully initialized.
Inline descriptor embedded in structures and arrays.
unsigned Offset
Offset inside the structure/array.