xref: /llvm-project/mlir/test/lib/Dialect/Test/TestOpsSyntax.cpp (revision db791b278a414fb6df1acc1799adcf11d8fb9169)
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 &region,
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 &region,
1998a7a7137SAlex Zinenko                                         MutableArrayRef<Region> varRegions) {
2008a7a7137SAlex Zinenko   printer.printRegion(region);
2018a7a7137SAlex Zinenko   if (!varRegions.empty()) {
2028a7a7137SAlex Zinenko     printer << ", ";
2038a7a7137SAlex Zinenko     for (Region &region : 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 &region = *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 &region,
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