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");
353 if (!isa<FloatType>(type))
354 return (
emitError(
"floating point value not valid for specified type"),
358 std::optional<APFloat>
result;
362 return FloatAttr::get(type, *
result);
368 StringRef spelling) {
371 bool isHex = spelling.size() > 1 && spelling[1] ==
'x';
372 if (spelling.getAsInteger(isHex ? 0 : 10,
result))
376 unsigned width = type.
isIndex() ? IndexType::kInternalStorageBitWidth
379 if (width >
result.getBitWidth()) {
381 }
else if (width <
result.getBitWidth()) {
384 if (
result.countl_zero() <
result.getBitWidth() - width)
395 }
else if (isNegative) {
399 if (!
result.isSignBitSet())
422 type =
builder.getIntegerType(64);
427 if (
auto floatType = dyn_cast<FloatType>(type)) {
428 std::optional<APFloat>
result;
430 floatType.getFloatSemantics())))
432 return FloatAttr::get(floatType, *
result);
435 if (!isa<IntegerType, IndexType>(type))
436 return emitError(loc,
"integer literal not valid for specified type"),
441 "negative integer literal not valid for unsigned integer type");
447 return emitError(loc,
"integer constant out of range for attribute"),
449 return builder.getIntegerAttr(type, *apInt);
461 result = std::move(*value);
465 tok.
getLoc(),
"expected string containing hex digits starting with `0x`");
472class TensorLiteralParser {
474 TensorLiteralParser(Parser &p) : p(p) {}
478 ParseResult
parse(
bool allowHex);
482 DenseElementsAttr getAttr(SMLoc loc, ShapedType type);
484 ArrayRef<int64_t>
getShape()
const {
return shape; }
488 ParseResult getIntAttrElements(SMLoc loc, Type eltTy,
489 std::vector<APInt> &intValues);
492 ParseResult getFloatAttrElements(SMLoc loc, FloatType eltTy,
493 std::vector<APFloat> &floatValues);
496 DenseElementsAttr getStringAttr(SMLoc loc, ShapedType type, Type eltTy);
499 DenseElementsAttr getHexAttr(SMLoc loc, ShapedType type);
505 ParseResult parseElement();
513 ParseResult parseList(SmallVectorImpl<int64_t> &dims);
516 ParseResult parseHexElements();
521 SmallVector<int64_t, 4> shape;
524 std::vector<std::pair<bool, Token>> storage;
527 std::optional<Token> hexStorage;
533ParseResult TensorLiteralParser::parse(
bool allowHex) {
535 if (allowHex && p.getToken().is(Token::string)) {
536 hexStorage = p.getToken();
537 p.consumeToken(Token::string);
541 if (p.getToken().is(Token::l_square))
542 return parseList(shape);
543 return parseElement();
548DenseElementsAttr TensorLiteralParser::getAttr(SMLoc loc, ShapedType type) {
549 Type eltType = type.getElementType();
554 return getHexAttr(loc, type);
558 if (!shape.empty() &&
getShape() != type.getShape()) {
559 p.emitError(loc) <<
"inferred shape of elements literal ([" <<
getShape()
560 <<
"]) does not match type ([" << type.getShape() <<
"])";
565 if (!hexStorage && storage.empty() && type.getNumElements()) {
566 p.emitError(loc) <<
"parsed zero elements, but type (" << type
567 <<
") expected at least 1";
572 bool isComplex =
false;
573 if (ComplexType complexTy = dyn_cast<ComplexType>(eltType)) {
574 eltType = complexTy.getElementType();
578 bool isSplat = shape.empty() && type.getNumElements() != 0;
579 if (isSplat && storage.size() != 2) {
580 p.emitError(loc) <<
"parsed " << storage.size() <<
" elements, but type ("
581 << complexTy <<
") expected 2 elements";
584 if (!shape.empty() &&
585 storage.size() !=
static_cast<size_t>(type.getNumElements()) * 2) {
586 p.emitError(loc) <<
"parsed " << storage.size() <<
" elements, but type ("
587 << type <<
") expected " << type.getNumElements() * 2
595 std::vector<APInt> intValues;
596 if (
failed(getIntAttrElements(loc, eltType, intValues)))
600 auto complexData = llvm::ArrayRef(
602 intValues.size() / 2);
608 if (FloatType floatTy = dyn_cast<FloatType>(eltType)) {
609 std::vector<APFloat> floatValues;
610 if (
failed(getFloatAttrElements(loc, floatTy, floatValues)))
614 auto complexData = llvm::ArrayRef(
616 floatValues.size() / 2);
623 return getStringAttr(loc, type, type.getElementType());
628TensorLiteralParser::getIntAttrElements(SMLoc loc, Type eltTy,
629 std::vector<APInt> &intValues) {
630 intValues.reserve(storage.size());
632 for (
const auto &signAndToken : storage) {
633 bool isNegative = signAndToken.first;
634 const Token &token = signAndToken.second;
635 auto tokenLoc = token.
getLoc();
637 if (isNegative && isUintType) {
638 return p.emitError(tokenLoc)
639 <<
"expected unsigned integer elements, but parsed negative value";
643 if (token.
is(Token::floatliteral)) {
644 return p.emitError(tokenLoc)
645 <<
"expected integer elements, but parsed floating-point";
648 if (token.
is(Token::string)) {
649 return p.emitError(tokenLoc)
650 <<
"expected integer elements, but parsed string";
652 assert(token.
isAny(Token::integer, Token::kw_true, Token::kw_false) &&
653 "unexpected token type");
654 if (token.
isAny(Token::kw_true, Token::kw_false)) {
656 return p.emitError(tokenLoc)
657 <<
"expected i1 type for 'true' or 'false' values";
659 APInt apInt(1, token.
is(Token::kw_true),
false);
660 intValues.push_back(apInt);
665 std::optional<APInt> apInt =
668 return p.emitError(tokenLoc,
"integer constant out of range for type");
669 intValues.push_back(*apInt);
676TensorLiteralParser::getFloatAttrElements(SMLoc loc, FloatType eltTy,
677 std::vector<APFloat> &floatValues) {
678 floatValues.reserve(storage.size());
679 for (
const auto &signAndToken : storage) {
680 bool isNegative = signAndToken.first;
681 const Token &token = signAndToken.second;
682 std::optional<APFloat>
result;
683 if (
failed(p.parseFloatFromLiteral(
result, token, isNegative,
684 eltTy.getFloatSemantics())))
686 floatValues.push_back(*
result);
692DenseElementsAttr TensorLiteralParser::getStringAttr(SMLoc loc, ShapedType type,
694 if (hexStorage.has_value()) {
695 auto stringValue = hexStorage->getStringValue();
696 return DenseStringElementsAttr::get(type, {stringValue});
699 std::vector<std::string> stringValues;
700 std::vector<StringRef> stringRefValues;
701 stringValues.reserve(storage.size());
702 stringRefValues.reserve(storage.size());
704 for (
auto val : storage) {
705 if (!val.second.is(Token::string)) {
706 p.emitError(loc) <<
"expected string token, got "
707 << val.second.getSpelling();
710 stringValues.push_back(val.second.getStringValue());
711 stringRefValues.emplace_back(stringValues.back());
714 return DenseStringElementsAttr::get(type, stringRefValues);
718DenseElementsAttr TensorLiteralParser::getHexAttr(SMLoc loc, ShapedType type) {
719 Type elementType = type.getElementType();
722 <<
"expected floating-point, integer, or complex element type, got "
731 ArrayRef<char> rawData(data);
733 p.emitError(loc) <<
"elements hex data size is invalid for provided type: "
738 if (llvm::endianness::native == llvm::endianness::big) {
743 SmallVector<char, 64> outDataVec(rawData.size());
744 MutableArrayRef<char> convRawData(outDataVec);
745 DenseTypedElementsAttr::convertEndianOfArrayRefForBEmachine(
746 rawData, convRawData, type);
753ParseResult TensorLiteralParser::parseElement() {
754 switch (p.getToken().getKind()) {
757 case Token::kw_false:
758 case Token::floatliteral:
760 storage.emplace_back(
false, p.getToken());
766 p.consumeToken(Token::minus);
767 if (!p.getToken().isAny(Token::floatliteral, Token::integer))
768 return p.emitError(
"expected integer or floating point literal");
769 storage.emplace_back(
true, p.getToken());
774 storage.emplace_back(
false, p.getToken());
780 p.consumeToken(Token::l_paren);
781 if (parseElement() ||
782 p.parseToken(Token::comma,
"expected ',' between complex elements") ||
784 p.parseToken(Token::r_paren,
"expected ')' after complex elements"))
789 return p.emitError(
"expected element literal of primitive type");
801ParseResult TensorLiteralParser::parseList(SmallVectorImpl<int64_t> &dims) {
802 auto checkDims = [&](
const SmallVectorImpl<int64_t> &prevDims,
803 const SmallVectorImpl<int64_t> &newDims) -> ParseResult {
804 if (prevDims == newDims)
806 return p.emitError(
"tensor literal is invalid; ranks are not consistent "
811 SmallVector<int64_t, 4> newDims;
813 auto parseOneElement = [&]() -> ParseResult {
814 SmallVector<int64_t, 4> thisDims;
815 if (p.getToken().getKind() == Token::l_square) {
816 if (parseList(thisDims))
818 }
else if (parseElement()) {
823 return checkDims(newDims, thisDims);
828 if (p.parseCommaSeparatedList(Parser::Delimiter::Square, parseOneElement))
833 dims.push_back(size);
834 dims.append(newDims.begin(), newDims.end());
845class DenseArrayElementParser {
847 explicit DenseArrayElementParser(Type type) : type(type) {}
850 ParseResult parseIntegerElement(Parser &p);
853 ParseResult parseFloatElement(Parser &p);
856 DenseArrayAttr getAttr() {
return DenseArrayAttr::get(type, size, rawData); }
860 void append(
const APInt &data);
865 std::vector<char> rawData;
871void DenseArrayElementParser::append(
const APInt &data) {
872 if (data.getBitWidth()) {
873 assert(data.getBitWidth() % 8 == 0);
874 unsigned byteSize = data.getBitWidth() / 8;
875 size_t offset = rawData.size();
876 rawData.insert(rawData.end(), byteSize, 0);
877 llvm::StoreIntToMemory(
878 data,
reinterpret_cast<uint8_t *
>(rawData.data() + offset), byteSize);
883ParseResult DenseArrayElementParser::parseIntegerElement(
Parser &p) {
884 bool isNegative = p.
consumeIf(Token::minus);
887 std::optional<APInt> value;
890 if (!type.isInteger(1))
891 return p.
emitError(
"expected i1 type for 'true' or 'false' values");
892 value = APInt(8, p.
getToken().
is(Token::kw_true),
893 !type.isUnsignedInteger());
895 }
else if (p.
consumeIf(Token::integer)) {
896 if (type.isInteger(1))
897 return p.
emitError(
"expected 'true' or 'false' values for i1 type");
900 return p.
emitError(
"integer constant out of range");
902 return p.
emitError(
"expected integer literal");
908ParseResult DenseArrayElementParser::parseFloatElement(
Parser &p) {
909 bool isNegative = p.
consumeIf(Token::minus);
911 std::optional<APFloat> fromIntLit;
914 cast<FloatType>(type).getFloatSemantics())))
917 append(fromIntLit->bitcastToAPInt());
924 if (
parseToken(Token::less,
"expected '<' after 'array'"))
930 emitError(typeLoc,
"expected an integer or floating point type");
937 emitError(typeLoc,
"expected integer or float type, got: ") << eltType;
941 emitError(typeLoc,
"element type bitwidth must be a multiple of 8");
947 return DenseArrayAttr::get(eltType, 0, {});
949 if (
parseToken(Token::colon,
"expected ':' after dense array type"))
952 DenseArrayElementParser eltParser(eltType);
953 if (isa<IntegerType>(eltType)) {
955 [&] {
return eltParser.parseIntegerElement(*
this); }))
959 [&] {
return eltParser.parseFloatElement(*
this); }))
962 if (
parseToken(Token::greater,
"expected '>' to close an array attribute"))
964 return eltParser.getAttr();
987 if (failed(*typeResult))
990 auto shapedType = dyn_cast<ShapedType>(type);
992 p.
emitError(typeLoc,
"expected a shaped type for dense elements");
995 if (!shapedType.hasStaticShape()) {
996 p.
emitError(typeLoc,
"dense elements type must have static shape");
1001 auto denseEltType = dyn_cast<DenseElementType>(shapedType.getElementType());
1002 if (!denseEltType) {
1004 "element type must implement DenseElementTypeInterface "
1005 "for type-first dense syntax");
1010 if (p.
parseToken(Token::colon,
"expected ':' after type in dense attribute"))
1017 auto parseSingleElement = [&]() -> ParseResult {
1021 if (failed(denseEltType.convertFromAttribute(elemAttr, rawData))) {
1022 p.
emitError(
"incompatible attribute for element type");
1032 if (remainingShape.empty())
1033 return parseSingleElement();
1036 int64_t expectedCount = remainingShape.front();
1040 auto parseOne = [&]() -> ParseResult {
1041 if (parseElements(innerShape))
1050 if (actualCount != expectedCount) {
1051 p.
emitError() <<
"expected " << expectedCount
1052 <<
" elements in dimension, got " << actualCount;
1061 if (parseSingleElement())
1063 }
else if (shapedType.getShape().empty()) {
1065 p.
emitError(loc,
"expected single element for scalar type, got list");
1069 if (parseElements(shapedType.getShape()))
1073 if (p.
parseToken(Token::greater,
"expected '>' to close dense attribute"))
1084 if (
parseToken(Token::less,
"expected '<' after 'dense'"))
1088 FailureOr<Attribute> typedResult =
1090 if (failed(typedResult))
1093 return *typedResult;
1097 TensorLiteralParser literalParser(*
this);
1099 if (literalParser.parse(
true) ||
1107 return literalParser.getAttr(attribLoc, type);
1113 if (
parseToken(Token::less,
"expected '<' after 'dense_resource'"))
1117 FailureOr<AsmDialectResourceHandle> rawHandle =
1119 if (failed(rawHandle) ||
parseToken(Token::greater,
"expected '>'"))
1122 auto *handle = dyn_cast<DenseResourceElementsHandle>(&*rawHandle);
1124 return emitError(loc,
"invalid `dense_resource` handle type"),
nullptr;
1127 SMLoc typeLoc = loc;
1134 ShapedType shapedType = dyn_cast<ShapedType>(attrType);
1136 emitError(typeLoc,
"`dense_resource` expected a shaped type");
1140 return DenseResourceElementsAttr::get(shapedType, *handle);
1151 if (
parseToken(Token::colon,
"expected ':'"))
1157 auto sType = dyn_cast<ShapedType>(type);
1159 emitError(loc,
"elements literal must be a shaped type");
1163 if (!sType.hasStaticShape()) {
1164 emitError(loc,
"elements literal type must have static shape");
1175 if (
parseToken(Token::less,
"Expected '<' after 'sparse'"))
1189 ShapedType indicesType =
1190 RankedTensorType::get({0, type.getRank()}, indiceEltType);
1191 ShapedType valuesType = RankedTensorType::get({0}, type.getElementType());
1200 TensorLiteralParser indiceParser(*
this);
1201 if (indiceParser.parse(
false))
1204 if (
parseToken(Token::comma,
"expected ','"))
1209 TensorLiteralParser valuesParser(*
this);
1210 if (valuesParser.parse(
true))
1213 if (
parseToken(Token::greater,
"expected '>'"))
1225 ShapedType indicesType;
1226 if (indiceParser.getShape().empty()) {
1227 indicesType = RankedTensorType::get({1, type.getRank()}, indiceEltType);
1230 indicesType = RankedTensorType::get(indiceParser.getShape(), indiceEltType);
1232 auto indices = indiceParser.getAttr(indicesLoc, indicesType);
1239 auto valuesEltType = type.getElementType();
1240 ShapedType valuesType =
1241 valuesParser.getShape().empty()
1242 ? RankedTensorType::get({indicesType.getDimSize(0)}, valuesEltType)
1243 : RankedTensorType::get(valuesParser.getShape(), valuesEltType);
1244 auto values = valuesParser.getAttr(valuesLoc, valuesType);
1255 auto errorEmitter = [&] {
return emitError(loc); };
1258 if (failed(
parseToken(Token::less,
"expected '<' after 'strided'")) ||
1259 failed(
parseToken(Token::l_square,
"expected '['")))
1265 auto parseStrideOrOffset = [&]() -> std::optional<int64_t> {
1267 return ShapedType::kDynamic;
1271 emitError(loc,
"expected a 64-bit signed integer or '?'");
1272 return std::nullopt;
1275 bool negative =
consumeIf(Token::minus);
1277 if (
getToken().is(Token::integer)) {
1280 *value >
static_cast<uint64_t
>(std::numeric_limits<int64_t>::max()))
1295 if (!
getToken().is(Token::r_square)) {
1297 std::optional<int64_t> stride = parseStrideOrOffset();
1300 strides.push_back(*stride);
1304 if (failed(
parseToken(Token::r_square,
"expected ']'")))
1309 if (failed(StridedLayoutAttr::verify(errorEmitter,
1312 return StridedLayoutAttr::get(
getContext(), 0, strides);
1315 if (failed(
parseToken(Token::comma,
"expected ','")) ||
1316 failed(
parseToken(Token::kw_offset,
"expected 'offset' after comma")) ||
1317 failed(
parseToken(Token::colon,
"expected ':' after 'offset'")))
1320 std::optional<int64_t> offset = parseStrideOrOffset();
1321 if (!offset || failed(
parseToken(Token::greater,
"expected '>'")))
1324 if (failed(StridedLayoutAttr::verify(errorEmitter, *offset, strides)))
1326 return StridedLayoutAttr::get(
getContext(), *offset, strides);
1338 if (
parseToken(Token::l_square,
"expected '[' after 'distinct'"))
1343 if (
parseToken(Token::integer,
"expected distinct ID"))
1347 emitError(
"expected an unsigned 64-bit integer");
1352 if (
parseToken(Token::r_square,
"expected ']' to close distinct ID") ||
1353 parseToken(Token::less,
"expected '<' after distinct ID"))
1357 if (
getToken().is(Token::greater)) {
1359 referencedAttr =
builder.getUnitAttr();
1362 if (!referencedAttr) {
1367 if (
parseToken(Token::greater,
"expected '>' to close distinct attribute"))
1375 state.symbols.distinctAttributes;
1376 auto it = distinctAttrs.find(*value);
1377 if (it == distinctAttrs.end()) {
1379 it = distinctAttrs.try_emplace(*value, distinctAttr).first;
1380 }
else if (it->getSecond().getReferencedAttr() != referencedAttr) {
1381 emitError(loc,
"referenced attribute does not match previous definition: ")
1382 << it->getSecond().getReferencedAttr();
1386 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.
static const llvm::fltSemantics * getFloatSemantics(TruncfSrcElemTypes etype)
Float semantics the element type attributes of xevm.truncf and xevm.extf stand for.
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.
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