18a7a7137SAlex Zinenko //===- TestOpsSyntax.cpp - Operations for testing syntax ------------------===//
28a7a7137SAlex Zinenko //
38a7a7137SAlex Zinenko // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
48a7a7137SAlex Zinenko // See https://llvm.org/LICENSE.txt for license information.
58a7a7137SAlex Zinenko // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68a7a7137SAlex Zinenko //
78a7a7137SAlex Zinenko //===----------------------------------------------------------------------===//
88a7a7137SAlex Zinenko
98a7a7137SAlex Zinenko #include "TestOpsSyntax.h"
108a7a7137SAlex Zinenko #include "TestDialect.h"
11e95e94adSJeff Niu #include "TestOps.h"
128a7a7137SAlex Zinenko #include "mlir/IR/OpImplementation.h"
138a7a7137SAlex Zinenko #include "llvm/Support/Base64.h"
148a7a7137SAlex Zinenko
158a7a7137SAlex Zinenko using namespace mlir;
168a7a7137SAlex Zinenko using namespace test;
178a7a7137SAlex Zinenko
188a7a7137SAlex Zinenko //===----------------------------------------------------------------------===//
198a7a7137SAlex Zinenko // Test Format* operations
208a7a7137SAlex Zinenko //===----------------------------------------------------------------------===//
218a7a7137SAlex Zinenko
228a7a7137SAlex Zinenko //===----------------------------------------------------------------------===//
238a7a7137SAlex Zinenko // Parsing
248a7a7137SAlex Zinenko
parseCustomOptionalOperand(OpAsmParser & parser,std::optional<OpAsmParser::UnresolvedOperand> & optOperand)258a7a7137SAlex Zinenko static ParseResult parseCustomOptionalOperand(
268a7a7137SAlex Zinenko OpAsmParser &parser,
278a7a7137SAlex Zinenko std::optional<OpAsmParser::UnresolvedOperand> &optOperand) {
288a7a7137SAlex Zinenko if (succeeded(parser.parseOptionalLParen())) {
298a7a7137SAlex Zinenko optOperand.emplace();
308a7a7137SAlex Zinenko if (parser.parseOperand(*optOperand) || parser.parseRParen())
318a7a7137SAlex Zinenko return failure();
328a7a7137SAlex Zinenko }
338a7a7137SAlex Zinenko return success();
348a7a7137SAlex Zinenko }
358a7a7137SAlex Zinenko
parseCustomDirectiveOperands(OpAsmParser & parser,OpAsmParser::UnresolvedOperand & operand,std::optional<OpAsmParser::UnresolvedOperand> & optOperand,SmallVectorImpl<OpAsmParser::UnresolvedOperand> & varOperands)368a7a7137SAlex Zinenko static ParseResult parseCustomDirectiveOperands(
378a7a7137SAlex Zinenko OpAsmParser &parser, OpAsmParser::UnresolvedOperand &operand,
388a7a7137SAlex Zinenko std::optional<OpAsmParser::UnresolvedOperand> &optOperand,
398a7a7137SAlex Zinenko SmallVectorImpl<OpAsmParser::UnresolvedOperand> &varOperands) {
408a7a7137SAlex Zinenko if (parser.parseOperand(operand))
418a7a7137SAlex Zinenko return failure();
428a7a7137SAlex Zinenko if (succeeded(parser.parseOptionalComma())) {
438a7a7137SAlex Zinenko optOperand.emplace();
448a7a7137SAlex Zinenko if (parser.parseOperand(*optOperand))
458a7a7137SAlex Zinenko return failure();
468a7a7137SAlex Zinenko }
478a7a7137SAlex Zinenko if (parser.parseArrow() || parser.parseLParen() ||
488a7a7137SAlex Zinenko parser.parseOperandList(varOperands) || parser.parseRParen())
498a7a7137SAlex Zinenko return failure();
508a7a7137SAlex Zinenko return success();
518a7a7137SAlex Zinenko }
528a7a7137SAlex Zinenko static ParseResult
parseCustomDirectiveResults(OpAsmParser & parser,Type & operandType,Type & optOperandType,SmallVectorImpl<Type> & varOperandTypes)538a7a7137SAlex Zinenko parseCustomDirectiveResults(OpAsmParser &parser, Type &operandType,
548a7a7137SAlex Zinenko Type &optOperandType,
558a7a7137SAlex Zinenko SmallVectorImpl<Type> &varOperandTypes) {
568a7a7137SAlex Zinenko if (parser.parseColon())
578a7a7137SAlex Zinenko return failure();
588a7a7137SAlex Zinenko
598a7a7137SAlex Zinenko if (parser.parseType(operandType))
608a7a7137SAlex Zinenko return failure();
618a7a7137SAlex Zinenko if (succeeded(parser.parseOptionalComma())) {
628a7a7137SAlex Zinenko if (parser.parseType(optOperandType))
638a7a7137SAlex Zinenko return failure();
648a7a7137SAlex Zinenko }
658a7a7137SAlex Zinenko if (parser.parseArrow() || parser.parseLParen() ||
668a7a7137SAlex Zinenko parser.parseTypeList(varOperandTypes) || parser.parseRParen())
678a7a7137SAlex Zinenko return failure();
688a7a7137SAlex Zinenko return success();
698a7a7137SAlex Zinenko }
708a7a7137SAlex Zinenko static ParseResult
parseCustomDirectiveWithTypeRefs(OpAsmParser & parser,Type operandType,Type optOperandType,const SmallVectorImpl<Type> & varOperandTypes)718a7a7137SAlex Zinenko parseCustomDirectiveWithTypeRefs(OpAsmParser &parser, Type operandType,
728a7a7137SAlex Zinenko Type optOperandType,
738a7a7137SAlex Zinenko const SmallVectorImpl<Type> &varOperandTypes) {
748a7a7137SAlex Zinenko if (parser.parseKeyword("type_refs_capture"))
758a7a7137SAlex Zinenko return failure();
768a7a7137SAlex Zinenko
778a7a7137SAlex Zinenko Type operandType2, optOperandType2;
788a7a7137SAlex Zinenko SmallVector<Type, 1> varOperandTypes2;
798a7a7137SAlex Zinenko if (parseCustomDirectiveResults(parser, operandType2, optOperandType2,
808a7a7137SAlex Zinenko varOperandTypes2))
818a7a7137SAlex Zinenko return failure();
828a7a7137SAlex Zinenko
838a7a7137SAlex Zinenko if (operandType != operandType2 || optOperandType != optOperandType2 ||
848a7a7137SAlex Zinenko varOperandTypes != varOperandTypes2)
858a7a7137SAlex Zinenko return failure();
868a7a7137SAlex Zinenko
878a7a7137SAlex Zinenko return success();
888a7a7137SAlex Zinenko }
parseCustomDirectiveOperandsAndTypes(OpAsmParser & parser,OpAsmParser::UnresolvedOperand & operand,std::optional<OpAsmParser::UnresolvedOperand> & optOperand,SmallVectorImpl<OpAsmParser::UnresolvedOperand> & varOperands,Type & operandType,Type & optOperandType,SmallVectorImpl<Type> & varOperandTypes)898a7a7137SAlex Zinenko static ParseResult parseCustomDirectiveOperandsAndTypes(
908a7a7137SAlex Zinenko OpAsmParser &parser, OpAsmParser::UnresolvedOperand &operand,
918a7a7137SAlex Zinenko std::optional<OpAsmParser::UnresolvedOperand> &optOperand,
928a7a7137SAlex Zinenko SmallVectorImpl<OpAsmParser::UnresolvedOperand> &varOperands,
938a7a7137SAlex Zinenko Type &operandType, Type &optOperandType,
948a7a7137SAlex Zinenko SmallVectorImpl<Type> &varOperandTypes) {
958a7a7137SAlex Zinenko if (parseCustomDirectiveOperands(parser, operand, optOperand, varOperands) ||
968a7a7137SAlex Zinenko parseCustomDirectiveResults(parser, operandType, optOperandType,
978a7a7137SAlex Zinenko varOperandTypes))
988a7a7137SAlex Zinenko return failure();
998a7a7137SAlex Zinenko return success();
1008a7a7137SAlex Zinenko }
parseCustomDirectiveRegions(OpAsmParser & parser,Region & region,SmallVectorImpl<std::unique_ptr<Region>> & varRegions)1018a7a7137SAlex Zinenko static ParseResult parseCustomDirectiveRegions(
1028a7a7137SAlex Zinenko OpAsmParser &parser, Region ®ion,
1038a7a7137SAlex Zinenko SmallVectorImpl<std::unique_ptr<Region>> &varRegions) {
1048a7a7137SAlex Zinenko if (parser.parseRegion(region))
1058a7a7137SAlex Zinenko return failure();
1068a7a7137SAlex Zinenko if (failed(parser.parseOptionalComma()))
1078a7a7137SAlex Zinenko return success();
1088a7a7137SAlex Zinenko std::unique_ptr<Region> varRegion = std::make_unique<Region>();
1098a7a7137SAlex Zinenko if (parser.parseRegion(*varRegion))
1108a7a7137SAlex Zinenko return failure();
1118a7a7137SAlex Zinenko varRegions.emplace_back(std::move(varRegion));
1128a7a7137SAlex Zinenko return success();
1138a7a7137SAlex Zinenko }
1148a7a7137SAlex Zinenko static ParseResult
parseCustomDirectiveSuccessors(OpAsmParser & parser,Block * & successor,SmallVectorImpl<Block * > & varSuccessors)1158a7a7137SAlex Zinenko parseCustomDirectiveSuccessors(OpAsmParser &parser, Block *&successor,
1168a7a7137SAlex Zinenko SmallVectorImpl<Block *> &varSuccessors) {
1178a7a7137SAlex Zinenko if (parser.parseSuccessor(successor))
1188a7a7137SAlex Zinenko return failure();
1198a7a7137SAlex Zinenko if (failed(parser.parseOptionalComma()))
1208a7a7137SAlex Zinenko return success();
1218a7a7137SAlex Zinenko Block *varSuccessor;
1228a7a7137SAlex Zinenko if (parser.parseSuccessor(varSuccessor))
1238a7a7137SAlex Zinenko return failure();
1248a7a7137SAlex Zinenko varSuccessors.append(2, varSuccessor);
1258a7a7137SAlex Zinenko return success();
1268a7a7137SAlex Zinenko }
parseCustomDirectiveAttributes(OpAsmParser & parser,IntegerAttr & attr,IntegerAttr & optAttr)1278a7a7137SAlex Zinenko static ParseResult parseCustomDirectiveAttributes(OpAsmParser &parser,
1288a7a7137SAlex Zinenko IntegerAttr &attr,
1298a7a7137SAlex Zinenko IntegerAttr &optAttr) {
1308a7a7137SAlex Zinenko if (parser.parseAttribute(attr))
1318a7a7137SAlex Zinenko return failure();
1328a7a7137SAlex Zinenko if (succeeded(parser.parseOptionalComma())) {
1338a7a7137SAlex Zinenko if (parser.parseAttribute(optAttr))
1348a7a7137SAlex Zinenko return failure();
1358a7a7137SAlex Zinenko }
1368a7a7137SAlex Zinenko return success();
1378a7a7137SAlex Zinenko }
parseCustomDirectiveSpacing(OpAsmParser & parser,mlir::StringAttr & attr)1388a7a7137SAlex Zinenko static ParseResult parseCustomDirectiveSpacing(OpAsmParser &parser,
1398a7a7137SAlex Zinenko mlir::StringAttr &attr) {
1408a7a7137SAlex Zinenko return parser.parseAttribute(attr);
1418a7a7137SAlex Zinenko }
parseCustomDirectiveAttrDict(OpAsmParser & parser,NamedAttrList & attrs)1428a7a7137SAlex Zinenko static ParseResult parseCustomDirectiveAttrDict(OpAsmParser &parser,
1438a7a7137SAlex Zinenko NamedAttrList &attrs) {
1448a7a7137SAlex Zinenko return parser.parseOptionalAttrDict(attrs);
1458a7a7137SAlex Zinenko }
parseCustomDirectiveOptionalOperandRef(OpAsmParser & parser,std::optional<OpAsmParser::UnresolvedOperand> & optOperand)1468a7a7137SAlex Zinenko static ParseResult parseCustomDirectiveOptionalOperandRef(
1478a7a7137SAlex Zinenko OpAsmParser &parser,
1488a7a7137SAlex Zinenko std::optional<OpAsmParser::UnresolvedOperand> &optOperand) {
1498a7a7137SAlex Zinenko int64_t operandCount = 0;
1508a7a7137SAlex Zinenko if (parser.parseInteger(operandCount))
1518a7a7137SAlex Zinenko return failure();
1528a7a7137SAlex Zinenko bool expectedOptionalOperand = operandCount == 0;
1538a7a7137SAlex Zinenko return success(expectedOptionalOperand != optOperand.has_value());
1548a7a7137SAlex Zinenko }
1558a7a7137SAlex Zinenko
1568a7a7137SAlex Zinenko //===----------------------------------------------------------------------===//
1578a7a7137SAlex Zinenko // Printing
1588a7a7137SAlex Zinenko
printCustomOptionalOperand(OpAsmPrinter & printer,Operation *,Value optOperand)1598a7a7137SAlex Zinenko static void printCustomOptionalOperand(OpAsmPrinter &printer, Operation *,
1608a7a7137SAlex Zinenko Value optOperand) {
1618a7a7137SAlex Zinenko if (optOperand)
1628a7a7137SAlex Zinenko printer << "(" << optOperand << ") ";
1638a7a7137SAlex Zinenko }
1648a7a7137SAlex Zinenko
printCustomDirectiveOperands(OpAsmPrinter & printer,Operation *,Value operand,Value optOperand,OperandRange varOperands)1658a7a7137SAlex Zinenko static void printCustomDirectiveOperands(OpAsmPrinter &printer, Operation *,
1668a7a7137SAlex Zinenko Value operand, Value optOperand,
1678a7a7137SAlex Zinenko OperandRange varOperands) {
1688a7a7137SAlex Zinenko printer << operand;
1698a7a7137SAlex Zinenko if (optOperand)
1708a7a7137SAlex Zinenko printer << ", " << optOperand;
1718a7a7137SAlex Zinenko printer << " -> (" << varOperands << ")";
1728a7a7137SAlex Zinenko }
printCustomDirectiveResults(OpAsmPrinter & printer,Operation *,Type operandType,Type optOperandType,TypeRange varOperandTypes)1738a7a7137SAlex Zinenko static void printCustomDirectiveResults(OpAsmPrinter &printer, Operation *,
1748a7a7137SAlex Zinenko Type operandType, Type optOperandType,
1758a7a7137SAlex Zinenko TypeRange varOperandTypes) {
1768a7a7137SAlex Zinenko printer << " : " << operandType;
1778a7a7137SAlex Zinenko if (optOperandType)
1788a7a7137SAlex Zinenko printer << ", " << optOperandType;
1798a7a7137SAlex Zinenko printer << " -> (" << varOperandTypes << ")";
1808a7a7137SAlex Zinenko }
printCustomDirectiveWithTypeRefs(OpAsmPrinter & printer,Operation * op,Type operandType,Type optOperandType,TypeRange varOperandTypes)1818a7a7137SAlex Zinenko static void printCustomDirectiveWithTypeRefs(OpAsmPrinter &printer,
1828a7a7137SAlex Zinenko Operation *op, Type operandType,
1838a7a7137SAlex Zinenko Type optOperandType,
1848a7a7137SAlex Zinenko TypeRange varOperandTypes) {
1858a7a7137SAlex Zinenko printer << " type_refs_capture ";
1868a7a7137SAlex Zinenko printCustomDirectiveResults(printer, op, operandType, optOperandType,
1878a7a7137SAlex Zinenko varOperandTypes);
1888a7a7137SAlex Zinenko }
printCustomDirectiveOperandsAndTypes(OpAsmPrinter & printer,Operation * op,Value operand,Value optOperand,OperandRange varOperands,Type operandType,Type optOperandType,TypeRange varOperandTypes)1898a7a7137SAlex Zinenko static void printCustomDirectiveOperandsAndTypes(
1908a7a7137SAlex Zinenko OpAsmPrinter &printer, Operation *op, Value operand, Value optOperand,
1918a7a7137SAlex Zinenko OperandRange varOperands, Type operandType, Type optOperandType,
1928a7a7137SAlex Zinenko TypeRange varOperandTypes) {
1938a7a7137SAlex Zinenko printCustomDirectiveOperands(printer, op, operand, optOperand, varOperands);
1948a7a7137SAlex Zinenko printCustomDirectiveResults(printer, op, operandType, optOperandType,
1958a7a7137SAlex Zinenko varOperandTypes);
1968a7a7137SAlex Zinenko }
printCustomDirectiveRegions(OpAsmPrinter & printer,Operation *,Region & region,MutableArrayRef<Region> varRegions)1978a7a7137SAlex Zinenko static void printCustomDirectiveRegions(OpAsmPrinter &printer, Operation *,
1988a7a7137SAlex Zinenko Region ®ion,
1998a7a7137SAlex Zinenko MutableArrayRef<Region> varRegions) {
2008a7a7137SAlex Zinenko printer.printRegion(region);
2018a7a7137SAlex Zinenko if (!varRegions.empty()) {
2028a7a7137SAlex Zinenko printer << ", ";
2038a7a7137SAlex Zinenko for (Region ®ion : varRegions)
2048a7a7137SAlex Zinenko printer.printRegion(region);
2058a7a7137SAlex Zinenko }
2068a7a7137SAlex Zinenko }
printCustomDirectiveSuccessors(OpAsmPrinter & printer,Operation *,Block * successor,SuccessorRange varSuccessors)2078a7a7137SAlex Zinenko static void printCustomDirectiveSuccessors(OpAsmPrinter &printer, Operation *,
2088a7a7137SAlex Zinenko Block *successor,
2098a7a7137SAlex Zinenko SuccessorRange varSuccessors) {
2108a7a7137SAlex Zinenko printer << successor;
2118a7a7137SAlex Zinenko if (!varSuccessors.empty())
2128a7a7137SAlex Zinenko printer << ", " << varSuccessors.front();
2138a7a7137SAlex Zinenko }
printCustomDirectiveAttributes(OpAsmPrinter & printer,Operation *,Attribute attribute,Attribute optAttribute)2148a7a7137SAlex Zinenko static void printCustomDirectiveAttributes(OpAsmPrinter &printer, Operation *,
2158a7a7137SAlex Zinenko Attribute attribute,
2168a7a7137SAlex Zinenko Attribute optAttribute) {
2178a7a7137SAlex Zinenko printer << attribute;
2188a7a7137SAlex Zinenko if (optAttribute)
2198a7a7137SAlex Zinenko printer << ", " << optAttribute;
2208a7a7137SAlex Zinenko }
printCustomDirectiveSpacing(OpAsmPrinter & printer,Operation * op,Attribute attribute)2218a7a7137SAlex Zinenko static void printCustomDirectiveSpacing(OpAsmPrinter &printer, Operation *op,
2228a7a7137SAlex Zinenko Attribute attribute) {
2238a7a7137SAlex Zinenko printer << attribute;
2248a7a7137SAlex Zinenko }
printCustomDirectiveAttrDict(OpAsmPrinter & printer,Operation * op,DictionaryAttr attrs)2258a7a7137SAlex Zinenko static void printCustomDirectiveAttrDict(OpAsmPrinter &printer, Operation *op,
2268a7a7137SAlex Zinenko DictionaryAttr attrs) {
2278a7a7137SAlex Zinenko printer.printOptionalAttrDict(attrs.getValue());
2288a7a7137SAlex Zinenko }
2298a7a7137SAlex Zinenko
printCustomDirectiveOptionalOperandRef(OpAsmPrinter & printer,Operation * op,Value optOperand)2308a7a7137SAlex Zinenko static void printCustomDirectiveOptionalOperandRef(OpAsmPrinter &printer,
2318a7a7137SAlex Zinenko Operation *op,
2328a7a7137SAlex Zinenko Value optOperand) {
2338a7a7137SAlex Zinenko printer << (optOperand ? "1" : "0");
2348a7a7137SAlex Zinenko }
2358a7a7137SAlex Zinenko //===----------------------------------------------------------------------===//
2368a7a7137SAlex Zinenko // Test parser.
2378a7a7137SAlex Zinenko //===----------------------------------------------------------------------===//
2388a7a7137SAlex Zinenko
parse(OpAsmParser & parser,OperationState & result)2398a7a7137SAlex Zinenko ParseResult ParseIntegerLiteralOp::parse(OpAsmParser &parser,
2408a7a7137SAlex Zinenko OperationState &result) {
2418a7a7137SAlex Zinenko if (parser.parseOptionalColon())
2428a7a7137SAlex Zinenko return success();
2438a7a7137SAlex Zinenko uint64_t numResults;
2448a7a7137SAlex Zinenko if (parser.parseInteger(numResults))
2458a7a7137SAlex Zinenko return failure();
2468a7a7137SAlex Zinenko
2478a7a7137SAlex Zinenko IndexType type = parser.getBuilder().getIndexType();
2488a7a7137SAlex Zinenko for (unsigned i = 0; i < numResults; ++i)
2498a7a7137SAlex Zinenko result.addTypes(type);
2508a7a7137SAlex Zinenko return success();
2518a7a7137SAlex Zinenko }
2528a7a7137SAlex Zinenko
print(OpAsmPrinter & p)2538a7a7137SAlex Zinenko void ParseIntegerLiteralOp::print(OpAsmPrinter &p) {
2548a7a7137SAlex Zinenko if (unsigned numResults = getNumResults())
2558a7a7137SAlex Zinenko p << " : " << numResults;
2568a7a7137SAlex Zinenko }
2578a7a7137SAlex Zinenko
parse(OpAsmParser & parser,OperationState & result)2588a7a7137SAlex Zinenko ParseResult ParseWrappedKeywordOp::parse(OpAsmParser &parser,
2598a7a7137SAlex Zinenko OperationState &result) {
2608a7a7137SAlex Zinenko StringRef keyword;
2618a7a7137SAlex Zinenko if (parser.parseKeyword(&keyword))
2628a7a7137SAlex Zinenko return failure();
2638a7a7137SAlex Zinenko result.addAttribute("keyword", parser.getBuilder().getStringAttr(keyword));
2648a7a7137SAlex Zinenko return success();
2658a7a7137SAlex Zinenko }
2668a7a7137SAlex Zinenko
print(OpAsmPrinter & p)2678a7a7137SAlex Zinenko void ParseWrappedKeywordOp::print(OpAsmPrinter &p) { p << " " << getKeyword(); }
2688a7a7137SAlex Zinenko
parse(OpAsmParser & parser,OperationState & result)2698a7a7137SAlex Zinenko ParseResult ParseB64BytesOp::parse(OpAsmParser &parser,
2708a7a7137SAlex Zinenko OperationState &result) {
2718a7a7137SAlex Zinenko std::vector<char> bytes;
2728a7a7137SAlex Zinenko if (parser.parseBase64Bytes(&bytes))
2738a7a7137SAlex Zinenko return failure();
2748a7a7137SAlex Zinenko result.addAttribute("b64", parser.getBuilder().getStringAttr(
2758a7a7137SAlex Zinenko StringRef(&bytes.front(), bytes.size())));
2768a7a7137SAlex Zinenko return success();
2778a7a7137SAlex Zinenko }
2788a7a7137SAlex Zinenko
print(OpAsmPrinter & p)2798a7a7137SAlex Zinenko void ParseB64BytesOp::print(OpAsmPrinter &p) {
2808a7a7137SAlex Zinenko p << " \"" << llvm::encodeBase64(getB64()) << "\"";
2818a7a7137SAlex Zinenko }
2828a7a7137SAlex Zinenko
inferReturnTypes(::mlir::MLIRContext * context,::std::optional<::mlir::Location> location,::mlir::ValueRange operands,::mlir::DictionaryAttr attributes,OpaqueProperties properties,::mlir::RegionRange regions,::llvm::SmallVectorImpl<::mlir::Type> & inferredReturnTypes)283*db791b27SRamkumar Ramachandra ::llvm::LogicalResult FormatInferType2Op::inferReturnTypes(
2848a7a7137SAlex Zinenko ::mlir::MLIRContext *context, ::std::optional<::mlir::Location> location,
2858a7a7137SAlex Zinenko ::mlir::ValueRange operands, ::mlir::DictionaryAttr attributes,
2868a7a7137SAlex Zinenko OpaqueProperties properties, ::mlir::RegionRange regions,
2878a7a7137SAlex Zinenko ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) {
2888a7a7137SAlex Zinenko inferredReturnTypes.assign({::mlir::IntegerType::get(context, 16)});
2898a7a7137SAlex Zinenko return ::mlir::success();
2908a7a7137SAlex Zinenko }
2918a7a7137SAlex Zinenko
2928a7a7137SAlex Zinenko //===----------------------------------------------------------------------===//
2938a7a7137SAlex Zinenko // Test WrapRegionOp - wrapping op exercising `parseGenericOperation()`.
2948a7a7137SAlex Zinenko
parse(OpAsmParser & parser,OperationState & result)2958a7a7137SAlex Zinenko ParseResult WrappingRegionOp::parse(OpAsmParser &parser,
2968a7a7137SAlex Zinenko OperationState &result) {
2978a7a7137SAlex Zinenko if (parser.parseKeyword("wraps"))
2988a7a7137SAlex Zinenko return failure();
2998a7a7137SAlex Zinenko
3008a7a7137SAlex Zinenko // Parse the wrapped op in a region
3018a7a7137SAlex Zinenko Region &body = *result.addRegion();
3028a7a7137SAlex Zinenko body.push_back(new Block);
3038a7a7137SAlex Zinenko Block &block = body.back();
3048a7a7137SAlex Zinenko Operation *wrappedOp = parser.parseGenericOperation(&block, block.begin());
3058a7a7137SAlex Zinenko if (!wrappedOp)
3068a7a7137SAlex Zinenko return failure();
3078a7a7137SAlex Zinenko
3088a7a7137SAlex Zinenko // Create a return terminator in the inner region, pass as operand to the
3098a7a7137SAlex Zinenko // terminator the returned values from the wrapped operation.
3108a7a7137SAlex Zinenko SmallVector<Value, 8> returnOperands(wrappedOp->getResults());
3118a7a7137SAlex Zinenko OpBuilder builder(parser.getContext());
3128a7a7137SAlex Zinenko builder.setInsertionPointToEnd(&block);
3138a7a7137SAlex Zinenko builder.create<TestReturnOp>(wrappedOp->getLoc(), returnOperands);
3148a7a7137SAlex Zinenko
3158a7a7137SAlex Zinenko // Get the results type for the wrapping op from the terminator operands.
3168a7a7137SAlex Zinenko Operation &returnOp = body.back().back();
3178a7a7137SAlex Zinenko result.types.append(returnOp.operand_type_begin(),
3188a7a7137SAlex Zinenko returnOp.operand_type_end());
3198a7a7137SAlex Zinenko
3208a7a7137SAlex Zinenko // Use the location of the wrapped op for the "test.wrapping_region" op.
3218a7a7137SAlex Zinenko result.location = wrappedOp->getLoc();
3228a7a7137SAlex Zinenko
3238a7a7137SAlex Zinenko return success();
3248a7a7137SAlex Zinenko }
3258a7a7137SAlex Zinenko
print(OpAsmPrinter & p)3268a7a7137SAlex Zinenko void WrappingRegionOp::print(OpAsmPrinter &p) {
3278a7a7137SAlex Zinenko p << " wraps ";
3288a7a7137SAlex Zinenko p.printGenericOp(&getRegion().front().front());
3298a7a7137SAlex Zinenko }
3308a7a7137SAlex Zinenko
3318a7a7137SAlex Zinenko //===----------------------------------------------------------------------===//
3328a7a7137SAlex Zinenko // Test PrettyPrintedRegionOp - exercising the following parser APIs
3338a7a7137SAlex Zinenko // parseGenericOperationAfterOpName
3348a7a7137SAlex Zinenko // parseCustomOperationName
3358a7a7137SAlex Zinenko //===----------------------------------------------------------------------===//
3368a7a7137SAlex Zinenko
parse(OpAsmParser & parser,OperationState & result)3378a7a7137SAlex Zinenko ParseResult PrettyPrintedRegionOp::parse(OpAsmParser &parser,
3388a7a7137SAlex Zinenko OperationState &result) {
3398a7a7137SAlex Zinenko
3408a7a7137SAlex Zinenko SMLoc loc = parser.getCurrentLocation();
3418a7a7137SAlex Zinenko Location currLocation = parser.getEncodedSourceLoc(loc);
3428a7a7137SAlex Zinenko
3438a7a7137SAlex Zinenko // Parse the operands.
3448a7a7137SAlex Zinenko SmallVector<OpAsmParser::UnresolvedOperand, 2> operands;
3458a7a7137SAlex Zinenko if (parser.parseOperandList(operands))
3468a7a7137SAlex Zinenko return failure();
3478a7a7137SAlex Zinenko
3488a7a7137SAlex Zinenko // Check if we are parsing the pretty-printed version
3498a7a7137SAlex Zinenko // test.pretty_printed_region start <inner-op> end : <functional-type>
3508a7a7137SAlex Zinenko // Else fallback to parsing the "non pretty-printed" version.
3518a7a7137SAlex Zinenko if (!succeeded(parser.parseOptionalKeyword("start")))
3528a7a7137SAlex Zinenko return parser.parseGenericOperationAfterOpName(result,
3538a7a7137SAlex Zinenko llvm::ArrayRef(operands));
3548a7a7137SAlex Zinenko
3558a7a7137SAlex Zinenko FailureOr<OperationName> parseOpNameInfo = parser.parseCustomOperationName();
3568a7a7137SAlex Zinenko if (failed(parseOpNameInfo))
3578a7a7137SAlex Zinenko return failure();
3588a7a7137SAlex Zinenko
3598a7a7137SAlex Zinenko StringAttr innerOpName = parseOpNameInfo->getIdentifier();
3608a7a7137SAlex Zinenko
3618a7a7137SAlex Zinenko FunctionType opFntype;
3628a7a7137SAlex Zinenko std::optional<Location> explicitLoc;
3638a7a7137SAlex Zinenko if (parser.parseKeyword("end") || parser.parseColon() ||
3648a7a7137SAlex Zinenko parser.parseType(opFntype) ||
3658a7a7137SAlex Zinenko parser.parseOptionalLocationSpecifier(explicitLoc))
3668a7a7137SAlex Zinenko return failure();
3678a7a7137SAlex Zinenko
3688a7a7137SAlex Zinenko // If location of the op is explicitly provided, then use it; Else use
3698a7a7137SAlex Zinenko // the parser's current location.
3708a7a7137SAlex Zinenko Location opLoc = explicitLoc.value_or(currLocation);
3718a7a7137SAlex Zinenko
3728a7a7137SAlex Zinenko // Derive the SSA-values for op's operands.
3738a7a7137SAlex Zinenko if (parser.resolveOperands(operands, opFntype.getInputs(), loc,
3748a7a7137SAlex Zinenko result.operands))
3758a7a7137SAlex Zinenko return failure();
3768a7a7137SAlex Zinenko
3778a7a7137SAlex Zinenko // Add a region for op.
3788a7a7137SAlex Zinenko Region ®ion = *result.addRegion();
3798a7a7137SAlex Zinenko
3808a7a7137SAlex Zinenko // Create a basic-block inside op's region.
3818a7a7137SAlex Zinenko Block &block = region.emplaceBlock();
3828a7a7137SAlex Zinenko
3838a7a7137SAlex Zinenko // Create and insert an "inner-op" operation in the block.
3848a7a7137SAlex Zinenko // Just for testing purposes, we can assume that inner op is a binary op with
3858a7a7137SAlex Zinenko // result and operand types all same as the test-op's first operand.
3868a7a7137SAlex Zinenko Type innerOpType = opFntype.getInput(0);
3878a7a7137SAlex Zinenko Value lhs = block.addArgument(innerOpType, opLoc);
3888a7a7137SAlex Zinenko Value rhs = block.addArgument(innerOpType, opLoc);
3898a7a7137SAlex Zinenko
3908a7a7137SAlex Zinenko OpBuilder builder(parser.getBuilder().getContext());
3918a7a7137SAlex Zinenko builder.setInsertionPointToStart(&block);
3928a7a7137SAlex Zinenko
3938a7a7137SAlex Zinenko Operation *innerOp =
3948a7a7137SAlex Zinenko builder.create(opLoc, innerOpName, /*operands=*/{lhs, rhs}, innerOpType);
3958a7a7137SAlex Zinenko
3968a7a7137SAlex Zinenko // Insert a return statement in the block returning the inner-op's result.
3978a7a7137SAlex Zinenko builder.create<TestReturnOp>(innerOp->getLoc(), innerOp->getResults());
3988a7a7137SAlex Zinenko
3998a7a7137SAlex Zinenko // Populate the op operation-state with result-type and location.
4008a7a7137SAlex Zinenko result.addTypes(opFntype.getResults());
4018a7a7137SAlex Zinenko result.location = innerOp->getLoc();
4028a7a7137SAlex Zinenko
4038a7a7137SAlex Zinenko return success();
4048a7a7137SAlex Zinenko }
4058a7a7137SAlex Zinenko
print(OpAsmPrinter & p)4068a7a7137SAlex Zinenko void PrettyPrintedRegionOp::print(OpAsmPrinter &p) {
4078a7a7137SAlex Zinenko p << ' ';
4088a7a7137SAlex Zinenko p.printOperands(getOperands());
4098a7a7137SAlex Zinenko
4108a7a7137SAlex Zinenko Operation &innerOp = getRegion().front().front();
4118a7a7137SAlex Zinenko // Assuming that region has a single non-terminator inner-op, if the inner-op
4128a7a7137SAlex Zinenko // meets some criteria (which in this case is a simple one based on the name
4138a7a7137SAlex Zinenko // of inner-op), then we can print the entire region in a succinct way.
4148a7a7137SAlex Zinenko // Here we assume that the prototype of "test.special.op" can be trivially
4158a7a7137SAlex Zinenko // derived while parsing it back.
416dec8055aSKazu Hirata if (innerOp.getName().getStringRef() == "test.special.op") {
4178a7a7137SAlex Zinenko p << " start test.special.op end";
4188a7a7137SAlex Zinenko } else {
4198a7a7137SAlex Zinenko p << " (";
4208a7a7137SAlex Zinenko p.printRegion(getRegion());
4218a7a7137SAlex Zinenko p << ")";
4228a7a7137SAlex Zinenko }
4238a7a7137SAlex Zinenko
4248a7a7137SAlex Zinenko p << " : ";
4258a7a7137SAlex Zinenko p.printFunctionalType(*this);
4268a7a7137SAlex Zinenko }
4278a7a7137SAlex Zinenko
4288a7a7137SAlex Zinenko //===----------------------------------------------------------------------===//
4298a7a7137SAlex Zinenko // Test PolyForOp - parse list of region arguments.
4308a7a7137SAlex Zinenko //===----------------------------------------------------------------------===//
4318a7a7137SAlex Zinenko
parse(OpAsmParser & parser,OperationState & result)4328a7a7137SAlex Zinenko ParseResult PolyForOp::parse(OpAsmParser &parser, OperationState &result) {
4338a7a7137SAlex Zinenko SmallVector<OpAsmParser::Argument, 4> ivsInfo;
4348a7a7137SAlex Zinenko // Parse list of region arguments without a delimiter.
4358a7a7137SAlex Zinenko if (parser.parseArgumentList(ivsInfo, OpAsmParser::Delimiter::None))
4368a7a7137SAlex Zinenko return failure();
4378a7a7137SAlex Zinenko
4388a7a7137SAlex Zinenko // Parse the body region.
4398a7a7137SAlex Zinenko Region *body = result.addRegion();
4408a7a7137SAlex Zinenko for (auto &iv : ivsInfo)
4418a7a7137SAlex Zinenko iv.type = parser.getBuilder().getIndexType();
4428a7a7137SAlex Zinenko return parser.parseRegion(*body, ivsInfo);
4438a7a7137SAlex Zinenko }
4448a7a7137SAlex Zinenko
print(OpAsmPrinter & p)4458a7a7137SAlex Zinenko void PolyForOp::print(OpAsmPrinter &p) {
4468a7a7137SAlex Zinenko p << " ";
4478a7a7137SAlex Zinenko llvm::interleaveComma(getRegion().getArguments(), p, [&](auto arg) {
4488a7a7137SAlex Zinenko p.printRegionArgument(arg, /*argAttrs =*/{}, /*omitType=*/true);
4498a7a7137SAlex Zinenko });
4508a7a7137SAlex Zinenko p << " ";
4518a7a7137SAlex Zinenko p.printRegion(getRegion(), /*printEntryBlockArgs=*/false);
4528a7a7137SAlex Zinenko }
4538a7a7137SAlex Zinenko
getAsmBlockArgumentNames(Region & region,OpAsmSetValueNameFn setNameFn)4548a7a7137SAlex Zinenko void PolyForOp::getAsmBlockArgumentNames(Region ®ion,
4558a7a7137SAlex Zinenko OpAsmSetValueNameFn setNameFn) {
4568a7a7137SAlex Zinenko auto arrayAttr = getOperation()->getAttrOfType<ArrayAttr>("arg_names");
4578a7a7137SAlex Zinenko if (!arrayAttr)
4588a7a7137SAlex Zinenko return;
4598a7a7137SAlex Zinenko auto args = getRegion().front().getArguments();
4608a7a7137SAlex Zinenko auto e = std::min(arrayAttr.size(), args.size());
4618a7a7137SAlex Zinenko for (unsigned i = 0; i < e; ++i) {
4628a7a7137SAlex Zinenko if (auto strAttr = dyn_cast<StringAttr>(arrayAttr[i]))
4638a7a7137SAlex Zinenko setNameFn(args[i], strAttr.getValue());
4648a7a7137SAlex Zinenko }
4658a7a7137SAlex Zinenko }
4668a7a7137SAlex Zinenko
4678a7a7137SAlex Zinenko //===----------------------------------------------------------------------===//
4688a7a7137SAlex Zinenko // TestAttrWithLoc - parse/printOptionalLocationSpecifier
4698a7a7137SAlex Zinenko //===----------------------------------------------------------------------===//
4708a7a7137SAlex Zinenko
parseOptionalLoc(OpAsmParser & p,Attribute & loc)4718a7a7137SAlex Zinenko static ParseResult parseOptionalLoc(OpAsmParser &p, Attribute &loc) {
4728a7a7137SAlex Zinenko std::optional<Location> result;
4738a7a7137SAlex Zinenko SMLoc sourceLoc = p.getCurrentLocation();
4748a7a7137SAlex Zinenko if (p.parseOptionalLocationSpecifier(result))
4758a7a7137SAlex Zinenko return failure();
4768a7a7137SAlex Zinenko if (result)
4778a7a7137SAlex Zinenko loc = *result;
4788a7a7137SAlex Zinenko else
4798a7a7137SAlex Zinenko loc = p.getEncodedSourceLoc(sourceLoc);
4808a7a7137SAlex Zinenko return success();
4818a7a7137SAlex Zinenko }
4828a7a7137SAlex Zinenko
printOptionalLoc(OpAsmPrinter & p,Operation * op,Attribute loc)4838a7a7137SAlex Zinenko static void printOptionalLoc(OpAsmPrinter &p, Operation *op, Attribute loc) {
4848a7a7137SAlex Zinenko p.printOptionalLocationSpecifier(cast<LocationAttr>(loc));
4858a7a7137SAlex Zinenko }
4868a7a7137SAlex Zinenko
4878a7a7137SAlex Zinenko #define GET_OP_CLASSES
4888a7a7137SAlex Zinenko #include "TestOpsSyntax.cpp.inc"
4898a7a7137SAlex Zinenko
registerOpsSyntax()4908a7a7137SAlex Zinenko void TestDialect::registerOpsSyntax() {
4918a7a7137SAlex Zinenko addOperations<
4928a7a7137SAlex Zinenko #define GET_OP_LIST
4938a7a7137SAlex Zinenko #include "TestOpsSyntax.cpp.inc"
4948a7a7137SAlex Zinenko >();
4958a7a7137SAlex Zinenko }
496