14 #ifndef DIALECT_LLVMIR_IR_TYPEDETAIL_H
15 #define DIALECT_LLVMIR_IR_TYPEDETAIL_H
21 #include "llvm/ADT/Bitfields.h"
22 #include "llvm/ADT/PointerIntPair.h"
72 Key(StringRef name,
bool opaque)
73 : name(name), identified(true), packed(false), opaque(opaque) {}
76 : types(types), identified(false), packed(packed), opaque(false) {}
82 "'packed' bit is not part of the key for identified structs");
87 "'opaque' bit is meaningless on literal structs");
94 "non-identified struct key cannot have an identifier");
101 "identified struct key cannot have a type list");
110 constexpr
static unsigned kIdentifiedHashFlag = 1;
111 constexpr
static unsigned kPackedHashFlag = 2;
115 flags |= kIdentifiedHashFlag;
119 flags |= kPackedHashFlag;
151 assert(
isIdentified() &&
"requested identifier on a non-identified struct");
152 return StringRef(
static_cast<const char *
>(keyPtr), keySize());
158 assert(!
isIdentified() &&
"requested typelist on an identified struct");
166 "requested struct body on a non-identified struct");
172 return llvm::Bitfield::get<KeyFlagIdentified>(keySizeAndFlags);
177 return isIdentified() ? llvm::Bitfield::get<MutableFlagPacked>(
178 identifiedBodySizeAndFlags)
179 : llvm::Bitfield::get<KeyFlagPacked>(keySizeAndFlags);
186 return llvm::Bitfield::get<MutableFlagOpaque>(identifiedBodySizeAndFlags);
192 return llvm::Bitfield::get<MutableFlagInitialized>(
193 identifiedBodySizeAndFlags);
203 keyPtr =
static_cast<const void *
>(types.data());
204 setKeySize(types.size());
205 llvm::Bitfield::set<KeyFlagPacked>(keySizeAndFlags, key.
isPacked());
210 keyPtr =
static_cast<const void *
>(name.data());
211 setKeySize(name.size());
212 llvm::Bitfield::set<KeyFlagIdentified>(keySizeAndFlags,
true);
216 llvm::Bitfield::set<MutableFlagInitialized>(identifiedBodySizeAndFlags,
218 llvm::Bitfield::set<MutableFlagOpaque>(identifiedBodySizeAndFlags,
243 llvm::Bitfield::set<MutableFlagInitialized>(identifiedBodySizeAndFlags,
245 llvm::Bitfield::set<MutableFlagPacked>(identifiedBodySizeAndFlags, packed);
248 identifiedBodyArray = typesInAllocator.data();
249 setIdentifiedBodySize(typesInAllocator.size());
256 unsigned keySize()
const {
257 return llvm::Bitfield::get<KeySize>(keySizeAndFlags);
261 void setKeySize(
unsigned value) {
262 llvm::Bitfield::set<KeySize>(keySizeAndFlags, value);
266 unsigned identifiedBodySize()
const {
267 return llvm::Bitfield::get<MutableSize>(identifiedBodySizeAndFlags);
270 void setIdentifiedBodySize(
unsigned value) {
271 llvm::Bitfield::set<MutableSize>(identifiedBodySizeAndFlags, value);
285 using KeyFlagIdentified =
286 llvm::Bitfield::Element<bool, 0, 1>;
287 using KeyFlagPacked = llvm::Bitfield::Element<bool, 1, 1>;
289 llvm::Bitfield::Element<unsigned, 2,
290 std::numeric_limits<unsigned>::digits - 2>;
297 using MutableFlagOpaque =
298 llvm::Bitfield::Element<bool, 0, 1>;
299 using MutableFlagPacked =
300 llvm::Bitfield::Element<bool, 1, 1>;
301 using MutableFlagInitialized =
302 llvm::Bitfield::Element<bool, 2, 1>;
304 llvm::Bitfield::Element<unsigned, 3,
305 std::numeric_limits<unsigned>::digits - 3>;
310 const void *keyPtr =
nullptr;
313 const Type *identifiedBodyArray =
nullptr;
317 unsigned keySizeAndFlags = 0;
321 unsigned identifiedBodySizeAndFlags = 0;
332 using KeyTy = std::tuple<Type, unsigned>;
Construction/uniquing key class for LLVM dialect structure storage.
bool isIdentified() const
Checks a specific property of the struct.
llvm::hash_code hashValue() const
Returns the hash value of the key.
StringRef getIdentifier() const
Returns the identifier of a key for identified structs.
bool operator==(const Key &other) const
Compares two keys.
Key copyIntoAllocator(TypeStorageAllocator &allocator) const
Copies dynamically-sized components of the key into the given allocator.
Key(StringRef name, bool opaque)
Constructs a key for an identified struct.
ArrayRef< Type > getTypeList() const
Returns the list of type contained in the key of a literal struct.
Key(ArrayRef< Type > types, bool packed)
Constructs a key for a literal struct.
This is a utility allocator used to allocate memory for instances of derived types.
ArrayRef< T > copyInto(ArrayRef< T > elements)
Copy the specified array of elements into memory managed by our bump pointer allocator.
T * allocate()
Allocate an instance of the provided type.
Base storage class appearing in a Type.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
@ Type
An inlay hint that for a type annotation.
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Type storage for LLVM structure types.
ArrayRef< Type > getTypeList() const
Returns the list of types (partially) identifying a literal struct.
StringRef getIdentifier() const
Returns the string identifier of an identified struct.
ArrayRef< Type > getIdentifiedStructBody() const
Returns the list of types contained in an identified struct.
LogicalResult mutate(TypeStorageAllocator &allocator, ArrayRef< Type > body, bool packed)
Sets the body of an identified struct.
static LLVMStructTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
static llvm::hash_code hashKey(const KeyTy &key)
bool operator==(const KeyTy &other) const
Hook into the type uniquing infrastructure.
LLVMStructTypeStorage(const KeyTy &key)
Constructs the storage from the given key.
bool isIdentified() const
Checks whether the struct is identified.
bool isInitialized() const
Checks whether an identified struct has been explicitly initialized either by setting its body or by ...
bool isOpaque() const
Checks whether a struct is marked as intentionally opaque (an uninitialized struct is also considered...
bool isPacked() const
Checks whether the struct is packed (both literal and identified structs).
Common storage used for LLVM dialect types that need an element type and a number: arrays,...
std::tuple< Type, unsigned > KeyTy
static LLVMTypeAndSizeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
bool operator==(const KeyTy &key) const
LLVMTypeAndSizeStorage(const KeyTy &key)
This class represents an efficient way to signal success or failure.