aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/AST/Interp/Descriptor.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/Interp/Descriptor.h')
-rw-r--r--contrib/llvm-project/clang/lib/AST/Interp/Descriptor.h66
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.