xref: /freebsd/contrib/llvm-project/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1*700637cbSDimitry Andric //===- CIRAttrs.cpp - MLIR CIR Attributes ---------------------------------===//
2*700637cbSDimitry Andric //
3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*700637cbSDimitry Andric //
7*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
8*700637cbSDimitry Andric //
9*700637cbSDimitry Andric // This file defines the attributes in the CIR dialect.
10*700637cbSDimitry Andric //
11*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
12*700637cbSDimitry Andric 
13*700637cbSDimitry Andric #include "clang/CIR/Dialect/IR/CIRDialect.h"
14*700637cbSDimitry Andric 
15*700637cbSDimitry Andric #include "mlir/IR/DialectImplementation.h"
16*700637cbSDimitry Andric #include "llvm/ADT/TypeSwitch.h"
17*700637cbSDimitry Andric 
18*700637cbSDimitry Andric //===-----------------------------------------------------------------===//
19*700637cbSDimitry Andric // IntLiteral
20*700637cbSDimitry Andric //===-----------------------------------------------------------------===//
21*700637cbSDimitry Andric 
22*700637cbSDimitry Andric static void printIntLiteral(mlir::AsmPrinter &p, llvm::APInt value,
23*700637cbSDimitry Andric                             cir::IntTypeInterface ty);
24*700637cbSDimitry Andric static mlir::ParseResult parseIntLiteral(mlir::AsmParser &parser,
25*700637cbSDimitry Andric                                          llvm::APInt &value,
26*700637cbSDimitry Andric                                          cir::IntTypeInterface ty);
27*700637cbSDimitry Andric //===-----------------------------------------------------------------===//
28*700637cbSDimitry Andric // FloatLiteral
29*700637cbSDimitry Andric //===-----------------------------------------------------------------===//
30*700637cbSDimitry Andric 
31*700637cbSDimitry Andric static void printFloatLiteral(mlir::AsmPrinter &p, llvm::APFloat value,
32*700637cbSDimitry Andric                               mlir::Type ty);
33*700637cbSDimitry Andric static mlir::ParseResult
34*700637cbSDimitry Andric parseFloatLiteral(mlir::AsmParser &parser,
35*700637cbSDimitry Andric                   mlir::FailureOr<llvm::APFloat> &value,
36*700637cbSDimitry Andric                   cir::FPTypeInterface fpType);
37*700637cbSDimitry Andric 
38*700637cbSDimitry Andric static mlir::ParseResult parseConstPtr(mlir::AsmParser &parser,
39*700637cbSDimitry Andric                                        mlir::IntegerAttr &value);
40*700637cbSDimitry Andric 
41*700637cbSDimitry Andric static void printConstPtr(mlir::AsmPrinter &p, mlir::IntegerAttr value);
42*700637cbSDimitry Andric 
43*700637cbSDimitry Andric #define GET_ATTRDEF_CLASSES
44*700637cbSDimitry Andric #include "clang/CIR/Dialect/IR/CIROpsAttributes.cpp.inc"
45*700637cbSDimitry Andric 
46*700637cbSDimitry Andric using namespace mlir;
47*700637cbSDimitry Andric using namespace cir;
48*700637cbSDimitry Andric 
49*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
50*700637cbSDimitry Andric // General CIR parsing / printing
51*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
52*700637cbSDimitry Andric 
parseAttribute(DialectAsmParser & parser,Type type) const53*700637cbSDimitry Andric Attribute CIRDialect::parseAttribute(DialectAsmParser &parser,
54*700637cbSDimitry Andric                                      Type type) const {
55*700637cbSDimitry Andric   llvm::SMLoc typeLoc = parser.getCurrentLocation();
56*700637cbSDimitry Andric   llvm::StringRef mnemonic;
57*700637cbSDimitry Andric   Attribute genAttr;
58*700637cbSDimitry Andric   OptionalParseResult parseResult =
59*700637cbSDimitry Andric       generatedAttributeParser(parser, &mnemonic, type, genAttr);
60*700637cbSDimitry Andric   if (parseResult.has_value())
61*700637cbSDimitry Andric     return genAttr;
62*700637cbSDimitry Andric   parser.emitError(typeLoc, "unknown attribute in CIR dialect");
63*700637cbSDimitry Andric   return Attribute();
64*700637cbSDimitry Andric }
65*700637cbSDimitry Andric 
printAttribute(Attribute attr,DialectAsmPrinter & os) const66*700637cbSDimitry Andric void CIRDialect::printAttribute(Attribute attr, DialectAsmPrinter &os) const {
67*700637cbSDimitry Andric   if (failed(generatedAttributePrinter(attr, os)))
68*700637cbSDimitry Andric     llvm_unreachable("unexpected CIR type kind");
69*700637cbSDimitry Andric }
70*700637cbSDimitry Andric 
71*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
72*700637cbSDimitry Andric // OptInfoAttr definitions
73*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
74*700637cbSDimitry Andric 
verify(function_ref<InFlightDiagnostic ()> emitError,unsigned level,unsigned size)75*700637cbSDimitry Andric LogicalResult OptInfoAttr::verify(function_ref<InFlightDiagnostic()> emitError,
76*700637cbSDimitry Andric                                   unsigned level, unsigned size) {
77*700637cbSDimitry Andric   if (level > 3)
78*700637cbSDimitry Andric     return emitError()
79*700637cbSDimitry Andric            << "optimization level must be between 0 and 3 inclusive";
80*700637cbSDimitry Andric   if (size > 2)
81*700637cbSDimitry Andric     return emitError()
82*700637cbSDimitry Andric            << "size optimization level must be between 0 and 2 inclusive";
83*700637cbSDimitry Andric   return success();
84*700637cbSDimitry Andric }
85*700637cbSDimitry Andric 
86*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
87*700637cbSDimitry Andric // ConstPtrAttr definitions
88*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
89*700637cbSDimitry Andric 
90*700637cbSDimitry Andric // TODO(CIR): Consider encoding the null value differently and use conditional
91*700637cbSDimitry Andric // assembly format instead of custom parsing/printing.
parseConstPtr(AsmParser & parser,mlir::IntegerAttr & value)92*700637cbSDimitry Andric static ParseResult parseConstPtr(AsmParser &parser, mlir::IntegerAttr &value) {
93*700637cbSDimitry Andric 
94*700637cbSDimitry Andric   if (parser.parseOptionalKeyword("null").succeeded()) {
95*700637cbSDimitry Andric     value = parser.getBuilder().getI64IntegerAttr(0);
96*700637cbSDimitry Andric     return success();
97*700637cbSDimitry Andric   }
98*700637cbSDimitry Andric 
99*700637cbSDimitry Andric   return parser.parseAttribute(value);
100*700637cbSDimitry Andric }
101*700637cbSDimitry Andric 
printConstPtr(AsmPrinter & p,mlir::IntegerAttr value)102*700637cbSDimitry Andric static void printConstPtr(AsmPrinter &p, mlir::IntegerAttr value) {
103*700637cbSDimitry Andric   if (!value.getInt())
104*700637cbSDimitry Andric     p << "null";
105*700637cbSDimitry Andric   else
106*700637cbSDimitry Andric     p << value;
107*700637cbSDimitry Andric }
108*700637cbSDimitry Andric 
109*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
110*700637cbSDimitry Andric // IntAttr definitions
111*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
112*700637cbSDimitry Andric 
113*700637cbSDimitry Andric template <typename IntT>
isTooLargeForType(const mlir::APInt & value,IntT expectedValue)114*700637cbSDimitry Andric static bool isTooLargeForType(const mlir::APInt &value, IntT expectedValue) {
115*700637cbSDimitry Andric   if constexpr (std::is_signed_v<IntT>) {
116*700637cbSDimitry Andric     return value.getSExtValue() != expectedValue;
117*700637cbSDimitry Andric   } else {
118*700637cbSDimitry Andric     return value.getZExtValue() != expectedValue;
119*700637cbSDimitry Andric   }
120*700637cbSDimitry Andric }
121*700637cbSDimitry Andric 
122*700637cbSDimitry Andric template <typename IntT>
parseIntLiteralImpl(mlir::AsmParser & p,llvm::APInt & value,cir::IntTypeInterface ty)123*700637cbSDimitry Andric static mlir::ParseResult parseIntLiteralImpl(mlir::AsmParser &p,
124*700637cbSDimitry Andric                                              llvm::APInt &value,
125*700637cbSDimitry Andric                                              cir::IntTypeInterface ty) {
126*700637cbSDimitry Andric   IntT ivalue;
127*700637cbSDimitry Andric   const bool isSigned = ty.isSigned();
128*700637cbSDimitry Andric   if (p.parseInteger(ivalue))
129*700637cbSDimitry Andric     return p.emitError(p.getCurrentLocation(), "expected integer value");
130*700637cbSDimitry Andric 
131*700637cbSDimitry Andric   value = mlir::APInt(ty.getWidth(), ivalue, isSigned, /*implicitTrunc=*/true);
132*700637cbSDimitry Andric   if (isTooLargeForType(value, ivalue))
133*700637cbSDimitry Andric     return p.emitError(p.getCurrentLocation(),
134*700637cbSDimitry Andric                        "integer value too large for the given type");
135*700637cbSDimitry Andric 
136*700637cbSDimitry Andric   return success();
137*700637cbSDimitry Andric }
138*700637cbSDimitry Andric 
parseIntLiteral(mlir::AsmParser & parser,llvm::APInt & value,cir::IntTypeInterface ty)139*700637cbSDimitry Andric mlir::ParseResult parseIntLiteral(mlir::AsmParser &parser, llvm::APInt &value,
140*700637cbSDimitry Andric                                   cir::IntTypeInterface ty) {
141*700637cbSDimitry Andric   if (ty.isSigned())
142*700637cbSDimitry Andric     return parseIntLiteralImpl<int64_t>(parser, value, ty);
143*700637cbSDimitry Andric   return parseIntLiteralImpl<uint64_t>(parser, value, ty);
144*700637cbSDimitry Andric }
145*700637cbSDimitry Andric 
printIntLiteral(mlir::AsmPrinter & p,llvm::APInt value,cir::IntTypeInterface ty)146*700637cbSDimitry Andric void printIntLiteral(mlir::AsmPrinter &p, llvm::APInt value,
147*700637cbSDimitry Andric                      cir::IntTypeInterface ty) {
148*700637cbSDimitry Andric   if (ty.isSigned())
149*700637cbSDimitry Andric     p << value.getSExtValue();
150*700637cbSDimitry Andric   else
151*700637cbSDimitry Andric     p << value.getZExtValue();
152*700637cbSDimitry Andric }
153*700637cbSDimitry Andric 
verify(function_ref<InFlightDiagnostic ()> emitError,cir::IntTypeInterface type,llvm::APInt value)154*700637cbSDimitry Andric LogicalResult IntAttr::verify(function_ref<InFlightDiagnostic()> emitError,
155*700637cbSDimitry Andric                               cir::IntTypeInterface type, llvm::APInt value) {
156*700637cbSDimitry Andric   if (value.getBitWidth() != type.getWidth())
157*700637cbSDimitry Andric     return emitError() << "type and value bitwidth mismatch: "
158*700637cbSDimitry Andric                        << type.getWidth() << " != " << value.getBitWidth();
159*700637cbSDimitry Andric   return success();
160*700637cbSDimitry Andric }
161*700637cbSDimitry Andric 
162*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
163*700637cbSDimitry Andric // FPAttr definitions
164*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
165*700637cbSDimitry Andric 
printFloatLiteral(AsmPrinter & p,APFloat value,Type ty)166*700637cbSDimitry Andric static void printFloatLiteral(AsmPrinter &p, APFloat value, Type ty) {
167*700637cbSDimitry Andric   p << value;
168*700637cbSDimitry Andric }
169*700637cbSDimitry Andric 
parseFloatLiteral(AsmParser & parser,FailureOr<APFloat> & value,cir::FPTypeInterface fpType)170*700637cbSDimitry Andric static ParseResult parseFloatLiteral(AsmParser &parser,
171*700637cbSDimitry Andric                                      FailureOr<APFloat> &value,
172*700637cbSDimitry Andric                                      cir::FPTypeInterface fpType) {
173*700637cbSDimitry Andric 
174*700637cbSDimitry Andric   APFloat parsedValue(0.0);
175*700637cbSDimitry Andric   if (parser.parseFloat(fpType.getFloatSemantics(), parsedValue))
176*700637cbSDimitry Andric     return failure();
177*700637cbSDimitry Andric 
178*700637cbSDimitry Andric   value.emplace(parsedValue);
179*700637cbSDimitry Andric   return success();
180*700637cbSDimitry Andric }
181*700637cbSDimitry Andric 
getZero(Type type)182*700637cbSDimitry Andric FPAttr FPAttr::getZero(Type type) {
183*700637cbSDimitry Andric   return get(type,
184*700637cbSDimitry Andric              APFloat::getZero(
185*700637cbSDimitry Andric                  mlir::cast<cir::FPTypeInterface>(type).getFloatSemantics()));
186*700637cbSDimitry Andric }
187*700637cbSDimitry Andric 
verify(function_ref<InFlightDiagnostic ()> emitError,cir::FPTypeInterface fpType,APFloat value)188*700637cbSDimitry Andric LogicalResult FPAttr::verify(function_ref<InFlightDiagnostic()> emitError,
189*700637cbSDimitry Andric                              cir::FPTypeInterface fpType, APFloat value) {
190*700637cbSDimitry Andric   if (APFloat::SemanticsToEnum(fpType.getFloatSemantics()) !=
191*700637cbSDimitry Andric       APFloat::SemanticsToEnum(value.getSemantics()))
192*700637cbSDimitry Andric     return emitError() << "floating-point semantics mismatch";
193*700637cbSDimitry Andric 
194*700637cbSDimitry Andric   return success();
195*700637cbSDimitry Andric }
196*700637cbSDimitry Andric 
197*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
198*700637cbSDimitry Andric // ConstComplexAttr definitions
199*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
200*700637cbSDimitry Andric 
201*700637cbSDimitry Andric LogicalResult
verify(function_ref<InFlightDiagnostic ()> emitError,cir::ComplexType type,mlir::TypedAttr real,mlir::TypedAttr imag)202*700637cbSDimitry Andric ConstComplexAttr::verify(function_ref<InFlightDiagnostic()> emitError,
203*700637cbSDimitry Andric                          cir::ComplexType type, mlir::TypedAttr real,
204*700637cbSDimitry Andric                          mlir::TypedAttr imag) {
205*700637cbSDimitry Andric   mlir::Type elemType = type.getElementType();
206*700637cbSDimitry Andric   if (real.getType() != elemType)
207*700637cbSDimitry Andric     return emitError()
208*700637cbSDimitry Andric            << "type of the real part does not match the complex type";
209*700637cbSDimitry Andric 
210*700637cbSDimitry Andric   if (imag.getType() != elemType)
211*700637cbSDimitry Andric     return emitError()
212*700637cbSDimitry Andric            << "type of the imaginary part does not match the complex type";
213*700637cbSDimitry Andric 
214*700637cbSDimitry Andric   return success();
215*700637cbSDimitry Andric }
216*700637cbSDimitry Andric 
217*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
218*700637cbSDimitry Andric // CIR ConstArrayAttr
219*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
220*700637cbSDimitry Andric 
221*700637cbSDimitry Andric LogicalResult
verify(function_ref<InFlightDiagnostic ()> emitError,Type type,Attribute elts,int trailingZerosNum)222*700637cbSDimitry Andric ConstArrayAttr::verify(function_ref<InFlightDiagnostic()> emitError, Type type,
223*700637cbSDimitry Andric                        Attribute elts, int trailingZerosNum) {
224*700637cbSDimitry Andric 
225*700637cbSDimitry Andric   if (!(mlir::isa<ArrayAttr, StringAttr>(elts)))
226*700637cbSDimitry Andric     return emitError() << "constant array expects ArrayAttr or StringAttr";
227*700637cbSDimitry Andric 
228*700637cbSDimitry Andric   if (auto strAttr = mlir::dyn_cast<StringAttr>(elts)) {
229*700637cbSDimitry Andric     const auto arrayTy = mlir::cast<ArrayType>(type);
230*700637cbSDimitry Andric     const auto intTy = mlir::dyn_cast<IntType>(arrayTy.getElementType());
231*700637cbSDimitry Andric 
232*700637cbSDimitry Andric     // TODO: add CIR type for char.
233*700637cbSDimitry Andric     if (!intTy || intTy.getWidth() != 8)
234*700637cbSDimitry Andric       return emitError()
235*700637cbSDimitry Andric              << "constant array element for string literals expects "
236*700637cbSDimitry Andric                 "!cir.int<u, 8> element type";
237*700637cbSDimitry Andric     return success();
238*700637cbSDimitry Andric   }
239*700637cbSDimitry Andric 
240*700637cbSDimitry Andric   assert(mlir::isa<ArrayAttr>(elts));
241*700637cbSDimitry Andric   const auto arrayAttr = mlir::cast<mlir::ArrayAttr>(elts);
242*700637cbSDimitry Andric   const auto arrayTy = mlir::cast<ArrayType>(type);
243*700637cbSDimitry Andric 
244*700637cbSDimitry Andric   // Make sure both number of elements and subelement types match type.
245*700637cbSDimitry Andric   if (arrayTy.getSize() != arrayAttr.size() + trailingZerosNum)
246*700637cbSDimitry Andric     return emitError() << "constant array size should match type size";
247*700637cbSDimitry Andric   return success();
248*700637cbSDimitry Andric }
249*700637cbSDimitry Andric 
parse(AsmParser & parser,Type type)250*700637cbSDimitry Andric Attribute ConstArrayAttr::parse(AsmParser &parser, Type type) {
251*700637cbSDimitry Andric   mlir::FailureOr<Type> resultTy;
252*700637cbSDimitry Andric   mlir::FailureOr<Attribute> resultVal;
253*700637cbSDimitry Andric 
254*700637cbSDimitry Andric   // Parse literal '<'
255*700637cbSDimitry Andric   if (parser.parseLess())
256*700637cbSDimitry Andric     return {};
257*700637cbSDimitry Andric 
258*700637cbSDimitry Andric   // Parse variable 'value'
259*700637cbSDimitry Andric   resultVal = FieldParser<Attribute>::parse(parser);
260*700637cbSDimitry Andric   if (failed(resultVal)) {
261*700637cbSDimitry Andric     parser.emitError(
262*700637cbSDimitry Andric         parser.getCurrentLocation(),
263*700637cbSDimitry Andric         "failed to parse ConstArrayAttr parameter 'value' which is "
264*700637cbSDimitry Andric         "to be a `Attribute`");
265*700637cbSDimitry Andric     return {};
266*700637cbSDimitry Andric   }
267*700637cbSDimitry Andric 
268*700637cbSDimitry Andric   // ArrayAttrrs have per-element type, not the type of the array...
269*700637cbSDimitry Andric   if (mlir::isa<ArrayAttr>(*resultVal)) {
270*700637cbSDimitry Andric     // Array has implicit type: infer from const array type.
271*700637cbSDimitry Andric     if (parser.parseOptionalColon().failed()) {
272*700637cbSDimitry Andric       resultTy = type;
273*700637cbSDimitry Andric     } else { // Array has explicit type: parse it.
274*700637cbSDimitry Andric       resultTy = FieldParser<Type>::parse(parser);
275*700637cbSDimitry Andric       if (failed(resultTy)) {
276*700637cbSDimitry Andric         parser.emitError(
277*700637cbSDimitry Andric             parser.getCurrentLocation(),
278*700637cbSDimitry Andric             "failed to parse ConstArrayAttr parameter 'type' which is "
279*700637cbSDimitry Andric             "to be a `::mlir::Type`");
280*700637cbSDimitry Andric         return {};
281*700637cbSDimitry Andric       }
282*700637cbSDimitry Andric     }
283*700637cbSDimitry Andric   } else {
284*700637cbSDimitry Andric     auto ta = mlir::cast<TypedAttr>(*resultVal);
285*700637cbSDimitry Andric     resultTy = ta.getType();
286*700637cbSDimitry Andric     if (mlir::isa<mlir::NoneType>(*resultTy)) {
287*700637cbSDimitry Andric       parser.emitError(parser.getCurrentLocation(),
288*700637cbSDimitry Andric                        "expected type declaration for string literal");
289*700637cbSDimitry Andric       return {};
290*700637cbSDimitry Andric     }
291*700637cbSDimitry Andric   }
292*700637cbSDimitry Andric 
293*700637cbSDimitry Andric   unsigned zeros = 0;
294*700637cbSDimitry Andric   if (parser.parseOptionalComma().succeeded()) {
295*700637cbSDimitry Andric     if (parser.parseOptionalKeyword("trailing_zeros").succeeded()) {
296*700637cbSDimitry Andric       unsigned typeSize =
297*700637cbSDimitry Andric           mlir::cast<cir::ArrayType>(resultTy.value()).getSize();
298*700637cbSDimitry Andric       mlir::Attribute elts = resultVal.value();
299*700637cbSDimitry Andric       if (auto str = mlir::dyn_cast<mlir::StringAttr>(elts))
300*700637cbSDimitry Andric         zeros = typeSize - str.size();
301*700637cbSDimitry Andric       else
302*700637cbSDimitry Andric         zeros = typeSize - mlir::cast<mlir::ArrayAttr>(elts).size();
303*700637cbSDimitry Andric     } else {
304*700637cbSDimitry Andric       return {};
305*700637cbSDimitry Andric     }
306*700637cbSDimitry Andric   }
307*700637cbSDimitry Andric 
308*700637cbSDimitry Andric   // Parse literal '>'
309*700637cbSDimitry Andric   if (parser.parseGreater())
310*700637cbSDimitry Andric     return {};
311*700637cbSDimitry Andric 
312*700637cbSDimitry Andric   return parser.getChecked<ConstArrayAttr>(
313*700637cbSDimitry Andric       parser.getCurrentLocation(), parser.getContext(), resultTy.value(),
314*700637cbSDimitry Andric       resultVal.value(), zeros);
315*700637cbSDimitry Andric }
316*700637cbSDimitry Andric 
print(AsmPrinter & printer) const317*700637cbSDimitry Andric void ConstArrayAttr::print(AsmPrinter &printer) const {
318*700637cbSDimitry Andric   printer << "<";
319*700637cbSDimitry Andric   printer.printStrippedAttrOrType(getElts());
320*700637cbSDimitry Andric   if (getTrailingZerosNum())
321*700637cbSDimitry Andric     printer << ", trailing_zeros";
322*700637cbSDimitry Andric   printer << ">";
323*700637cbSDimitry Andric }
324*700637cbSDimitry Andric 
325*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
326*700637cbSDimitry Andric // CIR ConstVectorAttr
327*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
328*700637cbSDimitry Andric 
329*700637cbSDimitry Andric LogicalResult
verify(function_ref<InFlightDiagnostic ()> emitError,Type type,ArrayAttr elts)330*700637cbSDimitry Andric cir::ConstVectorAttr::verify(function_ref<InFlightDiagnostic()> emitError,
331*700637cbSDimitry Andric                              Type type, ArrayAttr elts) {
332*700637cbSDimitry Andric 
333*700637cbSDimitry Andric   if (!mlir::isa<cir::VectorType>(type))
334*700637cbSDimitry Andric     return emitError() << "type of cir::ConstVectorAttr is not a "
335*700637cbSDimitry Andric                           "cir::VectorType: "
336*700637cbSDimitry Andric                        << type;
337*700637cbSDimitry Andric 
338*700637cbSDimitry Andric   const auto vecType = mlir::cast<cir::VectorType>(type);
339*700637cbSDimitry Andric 
340*700637cbSDimitry Andric   if (vecType.getSize() != elts.size())
341*700637cbSDimitry Andric     return emitError()
342*700637cbSDimitry Andric            << "number of constant elements should match vector size";
343*700637cbSDimitry Andric 
344*700637cbSDimitry Andric   // Check if the types of the elements match
345*700637cbSDimitry Andric   LogicalResult elementTypeCheck = success();
346*700637cbSDimitry Andric   elts.walkImmediateSubElements(
347*700637cbSDimitry Andric       [&](Attribute element) {
348*700637cbSDimitry Andric         if (elementTypeCheck.failed()) {
349*700637cbSDimitry Andric           // An earlier element didn't match
350*700637cbSDimitry Andric           return;
351*700637cbSDimitry Andric         }
352*700637cbSDimitry Andric         auto typedElement = mlir::dyn_cast<TypedAttr>(element);
353*700637cbSDimitry Andric         if (!typedElement ||
354*700637cbSDimitry Andric             typedElement.getType() != vecType.getElementType()) {
355*700637cbSDimitry Andric           elementTypeCheck = failure();
356*700637cbSDimitry Andric           emitError() << "constant type should match vector element type";
357*700637cbSDimitry Andric         }
358*700637cbSDimitry Andric       },
359*700637cbSDimitry Andric       [&](Type) {});
360*700637cbSDimitry Andric 
361*700637cbSDimitry Andric   return elementTypeCheck;
362*700637cbSDimitry Andric }
363*700637cbSDimitry Andric 
364*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
365*700637cbSDimitry Andric // CIR Dialect
366*700637cbSDimitry Andric //===----------------------------------------------------------------------===//
367*700637cbSDimitry Andric 
registerAttributes()368*700637cbSDimitry Andric void CIRDialect::registerAttributes() {
369*700637cbSDimitry Andric   addAttributes<
370*700637cbSDimitry Andric #define GET_ATTRDEF_LIST
371*700637cbSDimitry Andric #include "clang/CIR/Dialect/IR/CIROpsAttributes.cpp.inc"
372*700637cbSDimitry Andric       >();
373*700637cbSDimitry Andric }
374