clang 24.0.0git
CIRTypesDetails.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains implementation details, such as storage structures, of
10// CIR dialect types.
11//
12//===----------------------------------------------------------------------===//
13#ifndef CIR_DIALECT_IR_CIRTYPESDETAILS_H
14#define CIR_DIALECT_IR_CIRTYPESDETAILS_H
15
16#include "mlir/IR/BuiltinAttributes.h"
17#include "mlir/Support/LogicalResult.h"
19#include "llvm/ADT/Hashing.h"
20
21namespace cir {
22namespace detail {
23
24//===----------------------------------------------------------------------===//
25// CIR StructTypeStorage
26//===----------------------------------------------------------------------===//
27
28/// Type storage for CIR struct/class types.
29struct StructTypeStorage : public mlir::TypeStorage {
44
46 mlir::StringAttr name;
48 bool packed;
51
53 bool incomplete, bool packed,
55 bool is_class)
58 assert((name || !incomplete) && "Incomplete records must have a name");
59 assert(member_kinds.size() == members.size() &&
60 "every member must say what it holds");
61 }
62
66
67 bool operator==(const KeyTy &key) const {
68 if (name)
69 return (name == key.name) && (is_class == key.is_class);
70 return std::tie(members, name, incomplete, packed, member_kinds,
71 is_class) == std::tie(key.members, key.name, key.incomplete,
72 key.packed, key.member_kinds,
73 key.is_class);
74 }
75
76 static llvm::hash_code hashKey(const KeyTy &key) {
77 if (key.name)
78 return llvm::hash_combine(key.name, key.is_class);
79 return llvm::hash_combine(key.members, key.incomplete, key.packed,
80 key.member_kinds, key.is_class);
81 }
82
83 static StructTypeStorage *construct(mlir::TypeStorageAllocator &allocator,
84 const KeyTy &key) {
85 return new (allocator.allocate<StructTypeStorage>()) StructTypeStorage(
86 allocator.copyInto(key.members), key.name, key.incomplete, key.packed,
87 allocator.copyInto(key.member_kinds), key.is_class);
88 }
89
90 /// Mutates the members and attributes of an identified struct/class.
91 llvm::LogicalResult mutate(mlir::TypeStorageAllocator &allocator,
94 if (!name)
95 return llvm::failure();
96
97 // A second completion must agree with the first in every parameter,
98 // including the kinds: otherwise it silently keeps the kinds it was given
99 // the first time.
100 if (!incomplete)
101 return mlir::success((this->members == members) &&
102 (this->packed == packed) &&
103 (this->member_kinds == memberKinds));
104
105 // mutate is the one entrance verify() never sees, so check the length here
106 // rather than leave it to an assert.
107 if (memberKinds.size() != members.size())
108 return llvm::failure();
109
110 this->members = allocator.copyInto(members);
111 this->packed = packed;
112 this->member_kinds = allocator.copyInto(memberKinds);
113 incomplete = false;
114 return llvm::success();
115 }
116};
117
118//===----------------------------------------------------------------------===//
119// CIR UnionTypeStorage
120//===----------------------------------------------------------------------===//
121
122/// Type storage for CIR union types.
123struct UnionTypeStorage : public mlir::TypeStorage {
138
140 mlir::StringAttr name;
142 bool packed;
143 mlir::Type padding;
145
147 bool incomplete, bool packed, mlir::Type padding,
151 assert((name || !incomplete) && "Incomplete records must have a name");
152 assert(member_kinds.size() == members.size() &&
153 "every member must say what it holds");
154 }
155
159
160 bool operator==(const KeyTy &key) const {
161 if (name)
162 return name == key.name;
163 return std::tie(members, name, incomplete, packed, padding, member_kinds) ==
164 std::tie(key.members, key.name, key.incomplete, key.packed,
165 key.padding, key.member_kinds);
166 }
167
168 static llvm::hash_code hashKey(const KeyTy &key) {
169 if (key.name)
170 return llvm::hash_combine(key.name);
171 return llvm::hash_combine(key.members, key.incomplete, key.packed,
172 key.padding, key.member_kinds);
173 }
174
175 static UnionTypeStorage *construct(mlir::TypeStorageAllocator &allocator,
176 const KeyTy &key) {
177 return new (allocator.allocate<UnionTypeStorage>()) UnionTypeStorage(
178 allocator.copyInto(key.members), key.name, key.incomplete, key.packed,
179 key.padding, allocator.copyInto(key.member_kinds));
180 }
181
182 /// Mutates the members and attributes of an identified union.
183 llvm::LogicalResult mutate(mlir::TypeStorageAllocator &allocator,
185 mlir::Type padding,
187 if (!name)
188 return llvm::failure();
189
190 // A second completion must agree with the first in every parameter,
191 // including the kinds: otherwise it silently keeps the kinds it was given
192 // the first time.
193 if (!incomplete)
194 return mlir::success(
195 (this->members == members) && (this->packed == packed) &&
196 (this->padding == padding) && (this->member_kinds == memberKinds));
197
198 // mutate is the one entrance verify() never sees, so check the length here
199 // rather than leave it to an assert.
200 if (memberKinds.size() != members.size())
201 return llvm::failure();
202
203 this->members = allocator.copyInto(members);
204 this->packed = packed;
205 this->padding = padding;
206 this->member_kinds = allocator.copyInto(memberKinds);
207 incomplete = false;
208 return llvm::success();
209 }
210};
211
212} // namespace detail
213} // namespace cir
214
215#endif // CIR_DIALECT_IR_CIRTYPESDETAILS_H
KeyTy(llvm::ArrayRef< mlir::Type > members, mlir::StringAttr name, bool incomplete, bool packed, llvm::ArrayRef< RecordMemberKind > member_kinds, bool is_class)
llvm::ArrayRef< RecordMemberKind > member_kinds
llvm::ArrayRef< mlir::Type > members
static llvm::hash_code hashKey(const KeyTy &key)
llvm::LogicalResult mutate(mlir::TypeStorageAllocator &allocator, llvm::ArrayRef< mlir::Type > members, bool packed, llvm::ArrayRef< RecordMemberKind > memberKinds)
Mutates the members and attributes of an identified struct/class.
llvm::ArrayRef< mlir::Type > members
static StructTypeStorage * construct(mlir::TypeStorageAllocator &allocator, const KeyTy &key)
bool operator==(const KeyTy &key) const
llvm::ArrayRef< RecordMemberKind > member_kinds
StructTypeStorage(llvm::ArrayRef< mlir::Type > members, mlir::StringAttr name, bool incomplete, bool packed, llvm::ArrayRef< RecordMemberKind > member_kinds, bool is_class)
llvm::ArrayRef< RecordMemberKind > member_kinds
llvm::ArrayRef< mlir::Type > members
KeyTy(llvm::ArrayRef< mlir::Type > members, mlir::StringAttr name, bool incomplete, bool packed, mlir::Type padding, llvm::ArrayRef< RecordMemberKind > member_kinds)
llvm::ArrayRef< mlir::Type > members
bool operator==(const KeyTy &key) const
static llvm::hash_code hashKey(const KeyTy &key)
static UnionTypeStorage * construct(mlir::TypeStorageAllocator &allocator, const KeyTy &key)
llvm::ArrayRef< RecordMemberKind > member_kinds
llvm::LogicalResult mutate(mlir::TypeStorageAllocator &allocator, llvm::ArrayRef< mlir::Type > members, bool packed, mlir::Type padding, llvm::ArrayRef< RecordMemberKind > memberKinds)
Mutates the members and attributes of an identified union.
UnionTypeStorage(llvm::ArrayRef< mlir::Type > members, mlir::StringAttr name, bool incomplete, bool packed, mlir::Type padding, llvm::ArrayRef< RecordMemberKind > member_kinds)