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