24 NativePointerIndices.try_emplace(Ptr, NativePointers.size());
26 NativePointers.push_back(Ptr);
32 return NativePointers[Idx];
37 const size_t BitWidth = CharWidth * Ctx.getCharBit();
58 unsigned GlobalIndex = Globals.size();
60 auto *G =
new (Allocator, Sz)
Global(Ctx.getEvalID(), Desc,
true,
62 G->block()->invokeCtor();
64 new (G->block()->rawData())
70 std::memcpy(&Ptr.
elem<
char>(0), S->
getString().data(), StringLength);
73 for (
unsigned I = 0; I <= StringLength; ++I) {
74 uint32_t CodePoint = I == StringLength ? 0 : S->
getCodeUnit(I);
76 Ptr.
elem<
T>(I) = T::from(CodePoint, BitWidth););
85 assert(Idx < Globals.size());
86 return Pointer(Globals[Idx]->block());
90 if (
auto It = GlobalIndices.find(VD); It != GlobalIndices.end())
94 std::optional<unsigned> Index;
96 if (
auto It = GlobalIndices.find(P); It != GlobalIndices.end()) {
104 GlobalIndices[VD] = *Index;
110 if (
auto It = GlobalIndices.find(E); It != GlobalIndices.end())
121 GlobalIndices[VD] = *Idx;
130 if (
const auto *VD = dyn_cast_if_present<VarDecl>(dyn_cast<const Decl *>(D)))
131 D = VD->getFirstDecl();
134 if (
auto It = DummyVariables.find(D.getOpaqueValue());
135 It != DummyVariables.end())
140 if (
const auto *E = dyn_cast<const Expr *>(D)) {
144 IsWeak = VD->isWeak();
159 Desc = allocateDescriptor(D);
166 unsigned I = Globals.size();
170 false, IsWeak,
true);
171 G->block()->invokeCtor();
172 assert(G->block()->isDummy());
174 Globals.push_back(G);
175 DummyVariables[D.getOpaqueValue()] = I;
180 bool IsConstexprUnknown) {
181 bool IsStatic, IsExtern;
182 bool IsWeak = VD->
isWeak();
183 if (
const auto *Var = dyn_cast<VarDecl>(VD)) {
185 IsExtern = Var->hasExternalStorage();
198 IsWeak, IsConstexprUnknown,
Init);
202 Global *NewGlobal = Globals[*Idx];
203 GlobalIndices[VD] = *Idx;
209 if (
auto DummyIt = DummyVariables.find(Redecl);
210 DummyIt != DummyVariables.end()) {
211 Global *Dummy = Globals[DummyIt->second];
213 Globals[DummyIt->second] = NewGlobal;
214 DummyVariables.erase(DummyIt);
220 auto [Iter, Inserted] = GlobalIndices.try_emplace(Redecl);
222 GlobalIndices[Redecl] = *Idx;
226 Block *RedeclBlock = Globals[Iter->second]->block();
231 if (RedeclBlock != NewGlobal->block())
234 Globals[Iter->second] = NewGlobal;
247 GlobalIndices[E] = *Idx;
254 bool IsStatic,
bool IsExtern,
bool IsWeak,
255 bool IsConstexprUnknown,
266 const bool IsTemporary = D.dyn_cast<
const Expr *>();
270 IsTemporary,
false, IsVolatile);
273 IsTemporary,
false, IsVolatile);
280 unsigned I = Globals.size();
284 G->block()->invokeCtor();
290 Globals.push_back(G);
298 auto It = Funcs.find(F);
299 return It == Funcs.end() ?
nullptr : It->second.get();
314 auto [It, Inserted] = Records.try_emplace(RD);
319 unsigned BaseSize = 0;
321 unsigned VirtSize = 0;
324 auto GetBaseDesc = [
this](
const RecordDecl *BD,
328 return allocateDescriptor(BD, BR, std::nullopt,
false,
334 Record::BaseList Bases;
335 Record::VirtualBaseList VirtBases;
336 if (
const auto *CD = dyn_cast<CXXRecordDecl>(RD)) {
337 Bases.reserve(CD->getNumBases());
339 if (Spec.isVirtual())
343 const auto *BD = Spec.getType()->getAsCXXRecordDecl();
353 Bases.emplace_back(BD, Desc, BR, BaseSize);
358 const auto *BD = Spec.getType()->castAsCXXRecordDecl();
366 VirtBases.emplace_back(BD, Desc, BR, VirtSize);
372 Record::FieldList Fields;
374 bool HasPtrField =
false;
376 FD = FD->getFirstDecl();
387 const bool IsMutable = FD->isMutable();
392 false, IsMutable, IsVolatile);
393 HasPtrField = HasPtrField || (
T ==
PT_Ptr);
396 false, IsMutable, IsVolatile))) {
402 Desc = allocateDescriptor(FD);
404 Fields.emplace_back(FD, Desc, BaseSize);
408 Record *R =
new (Allocator)
409 Record(RD, std::move(Bases), std::move(Fields), std::move(VirtBases),
410 VirtSize, BaseSize, HasPtrField);
417 bool IsConst,
bool IsTemporary,
418 bool IsMutable,
bool IsVolatile,
423 return allocateDescriptor(D,
Record, MDSize, IsConst, IsTemporary,
424 IsMutable, IsVolatile);
425 return allocateDescriptor(D, MDSize);
432 if (
const auto *CAT = dyn_cast<ConstantArrayType>(
ArrayType)) {
433 size_t NumElems = CAT->getZExtSize();
440 return allocateDescriptor(D, CAT, *
T, MDSize, NumElems, IsConst,
441 IsTemporary, IsMutable, IsVolatile);
446 D, ElemTy.
getTypePtr(), std::nullopt, IsConst, IsTemporary);
450 if (std::numeric_limits<unsigned>::max() / ElemSize <= NumElems)
452 return allocateDescriptor(D, Ty, ElemDesc, MDSize, NumElems, IsConst,
453 IsTemporary, IsMutable);
461 return allocateDescriptor(D, *
T, MDSize, IsConst, IsTemporary,
465 D, ElemTy.
getTypePtr(), std::nullopt, IsConst, IsTemporary);
468 return allocateDescriptor(D, Desc, MDSize, IsTemporary,
475 const Type *InnerTy = AT->getValueType().getTypePtr();
482 OptPrimType ElemTy = Ctx.classify(CT->getElementType());
486 return allocateDescriptor(D, CT, *ElemTy, MDSize, 2, IsConst, IsTemporary,
487 IsMutable, IsVolatile);
492 OptPrimType ElemTy = Ctx.classify(VT->getElementType());
496 return allocateDescriptor(D, VT, *ElemTy, MDSize, VT->getNumElements(),
497 IsConst, IsTemporary, IsMutable, IsVolatile);
502 OptPrimType ElemTy = Ctx.classify(MT->getElementType());
506 return allocateDescriptor(D, MT, *ElemTy, MDSize,
507 MT->getNumElementsFlattened(), IsConst,
508 IsTemporary, IsMutable, IsVolatile);
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
llvm::MachO::Record Record
#define INT_TYPE_SWITCH_NO_BOOL(Expr, B)
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Represents a base class of a C++ class.
Complex values, per C99 6.2.5p11.
Represents a concrete matrix type with constant number of rows and columns.
Decl - This represents one declaration (or definition), e.g.
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration,...
This represents one expression.
Represents a member of a struct/union/class.
Represents a function declaration or definition.
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
bool isConstQualified() const
Determine whether this type is const-qualified.
Represents a struct/union/class.
unsigned getNumFields() const
Returns the number of fields (non-static data members) in this record.
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
unsigned getCharByteWidth() const
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
A template parameter object.
The base class of the type hierarchy.
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isPointerOrReferenceType() const
const T * getAs() const
Member-template getAs<specific type>'.
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a GCC generic vector type.
A memory block, either on the stack or in the heap.
void movePointersTo(Block *B)
Move all pointers from this block to.
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
OptPrimType classify(QualType T) const
Classifies a type.
unsigned getEvalID() const
A pointer to a memory block, live or dead.
void initializeAllElements() const
Initialize all elements of a primitive array at once.
T & elem(unsigned I) const
Dereferences the element at index I.
UnsignedOrNone createGlobal(const ValueDecl *VD, const Expr *Init, bool IsConstexprUnknown=false)
Creates a global and returns its index.
Function * getFunction(const FunctionDecl *F)
Returns a function.
Block * getGlobal(unsigned Idx)
Returns the value of a global.
UnsignedOrNone getOrCreateGlobal(const ValueDecl *VD, const Expr *Init=nullptr)
Returns or creates a global an creates an index to it.
unsigned getOrCreateNativePointer(const void *Ptr)
Marshals a native pointer to an ID for embedding in bytecode.
unsigned getOrCreateDummy(DeclTy D, bool IsConstexprUnknown=false)
Returns or creates a dummy value for unknown declarations.
Pointer getPtrGlobal(unsigned Idx) const
Returns a pointer to a global.
const void * getNativePointer(unsigned Idx) const
Returns the value of a marshalled native pointer.
Descriptor * createDescriptor(const DeclTy &D, PrimType T, const Type *SourceTy=nullptr, Descriptor::MetadataSize MDSize=std::nullopt, bool IsConst=false, bool IsTemporary=false, bool IsMutable=false, bool IsVolatile=false)
Creates a descriptor for a primitive type.
unsigned createGlobalString(const StringLiteral *S, const Expr *Base=nullptr)
Emits a string literal among global data.
UnsignedOrNone getCurrentDecl() const
Returns the current declaration ID.
Record * getOrCreateRecord(const RecordDecl *RD)
Returns a record or creates one if it does not exist.
Structure/Class descriptor.
bool hasPtrField() const
If this record (or any of its bases) contains a field of type PT_Ptr.
unsigned getSize() const
Returns the size of the record.
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool Init(InterpState &S, CodePtr OpPC)
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
OptionalUnsigned< unsigned > UnsignedOrNone
const FunctionProtoType * T
U cast(CodeGen::Address addr)
Token to denote structures of unknown size.
Describes a memory block created by an allocation site.
unsigned getAllocSize() const
Returns the allocated size, including metadata.
static constexpr MetadataSize GlobalMD
static constexpr unsigned MaxArrayElemBytes
Maximum number of bytes to be used for array elements.
std::optional< unsigned > MetadataSize
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
PrimType getPrimType() const
const Record *const ElemRecord
Pointer to the record, if block contains records.
Descriptor used for global variables.
Inline descriptor embedded in structures and arrays.