18 using namespace clang;
29 reinterpret_cast<T *
>(Ptr)->~
T();
33 static 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);
140 bool IsActive,
bool IsUnion,
const Descriptor *D,
141 unsigned FieldOffset) {
143 Desc->
Offset = FieldOffset;
145 Desc->IsInitialized = D->
IsArray;
146 Desc->IsBase =
false;
147 Desc->IsActive = IsActive && !IsUnion;
148 Desc->IsConst = IsConst || D->
IsConst;
149 Desc->IsFieldMutable = IsMutable || D->
IsMutable;
152 Fn(B, Ptr + FieldOffset, Desc->IsConst, Desc->IsFieldMutable,
156 static void initBase(
Block *B, std::byte *Ptr,
bool IsConst,
bool IsMutable,
157 bool IsActive,
const Descriptor *D,
unsigned FieldOffset,
158 bool IsVirtualBase) {
164 Desc->
Offset = FieldOffset;
166 Desc->IsInitialized = D->
IsArray;
168 Desc->IsActive = IsActive && !IsUnion;
169 Desc->IsConst = IsConst || D->
IsConst;
170 Desc->IsFieldMutable = IsMutable || D->
IsMutable;
173 initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive,
V.Desc,
176 initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, IsUnion, F.Desc,
186 initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive,
V.Desc,
193 initBase(B, Ptr, IsConst, IsMutable, IsActive,
V.Desc,
V.Offset,
false);
197 initBase(B, Ptr, IsConst, IsMutable, IsActive,
V.Desc,
V.Offset,
true);
201 auto DtorSub = [=](
unsigned SubOff,
const Descriptor *F) {
202 if (
auto Fn = F->DtorFn)
203 Fn(B, Ptr + SubOff, F);
206 DtorSub(F.Offset, F.Desc);
208 DtorSub(F.Offset, F.Desc);
210 DtorSub(F.Offset, F.Desc);
216 auto FieldOff = F.Offset;
217 auto *FieldDesc = F.Desc;
219 if (
auto Fn = FieldDesc->MoveFn)
220 Fn(B, Src + FieldOff, Dst + FieldOff, FieldDesc);
256 llvm_unreachable(
"unknown Expr");
261 llvm_unreachable(
"unknown Expr");
266 llvm_unreachable(
"unknown Expr");
271 bool IsConst,
bool IsTemporary,
bool IsMutable)
273 MDSize(MD.value_or(0)), AllocSize(
align(Size + MDSize)), PrimT(
Type),
274 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
277 assert(AllocSize >= Size);
278 assert(Source &&
"Missing source");
283 size_t NumElems,
bool IsConst,
bool IsTemporary,
285 : Source(D), ElemSize(
primSize(
Type)), Size(ElemSize * NumElems),
286 MDSize(MD.value_or(0)),
288 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
291 assert(Source &&
"Missing source");
297 : Source(D), ElemSize(
primSize(
Type)), Size(UnknownSizeMark),
298 MDSize(MD.value_or(0)),
299 AllocSize(MDSize + sizeof(
InitMapPtr) + alignof(void *)), IsConst(
true),
300 IsMutable(
false), IsTemporary(IsTemporary), IsArray(
true),
303 assert(Source &&
"Missing source");
308 unsigned NumElems,
bool IsConst,
bool IsTemporary,
311 Size(ElemSize * NumElems), MDSize(MD.value_or(0)),
312 AllocSize(
std::
max<
size_t>(alignof(void *), Size) + MDSize),
313 ElemDesc(Elem), IsConst(IsConst), IsMutable(IsMutable),
316 assert(Source &&
"Missing source");
323 Size(UnknownSizeMark), MDSize(MD.value_or(0)),
324 AllocSize(MDSize + alignof(void *)), ElemDesc(Elem), IsConst(
true),
325 IsMutable(
false), IsTemporary(IsTemporary), IsArray(
true),
327 assert(Source &&
"Missing source");
332 bool IsConst,
bool IsTemporary,
bool IsMutable)
333 : Source(D), ElemSize(
std::
max<
size_t>(alignof(void *), R->getFullSize())),
334 Size(ElemSize), MDSize(MD.value_or(0)), AllocSize(Size + MDSize),
335 ElemRecord(R), IsConst(IsConst), IsMutable(IsMutable),
338 assert(Source &&
"Missing source");
343 : Source(D), ElemSize(1), Size(1), MDSize(0), AllocSize(MDSize),
344 ElemRecord(nullptr), IsConst(
true), IsMutable(
false), IsTemporary(
false),
346 assert(Source &&
"Missing source");
354 if (
auto *
T = dyn_cast<TypeDecl>(
asDecl()))
356 llvm_unreachable(
"Invalid descriptor type");
361 const auto *AT = cast<ArrayType>(
getType());
362 return AT->getElementType();
366 if (
auto *D = Source.dyn_cast<
const Decl *>())
367 return D->getLocation();
368 if (
auto *E = Source.dyn_cast<
const Expr *>())
369 return E->getExprLoc();
370 llvm_unreachable(
"Invalid descriptor type");
374 : UninitFields(N),
Data(
std::make_unique<T[]>(numFields(N))) {
375 std::fill_n(data(), numFields(N), 0);
378 bool InitMap::initializeElement(
unsigned I) {
379 unsigned Bucket = I / PER_FIELD;
380 T Mask = T(1) << (I % PER_FIELD);
381 if (!(data()[Bucket] & Mask)) {
382 data()[Bucket] |= Mask;
385 return UninitFields == 0;
388 bool InitMap::isElementInitialized(
unsigned I)
const {
389 unsigned Bucket = I / PER_FIELD;
390 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 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 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.
Structure/Class descriptor.
bool isUnion() const
Checks if the record is a union.
llvm::iterator_range< const_base_iter > bases() const
llvm::iterator_range< const_field_iter > fields() const
llvm::iterator_range< const_virtual_iter > virtual_bases() 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.
unsigned llvm::PointerUnion< const Decl *, const Expr * > DeclTy
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.
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 Expr * asExpr() 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.
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.