diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/Interp/Descriptor.h')
-rw-r--r-- | contrib/llvm-project/clang/lib/AST/Interp/Descriptor.h | 66 |
1 files changed, 61 insertions, 5 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/Interp/Descriptor.h b/contrib/llvm-project/clang/lib/AST/Interp/Descriptor.h index 580c200f9095..0cc5d77c407e 100644 --- a/contrib/llvm-project/clang/lib/AST/Interp/Descriptor.h +++ b/contrib/llvm-project/clang/lib/AST/Interp/Descriptor.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_AST_INTERP_DESCRIPTOR_H #define LLVM_CLANG_AST_INTERP_DESCRIPTOR_H +#include "PrimType.h" #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" @@ -47,6 +48,18 @@ using BlockMoveFn = void (*)(Block *Storage, const std::byte *SrcFieldPtr, std::byte *DstFieldPtr, const Descriptor *FieldDesc); +enum class GlobalInitState { + Initialized, + NoInitializer, + InitializerFailed, +}; + +/// Descriptor used for global variables. +struct alignas(void *) GlobalInlineDescriptor { + GlobalInitState InitState = GlobalInitState::InitializerFailed; +}; +static_assert(sizeof(GlobalInlineDescriptor) == sizeof(void *), ""); + /// Inline descriptor embedded in structures and arrays. /// /// Such descriptors precede all composite array elements and structure fields. @@ -59,21 +72,36 @@ struct InlineDescriptor { /// Flag indicating if the storage is constant or not. /// Relevant for primitive fields. + LLVM_PREFERRED_TYPE(bool) unsigned IsConst : 1; /// For primitive fields, it indicates if the field was initialized. /// Primitive fields in static storage are always initialized. /// Arrays are always initialized, even though their elements might not be. /// Base classes are initialized after the constructor is invoked. + LLVM_PREFERRED_TYPE(bool) unsigned IsInitialized : 1; /// Flag indicating if the field is an embedded base class. + LLVM_PREFERRED_TYPE(bool) unsigned IsBase : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned IsVirtualBase : 1; /// Flag indicating if the field is the active member of a union. + LLVM_PREFERRED_TYPE(bool) unsigned IsActive : 1; /// Flag indicating if the field is mutable (if in a record). + LLVM_PREFERRED_TYPE(bool) unsigned IsFieldMutable : 1; const Descriptor *Desc; + + InlineDescriptor(const Descriptor *D) + : Offset(sizeof(InlineDescriptor)), IsConst(false), IsInitialized(false), + IsBase(false), IsActive(false), IsFieldMutable(false), Desc(D) {} + + void dump() const { dump(llvm::errs()); } + void dump(llvm::raw_ostream &OS) const; }; +static_assert(sizeof(GlobalInlineDescriptor) != sizeof(InlineDescriptor), ""); /// Describes a memory block created by an allocation site. struct Descriptor final { @@ -98,11 +126,21 @@ public: using MetadataSize = std::optional<unsigned>; static constexpr MetadataSize InlineDescMD = sizeof(InlineDescriptor); + static constexpr MetadataSize GlobalMD = sizeof(GlobalInlineDescriptor); + + /// Maximum number of bytes to be used for array elements. + static constexpr unsigned MaxArrayElemBytes = + std::numeric_limits<decltype(AllocSize)>::max() - sizeof(InitMapPtr) - + align(std::max(*InlineDescMD, *GlobalMD)); /// Pointer to the record, if block contains records. const Record *const ElemRecord = nullptr; /// Descriptor of the array element. const Descriptor *const ElemDesc = nullptr; + /// The primitive type this descriptor was created for, + /// or the primitive element type in case this is + /// a primitive array. + const std::optional<PrimType> PrimT = std::nullopt; /// Flag indicating if the block is mutable. const bool IsConst = false; /// Flag indicating if a field is mutable. @@ -112,7 +150,7 @@ public: /// Flag indicating if the block is an array. const bool IsArray = false; /// Flag indicating if this is a dummy descriptor. - const bool IsDummy = false; + bool IsDummy = false; /// Storage management methods. const BlockCtorFn CtorFn = nullptr; @@ -128,21 +166,26 @@ public: bool IsConst, bool IsTemporary, bool IsMutable); /// Allocates a descriptor for an array of primitives of unknown size. - Descriptor(const DeclTy &D, PrimType Type, bool IsTemporary, UnknownSize); + Descriptor(const DeclTy &D, PrimType Type, MetadataSize MDSize, + bool IsTemporary, UnknownSize); /// Allocates a descriptor for an array of composites. Descriptor(const DeclTy &D, const Descriptor *Elem, MetadataSize MD, unsigned NumElems, bool IsConst, bool IsTemporary, bool IsMutable); /// Allocates a descriptor for an array of composites of unknown size. - Descriptor(const DeclTy &D, const Descriptor *Elem, bool IsTemporary, - UnknownSize); + Descriptor(const DeclTy &D, const Descriptor *Elem, MetadataSize MD, + bool IsTemporary, UnknownSize); /// Allocates a descriptor for a record. Descriptor(const DeclTy &D, const Record *R, MetadataSize MD, bool IsConst, bool IsTemporary, bool IsMutable); - Descriptor(const DeclTy &D, MetadataSize MD); + /// Allocates a dummy descriptor. + Descriptor(const DeclTy &D); + + /// Make this descriptor a dummy descriptor. + void makeDummy() { IsDummy = true; } QualType getType() const; QualType getElemQualType() const; @@ -150,11 +193,16 @@ public: const Decl *asDecl() const { return Source.dyn_cast<const Decl *>(); } const Expr *asExpr() const { return Source.dyn_cast<const Expr *>(); } + const DeclTy &getSource() const { return Source; } const ValueDecl *asValueDecl() const { return dyn_cast_if_present<ValueDecl>(asDecl()); } + const VarDecl *asVarDecl() const { + return dyn_cast_if_present<VarDecl>(asDecl()); + } + const FieldDecl *asFieldDecl() const { return dyn_cast_if_present<FieldDecl>(asDecl()); } @@ -169,6 +217,11 @@ public: return Size; } + PrimType getPrimType() const { + assert(isPrimitiveArray() || isPrimitive()); + return *PrimT; + } + /// Returns the allocated size, including metadata. unsigned getAllocSize() const { return AllocSize; } /// returns the size of an element when the structure is viewed as an array. @@ -199,6 +252,9 @@ public: bool isRecord() const { return !IsArray && ElemRecord; } /// Checks if this is a dummy descriptor. bool isDummy() const { return IsDummy; } + + void dump() const; + void dump(llvm::raw_ostream &OS) const; }; /// Bitfield tracking the initialisation status of elements of primitive arrays. |