13#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
16#include "mlir/IR/Attributes.h"
17#include "mlir/IR/DialectImplementation.h"
18#include "llvm/ADT/TypeSwitch.h"
26 mlir::ArrayAttr &members);
33 cir::IntTypeInterface ty);
36 cir::IntTypeInterface ty);
43static mlir::ParseResult
45 mlir::FailureOr<llvm::APFloat> &value,
46 cir::FPTypeInterface fpType);
49 mlir::IntegerAttr &value);
53static mlir::ParseResult
55 mlir::DenseI32ArrayAttr &memberPath);
58 mlir::DenseI32ArrayAttr memberPath);
60#define GET_ATTRDEF_CLASSES
61#include "clang/CIR/Dialect/IR/CIROpsAttributes.cpp.inc"
71bool LangAddressSpaceAttr::isValidLoad(
72 mlir::Type type, mlir::ptr::AtomicOrdering ordering,
73 std::optional<int64_t> alignment,
const mlir::DataLayout *dataLayout,
74 llvm::function_ref<mlir::InFlightDiagnostic()> emitError)
const {
75 llvm_unreachable(
"isValidLoad for LangAddressSpaceAttr NYI");
78bool LangAddressSpaceAttr::isValidStore(
79 mlir::Type type, mlir::ptr::AtomicOrdering ordering,
80 std::optional<int64_t> alignment,
const mlir::DataLayout *dataLayout,
81 llvm::function_ref<mlir::InFlightDiagnostic()> emitError)
const {
82 llvm_unreachable(
"isValidStore for LangAddressSpaceAttr NYI");
85bool LangAddressSpaceAttr::isValidAtomicOp(
86 mlir::ptr::AtomicBinOp op, mlir::Type type,
87 mlir::ptr::AtomicOrdering ordering, std::optional<int64_t> alignment,
88 const mlir::DataLayout *dataLayout,
89 llvm::function_ref<mlir::InFlightDiagnostic()> emitError)
const {
90 llvm_unreachable(
"isValidAtomicOp for LangAddressSpaceAttr NYI");
93bool LangAddressSpaceAttr::isValidAtomicXchg(
94 mlir::Type type, mlir::ptr::AtomicOrdering successOrdering,
95 mlir::ptr::AtomicOrdering failureOrdering, std::optional<int64_t> alignment,
96 const mlir::DataLayout *dataLayout,
97 llvm::function_ref<mlir::InFlightDiagnostic()> emitError)
const {
98 llvm_unreachable(
"isValidAtomicXchg for LangAddressSpaceAttr NYI");
101bool LangAddressSpaceAttr::isValidAddrSpaceCast(
102 mlir::Type tgt, mlir::Type src,
103 llvm::function_ref<mlir::InFlightDiagnostic()> emitError)
const {
104 llvm_unreachable(
"isValidAddrSpaceCast for LangAddressSpaceAttr NYI");
107bool LangAddressSpaceAttr::isValidPtrIntCast(
108 mlir::Type intLikeTy, mlir::Type ptrLikeTy,
109 llvm::function_ref<mlir::InFlightDiagnostic()> emitError)
const {
110 llvm_unreachable(
"isValidPtrIntCast for LangAddressSpaceAttr NYI");
113bool TargetAddressSpaceAttr::isValidLoad(
114 mlir::Type type, mlir::ptr::AtomicOrdering ordering,
115 std::optional<int64_t> alignment,
const mlir::DataLayout *dataLayout,
116 llvm::function_ref<mlir::InFlightDiagnostic()> emitError)
const {
117 llvm_unreachable(
"isValidLoad for TargetAddressSpaceAttr NYI");
120bool TargetAddressSpaceAttr::isValidStore(
121 mlir::Type type, mlir::ptr::AtomicOrdering ordering,
122 std::optional<int64_t> alignment,
const mlir::DataLayout *dataLayout,
123 llvm::function_ref<mlir::InFlightDiagnostic()> emitError)
const {
124 llvm_unreachable(
"isValidStore for TargetAddressSpaceAttr NYI");
127bool TargetAddressSpaceAttr::isValidAtomicOp(
128 mlir::ptr::AtomicBinOp op, mlir::Type type,
129 mlir::ptr::AtomicOrdering ordering, std::optional<int64_t> alignment,
130 const mlir::DataLayout *dataLayout,
131 llvm::function_ref<mlir::InFlightDiagnostic()> emitError)
const {
132 llvm_unreachable(
"isValidAtomicOp for TargetAddressSpaceAttr NYI");
135bool TargetAddressSpaceAttr::isValidAtomicXchg(
136 mlir::Type type, mlir::ptr::AtomicOrdering successOrdering,
137 mlir::ptr::AtomicOrdering failureOrdering, std::optional<int64_t> alignment,
138 const mlir::DataLayout *dataLayout,
139 llvm::function_ref<mlir::InFlightDiagnostic()> emitError)
const {
140 llvm_unreachable(
"isValidAtomicXchg for TargetAddressSpaceAttr NYI");
143bool TargetAddressSpaceAttr::isValidAddrSpaceCast(
144 mlir::Type tgt, mlir::Type src,
145 llvm::function_ref<mlir::InFlightDiagnostic()> emitError)
const {
146 llvm_unreachable(
"isValidAddrSpaceCast for TargetAddressSpaceAttr NYI");
149bool TargetAddressSpaceAttr::isValidPtrIntCast(
150 mlir::Type intLikeTy, mlir::Type ptrLikeTy,
151 llvm::function_ref<mlir::InFlightDiagnostic()> emitError)
const {
152 llvm_unreachable(
"isValidPtrIntCast for TargetAddressSpaceAttr NYI");
159LogicalResult PtrSpecAttr::verify(function_ref<InFlightDiagnostic()> emitError,
162 constexpr unsigned kBitsInByte = 8;
163 if (size % kBitsInByte != 0)
164 return emitError() <<
"size entry must be divisible by 8";
165 if (abi % kBitsInByte != 0)
166 return emitError() <<
"abi entry must be divisible by 8";
167 if (preferred % kBitsInByte != 0)
168 return emitError() <<
"preferred entry must be divisible by 8";
169 if (index != kOptionalSpecValue && index % kBitsInByte != 0)
170 return emitError() <<
"index entry must be divisible by 8";
172 return emitError() <<
"preferred alignment is expected to be at least "
173 "as large as ABI alignment";
182BitFieldDeclAttr::verify(function_ref<InFlightDiagnostic()> emitError,
183 mlir::Type declaredType, uint64_t width,
185 if (width == 0 && !isUnnamed)
186 return emitError() <<
"zero-width bit-field cannot be named";
195 mlir::ArrayAttr members) {
197 llvm::interleaveComma(members, printer);
202 mlir::ArrayAttr &members) {
205 auto delimiter = AsmParser::Delimiter::Braces;
206 auto result = parser.parseCommaSeparatedList(delimiter, [&]() {
207 mlir::TypedAttr attr;
208 if (parser.parseAttribute(attr).failed())
209 return mlir::failure();
210 elts.push_back(attr);
211 return mlir::success();
215 return mlir::failure();
217 members = mlir::ArrayAttr::get(parser.getContext(), elts);
218 return mlir::success();
226 mlir::Type initType) {
227 auto memberArrayType = mlir::dyn_cast<cir::ArrayType>(memberType);
228 auto initArrayType = mlir::dyn_cast<cir::ArrayType>(initType);
229 return memberArrayType && memberArrayType.getSize() == 0 && initArrayType &&
230 memberArrayType.getElementType() == initArrayType.getElementType();
234ConstRecordAttr::verify(function_ref<InFlightDiagnostic()> emitError,
235 mlir::Type type, ArrayAttr members) {
236 auto sTy = mlir::dyn_cast_if_present<cir::RecordType>(type);
238 return emitError() <<
"expected !cir.struct or !cir.union type";
243 if (members.size() != 1)
244 return emitError() <<
"union constant must have exactly one element, got "
246 auto m = mlir::cast<mlir::TypedAttr>(members[0]);
248 if (!llvm::any_of(sTy.getMembers(), [&](mlir::Type memberTy) {
249 mlir::Type storageType = cir::memberStorageType(memberTy);
250 return storageType == m.getType() ||
251 isValidFlexibleArrayInit(storageType, m.getType());
253 return emitError() <<
"union element type " << m.getType()
254 <<
" is not a member of " << sTy;
262 for (mlir::Type memberTy : sTy.getMembers())
266 if (storedMembers.size() != members.size())
267 return emitError() <<
"number of elements must match";
269 for (
const auto &[attrIdx, member] : llvm::enumerate(storedMembers)) {
270 auto m = mlir::cast<mlir::TypedAttr>(members[attrIdx]);
275 if (attrIdx == storedMembers.size() - 1) {
276 auto memArrayTy = dyn_cast<cir::ArrayType>(member);
277 if (memArrayTy && memArrayTy.getSize() == 0) {
280 if (!isa<cir::ArrayType>(m.getType()))
282 <<
"element at index " << attrIdx <<
" has type "
283 << m.getType() <<
" but the expected type for this element is "
286 cir::ArrayType initArrayTy = cast<cir::ArrayType>(m.getType());
288 if (initArrayTy.getElementType() != memArrayTy.getElementType())
290 <<
"flexible array member at index " << attrIdx <<
" has type "
292 <<
" which doesn't match the expected element type of member "
298 if (member != m.getType())
299 return emitError() <<
"element at index " << attrIdx <<
" has type "
301 <<
" but the expected type for this element is "
312LogicalResult OptInfoAttr::verify(function_ref<InFlightDiagnostic()> emitError,
313 unsigned level,
unsigned size) {
316 <<
"optimization level must be between 0 and 3 inclusive";
319 <<
"size optimization level must be between 0 and 2 inclusive";
329static ParseResult
parseConstPtr(AsmParser &parser, mlir::IntegerAttr &value) {
331 if (parser.parseOptionalKeyword(
"null").succeeded()) {
332 value = parser.getBuilder().getI64IntegerAttr(0);
336 return parser.parseAttribute(value);
347 mlir::DenseI32ArrayAttr &memberPath) {
348 if (parser.parseOptionalKeyword(
"null").succeeded())
351 auto parsed = mlir::FieldParser<mlir::DenseI32ArrayAttr>::parse(parser);
352 if (mlir::failed(parsed))
354 memberPath = *parsed;
359 mlir::DenseI32ArrayAttr memberPath) {
363 p.printStrippedAttrOrType(memberPath);
371 cir::IntTypeInterface ty) {
372 llvm::SMLoc loc = parser.getCurrentLocation();
374 mlir::OptionalParseResult result = parser.parseOptionalInteger(parsed);
375 if (!result.has_value() || failed(*result))
376 return parser.emitError(loc,
"expected integer value");
378 const unsigned width = ty.getWidth();
380 ty.isSigned() ? parsed.getSignificantBits() <= width
381 : !parsed.isNegative() && parsed.getActiveBits() <= width;
383 return parser.emitError(loc,
"integer value too large for the given type");
385 value = ty.isSigned() ? parsed.sextOrTrunc(width) : parsed.zextOrTrunc(width);
390 cir::IntTypeInterface ty) {
392 value.toString(str, 10, ty.isSigned());
396LogicalResult IntAttr::verify(function_ref<InFlightDiagnostic()> emitError,
397 cir::IntTypeInterface type, llvm::APInt value) {
398 if (value.getBitWidth() != type.getWidth())
399 return emitError() <<
"type and value bitwidth mismatch: "
400 << type.getWidth() <<
" != " << value.getBitWidth();
413 FailureOr<APFloat> &value,
414 cir::FPTypeInterface fpType) {
416 APFloat parsedValue(0.0);
417 if (parser.parseFloat(fpType.getFloatSemantics(), parsedValue))
420 value.emplace(parsedValue);
428MemoryEffectsAttr MemoryEffectsAttr::none(MLIRContext *ctx) {
429 return get(ctx, ModRefInfo::NoModRef);
432MemoryEffectsAttr MemoryEffectsAttr::readOnly(MLIRContext *ctx) {
433 return get(ctx, ModRefInfo::Ref);
436MemoryEffectsAttr MemoryEffectsAttr::writeOnly(MLIRContext *ctx) {
437 return get(ctx, ModRefInfo::Mod);
440MemoryEffectsAttr MemoryEffectsAttr::argMemOnly(MLIRContext *ctx,
442 return get(ctx, ModRefInfo::NoModRef, mr,
443 ModRefInfo::NoModRef,
444 ModRefInfo::NoModRef,
445 ModRefInfo::NoModRef,
446 ModRefInfo::NoModRef);
449MemoryEffectsAttr MemoryEffectsAttr::inaccessibleMemOnly(MLIRContext *ctx,
451 return get(ctx, ModRefInfo::NoModRef,
452 ModRefInfo::NoModRef, mr,
453 ModRefInfo::NoModRef,
454 ModRefInfo::NoModRef,
455 ModRefInfo::NoModRef);
458MemoryEffectsAttr MemoryEffectsAttr::errnoMemOnly(MLIRContext *ctx,
460 return get(ctx, ModRefInfo::NoModRef,
461 ModRefInfo::NoModRef,
462 ModRefInfo::NoModRef, mr,
463 ModRefInfo::NoModRef,
464 ModRefInfo::NoModRef);
467MemoryEffectsAttr MemoryEffectsAttr::otherMemOnly(MLIRContext *ctx,
469 return get(ctx, mr, ModRefInfo::NoModRef,
470 ModRefInfo::NoModRef,
471 ModRefInfo::NoModRef,
472 ModRefInfo::NoModRef,
473 ModRefInfo::NoModRef);
476MemoryEffectsAttr MemoryEffectsAttr::inaccessibleOrArgMemOnly(MLIRContext *ctx,
478 return get(ctx, ModRefInfo::NoModRef, mr,
479 mr, ModRefInfo::NoModRef,
480 ModRefInfo::NoModRef,
481 ModRefInfo::NoModRef);
484MemoryEffectsAttr MemoryEffectsAttr::inaccessibleOrErrnoMemOnly(
485 MLIRContext *ctx, ModRefInfo inaccessibleMr, ModRefInfo errnoMr) {
486 return get(ctx, ModRefInfo::NoModRef,
487 ModRefInfo::NoModRef,
488 inaccessibleMr, errnoMr,
489 ModRefInfo::NoModRef,
490 ModRefInfo::NoModRef);
493MemoryEffectsAttr MemoryEffectsAttr::inaccessibleOrArgOrErrnoMemOnly(
494 MLIRContext *ctx, ModRefInfo inaccessibleOrArgMr, ModRefInfo errnoMr) {
495 return get(ctx, ModRefInfo::NoModRef,
497 inaccessibleOrArgMr, errnoMr,
498 ModRefInfo::NoModRef,
499 ModRefInfo::NoModRef);
503MemoryEffectsAttr::argumentOrErrnoMemOnly(MLIRContext *ctx, ModRefInfo argMr,
504 ModRefInfo errnoMr) {
505 return get(ctx, ModRefInfo::NoModRef, argMr,
506 ModRefInfo::NoModRef, errnoMr,
507 ModRefInfo::NoModRef,
508 ModRefInfo::NoModRef);
511FPAttr FPAttr::getZero(Type type) {
514 mlir::cast<cir::FPTypeInterface>(type).getFloatSemantics()));
517LogicalResult FPAttr::verify(function_ref<InFlightDiagnostic()> emitError,
518 cir::FPTypeInterface fpType, APFloat value) {
519 if (APFloat::SemanticsToEnum(fpType.getFloatSemantics()) !=
520 APFloat::SemanticsToEnum(value.getSemantics()))
521 return emitError() <<
"floating-point semantics mismatch";
530std::string CmpThreeWayInfoAttr::getAlias()
const {
531 std::string alias =
"cmpinfo";
533 switch (getOrdering()) {
534 case CmpOrdering::Strong:
535 alias.append(
"_strong_");
537 case CmpOrdering::Weak:
538 alias.append(
"_weak_");
540 case CmpOrdering::Partial:
541 alias.append(
"_partial_");
545 auto appendInt = [&](int64_t value) {
547 alias.push_back(
'n');
550 alias.append(std::to_string(value));
560 if (std::optional<int> unordered = getUnordered()) {
562 appendInt(unordered.value());
569CmpThreeWayInfoAttr::verify(function_ref<InFlightDiagnostic()> emitError,
570 CmpOrdering ordering, int64_t lt, int64_t eq,
571 int64_t gt, std::optional<int64_t> unordered) {
573 if ((ordering == CmpOrdering::Strong || ordering == CmpOrdering::Weak) &&
575 emitError() <<
"strong and weak ordering do not include unordered";
578 if (ordering == CmpOrdering::Partial && !unordered) {
579 emitError() <<
"partial ordering requires unordered value";
591ConstComplexAttr::verify(function_ref<InFlightDiagnostic()> emitError,
592 cir::ComplexType type, mlir::TypedAttr real,
593 mlir::TypedAttr imag) {
594 mlir::Type elemType = type.getElementType();
595 if (real.getType() != elemType)
597 <<
"type of the real part does not match the complex type";
599 if (imag.getType() != elemType)
601 <<
"type of the imaginary part does not match the complex type";
610void CUDAVarRegistrationInfoAttr::print(AsmPrinter &p)
const {
611 p <<
"<" << getDeviceSideName();
612 p <<
", " << stringifyEnum(
getKind());
622Attribute CUDAVarRegistrationInfoAttr::parse(AsmParser &parser, Type odsType) {
623 if (parser.parseLess())
626 std::string deviceSideName;
627 if (parser.parseKeywordOrString(&deviceSideName)) {
628 parser.emitError(parser.getCurrentLocation(),
629 "expected device variable name");
633 if (parser.parseComma())
638 if (parser.parseKeyword(&kindStr))
641 std::optional<CUDADeviceVarKind>
kind = symbolizeCUDADeviceVarKind(kindStr);
643 parser.emitError(parser.getCurrentLocation(),
644 "unknown device variable kind: ")
650 bool isExtern =
false;
651 bool isConstant =
false;
652 bool isManaged =
false;
654 while (parser.parseOptionalGreater().failed()) {
655 if (parser.parseComma())
659 if (parser.parseKeyword(&flag))
662 if (flag ==
"extern")
664 else if (flag ==
"constant")
666 else if (flag ==
"managed")
669 parser.emitError(parser.getCurrentLocation(),
"unknown flag: ") << flag;
674 return get(parser.getContext(), deviceSideName, *
kind, isExtern, isConstant,
683DataMemberAttr::verify(function_ref<InFlightDiagnostic()> emitError,
684 cir::DataMemberType ty,
685 mlir::DenseI32ArrayAttr memberPath) {
689 if (memberPath.empty())
690 return emitError() <<
"#cir.data_member path must not be empty";
692 mlir::Type currentTy = ty.getClassTy();
693 for (
auto [
step, idx] : llvm::enumerate(memberPath.asArrayRef())) {
694 auto recTy = mlir::dyn_cast<cir::RecordType>(currentTy);
696 return emitError() <<
"#cir.data_member path step " <<
step
697 <<
" reaches a non-record type";
699 if (recTy.isIncomplete())
702 if (idx < 0 ||
static_cast<unsigned>(idx) >= recTy.getNumElements())
703 return emitError() <<
"#cir.data_member path index " << idx <<
" at step "
704 <<
step <<
" is out of range";
706 currentTy = recTy.getMembers()[idx];
709 if (currentTy != ty.getMemberTy())
711 <<
"member type of a #cir.data_member attribute must match "
712 "the attribute type";
721LogicalResult MethodAttr::verify(function_ref<InFlightDiagnostic()> emitError,
722 cir::MethodType type,
723 std::optional<FlatSymbolRefAttr> symbol,
724 std::optional<uint64_t> vtable_offset) {
725 if (symbol.has_value() && vtable_offset.has_value())
727 <<
"at most one of symbol and vtable_offset can be present "
733Attribute MethodAttr::parse(AsmParser &parser, Type odsType) {
734 auto ty = mlir::cast<cir::MethodType>(odsType);
736 if (parser.parseLess().failed())
740 if (parser.parseOptionalKeyword(
"null").succeeded()) {
741 if (parser.parseGreater().failed())
748 FlatSymbolRefAttr symbol;
749 mlir::OptionalParseResult parseSymbolRefResult =
750 parser.parseOptionalAttribute(symbol);
751 if (parseSymbolRefResult.has_value()) {
752 if (parseSymbolRefResult.value().failed())
754 if (parser.parseGreater().failed())
756 return get(ty, symbol);
760 std::uint64_t vtableOffset = 0;
761 if (parser.parseKeyword(
"vtable_offset"))
763 if (parser.parseEqual())
765 if (parser.parseInteger(vtableOffset))
768 if (parser.parseGreater())
771 return get(ty, vtableOffset);
774void MethodAttr::print(AsmPrinter &printer)
const {
775 auto symbol = getSymbol();
776 auto vtableOffset = getVtableOffset();
779 if (symbol.has_value()) {
781 }
else if (vtableOffset.has_value()) {
782 printer <<
"vtable_offset = " << *vtableOffset;
794ConstArrayAttr::verify(function_ref<InFlightDiagnostic()> emitError, Type type,
795 Attribute elts,
int trailingZerosNum) {
797 if (!(mlir::isa<ArrayAttr, StringAttr>(elts)))
798 return emitError() <<
"constant array expects ArrayAttr or StringAttr";
800 if (
auto strAttr = mlir::dyn_cast<StringAttr>(elts)) {
801 const auto arrayTy = mlir::cast<ArrayType>(type);
802 const auto intTy = mlir::dyn_cast<IntType>(arrayTy.getElementType());
805 if (!intTy || intTy.getWidth() != 8)
807 <<
"constant array element for string literals expects "
808 "!cir.int<u, 8> element type";
812 assert(mlir::isa<ArrayAttr>(elts));
813 const auto arrayAttr = mlir::cast<mlir::ArrayAttr>(elts);
814 const auto arrayTy = mlir::cast<ArrayType>(type);
817 if (arrayAttr.size() > arrayTy.getSize())
818 return emitError() <<
"constant array has " << arrayAttr.size()
819 <<
" values but array type has size "
820 << arrayTy.getSize();
821 if (arrayTy.getSize() != arrayAttr.size() + trailingZerosNum)
822 return emitError() <<
"constant array size should match type size";
826Attribute ConstArrayAttr::parse(AsmParser &parser, Type type) {
827 mlir::FailureOr<Type> resultTy;
828 mlir::FailureOr<Attribute> resultVal;
831 if (parser.parseLess())
835 resultVal = FieldParser<Attribute>::parse(parser);
836 if (failed(resultVal)) {
838 parser.getCurrentLocation(),
839 "failed to parse ConstArrayAttr parameter 'value' which is "
840 "to be a `Attribute`");
845 if (mlir::isa<ArrayAttr>(*resultVal)) {
847 if (parser.parseOptionalColon().failed()) {
850 resultTy = FieldParser<Type>::parse(parser);
851 if (failed(resultTy)) {
853 parser.getCurrentLocation(),
854 "failed to parse ConstArrayAttr parameter 'type' which is "
855 "to be a `::mlir::Type`");
860 auto ta = mlir::cast<TypedAttr>(*resultVal);
861 resultTy = ta.getType();
862 if (mlir::isa<mlir::NoneType>(*resultTy)) {
863 parser.emitError(parser.getCurrentLocation(),
864 "expected type declaration for string literal");
870 if (parser.parseOptionalComma().succeeded()) {
871 if (parser.parseOptionalKeyword(
"trailing_zeros").succeeded()) {
872 unsigned totalSize = mlir::cast<cir::ArrayType>(type).getSize();
873 mlir::Attribute elts = resultVal.value();
874 if (
auto str = mlir::dyn_cast<mlir::StringAttr>(elts))
875 zeros = totalSize - str.size();
877 zeros = totalSize - mlir::cast<mlir::ArrayAttr>(elts).size();
884 if (parser.parseGreater())
887 return parser.getChecked<ConstArrayAttr>(parser.getCurrentLocation(),
888 parser.getContext(), type,
889 resultVal.value(), zeros);
892void ConstArrayAttr::print(AsmPrinter &printer)
const {
894 printer.printStrippedAttrOrType(getElts());
895 if (getTrailingZerosNum())
896 printer <<
", trailing_zeros";
905cir::ConstVectorAttr::verify(function_ref<InFlightDiagnostic()> emitError,
906 Type type, ArrayAttr elts) {
908 if (!mlir::isa<cir::VectorType>(type))
909 return emitError() <<
"type of cir::ConstVectorAttr is not a "
913 const auto vecType = mlir::cast<cir::VectorType>(type);
915 if (vecType.isScalable())
916 return emitError() <<
"scalable vector constants are not supported";
918 if (vecType.getFixedSize() != elts.size())
920 <<
"number of constant elements should match vector size";
923 LogicalResult elementTypeCheck =
success();
924 elts.walkImmediateSubElements(
925 [&](Attribute element) {
926 if (elementTypeCheck.failed()) {
930 auto typedElement = mlir::dyn_cast<TypedAttr>(element);
932 typedElement.getType() != vecType.getElementType()) {
933 elementTypeCheck = failure();
934 emitError() <<
"constant type should match vector element type";
939 return elementTypeCheck;
946LogicalResult cir::VTableAttr::verify(
947 llvm::function_ref<mlir::InFlightDiagnostic()> emitError, mlir::Type type,
948 mlir::ArrayAttr data) {
949 auto sTy = mlir::dyn_cast_if_present<cir::RecordType>(type);
951 return emitError() <<
"expected !cir.struct or !cir.union type result";
952 if (sTy.getMembers().empty() || data.empty())
953 return emitError() <<
"expected record type with one or more subtype";
955 if (cir::ConstRecordAttr::verify(emitError, type, data).failed())
958 for (
const auto &element : data.getAsRange<mlir::Attribute>()) {
959 const auto &constArrayAttr = mlir::dyn_cast<cir::ConstArrayAttr>(element);
961 return emitError() <<
"expected constant array subtype";
963 LogicalResult eltTypeCheck =
success();
964 auto arrayElts = mlir::cast<ArrayAttr>(constArrayAttr.getElts());
965 arrayElts.walkImmediateSubElements(
966 [&](mlir::Attribute attr) {
967 if (mlir::isa<ConstPtrAttr, GlobalViewAttr>(attr))
970 eltTypeCheck = emitError()
971 <<
"expected GlobalViewAttr or ConstPtrAttr";
973 [&](mlir::Type type) {});
974 if (eltTypeCheck.failed())
984std::string DynamicCastInfoAttr::getAlias()
const {
987 std::string alias =
"dyn_cast_info_";
989 alias.append(getSrcRtti().getSymbol().getValue());
990 alias.push_back(
'_');
991 alias.append(getDestRtti().getSymbol().getValue());
999 auto ptrTy = mlir::dyn_cast<cir::PointerType>(ty);
1003 auto pointeeIntTy = mlir::dyn_cast<cir::IntType>(ptrTy.getPointee());
1007 return pointeeIntTy.isUnsigned() && pointeeIntTy.getWidth() == 8;
1010LogicalResult DynamicCastInfoAttr::verify(
1011 function_ref<InFlightDiagnostic()> emitError, cir::GlobalViewAttr srcRtti,
1012 cir::GlobalViewAttr destRtti, mlir::FlatSymbolRefAttr runtimeFunc,
1013 mlir::FlatSymbolRefAttr badCastFunc, cir::IntAttr offsetHint) {
1015 return emitError() <<
"srcRtti must be an RTTI pointer";
1018 return emitError() <<
"destRtti must be an RTTI pointer";
1027LogicalResult EhFilterAttr::verify(function_ref<InFlightDiagnostic()> emitError,
1028 mlir::ArrayAttr permittedTypes) {
1029 for (mlir::Attribute typeAttr : permittedTypes) {
1030 auto rtti = mlir::dyn_cast<cir::GlobalViewAttr>(typeAttr);
1031 if (!rtti || !
isRttiPtr(rtti.getType()))
1032 return emitError() <<
"permitted type list must contain only type info "
1044 mlir::StringAttr name) {
1047 auto dict = mod->getAttrOfType<mlir::DictionaryAttr>(
1048 CIRDialect::getRecordLayoutsAttrName());
1051 return dict.getAs<RecordLayoutAttr>(name);
1055 mlir::StringAttr name) {
1057 assert(attr &&
"record layout entry missing for named record");
1065void CIRDialect::registerAttributes() {
1067#define GET_ATTRDEF_LIST
1068#include "clang/CIR/Dialect/IR/CIROpsAttributes.cpp.inc"
static mlir::ParseResult parseFloatLiteral(mlir::AsmParser &parser, mlir::FailureOr< llvm::APFloat > &value, cir::FPTypeInterface fpType)
static void printConstPtr(mlir::AsmPrinter &p, mlir::IntegerAttr value)
static void printRecordMembers(mlir::AsmPrinter &p, mlir::ArrayAttr members)
static mlir::ParseResult parseIntLiteral(mlir::AsmParser &parser, llvm::APInt &value, cir::IntTypeInterface ty)
static void printIntLiteral(mlir::AsmPrinter &p, llvm::APInt value, cir::IntTypeInterface ty)
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 parseDataMemberPath(mlir::AsmParser &parser, mlir::DenseI32ArrayAttr &memberPath)
static bool isRttiPtr(mlir::Type ty)
static void printDataMemberPath(mlir::AsmPrinter &p, mlir::DenseI32ArrayAttr memberPath)
static mlir::ParseResult parseRecordMembers(mlir::AsmParser &parser, mlir::ArrayAttr &members)
static bool isValidFlexibleArrayInit(mlir::Type memberType, mlir::Type initType)
static Decl::Kind getKind(const Decl *D)
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
RecordLayoutAttr tryGetRecordLayout(mlir::ModuleOp mod, mlir::StringAttr name)
Same lookup as getRecordLayout, but returns a null attribute instead of asserting when the record has...
RecordLayoutAttr getRecordLayout(mlir::ModuleOp mod, mlir::StringAttr name)
Look up the RecordLayoutAttr for a named record in the module's cir.record_layouts dictionary.
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...
bool memberOwnsBytes(mlir::Type memberTy)
Whether a record member occupies bytes of its record.
float __ovld __cnfn step(float, float)
Returns 0.0 if x < edge, otherwise it returns 1.0.