52 case Token::kw_affine_map: {
56 if (
parseToken(Token::less,
"expected '<' in affine map") ||
58 parseToken(Token::greater,
"expected '>' in affine map"))
60 return AffineMapAttr::get(map);
62 case Token::kw_affine_set: {
66 if (
parseToken(Token::less,
"expected '<' in integer set") ||
68 parseToken(Token::greater,
"expected '>' in integer set"))
70 return IntegerSetAttr::get(set);
74 case Token::l_square: {
77 auto parseElt = [&]() -> ParseResult {
79 return elements.back() ?
success() : failure();
84 return builder.getArrayAttr(elements);
90 return builder.getBoolAttr(
false);
93 return builder.getBoolAttr(
true);
100 case Token::kw_dense_resource:
104 case Token::kw_array:
108 case Token::l_brace: {
116 case Token::hash_identifier:
120 case Token::floatliteral:
128 if (
getToken().is(Token::floatliteral))
132 "expected constant integer or floating point value"),
137 case Token::kw_loc: {
141 if (
parseToken(Token::l_paren,
"expected '(' in inline location") ||
143 parseToken(Token::r_paren,
"expected ')' in inline location"))
149 case Token::kw_sparse:
153 case Token::kw_strided:
157 case Token::kw_distinct:
161 case Token::string: {
168 return type ? StringAttr::get(val, type)
173 case Token::at_identifier: {
178 referenceLocations.push_back(
getToken().getLocRange());
185 std::vector<FlatSymbolRefAttr> nestedRefs;
186 while (
getToken().is(Token::colon)) {
191 if (
getToken().isNot(Token::eof, Token::error)) {
192 state.lex.resetPointer(curPointer);
199 if (
getToken().isNot(Token::at_identifier)) {
200 emitError(curLoc,
"expected nested symbol reference identifier");
207 referenceLocations.push_back(
getToken().getLocRange());
211 nestedRefs.push_back(SymbolRefAttr::get(
getContext(), nameStr));
213 SymbolRefAttr symbolRefAttr =
214 SymbolRefAttr::get(
getContext(), nameStr, nestedRefs);
218 state.asmState->addUses(symbolRefAttr, referenceLocations);
219 return symbolRefAttr;
228 case Token::code_complete:
229 if (
getToken().isCodeCompletionFor(Token::hash_identifier))
248 case Token::at_identifier:
249 case Token::floatliteral:
251 case Token::hash_identifier:
252 case Token::kw_affine_map:
253 case Token::kw_affine_set:
254 case Token::kw_dense:
255 case Token::kw_dense_resource:
256 case Token::kw_false:
258 case Token::kw_sparse:
262 case Token::l_square:
266 return success(attribute !=
nullptr);
273 attribute = TypeAttr::get(type);
297 llvm::SmallDenseSet<StringAttr> seenKeys;
298 auto parseElt = [&]() -> ParseResult {
300 std::optional<StringAttr> nameId;
303 else if (
getToken().isAny(Token::bare_identifier, Token::inttype) ||
310 return emitError(
"expected valid attribute name");
312 if (!seenKeys.insert(*nameId).second)
314 << nameId->getValue() <<
"' in dictionary attribute";
318 auto splitName = nameId->strref().split(
'.');
319 if (!splitName.second.empty())
337 " in attribute dictionary");
345 return (
emitError(
"floating point value too large for attribute"),
nullptr);
354 if (!isa<FloatType>(type))
355 return (
emitError(
"floating point value not valid for specified type"),
360 if (isNegative && !APFloat::semanticsHasSignedRepr(
361 cast<FloatType>(type).getFloatSemantics()))
362 return (
emitError(loc,
"negative floating point literal for a type with no "
363 "signed representation"),
365 return FloatAttr::get(type, isNegative ? -*val : *val);
371 StringRef spelling) {
374 bool isHex = spelling.size() > 1 && spelling[1] ==
'x';
375 if (spelling.getAsInteger(isHex ? 0 : 10,
result))
379 unsigned width = type.
isIndex() ? IndexType::kInternalStorageBitWidth
382 if (width >
result.getBitWidth()) {
384 }
else if (width <
result.getBitWidth()) {
387 if (
result.countl_zero() <
result.getBitWidth() - width)
398 }
else if (isNegative) {
402 if (!
result.isSignBitSet())
425 type =
builder.getIntegerType(64);
430 if (
auto floatType = dyn_cast<FloatType>(type)) {
431 std::optional<APFloat>
result;
433 floatType.getFloatSemantics())))
435 return FloatAttr::get(floatType, *
result);
438 if (!isa<IntegerType, IndexType>(type))
439 return emitError(loc,
"integer literal not valid for specified type"),
444 "negative integer literal not valid for unsigned integer type");
450 return emitError(loc,
"integer constant out of range for attribute"),
452 return builder.getIntegerAttr(type, *apInt);
464 result = std::move(*value);
468 tok.
getLoc(),
"expected string containing hex digits starting with `0x`");
475class TensorLiteralParser {
477 TensorLiteralParser(Parser &p) : p(p) {}
481 ParseResult
parse(
bool allowHex);
485 DenseElementsAttr getAttr(SMLoc loc, ShapedType type);
487 ArrayRef<int64_t>
getShape()
const {
return shape; }
491 ParseResult getIntAttrElements(SMLoc loc, Type eltTy,
492 std::vector<APInt> &intValues);
495 ParseResult getFloatAttrElements(SMLoc loc, FloatType eltTy,
496 std::vector<APFloat> &floatValues);
499 DenseElementsAttr getStringAttr(SMLoc loc, ShapedType type, Type eltTy);
502 DenseElementsAttr getHexAttr(SMLoc loc, ShapedType type);
508 ParseResult parseElement();
516 ParseResult parseList(SmallVectorImpl<int64_t> &dims);
519 ParseResult parseHexElements();
524 SmallVector<int64_t, 4> shape;
527 std::vector<std::pair<bool, Token>> storage;
530 std::optional<Token> hexStorage;
536ParseResult TensorLiteralParser::parse(
bool allowHex) {
538 if (allowHex && p.getToken().is(Token::string)) {
539 hexStorage = p.getToken();
540 p.consumeToken(Token::string);
544 if (p.getToken().is(Token::l_square))
545 return parseList(shape);
546 return parseElement();
551DenseElementsAttr TensorLiteralParser::getAttr(SMLoc loc, ShapedType type) {
552 Type eltType = type.getElementType();
557 return getHexAttr(loc, type);
561 if (!shape.empty() &&
getShape() != type.getShape()) {
562 p.emitError(loc) <<
"inferred shape of elements literal ([" <<
getShape()
563 <<
"]) does not match type ([" << type.getShape() <<
"])";
568 if (!hexStorage && storage.empty() && type.getNumElements()) {
569 p.emitError(loc) <<
"parsed zero elements, but type (" << type
570 <<
") expected at least 1";
575 bool isComplex =
false;
576 if (ComplexType complexTy = dyn_cast<ComplexType>(eltType)) {
577 eltType = complexTy.getElementType();
581 bool isSplat = shape.empty() && type.getNumElements() != 0;
582 if (isSplat && storage.size() != 2) {
583 p.emitError(loc) <<
"parsed " << storage.size() <<
" elements, but type ("
584 << complexTy <<
") expected 2 elements";
587 if (!shape.empty() &&
588 storage.size() !=
static_cast<size_t>(type.getNumElements()) * 2) {
589 p.emitError(loc) <<
"parsed " << storage.size() <<
" elements, but type ("
590 << type <<
") expected " << type.getNumElements() * 2
598 std::vector<APInt> intValues;
599 if (
failed(getIntAttrElements(loc, eltType, intValues)))
603 auto complexData = llvm::ArrayRef(
605 intValues.size() / 2);
611 if (FloatType floatTy = dyn_cast<FloatType>(eltType)) {
612 std::vector<APFloat> floatValues;
613 if (
failed(getFloatAttrElements(loc, floatTy, floatValues)))
617 auto complexData = llvm::ArrayRef(
619 floatValues.size() / 2);
626 return getStringAttr(loc, type, type.getElementType());
631TensorLiteralParser::getIntAttrElements(SMLoc loc, Type eltTy,
632 std::vector<APInt> &intValues) {
633 intValues.reserve(storage.size());
635 for (
const auto &signAndToken : storage) {
636 bool isNegative = signAndToken.first;
637 const Token &token = signAndToken.second;
638 auto tokenLoc = token.
getLoc();
640 if (isNegative && isUintType) {
641 return p.emitError(tokenLoc)
642 <<
"expected unsigned integer elements, but parsed negative value";
646 if (token.
is(Token::floatliteral)) {
647 return p.emitError(tokenLoc)
648 <<
"expected integer elements, but parsed floating-point";
651 assert(token.
isAny(Token::integer, Token::kw_true, Token::kw_false) &&
652 "unexpected token type");
653 if (token.
isAny(Token::kw_true, Token::kw_false)) {
655 return p.emitError(tokenLoc)
656 <<
"expected i1 type for 'true' or 'false' values";
658 APInt apInt(1, token.
is(Token::kw_true),
false);
659 intValues.push_back(apInt);
664 std::optional<APInt> apInt =
667 return p.emitError(tokenLoc,
"integer constant out of range for type");
668 intValues.push_back(*apInt);
675TensorLiteralParser::getFloatAttrElements(SMLoc loc, FloatType eltTy,
676 std::vector<APFloat> &floatValues) {
677 floatValues.reserve(storage.size());
678 for (
const auto &signAndToken : storage) {
679 bool isNegative = signAndToken.first;
680 const Token &token = signAndToken.second;
681 std::optional<APFloat>
result;
682 if (
failed(p.parseFloatFromLiteral(
result, token, isNegative,
683 eltTy.getFloatSemantics())))
685 floatValues.push_back(*
result);
691DenseElementsAttr TensorLiteralParser::getStringAttr(SMLoc loc, ShapedType type,
693 if (hexStorage.has_value()) {
694 auto stringValue = hexStorage->getStringValue();
695 return DenseStringElementsAttr::get(type, {stringValue});
698 std::vector<std::string> stringValues;
699 std::vector<StringRef> stringRefValues;
700 stringValues.reserve(storage.size());
701 stringRefValues.reserve(storage.size());
703 for (
auto val : storage) {
704 if (!val.second.is(Token::string)) {
705 p.emitError(loc) <<
"expected string token, got "
706 << val.second.getSpelling();
709 stringValues.push_back(val.second.getStringValue());
710 stringRefValues.emplace_back(stringValues.back());
713 return DenseStringElementsAttr::get(type, stringRefValues);
717DenseElementsAttr TensorLiteralParser::getHexAttr(SMLoc loc, ShapedType type) {
718 Type elementType = type.getElementType();
721 <<
"expected floating-point, integer, or complex element type, got "
730 ArrayRef<char> rawData(data);
732 p.emitError(loc) <<
"elements hex data size is invalid for provided type: "
737 if (llvm::endianness::native == llvm::endianness::big) {
742 SmallVector<char, 64> outDataVec(rawData.size());
743 MutableArrayRef<char> convRawData(outDataVec);
744 DenseTypedElementsAttr::convertEndianOfArrayRefForBEmachine(
745 rawData, convRawData, type);
752ParseResult TensorLiteralParser::parseElement() {
753 switch (p.getToken().getKind()) {
756 case Token::kw_false:
757 case Token::floatliteral:
759 storage.emplace_back(
false, p.getToken());
765 p.consumeToken(Token::minus);
766 if (!p.getToken().isAny(Token::floatliteral, Token::integer))
767 return p.emitError(
"expected integer or floating point literal");
768 storage.emplace_back(
true, p.getToken());
773 storage.emplace_back(
false, p.getToken());
779 p.consumeToken(Token::l_paren);
780 if (parseElement() ||
781 p.parseToken(Token::comma,
"expected ',' between complex elements") ||
783 p.parseToken(Token::r_paren,
"expected ')' after complex elements"))
788 return p.emitError(
"expected element literal of primitive type");
800ParseResult TensorLiteralParser::parseList(SmallVectorImpl<int64_t> &dims) {
801 auto checkDims = [&](
const SmallVectorImpl<int64_t> &prevDims,
802 const SmallVectorImpl<int64_t> &newDims) -> ParseResult {
803 if (prevDims == newDims)
805 return p.emitError(
"tensor literal is invalid; ranks are not consistent "
810 SmallVector<int64_t, 4> newDims;
812 auto parseOneElement = [&]() -> ParseResult {
813 SmallVector<int64_t, 4> thisDims;
814 if (p.getToken().getKind() == Token::l_square) {
815 if (parseList(thisDims))
817 }
else if (parseElement()) {
822 return checkDims(newDims, thisDims);
827 if (p.parseCommaSeparatedList(Parser::Delimiter::Square, parseOneElement))
832 dims.push_back(size);
833 dims.append(newDims.begin(), newDims.end());
844class DenseArrayElementParser {
846 explicit DenseArrayElementParser(Type type) : type(type) {}
849 ParseResult parseIntegerElement(Parser &p);
852 ParseResult parseFloatElement(Parser &p);
855 DenseArrayAttr getAttr() {
return DenseArrayAttr::get(type, size, rawData); }
859 void append(
const APInt &data);
864 std::vector<char> rawData;
870void DenseArrayElementParser::append(
const APInt &data) {
871 if (data.getBitWidth()) {
872 assert(data.getBitWidth() % 8 == 0);
873 unsigned byteSize = data.getBitWidth() / 8;
874 size_t offset = rawData.size();
875 rawData.insert(rawData.end(), byteSize, 0);
876 llvm::StoreIntToMemory(
877 data,
reinterpret_cast<uint8_t *
>(rawData.data() + offset), byteSize);
882ParseResult DenseArrayElementParser::parseIntegerElement(
Parser &p) {
883 bool isNegative = p.
consumeIf(Token::minus);
886 std::optional<APInt> value;
889 if (!type.isInteger(1))
890 return p.
emitError(
"expected i1 type for 'true' or 'false' values");
891 value = APInt(8, p.
getToken().
is(Token::kw_true),
892 !type.isUnsignedInteger());
894 }
else if (p.
consumeIf(Token::integer)) {
895 if (type.isInteger(1))
896 return p.
emitError(
"expected 'true' or 'false' values for i1 type");
899 return p.
emitError(
"integer constant out of range");
901 return p.
emitError(
"expected integer literal");
907ParseResult DenseArrayElementParser::parseFloatElement(
Parser &p) {
908 bool isNegative = p.
consumeIf(Token::minus);
910 std::optional<APFloat> fromIntLit;
913 cast<FloatType>(type).getFloatSemantics())))
916 append(fromIntLit->bitcastToAPInt());
923 if (
parseToken(Token::less,
"expected '<' after 'array'"))
929 emitError(typeLoc,
"expected an integer or floating point type");
936 emitError(typeLoc,
"expected integer or float type, got: ") << eltType;
940 emitError(typeLoc,
"element type bitwidth must be a multiple of 8");
946 return DenseArrayAttr::get(eltType, 0, {});
948 if (
parseToken(Token::colon,
"expected ':' after dense array type"))
951 DenseArrayElementParser eltParser(eltType);
952 if (isa<IntegerType>(eltType)) {
954 [&] {
return eltParser.parseIntegerElement(*
this); }))
958 [&] {
return eltParser.parseFloatElement(*
this); }))
961 if (
parseToken(Token::greater,
"expected '>' to close an array attribute"))
963 return eltParser.getAttr();
986 if (failed(*typeResult))
989 auto shapedType = dyn_cast<ShapedType>(type);
991 p.
emitError(typeLoc,
"expected a shaped type for dense elements");
994 if (!shapedType.hasStaticShape()) {
995 p.
emitError(typeLoc,
"dense elements type must have static shape");
1000 auto denseEltType = dyn_cast<DenseElementType>(shapedType.getElementType());
1001 if (!denseEltType) {
1003 "element type must implement DenseElementTypeInterface "
1004 "for type-first dense syntax");
1009 if (p.
parseToken(Token::colon,
"expected ':' after type in dense attribute"))
1016 auto parseSingleElement = [&]() -> ParseResult {
1020 if (failed(denseEltType.convertFromAttribute(elemAttr, rawData))) {
1021 p.
emitError(
"incompatible attribute for element type");
1031 if (remainingShape.empty())
1032 return parseSingleElement();
1035 int64_t expectedCount = remainingShape.front();
1039 auto parseOne = [&]() -> ParseResult {
1040 if (parseElements(innerShape))
1049 if (actualCount != expectedCount) {
1050 p.
emitError() <<
"expected " << expectedCount
1051 <<
" elements in dimension, got " << actualCount;
1060 if (parseSingleElement())
1062 }
else if (shapedType.getShape().empty()) {
1064 p.
emitError(loc,
"expected single element for scalar type, got list");
1068 if (parseElements(shapedType.getShape()))
1072 if (p.
parseToken(Token::greater,
"expected '>' to close dense attribute"))
1083 if (
parseToken(Token::less,
"expected '<' after 'dense'"))
1087 FailureOr<Attribute> typedResult =
1089 if (failed(typedResult))
1092 return *typedResult;
1096 TensorLiteralParser literalParser(*
this);
1098 if (literalParser.parse(
true) ||
1106 return literalParser.getAttr(attribLoc, type);
1112 if (
parseToken(Token::less,
"expected '<' after 'dense_resource'"))
1116 FailureOr<AsmDialectResourceHandle> rawHandle =
1118 if (failed(rawHandle) ||
parseToken(Token::greater,
"expected '>'"))
1121 auto *handle = dyn_cast<DenseResourceElementsHandle>(&*rawHandle);
1123 return emitError(loc,
"invalid `dense_resource` handle type"),
nullptr;
1126 SMLoc typeLoc = loc;
1133 ShapedType shapedType = dyn_cast<ShapedType>(attrType);
1135 emitError(typeLoc,
"`dense_resource` expected a shaped type");
1139 return DenseResourceElementsAttr::get(shapedType, *handle);
1150 if (
parseToken(Token::colon,
"expected ':'"))
1156 auto sType = dyn_cast<ShapedType>(type);
1158 emitError(loc,
"elements literal must be a shaped type");
1162 if (!sType.hasStaticShape()) {
1163 emitError(loc,
"elements literal type must have static shape");
1174 if (
parseToken(Token::less,
"Expected '<' after 'sparse'"))
1188 ShapedType indicesType =
1189 RankedTensorType::get({0, type.getRank()}, indiceEltType);
1190 ShapedType valuesType = RankedTensorType::get({0}, type.getElementType());
1199 TensorLiteralParser indiceParser(*
this);
1200 if (indiceParser.parse(
false))
1203 if (
parseToken(Token::comma,
"expected ','"))
1208 TensorLiteralParser valuesParser(*
this);
1209 if (valuesParser.parse(
true))
1212 if (
parseToken(Token::greater,
"expected '>'"))
1224 ShapedType indicesType;
1225 if (indiceParser.getShape().empty()) {
1226 indicesType = RankedTensorType::get({1, type.getRank()}, indiceEltType);
1229 indicesType = RankedTensorType::get(indiceParser.getShape(), indiceEltType);
1231 auto indices = indiceParser.getAttr(indicesLoc, indicesType);
1238 auto valuesEltType = type.getElementType();
1239 ShapedType valuesType =
1240 valuesParser.getShape().empty()
1241 ? RankedTensorType::get({indicesType.getDimSize(0)}, valuesEltType)
1242 : RankedTensorType::get(valuesParser.getShape(), valuesEltType);
1243 auto values = valuesParser.getAttr(valuesLoc, valuesType);
1254 auto errorEmitter = [&] {
return emitError(loc); };
1257 if (failed(
parseToken(Token::less,
"expected '<' after 'strided'")) ||
1258 failed(
parseToken(Token::l_square,
"expected '['")))
1264 auto parseStrideOrOffset = [&]() -> std::optional<int64_t> {
1266 return ShapedType::kDynamic;
1270 emitError(loc,
"expected a 64-bit signed integer or '?'");
1271 return std::nullopt;
1274 bool negative =
consumeIf(Token::minus);
1276 if (
getToken().is(Token::integer)) {
1279 *value >
static_cast<uint64_t
>(std::numeric_limits<int64_t>::max()))
1294 if (!
getToken().is(Token::r_square)) {
1296 std::optional<int64_t> stride = parseStrideOrOffset();
1299 strides.push_back(*stride);
1303 if (failed(
parseToken(Token::r_square,
"expected ']'")))
1308 if (failed(StridedLayoutAttr::verify(errorEmitter,
1311 return StridedLayoutAttr::get(
getContext(), 0, strides);
1314 if (failed(
parseToken(Token::comma,
"expected ','")) ||
1315 failed(
parseToken(Token::kw_offset,
"expected 'offset' after comma")) ||
1316 failed(
parseToken(Token::colon,
"expected ':' after 'offset'")))
1319 std::optional<int64_t> offset = parseStrideOrOffset();
1320 if (!offset || failed(
parseToken(Token::greater,
"expected '>'")))
1323 if (failed(StridedLayoutAttr::verify(errorEmitter, *offset, strides)))
1325 return StridedLayoutAttr::get(
getContext(), *offset, strides);
1337 if (
parseToken(Token::l_square,
"expected '[' after 'distinct'"))
1342 if (
parseToken(Token::integer,
"expected distinct ID"))
1346 emitError(
"expected an unsigned 64-bit integer");
1351 if (
parseToken(Token::r_square,
"expected ']' to close distinct ID") ||
1352 parseToken(Token::less,
"expected '<' after distinct ID"))
1356 if (
getToken().is(Token::greater)) {
1358 referencedAttr =
builder.getUnitAttr();
1361 if (!referencedAttr) {
1366 if (
parseToken(Token::greater,
"expected '>' to close distinct attribute"))
1374 state.symbols.distinctAttributes;
1375 auto it = distinctAttrs.find(*value);
1376 if (it == distinctAttrs.end()) {
1378 it = distinctAttrs.try_emplace(*value, distinctAttr).first;
1379 }
else if (it->getSecond().getReferencedAttr() != referencedAttr) {
1380 emitError(loc,
"referenced attribute does not match previous definition: ")
1381 << it->getSecond().getReferencedAttr();
1385 return it->getSecond();
static FailureOr< Attribute > parseDenseElementsAttrTyped(Parser &p, SMLoc loc)
Try to parse a dense elements attribute with the type-first syntax.
static std::optional< APInt > buildAttributeAPInt(Type type, bool isNegative, StringRef spelling)
Construct an APint from a parsed value, a known attribute type and sign.
static ParseResult parseElementAttrHexValues(Parser &parser, Token tok, std::string &result)
Parse elements values stored within a hex string.
static ArrayRef< int64_t > getShape(Type type)
Returns the shape of the given type.
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
Attributes are known-constant values of operations.
static DenseElementsAttr getFromRawBuffer(ShapedType type, ArrayRef< char > rawBuffer)
Construct a dense elements attribute from a raw buffer representing the data for this attribute.
static bool isValidRawBuffer(ShapedType type, ArrayRef< char > rawBuffer)
Returns true if the given buffer is a valid raw buffer for the given type.
static DenseElementsAttr get(ShapedType type, ArrayRef< Attribute > values)
Constructs a dense elements attribute from an array of element values.
An attribute that associates a referenced attribute with a unique identifier.
static DistinctAttr create(Attribute referencedAttr)
Creates a distinct attribute that associates a referenced attribute with a unique identifier.
An integer set representing a conjunction of one or more affine equalities and inequalities.
Location objects represent source locations information in MLIR.
T * getOrLoadDialect()
Get (or create) a dialect for the given derived dialect type.
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
DictionaryAttr getDictionary(MLIRContext *context) const
Return a dictionary attribute for the underlying dictionary.
void push_back(NamedAttribute newAttribute)
Add an attribute with the specified name.
This class implements Optional functionality for ParseResult.
bool has_value() const
Returns true if we contain a valid ParseResult value.
This represents a token in the MLIR syntax.
std::string getStringValue() const
Given a token containing a string literal, return its value, including removing the quote characters ...
std::string getSymbolReference() const
Given a token containing a symbol reference, return the unescaped string value.
static std::optional< uint64_t > getUInt64IntegerValue(StringRef spelling)
For an integer token, return its value as an uint64_t.
std::optional< double > getFloatingPointValue() const
For a floatliteral token, return its value as a double.
bool isAny(Kind k1, Kind k2) const
StringRef getSpelling() const
std::optional< std::string > getHexStringValue() const
Given a token containing a hex string literal, return its value or std::nullopt if the token does not...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
bool isSignedInteger() const
Return true if this is a signed integer type (with the specified width).
bool isIntOrIndexOrFloat() const
Return true if this is an integer (of any signedness), index, or float type.
bool isUnsignedInteger() const
Return true if this is an unsigned integer type (with the specified width).
bool isIntOrIndex() const
Return true if this is an integer (of any signedness) or an index type.
bool isInteger() const
Return true if this is an integer type (with the specified width).
bool isIntOrFloat() const
Return true if this is an integer (of any signedness) or a float type.
unsigned getIntOrFloatBitWidth() const
Return the bit width of an integer or a float type, assert failure on other types.
This class implement support for parsing global entities like attributes and types.
ParseResult parseFloatFromLiteral(std::optional< APFloat > &result, const Token &tok, bool isNegative, const llvm::fltSemantics &semantics)
Parse a floating point value from a literal.
Attribute parseDenseArrayAttr(Type type)
Parse a DenseArrayAttr.
Attribute parseStridedLayoutAttr()
Parse a strided layout attribute.
Attribute parseDecOrHexAttr(Type type, bool isNegative)
Parse a decimal or a hexadecimal literal, which can be either an integer or a float attribute.
T getChecked(SMLoc loc, ParamsT &&...params)
Invoke the getChecked method of the given Attribute or Type class, using the provided location to emi...
OptionalParseResult parseOptionalType(Type &type)
Optionally parse a type.
ParseResult parseToken(Token::Kind expectedToken, const Twine &message)
Consume the specified token if present and return success.
ParseResult parseCommaSeparatedListUntil(Token::Kind rightToken, function_ref< ParseResult()> parseElement, bool allowEmptyList=true)
Parse a comma-separated list of elements up until the specified end token.
Type parseType()
Parse an arbitrary type.
Attribute parseDenseElementsAttr(Type attrType)
Parse a dense elements attribute.
Attribute parseDenseResourceElementsAttr(Type attrType)
Parse a dense resource elements attribute.
ParseResult parseAffineMapReference(AffineMap &map)
InFlightDiagnostic emitError(const Twine &message={})
Emit an error and return failure.
ParserState & state
The Parser is subclassed and reinstantiated.
Attribute parseAttribute(Type type={})
Parse an arbitrary attribute with an optional type.
StringRef getTokenSpelling() const
FailureOr< AsmDialectResourceHandle > parseResourceHandle(const OpAsmDialectInterface *dialect, std::string &name)
Parse a handle to a dialect resource within the assembly format.
ParseResult parseLocationInstance(LocationAttr &loc)
Parse a raw location instance.
void consumeToken()
Advance the current lexer onto the next token.
Attribute codeCompleteAttribute()
ParseResult parseAttributeDict(NamedAttrList &attributes)
Parse an attribute dictionary.
Attribute parseDistinctAttr(Type type)
Parse a distinct attribute.
InFlightDiagnostic emitWrongTokenError(const Twine &message={})
Emit an error about a "wrong token".
ParseResult parseCommaSeparatedList(Delimiter delimiter, function_ref< ParseResult()> parseElementFn, StringRef contextMessage=StringRef())
Parse a list of comma-separated items with an optional delimiter.
Attribute parseSparseElementsAttr(Type attrType)
Parse a sparse elements attribute.
OptionalParseResult parseOptionalAttribute(Attribute &attribute, Type type={})
Parse an optional attribute with the provided type.
Attribute parseFloatAttr(Type type, bool isNegative)
Parse a float attribute.
ParseResult parseFloatFromIntegerLiteral(std::optional< APFloat > &result, const Token &tok, bool isNegative, const llvm::fltSemantics &semantics)
Parse a floating point value from an integer literal token.
ParseResult parseIntegerSetReference(IntegerSet &set)
const Token & getToken() const
Return the current token the parser is inspecting.
Attribute parseExtendedAttr(Type type)
Parse an extended attribute.
MLIRContext * getContext() const
ShapedType parseElementsLiteralType(SMLoc loc, Type type)
Shaped type for elements attribute.
bool consumeIf(Token::Kind kind)
If the current token has the specified kind, consume it and return true.
OptionalParseResult parseOptionalAttributeWithToken(Token::Kind kind, AttributeT &attr, Type type={})
Parse an optional attribute that is demarcated by a specific token.
QueryRef parse(llvm::StringRef line, const QuerySession &qs)
Include the generated interface declarations.
std::conditional_t< std::is_floating_point_v< T >, std::complex< T >, NonFloatComplex< T > > Complex
llvm::DenseMap< KeyT, ValueT, KeyInfoT, BucketT > DenseMap