13#ifndef LLVM_CLANG_AST_INTERP_POINTER_H
14#define LLVM_CLANG_AST_INTERP_POINTER_H
24#include "llvm/Support/raw_ostream.h"
61 return Base ==
Pointee->getDescriptor()->getMetadataSize();
76 assert(
Offset != 0 &&
"Not a nested pointer");
83 return Pointee->getDescriptor();
136 (
Next ==
Pointee->getDescriptor()->getMetadataSize())
146 while (
V.isBaseClass())
152 assert(
Offset !=
Base &&
"not an array element");
159 return ElemDesc ? ElemDesc->
ElemRecord :
nullptr;
236 assert(
isLive() &&
"Invalid pointer");
240 return *
reinterpret_cast<T *
>(
Pointee->rawData() +
Base +
246 template <
typename T>
T &
elem(
unsigned I)
const {
247 assert(
isLive() &&
"Invalid pointer");
254 assert(ReadOffset +
sizeof(
T) <=
Pointee->getDescriptor()->getAllocSize());
256 return *
reinterpret_cast<T *
>(
Pointee->rawData() + ReadOffset);
265 unsigned F = this->Offset +
Offset;
275 return VD->getType();
282 return AT->getElementType();
284 return CT->getElementType();
286 return CT->getElementType();
298 assert(
Pointee &&
"Cannot check if null pointer was initialized");
347 std::optional<IntPointer>
atOffset(
const Context &Ctx,
unsigned Offset)
const;
417 : Offset(Offset), StorageKind(
Storage::
Fn),
Fn{F} {}
421 Typeid.TypeInfoType = TypeInfoType;
433 if (P.StorageKind != StorageKind)
440 return P.
Fn.
Func ==
Fn.Func && P.Offset == Offset;
457 return reinterpret_cast<uint64_t
>(
Fn.Func) + Offset;
458 return reinterpret_cast<uint64_t
>(
BS.Pointee) + Offset;
488 assert(Offset >=
Off);
489 unsigned O = Offset -
Off;
509 switch (StorageKind) {
511 return Int.Value == 0 && Offset == 0;
513 return BS.Pointee ==
nullptr;
519 llvm_unreachable(
"Unknown clang::interp::Storage enum");
542 return BS.Pointee->Desc;
554 llvm_unreachable(
"Unsupported pointer type in getSource()");
570 return getInlineDesc()->Desc;
575 switch (StorageKind) {
577 return Int.getPointeeType();
581 return Fn.Func->getDecl()->getType();
585 llvm_unreachable(
"Unhandled StorageKind");
659 return BS.Pointee &&
BS.Base > 0;
695 return FD->asFieldDecl();
702 return BS.Pointee &&
BS.Pointee->isExtern();
710 return BS.Pointee->isStatic();
716 return BS.Pointee->isTemporary();
724 return BS.Pointee->isDynamic();
740 if (!
Fn.Func || !
Fn.Func->getDecl())
743 return Fn.Func->getDecl()->isWeak();
749 return BS.Pointee->isWeak();
777 return isRoot() ?
false : getInlineDesc()->IsConstInMutable;
791 return BS.Pointee->getDeclID();
799 return Int.Value + Offset;
820 return BS.Pointee->rawData() + Offset;
850 return !
isZero() && Offset >
BS.Pointee->getSize();
861 return Desc->isZeroSizeArray();
868 return (FieldDesc->isPrimitive() || FieldDesc->isPrimitiveArray()) &&
869 FieldDesc->getPrimType() ==
T;
876 assert(
isLive() &&
"Invalid pointer");
880 assert(Offset +
sizeof(
T) <=
BS.Pointee->getDescriptor()->getAllocSize());
887 template <
typename T>
T &
elem(
unsigned I)
const {
888 assert(
isLive() &&
"Invalid pointer");
991 if (Offset <
Other.Offset)
993 if (Offset >
Other.Offset)
1006 static std::optional<std::pair<PtrView, PtrView>>
1018 return dyn_cast_if_present<AddrLabelExpr>(Desc->asExpr());
1023 void print(llvm::raw_ostream &OS)
const;
1028 std::optional<size_t>
1046 assert(
BS.Base <=
BS.Pointee->getSize());
1048 return getDescriptor(
BS.Base);
1053 assert(Offset != 0 &&
"Not a nested pointer");
1060 InitMapPtr &getInitMap()
const {
1067 uint64_t Offset = 0;
1088 OS <<
" one-past-the-end";
1091 std::string Indices;
1092 llvm::raw_string_ostream SS(Indices);
1098 std::reverse(Indices.begin(), Indices.end());
1109 OS <<
" base-class";
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
AddrLabelExpr - The GNU address of label extension, representing &&label.
QualType getElementType() const
Represents a member of a struct/union/class.
A (possibly-)qualified type.
QualType IgnoreParens() const
Returns the specified type after dropping any outer-level parentheses.
Encodes a location in the source.
The base class of the type hierarchy.
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
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
A memory block, either on the stack or in the heap.
Holds all information required to evaluate constexpr code in a module.
Descriptor for a dead block.
const FunctionDecl * getDecl() const
Returns the original FunctionDecl.
A pointer to a memory block, live or dead.
static bool hasSameBase(const Pointer &A, const Pointer &B)
Checks if two pointers are comparable.
Pointer narrow() const
Restricts the scope of an array element pointer.
UnsignedOrNone getDeclID() const
Returns the declaration ID.
Pointer stripBaseCasts() const
Strip base casts from this Pointer.
bool isVolatile() const
Checks if an object or a subfield is volatile.
bool isInitialized() const
Checks if an object was initialized.
bool pointsToLabel() const
Whether this points to a block created for an AddrLabelExpr.
bool isStatic() const
Checks if the storage is static.
bool isDynamic() const
Checks if the storage has been dynamically allocated.
const VarDecl * getRootVarDecl() const
bool isZeroSizeArray() const
Checks if the pointer is pointing to a zero-size array.
bool allElementsInitialized() const
Pointer atIndex(uint64_t Idx) const
Offsets a pointer inside an array.
bool isDummy() const
Checks if the pointer points to a dummy value.
const AddrLabelExpr * getPointedToLabel() const
Returns the AddrLabelExpr the Pointer points to, if any.
Pointer atFieldSub(unsigned Off) const
Subtract the given offset from the current Base and Offset of the pointer.
bool inPrimitiveArray() const
Checks if the structure is a primitive array.
void print(llvm::raw_ostream &OS) const
Prints the pointer.
bool isExtern() const
Checks if the storage is extern.
int64_t getIndex() const
Returns the index into an array.
friend class MemberPointer
bool isActive() const
Checks if the object is active.
bool canDeref(PrimType T) const
Checks whether the pointer can be dereferenced to the given PrimType.
bool isConst() const
Checks if an object or a subfield is mutable.
Pointer(uint64_t Address, const Type *Ty, uint64_t Offset=0)
Pointer atField(unsigned Off) const
Creates a pointer to a field.
T & deref() const
Dereferences the pointer, if it's live.
Pointer(IntPointer &&IntPtr)
bool isMutable() const
Checks if the field is mutable.
bool isConstInMutable() const
DeclTy getSource() const
Returns the expression or declaration the pointer has been created for.
unsigned getNumElems() const
Returns the number of elements.
Pointer getArray() const
Returns the parent array.
bool isUnknownSizeArray() const
Checks if the structure is an array of unknown size.
const TypeidPointer & asTypeidPointer() const
bool isIntegralPointer() const
QualType getType() const
Returns the type of the innermost field.
bool operator==(const Pointer &P) const
Equality operators are just for tests.
bool isArrayElement() const
Checks if the pointer points to an array.
void initializeAllElements() const
Initialize all elements of a primitive array at once.
bool pointsToStringLiteral() const
void initialize() const
Initializes a field.
std::optional< size_t > computeOffsetForComparison(const ASTContext &ASTCtx) const
Compute an integer that can be used to compare this pointer to another one.
bool isArrayRoot() const
Whether this array refers to an array, but not to the first element.
bool isLive() const
Checks if the pointer is live.
static bool elemsOfSameArray(const Pointer &A, const Pointer &B)
Checks if two pointers can be subtracted.
bool inArray() const
Checks if the innermost field is an array.
bool isElementAlive(unsigned Index) const
bool isStaticTemporary() const
Checks if the storage is a static temporary.
Pointer(const Type *TypePtr, const Type *TypeInfoType, uint64_t Offset=0)
T & elem(unsigned I) const
Dereferences the element at index I.
bool pointsToLiteral() const
Whether this points to a block that's been created for a "literal lvalue", i.e.
std::optional< size_t > computeLayoutOffset(const ASTContext &ASTCtx) const
Compute the pointer offset as given by the ASTRecordLayout.
bool allElementsAlive() const
Pointer getBase() const
Returns a pointer to the object of which this pointer is a field.
uint64_t getByteOffset() const
Returns the byte offset from the start.
bool isTypeidPointer() const
std::string toDiagnosticString(const ASTContext &Ctx) const
Converts the pointer to a string usable in diagnostics.
bool isZero() const
Checks if the pointer is null.
Pointer & operator=(const Pointer &P)
ComparisonCategoryResult compare(const Pointer &Other) const
Compare two pointers.
bool isConstexprUnknown() const
const IntPointer & asIntPointer() const
bool isRoot() const
Pointer points directly to a block.
const Descriptor * getDeclDesc() const
Accessor for information about the declaration site.
void activate() const
Activates a field.
const Record * getElemRecord() const
Returns the element record type, if this is a non-primive array.
static bool pointToSameBlock(const Pointer &A, const Pointer &B)
Checks if both given pointers point to the same block.
APValue toAPValue(const ASTContext &ASTCtx) const
Converts the pointer to an APValue.
unsigned getOffset() const
Returns the offset into an array.
friend class DynamicAllocator
void endLifetime() const
Ends the lifetime of the pointer.
void setLifeState(Lifetime L) const
bool isOnePastEnd() const
Checks if the index is one past end.
uint64_t getIntegerRepresentation() const
bool isPastEnd() const
Checks if the pointer points past the end of the object.
Pointer(const Function *F, uint64_t Offset=0)
const FieldDecl * getField() const
Returns the field information.
Pointer expand() const
Expands a pointer to the containing array, undoing narrowing.
bool isElementPastEnd() const
Checks if the pointer is an out-of-bounds element pointer.
bool isDereferencable() const
Whether this block can be read from at all.
void startLifetime() const
Start the lifetime of this pointer.
bool isBlockPointer() const
bool operator!=(const Pointer &P) const
void deactivate() const
Deactivates an entire strurcutre.
std::optional< APValue > toRValue(const Context &Ctx, QualType ResultType) const
Converts the pointer to an APValue that is an rvalue.
size_t getSize() const
Returns the total size of the innermost field.
bool isTemporary() const
Checks if the storage is temporary.
const FunctionPointer & asFunctionPointer() const
SourceLocation getDeclLoc() const
const Block * block() const
void initializeElement(unsigned Index) const
Initialized the given element of a primitive array.
bool isFunctionPointer() const
Pointer getDeclPtr() const
const Descriptor * getFieldDesc() const
Accessors for information about the innermost field.
bool isVirtualBaseClass() const
bool isBaseClass() const
Checks if a structure is a base class.
size_t elemSize() const
Returns the element size of the innermost field.
bool canBeInitialized() const
If this pointer has an InlineDescriptor we can use to initialize.
Lifetime getLifetime() const
const BlockPointer & asBlockPointer() const
const std::byte * getRawAddress() const
If backed by actual data (i.e.
bool isField() const
Checks if the item is a field in an object.
static std::optional< std::pair< PtrView, PtrView > > computeSplitPoint(const Pointer &A, const Pointer &B)
bool isElementInitialized(unsigned Index) const
Like isInitialized(), but for primitive arrays.
const Record * getRecord() const
Returns the record descriptor of a class.
Structure/Class descriptor.
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
@ Address
A pointer to a ValueDecl.
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const Boolean &B)
PrimType
Enumeration of the primitive types of the VM.
The JSON file list parser is used to communicate input to InstallAPI.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
OptionalUnsigned< unsigned > UnsignedOrNone
const FunctionProtoType * T
@ Off
Never emit colors regardless of the output stream.
@ Other
Other implicit parameter.
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Pointer * Prev
Previous link in the pointer chain.
Pointer * Next
Next link in the pointer chain.
unsigned Base
Start of the current subfield.
Block * Pointee
The block the pointer is pointing to.
Describes a memory block created by an allocation site.
const bool IsConst
Flag indicating if the block is mutable.
unsigned getSize() const
Returns the size of the object without metadata.
const DeclTy & getSource() const
const Decl * asDecl() const
const Descriptor *const ElemDesc
Descriptor of the array element.
SourceLocation getLocation() const
bool isUnknownSizeArray() const
Checks if the descriptor is of an array of unknown size.
unsigned getElemSize() const
returns the size of an element when the structure is viewed as an array.
const bool IsArray
Flag indicating if the block is an array.
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
bool isZeroSizeArray() const
Checks if the descriptor is of an array of zero size.
const FieldDecl * asFieldDecl() const
const Record *const ElemRecord
Pointer to the record, if block contains records.
Descriptor used for global variables.
GlobalInitState InitState
A pointer-sized struct we use to allocate into data storage.
Inline descriptor embedded in structures and arrays.
unsigned IsActive
Flag indicating if the field is the active member of a union.
unsigned IsBase
Flag indicating if the field is an embedded base class.
unsigned IsVirtualBase
Flag inidcating if the field is a virtual base class.
unsigned InUnion
Flag indicating if this field is in a union (even if nested).
unsigned Offset
Offset inside the structure/array.
unsigned IsInitialized
For primitive fields, it indicates if the field was initialized.
unsigned IsConst
Flag indicating if the storage is constant or not.
unsigned IsFieldMutable
Flag indicating if the field is mutable (if in a record).
QualType getPointeeType() const
IntPointer baseCast(const Context &Ctx, unsigned BaseOffset) const
std::optional< IntPointer > atOffset(const Context &Ctx, unsigned Offset) const
bool isUnknownSizeArray() const
const Descriptor * getDeclDesc() const
bool allElementsInitialized() const
PtrView atField(unsigned Offset) const
const Record * getRecord() const
const Descriptor * getFieldDesc() const
const FieldDecl * getField() const
bool isElementInitialized(unsigned Index) const
static constexpr unsigned PastEndMark
PtrView atIndex(unsigned Idx) const
bool inPrimitiveArray() const
InlineDescriptor * getDescriptor(unsigned Offset) const
void startLifetime() const
T & elem(unsigned I) const
bool isElementPastEnd() const
const Block * block() const
bool isInitialized() const
bool isArrayElement() const
const Record * getElemRecord() const
unsigned getNumElems() const
InitMapPtr & getInitMap() const
InlineDescriptor * getInlineDesc() const
void initializeElement(unsigned Index) const
bool operator==(const PtrView &Other) const
bool isOnePastEnd() const
void setLifeState(Lifetime L) const
Lifetime getLifetime() const
unsigned getOffset() const
bool isVirtualBaseClass() const
bool isZeroSizeArray() const
bool operator!=(const PtrView &Other) const
PtrView stripBaseCasts() const
const Type * TypeInfoType