14 using namespace clang;
23 reinterpret_cast<T *
>(Ptr)->~T();
28 auto *SrcPtr =
reinterpret_cast<T *
>(Src);
29 auto *DstPtr =
reinterpret_cast<T *
>(Dst);
30 new (DstPtr) T(std::move(*SrcPtr));
36 new (&
reinterpret_cast<T *
>(Ptr)[I]) T();
43 reinterpret_cast<T *
>(Ptr)[I].~T();
50 auto *SrcPtr = &
reinterpret_cast<T *
>(Src)[I];
51 auto *DstPtr = &
reinterpret_cast<T *
>(Dst)[I];
52 new (DstPtr) T(std::move(*SrcPtr));
59 const unsigned ElemSize =
62 unsigned ElemOffset = 0;
63 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
64 auto *ElemPtr = Ptr + ElemOffset;
66 auto *ElemLoc =
reinterpret_cast<char *
>(Desc + 1);
71 Desc->IsInitialized =
true;
73 Desc->IsActive = IsActive;
75 Desc->IsMutable = IsMutable || D->
IsMutable;
77 Fn(B, ElemLoc, Desc->IsConst, Desc->IsMutable, IsActive, D->
ElemDesc);
83 const unsigned ElemSize =
86 unsigned ElemOffset = 0;
87 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
88 auto *ElemPtr = Ptr + ElemOffset;
90 auto *ElemLoc =
reinterpret_cast<char *
>(Desc + 1);
98 const unsigned ElemSize =
101 unsigned ElemOffset = 0;
102 for (
unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) {
103 auto *SrcPtr = Src + ElemOffset;
104 auto *DstPtr = Dst + ElemOffset;
107 auto *SrcElemLoc =
reinterpret_cast<char *
>(SrcDesc + 1);
109 auto *DstElemLoc =
reinterpret_cast<char *
>(DstDesc + 1);
113 Fn(B, SrcElemLoc, DstElemLoc, D->
ElemDesc);
120 auto CtorSub = [=](
unsigned SubOff,
Descriptor *F,
bool IsBase) {
124 Desc->IsInitialized = (B->
isStatic() || F->IsArray) && !IsBase;
125 Desc->IsBase = IsBase;
126 Desc->IsActive = IsActive && !IsUnion;
127 Desc->IsConst = IsConst || F->IsConst;
128 Desc->IsMutable = IsMutable || F->IsMutable;
129 if (
auto Fn = F->CtorFn)
130 Fn(B, Ptr + SubOff, Desc->IsConst, Desc->IsMutable, Desc->IsActive, F);
133 CtorSub(B.Offset, B.
Desc,
true);
135 CtorSub(F.Offset, F.Desc,
false);
137 CtorSub(
V.Offset,
V.Desc,
true);
141 auto DtorSub = [=](
unsigned SubOff,
Descriptor *F) {
142 if (
auto Fn = F->DtorFn)
143 Fn(B, Ptr + SubOff, F);
146 DtorSub(F.Offset, F.Desc);
148 DtorSub(F.Offset, F.Desc);
150 DtorSub(F.Offset, F.Desc);
155 auto FieldOff = F.Offset;
156 auto FieldDesc = F.Desc;
158 *(
reinterpret_cast<Descriptor **
>(Dst + FieldOff) - 1) = FieldDesc;
159 if (
auto Fn = FieldDesc->MoveFn)
160 Fn(B, Src + FieldOff, Dst + FieldOff, FieldDesc);
189 bool IsTemporary,
bool IsMutable)
190 : Source(D), ElemSize(
primSize(Type)), Size(ElemSize), AllocSize(Size),
191 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
194 assert(Source &&
"Missing source");
199 : Source(D), ElemSize(
primSize(Type)), Size(ElemSize * NumElems),
200 AllocSize(
align(Size) + sizeof(
InitMap *)), IsConst(IsConst),
201 IsMutable(IsMutable), IsTemporary(IsTemporary),
IsArray(
true),
204 assert(Source &&
"Missing source");
209 : Source(D), ElemSize(
primSize(Type)), Size(UnknownSizeMark),
213 assert(Source &&
"Missing source");
219 Size(ElemSize * NumElems),
221 IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
224 assert(Source &&
"Missing source");
233 assert(Source &&
"Missing source");
239 Size(ElemSize), AllocSize(Size),
ElemRecord(R), IsConst(IsConst),
242 assert(Source &&
"Missing source");
250 llvm_unreachable(
"Invalid descriptor type");
254 if (
auto *D = Source.dyn_cast<
const Decl *>())
255 return D->getLocation();
256 if (
auto *E = Source.dyn_cast<
const Expr *>())
257 return E->getExprLoc();
258 llvm_unreachable(
"Invalid descriptor type");
261 InitMap::InitMap(
unsigned N) : UninitFields(N) {
262 for (
unsigned I = 0; I < N / PER_FIELD; ++I) {
267 InitMap::T *InitMap::data() {
268 auto *Start =
reinterpret_cast<char *
>(
this) +
align(
sizeof(
InitMap));
269 return reinterpret_cast<T *
>(Start);
273 unsigned Bucket = I / PER_FIELD;
274 unsigned Mask = 1ull << static_cast<uint64_t>(I % PER_FIELD);
275 if (!(data()[Bucket] & Mask)) {
276 data()[Bucket] |= Mask;
279 return UninitFields == 0;
283 unsigned Bucket = I / PER_FIELD;
284 unsigned Mask = 1ull << static_cast<uint64_t>(I % PER_FIELD);
285 return data()[Bucket] & Mask;
289 const size_t NumFields = ((N + PER_FIELD - 1) / PER_FIELD);
290 const size_t Size =
align(
sizeof(
InitMap)) + NumFields * PER_FIELD;
291 return new (malloc(Size))
InitMap(N);
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
unsigned llvm::PointerUnion< const Decl *, const Expr * > DeclTy
A (possibly-)qualified type.
Decl - This represents one declaration (or definition), e.g.
static BlockCtorFn getCtorPrim(PrimType Type)
llvm::iterator_range< const_virtual_iter > virtual_bases() const
The base class of the type hierarchy.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Descriptor(const DeclTy &D, PrimType Type, bool IsConst, bool IsTemporary, bool IsMutable)
Allocates a descriptor for a primitive.
Descriptor * Desc
Pointer to the stack slot descriptor.
static BlockCtorFn getCtorArrayPrim(PrimType Type)
Bitfield tracking the initialisation status of elements of primitive arrays.
A memory block, either on the stack or in the heap.
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
static void dtorArrayDesc(Block *B, char *Ptr, Descriptor *D)
Token to denote structures of unknown size.
__DEVICE__ int max(int __a, int __b)
static void ctorRecord(Block *B, char *Ptr, bool IsConst, bool IsMutable, bool IsActive, Descriptor *D)
Structure/Class descriptor.
static void ctorTy(Block *, char *Ptr, bool, bool, bool, Descriptor *)
Inline descriptor embedded in structures and arrays.
PrimType
Enumeration of the primitive types of the VM.
bool isInitialized(unsigned I)
Checks if an element was initialized.
static void dtorTy(Block *, char *Ptr, Descriptor *)
const ValueDecl * asValueDecl() const
const bool IsConst
Flag indicating if the block is mutable.
Describes a memory block created by an allocation site.
static void dtorRecord(Block *B, char *Ptr, Descriptor *D)
static BlockDtorFn getDtorPrim(PrimType Type)
bool isUnion() const
Checks if the record is a union.
This represents one expression.
static void moveArrayTy(Block *, char *Src, char *Dst, Descriptor *D)
void(*)(Block *Storage, char *SrcFieldPtr, char *DstFieldPtr, Descriptor *FieldDesc) BlockMoveFn
Invoked when a block with pointers referencing it goes out of scope.
const bool IsTemporary
Flag indicating if the block is a temporary.
static void ctorArrayDesc(Block *B, char *Ptr, bool IsConst, bool IsMutable, bool IsActive, Descriptor *D)
static void moveTy(Block *, char *Src, char *Dst, Descriptor *)
const BlockCtorFn CtorFn
Storage management methods.
#define COMPOSITE_TYPE_SWITCH(Expr, B, D)
Encodes a location in the source.
unsigned getAllocSize() const
Returns the allocated size, including metadata.
const bool IsArray
Flag indicating if the block is an array.
void(*)(Block *Storage, char *FieldPtr, Descriptor *FieldDesc) BlockDtorFn
Invoked when a block is destroyed.
bool isStatic() const
Checks if the block has static storage duration.
const Expr * asExpr() const
SourceLocation getLocation() const
bool initialize(unsigned I)
Initializes an element. Returns true when object if fully initialized.
static BlockMoveFn getMovePrim(PrimType Type)
static InitMap * allocate(unsigned N)
Allocates a map holding N elements.
Dataflow Directional Tag Classes.
llvm::iterator_range< const_field_iter > fields() const
const bool IsMutable
Flag indicating if a field is mutable.
bool NE(InterpState &S, CodePtr OpPC)
void(*)(Block *Storage, char *FieldPtr, bool IsConst, bool IsMutable, bool IsActive, Descriptor *FieldDesc) BlockCtorFn
Invoked whenever a block is created.
static BlockMoveFn getMoveArrayPrim(PrimType Type)
llvm::iterator_range< const_base_iter > bases() const
static BlockDtorFn getDtorArrayPrim(PrimType Type)
Record *const ElemRecord
Pointer to the record, if block contains records.
unsigned getNumElems() const
Returns the number of elements stored in the block.
static void moveRecord(Block *B, char *Src, char *Dst, Descriptor *D)
static void moveArrayDesc(Block *B, char *Src, char *Dst, Descriptor *D)
static void dtorArrayTy(Block *, char *Ptr, Descriptor *D)
static void ctorArrayTy(Block *, char *Ptr, bool, bool, bool, Descriptor *D)
Descriptor *const ElemDesc
Descriptor of the array element.
unsigned Offset
Offset inside the structure/array.