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");
344 return (
emitError(
"floating point value too large for attribute"),
nullptr);
353 if (!isa<FloatType>(type))
354 return (
emitError(
"floating point value not valid for specified type"),
356 return FloatAttr::get(type, isNegative ? -*val : *val);
362 StringRef spelling) {
365 bool isHex = spelling.size() > 1 && spelling[1] ==
'x';
366 if (spelling.getAsInteger(isHex ? 0 : 10,
result))
370 unsigned width = type.
isIndex() ? IndexType::kInternalStorageBitWidth
373 if (width >
result.getBitWidth()) {
375 }
else if (width <
result.getBitWidth()) {
378 if (
result.countl_zero() <
result.getBitWidth() - width)
389 }
else if (isNegative) {
393 if (!
result.isSignBitSet())
416 type =
builder.getIntegerType(64);
421 if (
auto floatType = dyn_cast<FloatType>(type)) {
422 std::optional<APFloat>
result;
424 floatType.getFloatSemantics())))
426 return FloatAttr::get(floatType, *
result);
429 if (!isa<IntegerType, IndexType>(type))
430 return emitError(loc,
"integer literal not valid for specified type"),
435 "negative integer literal not valid for unsigned integer type");
441 return emitError(loc,
"integer constant out of range for attribute"),
443 return builder.getIntegerAttr(type, *apInt);
455 result = std::move(*value);
459 tok.
getLoc(),
"expected string containing hex digits starting with `0x`");
466class TensorLiteralParser {
468 TensorLiteralParser(Parser &p) : p(p) {}
472 ParseResult
parse(
bool allowHex);
476 DenseElementsAttr getAttr(SMLoc loc, ShapedType type);
478 ArrayRef<int64_t>
getShape()
const {
return shape; }
482 ParseResult getIntAttrElements(SMLoc loc, Type eltTy,
483 std::vector<APInt> &intValues);
486 ParseResult getFloatAttrElements(SMLoc loc, FloatType eltTy,
487 std::vector<APFloat> &floatValues);
490 DenseElementsAttr getStringAttr(SMLoc loc, ShapedType type, Type eltTy);
493 DenseElementsAttr getHexAttr(SMLoc loc, ShapedType type);
499 ParseResult parseElement();
507 ParseResult parseList(SmallVectorImpl<int64_t> &dims);
510 ParseResult parseHexElements();
515 SmallVector<int64_t, 4> shape;
518 std::vector<std::pair<bool, Token>> storage;
521 std::optional<Token> hexStorage;
527ParseResult TensorLiteralParser::parse(
bool allowHex) {
529 if (allowHex && p.getToken().is(Token::string)) {
530 hexStorage = p.getToken();
531 p.consumeToken(Token::string);
535 if (p.getToken().is(Token::l_square))
536 return parseList(shape);
537 return parseElement();
542DenseElementsAttr TensorLiteralParser::getAttr(SMLoc loc, ShapedType type) {
543 Type eltType = type.getElementType();
548 return getHexAttr(loc, type);
552 if (!shape.empty() &&
getShape() != type.getShape()) {
553 p.emitError(loc) <<
"inferred shape of elements literal ([" <<
getShape()
554 <<
"]) does not match type ([" << type.getShape() <<
"])";
559 if (!hexStorage && storage.empty() && type.getNumElements()) {
560 p.emitError(loc) <<
"parsed zero elements, but type (" << type
561 <<
") expected at least 1";
566 bool isComplex =
false;
567 if (ComplexType complexTy = dyn_cast<ComplexType>(eltType)) {
568 eltType = complexTy.getElementType();
572 bool isSplat = shape.empty() && type.getNumElements() != 0;
573 if (isSplat && storage.size() != 2) {
574 p.emitError(loc) <<
"parsed " << storage.size() <<
" elements, but type ("
575 << complexTy <<
") expected 2 elements";
578 if (!shape.empty() &&
579 storage.size() !=
static_cast<size_t>(type.getNumElements()) * 2) {
580 p.emitError(loc) <<
"parsed " << storage.size() <<
" elements, but type ("
581 << type <<
") expected " << type.getNumElements() * 2
589 std::vector<APInt> intValues;
590 if (
failed(getIntAttrElements(loc, eltType, intValues)))
594 auto complexData = llvm::ArrayRef(
595 reinterpret_cast<std::complex<APInt> *
>(intValues.data()),
596 intValues.size() / 2);
602 if (FloatType floatTy = dyn_cast<FloatType>(eltType)) {
603 std::vector<APFloat> floatValues;
604 if (
failed(getFloatAttrElements(loc, floatTy, floatValues)))
608 auto complexData = llvm::ArrayRef(
609 reinterpret_cast<std::complex<APFloat> *
>(floatValues.data()),
610 floatValues.size() / 2);
617 return getStringAttr(loc, type, type.getElementType());
622TensorLiteralParser::getIntAttrElements(SMLoc loc, Type eltTy,
623 std::vector<APInt> &intValues) {
624 intValues.reserve(storage.size());
626 for (
const auto &signAndToken : storage) {
627 bool isNegative = signAndToken.first;
628 const Token &token = signAndToken.second;
629 auto tokenLoc = token.
getLoc();
631 if (isNegative && isUintType) {
632 return p.emitError(tokenLoc)
633 <<
"expected unsigned integer elements, but parsed negative value";
637 if (token.
is(Token::floatliteral)) {
638 return p.emitError(tokenLoc)
639 <<
"expected integer elements, but parsed floating-point";
642 assert(token.
isAny(Token::integer, Token::kw_true, Token::kw_false) &&
643 "unexpected token type");
644 if (token.
isAny(Token::kw_true, Token::kw_false)) {
646 return p.emitError(tokenLoc)
647 <<
"expected i1 type for 'true' or 'false' values";
649 APInt apInt(1, token.
is(Token::kw_true),
false);
650 intValues.push_back(apInt);
655 std::optional<APInt> apInt =
658 return p.emitError(tokenLoc,
"integer constant out of range for type");
659 intValues.push_back(*apInt);
666TensorLiteralParser::getFloatAttrElements(SMLoc loc, FloatType eltTy,
667 std::vector<APFloat> &floatValues) {
668 floatValues.reserve(storage.size());
669 for (
const auto &signAndToken : storage) {
670 bool isNegative = signAndToken.first;
671 const Token &token = signAndToken.second;
672 std::optional<APFloat>
result;
673 if (
failed(p.parseFloatFromLiteral(
result, token, isNegative,
674 eltTy.getFloatSemantics())))
676 floatValues.push_back(*
result);
682DenseElementsAttr TensorLiteralParser::getStringAttr(SMLoc loc, ShapedType type,
684 if (hexStorage.has_value()) {
685 auto stringValue = hexStorage->getStringValue();
686 return DenseStringElementsAttr::get(type, {stringValue});
689 std::vector<std::string> stringValues;
690 std::vector<StringRef> stringRefValues;
691 stringValues.reserve(storage.size());
692 stringRefValues.reserve(storage.size());
694 for (
auto val : storage) {
695 if (!val.second.is(Token::string)) {
696 p.emitError(loc) <<
"expected string token, got "
697 << val.second.getSpelling();
700 stringValues.push_back(val.second.getStringValue());
701 stringRefValues.emplace_back(stringValues.back());
704 return DenseStringElementsAttr::get(type, stringRefValues);
708DenseElementsAttr TensorLiteralParser::getHexAttr(SMLoc loc, ShapedType type) {
709 Type elementType = type.getElementType();
712 <<
"expected floating-point, integer, or complex element type, got "
721 ArrayRef<char> rawData(data);
723 p.emitError(loc) <<
"elements hex data size is invalid for provided type: "
728 if (llvm::endianness::native == llvm::endianness::big) {
733 SmallVector<char, 64> outDataVec(rawData.size());
734 MutableArrayRef<char> convRawData(outDataVec);
735 DenseTypedElementsAttr::convertEndianOfArrayRefForBEmachine(
736 rawData, convRawData, type);
743ParseResult TensorLiteralParser::parseElement() {
744 switch (p.getToken().getKind()) {
747 case Token::kw_false:
748 case Token::floatliteral:
750 storage.emplace_back(
false, p.getToken());
756 p.consumeToken(Token::minus);
757 if (!p.getToken().isAny(Token::floatliteral, Token::integer))
758 return p.emitError(
"expected integer or floating point literal");
759 storage.emplace_back(
true, p.getToken());
764 storage.emplace_back(
false, p.getToken());
770 p.consumeToken(Token::l_paren);
771 if (parseElement() ||
772 p.parseToken(Token::comma,
"expected ',' between complex elements") ||
774 p.parseToken(Token::r_paren,
"expected ')' after complex elements"))
779 return p.emitError(
"expected element literal of primitive type");
791ParseResult TensorLiteralParser::parseList(SmallVectorImpl<int64_t> &dims) {
792 auto checkDims = [&](
const SmallVectorImpl<int64_t> &prevDims,
793 const SmallVectorImpl<int64_t> &newDims) -> ParseResult {
794 if (prevDims == newDims)
796 return p.emitError(
"tensor literal is invalid; ranks are not consistent "
801 SmallVector<int64_t, 4> newDims;
803 auto parseOneElement = [&]() -> ParseResult {
804 SmallVector<int64_t, 4> thisDims;
805 if (p.getToken().getKind() == Token::l_square) {
806 if (parseList(thisDims))
808 }
else if (parseElement()) {
813 return checkDims(newDims, thisDims);
818 if (p.parseCommaSeparatedList(Parser::Delimiter::Square, parseOneElement))
823 dims.push_back(size);
824 dims.append(newDims.begin(), newDims.end());
835class DenseArrayElementParser {
837 explicit DenseArrayElementParser(Type type) : type(type) {}
840 ParseResult parseIntegerElement(Parser &p);
843 ParseResult parseFloatElement(Parser &p);
846 DenseArrayAttr getAttr() {
return DenseArrayAttr::get(type, size, rawData); }
850 void append(
const APInt &data);
855 std::vector<char> rawData;
861void DenseArrayElementParser::append(
const APInt &data) {
862 if (data.getBitWidth()) {
863 assert(data.getBitWidth() % 8 == 0);
864 unsigned byteSize = data.getBitWidth() / 8;
865 size_t offset = rawData.size();
866 rawData.insert(rawData.end(), byteSize, 0);
867 llvm::StoreIntToMemory(
868 data,
reinterpret_cast<uint8_t *
>(rawData.data() + offset), byteSize);
873ParseResult DenseArrayElementParser::parseIntegerElement(
Parser &p) {
874 bool isNegative = p.
consumeIf(Token::minus);
877 std::optional<APInt> value;
880 if (!type.isInteger(1))
881 return p.
emitError(
"expected i1 type for 'true' or 'false' values");
882 value = APInt(8, p.
getToken().
is(Token::kw_true),
883 !type.isUnsignedInteger());
885 }
else if (p.
consumeIf(Token::integer)) {
886 if (type.isInteger(1))
887 return p.
emitError(
"expected 'true' or 'false' values for i1 type");
890 return p.
emitError(
"integer constant out of range");
892 return p.
emitError(
"expected integer literal");
898ParseResult DenseArrayElementParser::parseFloatElement(
Parser &p) {
899 bool isNegative = p.
consumeIf(Token::minus);
901 std::optional<APFloat> fromIntLit;
904 cast<FloatType>(type).getFloatSemantics())))
907 append(fromIntLit->bitcastToAPInt());
914 if (
parseToken(Token::less,
"expected '<' after 'array'"))
920 emitError(typeLoc,
"expected an integer or floating point type");
927 emitError(typeLoc,
"expected integer or float type, got: ") << eltType;
931 emitError(typeLoc,
"element type bitwidth must be a multiple of 8");
937 return DenseArrayAttr::get(eltType, 0, {});
939 if (
parseToken(Token::colon,
"expected ':' after dense array type"))
942 DenseArrayElementParser eltParser(eltType);
943 if (isa<IntegerType>(eltType)) {
945 [&] {
return eltParser.parseIntegerElement(*
this); }))
949 [&] {
return eltParser.parseFloatElement(*
this); }))
952 if (
parseToken(Token::greater,
"expected '>' to close an array attribute"))
954 return eltParser.getAttr();
977 if (failed(*typeResult))
980 auto shapedType = dyn_cast<ShapedType>(type);
982 p.
emitError(typeLoc,
"expected a shaped type for dense elements");
985 if (!shapedType.hasStaticShape()) {
986 p.
emitError(typeLoc,
"dense elements type must have static shape");
991 auto denseEltType = dyn_cast<DenseElementType>(shapedType.getElementType());
994 "element type must implement DenseElementTypeInterface "
995 "for type-first dense syntax");
1000 if (p.
parseToken(Token::colon,
"expected ':' after type in dense attribute"))
1007 auto parseSingleElement = [&]() -> ParseResult {
1011 if (failed(denseEltType.convertFromAttribute(elemAttr, rawData))) {
1012 p.
emitError(
"incompatible attribute for element type");
1022 if (remainingShape.empty())
1023 return parseSingleElement();
1026 int64_t expectedCount = remainingShape.front();
1030 auto parseOne = [&]() -> ParseResult {
1031 if (parseElements(innerShape))
1040 if (actualCount != expectedCount) {
1041 p.
emitError() <<
"expected " << expectedCount
1042 <<
" elements in dimension, got " << actualCount;
1051 if (parseSingleElement())
1053 }
else if (shapedType.getShape().empty()) {
1055 p.
emitError(loc,
"expected single element for scalar type, got list");
1059 if (parseElements(shapedType.getShape()))
1063 if (p.
parseToken(Token::greater,
"expected '>' to close dense attribute"))
1074 if (
parseToken(Token::less,
"expected '<' after 'dense'"))
1078 FailureOr<Attribute> typedResult =
1080 if (failed(typedResult))
1083 return *typedResult;
1087 TensorLiteralParser literalParser(*
this);
1089 if (literalParser.parse(
true) ||
1097 return literalParser.getAttr(attribLoc, type);
1103 if (
parseToken(Token::less,
"expected '<' after 'dense_resource'"))
1107 FailureOr<AsmDialectResourceHandle> rawHandle =
1109 if (failed(rawHandle) ||
parseToken(Token::greater,
"expected '>'"))
1112 auto *handle = dyn_cast<DenseResourceElementsHandle>(&*rawHandle);
1114 return emitError(loc,
"invalid `dense_resource` handle type"),
nullptr;
1117 SMLoc typeLoc = loc;
1124 ShapedType shapedType = dyn_cast<ShapedType>(attrType);
1126 emitError(typeLoc,
"`dense_resource` expected a shaped type");
1130 return DenseResourceElementsAttr::get(shapedType, *handle);
1141 if (
parseToken(Token::colon,
"expected ':'"))
1147 auto sType = dyn_cast<ShapedType>(type);
1149 emitError(loc,
"elements literal must be a shaped type");
1153 if (!sType.hasStaticShape()) {
1154 emitError(loc,
"elements literal type must have static shape");
1165 if (
parseToken(Token::less,
"Expected '<' after 'sparse'"))
1179 ShapedType indicesType =
1180 RankedTensorType::get({0, type.getRank()}, indiceEltType);
1181 ShapedType valuesType = RankedTensorType::get({0}, type.getElementType());
1190 TensorLiteralParser indiceParser(*
this);
1191 if (indiceParser.parse(
false))
1194 if (
parseToken(Token::comma,
"expected ','"))
1199 TensorLiteralParser valuesParser(*
this);
1200 if (valuesParser.parse(
true))
1203 if (
parseToken(Token::greater,
"expected '>'"))
1215 ShapedType indicesType;
1216 if (indiceParser.getShape().empty()) {
1217 indicesType = RankedTensorType::get({1, type.getRank()}, indiceEltType);
1220 indicesType = RankedTensorType::get(indiceParser.getShape(), indiceEltType);
1222 auto indices = indiceParser.getAttr(indicesLoc, indicesType);
1229 auto valuesEltType = type.getElementType();
1230 ShapedType valuesType =
1231 valuesParser.getShape().empty()
1232 ? RankedTensorType::get({indicesType.getDimSize(0)}, valuesEltType)
1233 : RankedTensorType::get(valuesParser.getShape(), valuesEltType);
1234 auto values = valuesParser.getAttr(valuesLoc, valuesType);
1245 auto errorEmitter = [&] {
return emitError(loc); };
1248 if (failed(
parseToken(Token::less,
"expected '<' after 'strided'")) ||
1249 failed(
parseToken(Token::l_square,
"expected '['")))
1255 auto parseStrideOrOffset = [&]() -> std::optional<int64_t> {
1257 return ShapedType::kDynamic;
1261 emitError(loc,
"expected a 64-bit signed integer or '?'");
1262 return std::nullopt;
1265 bool negative =
consumeIf(Token::minus);
1267 if (
getToken().is(Token::integer)) {
1270 *value >
static_cast<uint64_t
>(std::numeric_limits<int64_t>::max()))
1285 if (!
getToken().is(Token::r_square)) {
1287 std::optional<int64_t> stride = parseStrideOrOffset();
1290 strides.push_back(*stride);
1294 if (failed(
parseToken(Token::r_square,
"expected ']'")))
1299 if (failed(StridedLayoutAttr::verify(errorEmitter,
1302 return StridedLayoutAttr::get(
getContext(), 0, strides);
1305 if (failed(
parseToken(Token::comma,
"expected ','")) ||
1306 failed(
parseToken(Token::kw_offset,
"expected 'offset' after comma")) ||
1307 failed(
parseToken(Token::colon,
"expected ':' after 'offset'")))
1310 std::optional<int64_t> offset = parseStrideOrOffset();
1311 if (!offset || failed(
parseToken(Token::greater,
"expected '>'")))
1314 if (failed(StridedLayoutAttr::verify(errorEmitter, *offset, strides)))
1316 return StridedLayoutAttr::get(
getContext(), *offset, strides);
1328 if (
parseToken(Token::l_square,
"expected '[' after 'distinct'"))
1333 if (
parseToken(Token::integer,
"expected distinct ID"))
1337 emitError(
"expected an unsigned 64-bit integer");
1342 if (
parseToken(Token::r_square,
"expected ']' to close distinct ID") ||
1343 parseToken(Token::less,
"expected '<' after distinct ID"))
1347 if (
getToken().is(Token::greater)) {
1349 referencedAttr =
builder.getUnitAttr();
1352 if (!referencedAttr) {
1357 if (
parseToken(Token::greater,
"expected '>' to close distinct attribute"))
1365 state.symbols.distinctAttributes;
1366 auto it = distinctAttrs.find(*value);
1367 if (it == distinctAttrs.end()) {
1369 it = distinctAttrs.try_emplace(*value, distinctAttr).first;
1370 }
else if (it->getSecond().getReferencedAttr() != referencedAttr) {
1371 emitError(loc,
"referenced attribute does not match previous definition: ")
1372 << it->getSecond().getReferencedAttr();
1376 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.
llvm::DenseMap< KeyT, ValueT, KeyInfoT, BucketT > DenseMap