clang 24.0.0git
CIRTypes.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 declares the types in the CIR dialect.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef CLANG_CIR_DIALECT_IR_CIRTYPES_H
14#define CLANG_CIR_DIALECT_IR_CIRTYPES_H
15
16#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
17#include "mlir/IR/Attributes.h"
18#include "mlir/IR/BuiltinAttributes.h"
19#include "mlir/IR/MLIRContext.h"
20#include "mlir/IR/Types.h"
21#include "mlir/Interfaces/DataLayoutInterfaces.h"
26#include "llvm/ADT/ArrayRef.h"
27#include "llvm/ADT/STLExtras.h"
28#include "llvm/ADT/SmallVector.h"
29#include "llvm/Support/TypeSize.h"
30
31namespace llvm {
32struct fltSemantics;
33} // namespace llvm
34
35namespace cir {
36
37namespace detail {
39struct UnionTypeStorage;
40} // namespace detail
41
42bool isValidFundamentalIntWidth(unsigned width);
43
44/// Whether a member of this kind holds data for argument passing. An `empty`
45/// member can hold data all the same, since an access unit of unnamed
46/// bit-fields takes that mark and is storage the classifier reads; use
47/// RecordType::isEmptyForABI to ask about a whole record.
48inline bool holdsDataForABI(RecordMemberKind kind) {
49 return kind == RecordMemberKind::Data || kind == RecordMemberKind::BitField;
50}
51
52/// Whether any member holds data for argument passing on its mark alone.
54 return llvm::any_of(
55 kinds, [](RecordMemberKind kind) { return holdsDataForABI(kind); });
56}
57
58/// Whether a member of this kind is an access unit the source can read a
59/// bit-field of. A unit can be narrower than the type a bit-field in it was
60/// declared with, so its extent does not answer what the source declared;
61/// `!cir.bitfield` carries that. A true answer does not mean the member is an
62/// access unit: a union's base subobject takes this mark when any variant is
63/// one, whatever its own storage type came from. A unit of nothing but
64/// unnamed bit-fields is `empty` instead.
65inline bool isNamedBitField(RecordMemberKind kind) {
66 return kind == RecordMemberKind::BitField;
67}
68
69/// Returns true if the type is a CIR sized type.
70///
71/// Types are sized if they implement SizedTypeInterface and
72/// return true from its method isSized.
73///
74/// Unsized types are those that do not have a size, such as
75/// void, or abstract types.
76bool isSized(mlir::Type ty);
77
78/// Returns the CIR floating-point type for the given semantics, or a null
79/// type if CIR has no type for it (e.g. PPCDoubleDouble or a Float8 format).
80/// Mirrors llvm::Type::getFloatingPointTy.
81cir::FPTypeInterface getFloatingPointType(const llvm::fltSemantics &sem,
82 mlir::MLIRContext *ctx);
83
84//===----------------------------------------------------------------------===//
85// AddressSpace helpers
86//===----------------------------------------------------------------------===//
87
88cir::LangAddressSpace toCIRLangAddressSpace(clang::LangAS langAS);
89
90// Compare a CIR memory space attribute with a Clang LangAS.
91bool isMatchingAddressSpace(mlir::ptr::MemorySpaceAttrInterface cirAS,
92 clang::LangAS as);
93
94/// Convert an AST LangAS to the appropriate CIR address space attribute
95/// interface.
96mlir::ptr::MemorySpaceAttrInterface
97toCIRAddressSpaceAttr(mlir::MLIRContext &ctx, clang::LangAS langAS);
98
99/// Normalize LangAddressSpace::Default to null (empty attribute).
100mlir::ptr::MemorySpaceAttrInterface
101normalizeDefaultAddressSpace(mlir::ptr::MemorySpaceAttrInterface addrSpace);
102
104 mlir::ptr::MemorySpaceAttrInterface memorySpace);
105
106} // namespace cir
107
108//===----------------------------------------------------------------------===//
109// CIR Dialect Tablegen'd Types
110//===----------------------------------------------------------------------===//
111
112namespace cir {
113
114#include "clang/CIR/Dialect/IR/CIRTypeConstraints.h.inc"
115
116} // namespace cir
117
118#define GET_TYPEDEF_CLASSES
119#include "clang/CIR/Dialect/IR/CIROpsTypes.h.inc"
120
121namespace cir {
122
123/// Whether a record member occupies bytes of its record. Every member does
124/// except a zero-width bit-field, which contributes neither size nor alignment
125/// to the record and is left out of the lowered LLVM struct body.
126inline bool memberOwnsBytes(mlir::Type memberTy) {
127 if (auto bfTy = mlir::dyn_cast<cir::BitFieldType>(memberTy))
128 return bfTy.ownsBytes();
129 return true;
130}
131
132/// The storage a member is stored as: the access unit for a bit-field member,
133/// and the member type itself for anything else. Null for a zero-width
134/// bit-field, which has no storage.
135inline mlir::Type memberStorageType(mlir::Type memberTy) {
136 if (auto bfTy = mlir::dyn_cast<cir::BitFieldType>(memberTy))
137 return bfTy.getStorageType();
138 return memberTy;
139}
140
141/// C++ view class that accepts both !cir.struct and !cir.union types.
142///
143/// Follows the MLIR BaseMemRefType pattern: StructType and UnionType are the
144/// concrete tablegen types; RecordType is a hand-written view class that
145/// covers both. Use it when code must handle either kind generically.
146///
147/// Methods that are common to both types are forwarded through dyn_cast
148/// dispatch. Type-specific methods (getPadding, getUnionStorageType) are only
149/// available on the concrete type.
150class RecordType : public mlir::Type {
151public:
152 using mlir::Type::Type;
153
154 // Allow implicit construction from concrete record types so that
155 // functions returning cir::RecordType can return StructType/UnionType
156 // values without an explicit cast.
157 // NOLINTNEXTLINE(google-explicit-constructor)
158 RecordType(StructType t) : mlir::Type(t) {}
159 // NOLINTNEXTLINE(google-explicit-constructor)
160 RecordType(UnionType t) : mlir::Type(t) {}
161
162 static bool classof(mlir::Type t) {
163 return mlir::isa<StructType>(t) || mlir::isa<UnionType>(t);
164 }
165
167 mlir::StringAttr getName() const;
168 bool isIncomplete() const;
169 bool isComplete() const { return !isIncomplete(); }
170 bool getPacked() const;
171 bool getPadded() const;
173
174 bool isClass() const;
175 bool isStruct() const;
176 bool isUnion() const { return mlir::isa<UnionType>(*this); }
177
178 /// Whether no member holds data. Vacuously true for a complete record with
179 /// no members, and false for an incomplete one, whose members are not known
180 /// yet. A union's tail-padding slot is not a member and does not count.
181 bool isEmptyForABI() const;
182
183 /// One `Data` kind per member. Takes the member list rather than a count so
184 /// the length cannot drift from the record it describes.
187
188 size_t getNumElements() const { return getMembers().size(); }
189 mlir::Type getElementType(size_t idx) const { return getMembers()[idx]; }
190 std::string getKindAsStr() const;
191 std::string getPrefixedName() const;
192
193 /// \p padding is union-only. A struct carries its padding as a member
194 /// marked pad.
195 void complete(llvm::ArrayRef<mlir::Type> members, bool packed,
196 mlir::Type padding,
198 uint64_t getElementOffset(const mlir::DataLayout &dataLayout,
199 unsigned idx) const;
200 bool isLayoutIdentical(const RecordType &other);
201
202 bool isABIConvertedRecord() const;
203 mlir::StringAttr getABIConvertedName() const;
205};
206
207} // namespace cir
208
209#endif // CLANG_CIR_DIALECT_IR_CIRTYPES_H
Provides definitions for the various language-specific address spaces.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
C++ view class that accepts both !cir.struct and !cir.union types.
Definition CIRTypes.h:150
bool isUnion() const
Definition CIRTypes.h:176
bool isLayoutIdentical(const RecordType &other)
Definition CIRTypes.cpp:712
mlir::Type getElementType(size_t idx) const
Definition CIRTypes.h:189
bool isComplete() const
Definition CIRTypes.h:169
bool isABIConvertedRecord() const
Definition CIRTypes.cpp:725
bool isIncomplete() const
Definition CIRTypes.cpp:658
bool isEmptyForABI() const
Whether no member holds data.
Definition CIRTypes.cpp:741
std::string getPrefixedName() const
Definition CIRTypes.cpp:693
llvm::ArrayRef< mlir::Type > getMembers() const
Definition CIRTypes.cpp:648
RecordType(UnionType t)
Definition CIRTypes.h:160
bool isClass() const
Definition CIRTypes.cpp:678
void removeABIConversionNamePrefix()
Definition CIRTypes.cpp:735
static bool classof(mlir::Type t)
Definition CIRTypes.h:162
bool getPacked() const
Definition CIRTypes.cpp:663
static llvm::SmallVector< RecordMemberKind > getAllDataKinds(llvm::ArrayRef< mlir::Type > members)
One Data kind per member.
Definition CIRTypes.cpp:151
RecordType(StructType t)
Definition CIRTypes.h:158
mlir::StringAttr getName() const
Definition CIRTypes.cpp:653
void complete(llvm::ArrayRef< mlir::Type > members, bool packed, mlir::Type padding, llvm::ArrayRef< RecordMemberKind > memberKinds)
padding is union-only.
Definition CIRTypes.cpp:696
mlir::StringAttr getABIConvertedName() const
Definition CIRTypes.cpp:730
std::string getKindAsStr() const
Definition CIRTypes.cpp:688
bool isStruct() const
Definition CIRTypes.cpp:683
bool getPadded() const
Definition CIRTypes.cpp:668
llvm::ArrayRef< RecordMemberKind > getMemberKinds() const
Definition CIRTypes.cpp:673
size_t getNumElements() const
Definition CIRTypes.h:188
uint64_t getElementOffset(const mlir::DataLayout &dataLayout, unsigned idx) const
Definition CIRTypes.cpp:706
bool isMatchingAddressSpace(mlir::ptr::MemorySpaceAttrInterface cirAS, clang::LangAS as)
cir::LangAddressSpace toCIRLangAddressSpace(clang::LangAS langAS)
mlir::Type memberStorageType(mlir::Type memberTy)
The storage a member is stored as: the access unit for a bit-field member, and the member type itself...
Definition CIRTypes.h:135
bool memberOwnsBytes(mlir::Type memberTy)
Whether a record member occupies bytes of its record.
Definition CIRTypes.h:126
bool isValidFundamentalIntWidth(unsigned width)
cir::FPTypeInterface getFloatingPointType(const llvm::fltSemantics &sem, mlir::MLIRContext *ctx)
Returns the CIR floating-point type for the given semantics, or a null type if CIR has no type for it...
Definition CIRTypes.cpp:43
mlir::ptr::MemorySpaceAttrInterface toCIRAddressSpaceAttr(mlir::MLIRContext &ctx, clang::LangAS langAS)
Convert an AST LangAS to the appropriate CIR address space attribute interface.
bool anyMemberHoldsDataForABI(llvm::ArrayRef< RecordMemberKind > kinds)
Whether any member holds data for argument passing on its mark alone.
Definition CIRTypes.h:53
bool isNamedBitField(RecordMemberKind kind)
Whether a member of this kind is an access unit the source can read a bit-field of.
Definition CIRTypes.h:65
mlir::ptr::MemorySpaceAttrInterface normalizeDefaultAddressSpace(mlir::ptr::MemorySpaceAttrInterface addrSpace)
Normalize LangAddressSpace::Default to null (empty attribute).
bool isSized(mlir::Type ty)
Returns true if the type is a CIR sized type.
Definition CIRTypes.cpp:36
bool holdsDataForABI(RecordMemberKind kind)
Whether a member of this kind holds data for argument passing.
Definition CIRTypes.h:48
bool isSupportedCIRMemorySpaceAttr(mlir::ptr::MemorySpaceAttrInterface memorySpace)
LangAS
Defines the address space values used by the address space qualifier of QualType.
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
Type storage for CIR struct/class types.
Type storage for CIR union types.