clang 20.0.0git
CIRAttrs.cpp
Go to the documentation of this file.
1//===- CIRAttrs.cpp - MLIR CIR Attributes ---------------------------------===//
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 defines the attributes in the CIR dialect.
10//
11//===----------------------------------------------------------------------===//
12
14
15#include "mlir/IR/DialectImplementation.h"
16#include "llvm/ADT/TypeSwitch.h"
17
18static void printFloatLiteral(mlir::AsmPrinter &p, llvm::APFloat value,
19 mlir::Type ty);
20static mlir::ParseResult
21parseFloatLiteral(mlir::AsmParser &parser,
22 mlir::FailureOr<llvm::APFloat> &value,
23 cir::CIRFPTypeInterface fpType);
24
25static mlir::ParseResult parseConstPtr(mlir::AsmParser &parser,
26 mlir::IntegerAttr &value);
27
28static void printConstPtr(mlir::AsmPrinter &p, mlir::IntegerAttr value);
29
30#define GET_ATTRDEF_CLASSES
31#include "clang/CIR/Dialect/IR/CIROpsAttributes.cpp.inc"
32
33using namespace mlir;
34using namespace cir;
35
36//===----------------------------------------------------------------------===//
37// General CIR parsing / printing
38//===----------------------------------------------------------------------===//
39
40Attribute CIRDialect::parseAttribute(DialectAsmParser &parser,
41 Type type) const {
42 llvm::SMLoc typeLoc = parser.getCurrentLocation();
43 llvm::StringRef mnemonic;
44 Attribute genAttr;
45 OptionalParseResult parseResult =
46 generatedAttributeParser(parser, &mnemonic, type, genAttr);
47 if (parseResult.has_value())
48 return genAttr;
49 parser.emitError(typeLoc, "unknown attribute in CIR dialect");
50 return Attribute();
51}
52
53void CIRDialect::printAttribute(Attribute attr, DialectAsmPrinter &os) const {
54 if (failed(generatedAttributePrinter(attr, os)))
55 llvm_unreachable("unexpected CIR type kind");
56}
57
58//===----------------------------------------------------------------------===//
59// ConstPtrAttr definitions
60//===----------------------------------------------------------------------===//
61
62// TODO(CIR): Consider encoding the null value differently and use conditional
63// assembly format instead of custom parsing/printing.
64static ParseResult parseConstPtr(AsmParser &parser, mlir::IntegerAttr &value) {
65
66 if (parser.parseOptionalKeyword("null").succeeded()) {
67 value = mlir::IntegerAttr::get(
68 mlir::IntegerType::get(parser.getContext(), 64), 0);
69 return success();
70 }
71
72 return parser.parseAttribute(value);
73}
74
75static void printConstPtr(AsmPrinter &p, mlir::IntegerAttr value) {
76 if (!value.getInt())
77 p << "null";
78 else
79 p << value;
80}
81
82//===----------------------------------------------------------------------===//
83// IntAttr definitions
84//===----------------------------------------------------------------------===//
85
86Attribute IntAttr::parse(AsmParser &parser, Type odsType) {
87 mlir::APInt apValue;
88
89 if (!mlir::isa<IntType>(odsType))
90 return {};
91 auto type = mlir::cast<IntType>(odsType);
92
93 // Consume the '<' symbol.
94 if (parser.parseLess())
95 return {};
96
97 // Fetch arbitrary precision integer value.
98 if (type.isSigned()) {
99 int64_t value = 0;
100 if (parser.parseInteger(value)) {
101 parser.emitError(parser.getCurrentLocation(), "expected integer value");
102 } else {
103 apValue = mlir::APInt(type.getWidth(), value, type.isSigned(),
104 /*implicitTrunc=*/true);
105 if (apValue.getSExtValue() != value)
106 parser.emitError(parser.getCurrentLocation(),
107 "integer value too large for the given type");
108 }
109 } else {
110 uint64_t value = 0;
111 if (parser.parseInteger(value)) {
112 parser.emitError(parser.getCurrentLocation(), "expected integer value");
113 } else {
114 apValue = mlir::APInt(type.getWidth(), value, type.isSigned(),
115 /*implicitTrunc=*/true);
116 if (apValue.getZExtValue() != value)
117 parser.emitError(parser.getCurrentLocation(),
118 "integer value too large for the given type");
119 }
120 }
121
122 // Consume the '>' symbol.
123 if (parser.parseGreater())
124 return {};
125
126 return IntAttr::get(type, apValue);
127}
128
129void IntAttr::print(AsmPrinter &printer) const {
130 auto type = mlir::cast<IntType>(getType());
131 printer << '<';
132 if (type.isSigned())
133 printer << getSInt();
134 else
135 printer << getUInt();
136 printer << '>';
137}
138
139LogicalResult IntAttr::verify(function_ref<InFlightDiagnostic()> emitError,
140 Type type, APInt value) {
141 if (!mlir::isa<IntType>(type)) {
142 emitError() << "expected 'simple.int' type";
143 return failure();
144 }
145
146 auto intType = mlir::cast<IntType>(type);
147 if (value.getBitWidth() != intType.getWidth()) {
148 emitError() << "type and value bitwidth mismatch: " << intType.getWidth()
149 << " != " << value.getBitWidth();
150 return failure();
151 }
152
153 return success();
154}
155
156//===----------------------------------------------------------------------===//
157// FPAttr definitions
158//===----------------------------------------------------------------------===//
159
160static void printFloatLiteral(AsmPrinter &p, APFloat value, Type ty) {
161 p << value;
162}
163
164static ParseResult parseFloatLiteral(AsmParser &parser,
165 FailureOr<APFloat> &value,
166 CIRFPTypeInterface fpType) {
167
168 APFloat parsedValue(0.0);
169 if (parser.parseFloat(fpType.getFloatSemantics(), parsedValue))
170 return failure();
171
172 value.emplace(parsedValue);
173 return success();
174}
175
176FPAttr FPAttr::getZero(Type type) {
177 return get(type,
178 APFloat::getZero(
179 mlir::cast<CIRFPTypeInterface>(type).getFloatSemantics()));
180}
181
182LogicalResult FPAttr::verify(function_ref<InFlightDiagnostic()> emitError,
183 CIRFPTypeInterface fpType, APFloat value) {
184 if (APFloat::SemanticsToEnum(fpType.getFloatSemantics()) !=
185 APFloat::SemanticsToEnum(value.getSemantics())) {
186 emitError() << "floating-point semantics mismatch";
187 return failure();
188 }
189
190 return success();
191}
192
193//===----------------------------------------------------------------------===//
194// CIR Dialect
195//===----------------------------------------------------------------------===//
196
197void CIRDialect::registerAttributes() {
198 addAttributes<
199#define GET_ATTRDEF_LIST
200#include "clang/CIR/Dialect/IR/CIROpsAttributes.cpp.inc"
201 >();
202}
MatchType Type
static void printConstPtr(mlir::AsmPrinter &p, mlir::IntegerAttr value)
static mlir::ParseResult parseConstPtr(mlir::AsmParser &parser, mlir::IntegerAttr &value)
static void printFloatLiteral(mlir::AsmPrinter &p, llvm::APFloat value, mlir::Type ty)
static mlir::ParseResult parseFloatLiteral(mlir::AsmParser &parser, mlir::FailureOr< llvm::APFloat > &value, cir::CIRFPTypeInterface fpType)
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
unsigned long uint64_t
long int64_t