MLIR  14.0.0git
OpImplementation.h
Go to the documentation of this file.
1 //===- OpImplementation.h - Classes for implementing Op types ---*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This classes used by the implementation details of Op types.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef MLIR_IR_OPIMPLEMENTATION_H
14 #define MLIR_IR_OPIMPLEMENTATION_H
15 
16 #include "mlir/IR/BuiltinTypes.h"
18 #include "mlir/IR/OpDefinition.h"
19 #include "llvm/ADT/Twine.h"
20 #include "llvm/Support/SMLoc.h"
21 
22 namespace mlir {
23 
24 class Builder;
25 
26 //===----------------------------------------------------------------------===//
27 // AsmPrinter
28 //===----------------------------------------------------------------------===//
29 
30 /// This base class exposes generic asm printer hooks, usable across the various
31 /// derived printers.
32 class AsmPrinter {
33 public:
34  /// This class contains the internal default implementation of the base
35  /// printer methods.
36  class Impl;
37 
38  /// Initialize the printer with the given internal implementation.
39  AsmPrinter(Impl &impl) : impl(&impl) {}
40  virtual ~AsmPrinter();
41 
42  /// Return the raw output stream used by this printer.
43  virtual raw_ostream &getStream() const;
44 
45  /// Print the given floating point value in a stabilized form that can be
46  /// roundtripped through the IR. This is the companion to the 'parseFloat'
47  /// hook on the AsmParser.
48  virtual void printFloat(const APFloat &value);
49 
50  virtual void printType(Type type);
51  virtual void printAttribute(Attribute attr);
52 
53  /// Trait to check if `AttrType` provides a `print` method.
54  template <typename AttrOrType>
55  using has_print_method =
56  decltype(std::declval<AttrOrType>().print(std::declval<AsmPrinter &>()));
57  template <typename AttrOrType>
59  llvm::is_detected<has_print_method, AttrOrType>;
60 
61  /// Print the provided attribute in the context of an operation custom
62  /// printer/parser: this will invoke directly the print method on the
63  /// attribute class and skip the `#dialect.mnemonic` prefix in most cases.
64  template <typename AttrOrType,
66  *sfinae = nullptr>
67  void printStrippedAttrOrType(AttrOrType attrOrType) {
68  if (succeeded(printAlias(attrOrType)))
69  return;
70  attrOrType.print(*this);
71  }
72 
73  /// SFINAE for printing the provided attribute in the context of an operation
74  /// custom printer in the case where the attribute does not define a print
75  /// method.
76  template <typename AttrOrType,
78  *sfinae = nullptr>
79  void printStrippedAttrOrType(AttrOrType attrOrType) {
80  *this << attrOrType;
81  }
82 
83  /// Print the given attribute without its type. The corresponding parser must
84  /// provide a valid type for the attribute.
85  virtual void printAttributeWithoutType(Attribute attr);
86 
87  /// Print the given string as a keyword, or a quoted and escaped string if it
88  /// has any special or non-printable characters in it.
89  virtual void printKeywordOrString(StringRef keyword);
90 
91  /// Print the given string as a symbol reference, i.e. a form representable by
92  /// a SymbolRefAttr. A symbol reference is represented as a string prefixed
93  /// with '@'. The reference is surrounded with ""'s and escaped if it has any
94  /// special or non-printable characters in it.
95  virtual void printSymbolName(StringRef symbolRef);
96 
97  /// Print an optional arrow followed by a type list.
98  template <typename TypeRange>
100  if (types.begin() != types.end())
101  printArrowTypeList(types);
102  }
103  template <typename TypeRange>
105  auto &os = getStream() << " -> ";
106 
107  bool wrapped = !llvm::hasSingleElement(types) ||
108  (*types.begin()).template isa<FunctionType>();
109  if (wrapped)
110  os << '(';
111  llvm::interleaveComma(types, *this);
112  if (wrapped)
113  os << ')';
114  }
115 
116  /// Print the two given type ranges in a functional form.
117  template <typename InputRangeT, typename ResultRangeT>
118  void printFunctionalType(InputRangeT &&inputs, ResultRangeT &&results) {
119  auto &os = getStream();
120  os << '(';
121  llvm::interleaveComma(inputs, *this);
122  os << ')';
123  printArrowTypeList(results);
124  }
125 
126 protected:
127  /// Initialize the printer with no internal implementation. In this case, all
128  /// virtual methods of this class must be overriden.
130 
131 private:
132  AsmPrinter(const AsmPrinter &) = delete;
133  void operator=(const AsmPrinter &) = delete;
134 
135  /// Print the alias for the given attribute, return failure if no alias could
136  /// be printed.
137  virtual LogicalResult printAlias(Attribute attr);
138 
139  /// Print the alias for the given type, return failure if no alias could
140  /// be printed.
141  virtual LogicalResult printAlias(Type type);
142 
143  /// The internal implementation of the printer.
144  Impl *impl{nullptr};
145 };
146 
147 template <typename AsmPrinterT>
149  AsmPrinterT &>
150 operator<<(AsmPrinterT &p, Type type) {
151  p.printType(type);
152  return p;
153 }
154 
155 template <typename AsmPrinterT>
156 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
157  AsmPrinterT &>
158 operator<<(AsmPrinterT &p, Attribute attr) {
159  p.printAttribute(attr);
160  return p;
161 }
162 
163 template <typename AsmPrinterT>
164 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
165  AsmPrinterT &>
166 operator<<(AsmPrinterT &p, const APFloat &value) {
167  p.printFloat(value);
168  return p;
169 }
170 template <typename AsmPrinterT>
171 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
172  AsmPrinterT &>
173 operator<<(AsmPrinterT &p, float value) {
174  return p << APFloat(value);
175 }
176 template <typename AsmPrinterT>
177 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
178  AsmPrinterT &>
179 operator<<(AsmPrinterT &p, double value) {
180  return p << APFloat(value);
181 }
182 
183 // Support printing anything that isn't convertible to one of the other
184 // streamable types, even if it isn't exactly one of them. For example, we want
185 // to print FunctionType with the Type version above, not have it match this.
186 template <
187  typename AsmPrinterT, typename T,
194  T>::type * = nullptr>
195 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
196  AsmPrinterT &>
197 operator<<(AsmPrinterT &p, const T &other) {
198  p.getStream() << other;
199  return p;
200 }
201 
202 template <typename AsmPrinterT>
203 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
204  AsmPrinterT &>
205 operator<<(AsmPrinterT &p, bool value) {
206  return p << (value ? StringRef("true") : "false");
207 }
208 
209 template <typename AsmPrinterT, typename ValueRangeT>
210 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
211  AsmPrinterT &>
212 operator<<(AsmPrinterT &p, const ValueTypeRange<ValueRangeT> &types) {
213  llvm::interleaveComma(types, p);
214  return p;
215 }
216 template <typename AsmPrinterT>
217 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
218  AsmPrinterT &>
219 operator<<(AsmPrinterT &p, const TypeRange &types) {
220  llvm::interleaveComma(types, p);
221  return p;
222 }
223 template <typename AsmPrinterT, typename ElementT>
224 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
225  AsmPrinterT &>
226 operator<<(AsmPrinterT &p, ArrayRef<ElementT> types) {
227  llvm::interleaveComma(types, p);
228  return p;
229 }
230 
231 //===----------------------------------------------------------------------===//
232 // OpAsmPrinter
233 //===----------------------------------------------------------------------===//
234 
235 /// This is a pure-virtual base class that exposes the asmprinter hooks
236 /// necessary to implement a custom print() method.
237 class OpAsmPrinter : public AsmPrinter {
238 public:
240  ~OpAsmPrinter() override;
241 
242  /// Print a newline and indent the printer to the start of the current
243  /// operation.
244  virtual void printNewline() = 0;
245 
246  /// Print a block argument in the usual format of:
247  /// %ssaName : type {attr1=42} loc("here")
248  /// where location printing is controlled by the standard internal option.
249  /// You may pass omitType=true to not print a type, and pass an empty
250  /// attribute list if you don't care for attributes.
251  virtual void printRegionArgument(BlockArgument arg,
252  ArrayRef<NamedAttribute> argAttrs = {},
253  bool omitType = false) = 0;
254 
255  /// Print implementations for various things an operation contains.
256  virtual void printOperand(Value value) = 0;
257  virtual void printOperand(Value value, raw_ostream &os) = 0;
258 
259  /// Print a comma separated list of operands.
260  template <typename ContainerType>
261  void printOperands(const ContainerType &container) {
262  printOperands(container.begin(), container.end());
263  }
264 
265  /// Print a comma separated list of operands.
266  template <typename IteratorType>
268  if (it == end)
269  return;
270  printOperand(*it);
271  for (++it; it != end; ++it) {
272  getStream() << ", ";
273  printOperand(*it);
274  }
275  }
276 
277  /// Print the given successor.
278  virtual void printSuccessor(Block *successor) = 0;
279 
280  /// Print the successor and its operands.
281  virtual void printSuccessorAndUseList(Block *successor,
282  ValueRange succOperands) = 0;
283 
284  /// If the specified operation has attributes, print out an attribute
285  /// dictionary with their values. elidedAttrs allows the client to ignore
286  /// specific well known attributes, commonly used if the attribute value is
287  /// printed some other way (like as a fixed operand).
288  virtual void printOptionalAttrDict(ArrayRef<NamedAttribute> attrs,
289  ArrayRef<StringRef> elidedAttrs = {}) = 0;
290 
291  /// If the specified operation has attributes, print out an attribute
292  /// dictionary prefixed with 'attributes'.
293  virtual void
294  printOptionalAttrDictWithKeyword(ArrayRef<NamedAttribute> attrs,
295  ArrayRef<StringRef> elidedAttrs = {}) = 0;
296 
297  /// Print the entire operation with the default generic assembly form.
298  /// If `printOpName` is true, then the operation name is printed (the default)
299  /// otherwise it is omitted and the print will start with the operand list.
300  virtual void printGenericOp(Operation *op, bool printOpName = true) = 0;
301 
302  /// Prints a region.
303  /// If 'printEntryBlockArgs' is false, the arguments of the
304  /// block are not printed. If 'printBlockTerminator' is false, the terminator
305  /// operation of the block is not printed. If printEmptyBlock is true, then
306  /// the block header is printed even if the block is empty.
307  virtual void printRegion(Region &blocks, bool printEntryBlockArgs = true,
308  bool printBlockTerminators = true,
309  bool printEmptyBlock = false) = 0;
310 
311  /// Renumber the arguments for the specified region to the same names as the
312  /// SSA values in namesToUse. This may only be used for IsolatedFromAbove
313  /// operations. If any entry in namesToUse is null, the corresponding
314  /// argument name is left alone.
315  virtual void shadowRegionArgs(Region &region, ValueRange namesToUse) = 0;
316 
317  /// Prints an affine map of SSA ids, where SSA id names are used in place
318  /// of dims/symbols.
319  /// Operand values must come from single-result sources, and be valid
320  /// dimensions/symbol identifiers according to mlir::isValidDim/Symbol.
321  virtual void printAffineMapOfSSAIds(AffineMapAttr mapAttr,
322  ValueRange operands) = 0;
323 
324  /// Prints an affine expression of SSA ids with SSA id names used instead of
325  /// dims and symbols.
326  /// Operand values must come from single-result sources, and be valid
327  /// dimensions/symbol identifiers according to mlir::isValidDim/Symbol.
328  virtual void printAffineExprOfSSAIds(AffineExpr expr, ValueRange dimOperands,
329  ValueRange symOperands) = 0;
330 
331  /// Print the complete type of an operation in functional form.
332  void printFunctionalType(Operation *op);
334 };
335 
336 // Make the implementations convenient to use.
338  p.printOperand(value);
339  return p;
340 }
341 
342 template <typename T,
345  T>::type * = nullptr>
346 inline OpAsmPrinter &operator<<(OpAsmPrinter &p, const T &values) {
347  p.printOperands(values);
348  return p;
349 }
350 
352  p.printSuccessor(value);
353  return p;
354 }
355 
356 //===----------------------------------------------------------------------===//
357 // AsmParser
358 //===----------------------------------------------------------------------===//
359 
360 /// This base class exposes generic asm parser hooks, usable across the various
361 /// derived parsers.
362 class AsmParser {
363 public:
364  AsmParser() = default;
365  virtual ~AsmParser();
366 
367  MLIRContext *getContext() const;
368 
369  /// Return the location of the original name token.
370  virtual llvm::SMLoc getNameLoc() const = 0;
371 
372  //===--------------------------------------------------------------------===//
373  // Utilities
374  //===--------------------------------------------------------------------===//
375 
376  /// Emit a diagnostic at the specified location and return failure.
377  virtual InFlightDiagnostic emitError(llvm::SMLoc loc,
378  const Twine &message = {}) = 0;
379 
380  /// Return a builder which provides useful access to MLIRContext, global
381  /// objects like types and attributes.
382  virtual Builder &getBuilder() const = 0;
383 
384  /// Get the location of the next token and store it into the argument. This
385  /// always succeeds.
386  virtual llvm::SMLoc getCurrentLocation() = 0;
387  ParseResult getCurrentLocation(llvm::SMLoc *loc) {
388  *loc = getCurrentLocation();
389  return success();
390  }
391 
392  /// Re-encode the given source location as an MLIR location and return it.
393  /// Note: This method should only be used when a `Location` is necessary, as
394  /// the encoding process is not efficient.
395  virtual Location getEncodedSourceLoc(llvm::SMLoc loc) = 0;
396 
397  //===--------------------------------------------------------------------===//
398  // Token Parsing
399  //===--------------------------------------------------------------------===//
400 
401  /// Parse a '->' token.
402  virtual ParseResult parseArrow() = 0;
403 
404  /// Parse a '->' token if present
405  virtual ParseResult parseOptionalArrow() = 0;
406 
407  /// Parse a `{` token.
408  virtual ParseResult parseLBrace() = 0;
409 
410  /// Parse a `{` token if present.
411  virtual ParseResult parseOptionalLBrace() = 0;
412 
413  /// Parse a `}` token.
414  virtual ParseResult parseRBrace() = 0;
415 
416  /// Parse a `}` token if present.
417  virtual ParseResult parseOptionalRBrace() = 0;
418 
419  /// Parse a `:` token.
420  virtual ParseResult parseColon() = 0;
421 
422  /// Parse a `:` token if present.
423  virtual ParseResult parseOptionalColon() = 0;
424 
425  /// Parse a `,` token.
426  virtual ParseResult parseComma() = 0;
427 
428  /// Parse a `,` token if present.
429  virtual ParseResult parseOptionalComma() = 0;
430 
431  /// Parse a `=` token.
432  virtual ParseResult parseEqual() = 0;
433 
434  /// Parse a `=` token if present.
435  virtual ParseResult parseOptionalEqual() = 0;
436 
437  /// Parse a '<' token.
438  virtual ParseResult parseLess() = 0;
439 
440  /// Parse a '<' token if present.
441  virtual ParseResult parseOptionalLess() = 0;
442 
443  /// Parse a '>' token.
444  virtual ParseResult parseGreater() = 0;
445 
446  /// Parse a '>' token if present.
447  virtual ParseResult parseOptionalGreater() = 0;
448 
449  /// Parse a '?' token.
450  virtual ParseResult parseQuestion() = 0;
451 
452  /// Parse a '?' token if present.
453  virtual ParseResult parseOptionalQuestion() = 0;
454 
455  /// Parse a '+' token.
456  virtual ParseResult parsePlus() = 0;
457 
458  /// Parse a '+' token if present.
459  virtual ParseResult parseOptionalPlus() = 0;
460 
461  /// Parse a '*' token.
462  virtual ParseResult parseStar() = 0;
463 
464  /// Parse a '*' token if present.
465  virtual ParseResult parseOptionalStar() = 0;
466 
467  /// Parse a quoted string token.
468  ParseResult parseString(std::string *string) {
469  auto loc = getCurrentLocation();
470  if (parseOptionalString(string))
471  return emitError(loc, "expected string");
472  return success();
473  }
474 
475  /// Parse a quoted string token if present.
476  virtual ParseResult parseOptionalString(std::string *string) = 0;
477 
478  /// Parse a given keyword.
479  ParseResult parseKeyword(StringRef keyword, const Twine &msg = "") {
480  auto loc = getCurrentLocation();
481  if (parseOptionalKeyword(keyword))
482  return emitError(loc, "expected '") << keyword << "'" << msg;
483  return success();
484  }
485 
486  /// Parse a keyword into 'keyword'.
487  ParseResult parseKeyword(StringRef *keyword) {
488  auto loc = getCurrentLocation();
489  if (parseOptionalKeyword(keyword))
490  return emitError(loc, "expected valid keyword");
491  return success();
492  }
493 
494  /// Parse the given keyword if present.
495  virtual ParseResult parseOptionalKeyword(StringRef keyword) = 0;
496 
497  /// Parse a keyword, if present, into 'keyword'.
498  virtual ParseResult parseOptionalKeyword(StringRef *keyword) = 0;
499 
500  /// Parse a keyword, if present, and if one of the 'allowedValues',
501  /// into 'keyword'
502  virtual ParseResult
503  parseOptionalKeyword(StringRef *keyword,
504  ArrayRef<StringRef> allowedValues) = 0;
505 
506  /// Parse a keyword or a quoted string.
507  ParseResult parseKeywordOrString(std::string *result) {
508  if (failed(parseOptionalKeywordOrString(result)))
509  return emitError(getCurrentLocation())
510  << "expected valid keyword or string";
511  return success();
512  }
513 
514  /// Parse an optional keyword or string.
515  virtual ParseResult parseOptionalKeywordOrString(std::string *result) = 0;
516 
517  /// Parse a `(` token.
518  virtual ParseResult parseLParen() = 0;
519 
520  /// Parse a `(` token if present.
521  virtual ParseResult parseOptionalLParen() = 0;
522 
523  /// Parse a `)` token.
524  virtual ParseResult parseRParen() = 0;
525 
526  /// Parse a `)` token if present.
527  virtual ParseResult parseOptionalRParen() = 0;
528 
529  /// Parse a `[` token.
530  virtual ParseResult parseLSquare() = 0;
531 
532  /// Parse a `[` token if present.
533  virtual ParseResult parseOptionalLSquare() = 0;
534 
535  /// Parse a `]` token.
536  virtual ParseResult parseRSquare() = 0;
537 
538  /// Parse a `]` token if present.
539  virtual ParseResult parseOptionalRSquare() = 0;
540 
541  /// Parse a `...` token if present;
542  virtual ParseResult parseOptionalEllipsis() = 0;
543 
544  /// Parse a floating point value from the stream.
545  virtual ParseResult parseFloat(double &result) = 0;
546 
547  /// Parse an integer value from the stream.
548  template <typename IntT>
549  ParseResult parseInteger(IntT &result) {
550  auto loc = getCurrentLocation();
551  OptionalParseResult parseResult = parseOptionalInteger(result);
552  if (!parseResult.hasValue())
553  return emitError(loc, "expected integer value");
554  return *parseResult;
555  }
556 
557  /// Parse an optional integer value from the stream.
558  virtual OptionalParseResult parseOptionalInteger(APInt &result) = 0;
559 
560  template <typename IntT>
562  auto loc = getCurrentLocation();
563 
564  // Parse the unsigned variant.
565  APInt uintResult;
566  OptionalParseResult parseResult = parseOptionalInteger(uintResult);
567  if (!parseResult.hasValue() || failed(*parseResult))
568  return parseResult;
569 
570  // Try to convert to the provided integer type. sextOrTrunc is correct even
571  // for unsigned types because parseOptionalInteger ensures the sign bit is
572  // zero for non-negated integers.
573  result =
574  (IntT)uintResult.sextOrTrunc(sizeof(IntT) * CHAR_BIT).getLimitedValue();
575  if (APInt(uintResult.getBitWidth(), result) != uintResult)
576  return emitError(loc, "integer value too large");
577  return success();
578  }
579 
580  /// These are the supported delimiters around operand lists and region
581  /// argument lists, used by parseOperandList and parseRegionArgumentList.
582  enum class Delimiter {
583  /// Zero or more operands with no delimiters.
584  None,
585  /// Parens surrounding zero or more operands.
586  Paren,
587  /// Square brackets surrounding zero or more operands.
588  Square,
589  /// <> brackets surrounding zero or more operands.
590  LessGreater,
591  /// {} brackets surrounding zero or more operands.
592  Braces,
593  /// Parens supporting zero or more operands, or nothing.
594  OptionalParen,
595  /// Square brackets supporting zero or more ops, or nothing.
596  OptionalSquare,
597  /// <> brackets supporting zero or more ops, or nothing.
598  OptionalLessGreater,
599  /// {} brackets surrounding zero or more operands, or nothing.
600  OptionalBraces,
601  };
602 
603  /// Parse a list of comma-separated items with an optional delimiter. If a
604  /// delimiter is provided, then an empty list is allowed. If not, then at
605  /// least one element will be parsed.
606  ///
607  /// contextMessage is an optional message appended to "expected '('" sorts of
608  /// diagnostics when parsing the delimeters.
609  virtual ParseResult
610  parseCommaSeparatedList(Delimiter delimiter,
611  function_ref<ParseResult()> parseElementFn,
612  StringRef contextMessage = StringRef()) = 0;
613 
614  /// Parse a comma separated list of elements that must have at least one entry
615  /// in it.
618  return parseCommaSeparatedList(Delimiter::None, parseElementFn);
619  }
620 
621  //===--------------------------------------------------------------------===//
622  // Attribute/Type Parsing
623  //===--------------------------------------------------------------------===//
624 
625  /// Invoke the `getChecked` method of the given Attribute or Type class, using
626  /// the provided location to emit errors in the case of failure. Note that
627  /// unlike `OpBuilder::getType`, this method does not implicitly insert a
628  /// context parameter.
629  template <typename T, typename... ParamsT>
630  T getChecked(llvm::SMLoc loc, ParamsT &&... params) {
631  return T::getChecked([&] { return emitError(loc); },
632  std::forward<ParamsT>(params)...);
633  }
634  /// A variant of `getChecked` that uses the result of `getNameLoc` to emit
635  /// errors.
636  template <typename T, typename... ParamsT>
637  T getChecked(ParamsT &&... params) {
638  return T::getChecked([&] { return emitError(getNameLoc()); },
639  std::forward<ParamsT>(params)...);
640  }
641 
642  //===--------------------------------------------------------------------===//
643  // Attribute Parsing
644  //===--------------------------------------------------------------------===//
645 
646  /// Parse an arbitrary attribute of a given type and return it in result.
647  virtual ParseResult parseAttribute(Attribute &result, Type type = {}) = 0;
648 
649  /// Parse a custom attribute with the provided callback, unless the next
650  /// token is `#`, in which case the generic parser is invoked.
651  virtual ParseResult parseCustomAttributeWithFallback(
652  Attribute &result, Type type,
653  function_ref<ParseResult(Attribute &result, Type type)>
654  parseAttribute) = 0;
655 
656  /// Parse an attribute of a specific kind and type.
657  template <typename AttrType>
658  ParseResult parseAttribute(AttrType &result, Type type = {}) {
659  llvm::SMLoc loc = getCurrentLocation();
660 
661  // Parse any kind of attribute.
662  Attribute attr;
663  if (parseAttribute(attr, type))
664  return failure();
665 
666  // Check for the right kind of attribute.
667  if (!(result = attr.dyn_cast<AttrType>()))
668  return emitError(loc, "invalid kind of attribute specified");
669 
670  return success();
671  }
672 
673  /// Parse an arbitrary attribute and return it in result. This also adds the
674  /// attribute to the specified attribute list with the specified name.
675  ParseResult parseAttribute(Attribute &result, StringRef attrName,
676  NamedAttrList &attrs) {
677  return parseAttribute(result, Type(), attrName, attrs);
678  }
679 
680  /// Parse an attribute of a specific kind and type.
681  template <typename AttrType>
682  ParseResult parseAttribute(AttrType &result, StringRef attrName,
683  NamedAttrList &attrs) {
684  return parseAttribute(result, Type(), attrName, attrs);
685  }
686 
687  /// Parse an arbitrary attribute of a given type and populate it in `result`.
688  /// This also adds the attribute to the specified attribute list with the
689  /// specified name.
690  template <typename AttrType>
691  ParseResult parseAttribute(AttrType &result, Type type, StringRef attrName,
692  NamedAttrList &attrs) {
693  llvm::SMLoc loc = getCurrentLocation();
694 
695  // Parse any kind of attribute.
696  Attribute attr;
697  if (parseAttribute(attr, type))
698  return failure();
699 
700  // Check for the right kind of attribute.
701  result = attr.dyn_cast<AttrType>();
702  if (!result)
703  return emitError(loc, "invalid kind of attribute specified");
704 
705  attrs.append(attrName, result);
706  return success();
707  }
708 
709  /// Trait to check if `AttrType` provides a `parse` method.
710  template <typename AttrType>
711  using has_parse_method = decltype(AttrType::parse(std::declval<AsmParser &>(),
712  std::declval<Type>()));
713  template <typename AttrType>
714  using detect_has_parse_method = llvm::is_detected<has_parse_method, AttrType>;
715 
716  /// Parse a custom attribute of a given type unless the next token is `#`, in
717  /// which case the generic parser is invoked. The parsed attribute is
718  /// populated in `result` and also added to the specified attribute list with
719  /// the specified name.
720  template <typename AttrType>
722  parseCustomAttributeWithFallback(AttrType &result, Type type,
723  StringRef attrName, NamedAttrList &attrs) {
724  llvm::SMLoc loc = getCurrentLocation();
725 
726  // Parse any kind of attribute.
727  Attribute attr;
728  if (parseCustomAttributeWithFallback(
729  attr, type, [&](Attribute &result, Type type) -> ParseResult {
730  result = AttrType::parse(*this, type);
731  if (!result)
732  return failure();
733  return success();
734  }))
735  return failure();
736 
737  // Check for the right kind of attribute.
738  result = attr.dyn_cast<AttrType>();
739  if (!result)
740  return emitError(loc, "invalid kind of attribute specified");
741 
742  attrs.append(attrName, result);
743  return success();
744  }
745 
746  /// SFINAE parsing method for Attribute that don't implement a parse method.
747  template <typename AttrType>
749  parseCustomAttributeWithFallback(AttrType &result, Type type,
750  StringRef attrName, NamedAttrList &attrs) {
751  return parseAttribute(result, type, attrName, attrs);
752  }
753 
754  /// Parse a custom attribute of a given type unless the next token is `#`, in
755  /// which case the generic parser is invoked. The parsed attribute is
756  /// populated in `result`.
757  template <typename AttrType>
760  llvm::SMLoc loc = getCurrentLocation();
761 
762  // Parse any kind of attribute.
763  Attribute attr;
764  if (parseCustomAttributeWithFallback(
765  attr, {}, [&](Attribute &result, Type type) -> ParseResult {
766  result = AttrType::parse(*this, type);
767  return success(!!result);
768  }))
769  return failure();
770 
771  // Check for the right kind of attribute.
772  result = attr.dyn_cast<AttrType>();
773  if (!result)
774  return emitError(loc, "invalid kind of attribute specified");
775  return success();
776  }
777 
778  /// SFINAE parsing method for Attribute that don't implement a parse method.
779  template <typename AttrType>
782  return parseAttribute(result);
783  }
784 
785  /// Parse an arbitrary optional attribute of a given type and return it in
786  /// result.
787  virtual OptionalParseResult parseOptionalAttribute(Attribute &result,
788  Type type = {}) = 0;
789 
790  /// Parse an optional array attribute and return it in result.
791  virtual OptionalParseResult parseOptionalAttribute(ArrayAttr &result,
792  Type type = {}) = 0;
793 
794  /// Parse an optional string attribute and return it in result.
795  virtual OptionalParseResult parseOptionalAttribute(StringAttr &result,
796  Type type = {}) = 0;
797 
798  /// Parse an optional attribute of a specific type and add it to the list with
799  /// the specified name.
800  template <typename AttrType>
802  StringRef attrName,
803  NamedAttrList &attrs) {
804  return parseOptionalAttribute(result, Type(), attrName, attrs);
805  }
806 
807  /// Parse an optional attribute of a specific type and add it to the list with
808  /// the specified name.
809  template <typename AttrType>
811  StringRef attrName,
812  NamedAttrList &attrs) {
813  OptionalParseResult parseResult = parseOptionalAttribute(result, type);
814  if (parseResult.hasValue() && succeeded(*parseResult))
815  attrs.append(attrName, result);
816  return parseResult;
817  }
818 
819  /// Parse a named dictionary into 'result' if it is present.
820  virtual ParseResult parseOptionalAttrDict(NamedAttrList &result) = 0;
821 
822  /// Parse a named dictionary into 'result' if the `attributes` keyword is
823  /// present.
824  virtual ParseResult
825  parseOptionalAttrDictWithKeyword(NamedAttrList &result) = 0;
826 
827  /// Parse an affine map instance into 'map'.
828  virtual ParseResult parseAffineMap(AffineMap &map) = 0;
829 
830  /// Parse an integer set instance into 'set'.
831  virtual ParseResult printIntegerSet(IntegerSet &set) = 0;
832 
833  //===--------------------------------------------------------------------===//
834  // Identifier Parsing
835  //===--------------------------------------------------------------------===//
836 
837  /// Parse an @-identifier and store it (without the '@' symbol) in a string
838  /// attribute named 'attrName'.
839  ParseResult parseSymbolName(StringAttr &result, StringRef attrName,
840  NamedAttrList &attrs) {
841  if (failed(parseOptionalSymbolName(result, attrName, attrs)))
842  return emitError(getCurrentLocation())
843  << "expected valid '@'-identifier for symbol name";
844  return success();
845  }
846 
847  /// Parse an optional @-identifier and store it (without the '@' symbol) in a
848  /// string attribute named 'attrName'.
849  virtual ParseResult parseOptionalSymbolName(StringAttr &result,
850  StringRef attrName,
851  NamedAttrList &attrs) = 0;
852 
853  //===--------------------------------------------------------------------===//
854  // Type Parsing
855  //===--------------------------------------------------------------------===//
856 
857  /// Parse a type.
858  virtual ParseResult parseType(Type &result) = 0;
859 
860  /// Parse a custom type with the provided callback, unless the next
861  /// token is `#`, in which case the generic parser is invoked.
862  virtual ParseResult parseCustomTypeWithFallback(
863  Type &result, function_ref<ParseResult(Type &result)> parseType) = 0;
864 
865  /// Parse an optional type.
866  virtual OptionalParseResult parseOptionalType(Type &result) = 0;
867 
868  /// Parse a type of a specific type.
869  template <typename TypeT>
870  ParseResult parseType(TypeT &result) {
871  llvm::SMLoc loc = getCurrentLocation();
872 
873  // Parse any kind of type.
874  Type type;
875  if (parseType(type))
876  return failure();
877 
878  // Check for the right kind of type.
879  result = type.dyn_cast<TypeT>();
880  if (!result)
881  return emitError(loc, "invalid kind of type specified");
882 
883  return success();
884  }
885 
886  /// Trait to check if `TypeT` provides a `parse` method.
887  template <typename TypeT>
888  using type_has_parse_method =
889  decltype(TypeT::parse(std::declval<AsmParser &>()));
890  template <typename TypeT>
892  llvm::is_detected<type_has_parse_method, TypeT>;
893 
894  /// Parse a custom Type of a given type unless the next token is `#`, in
895  /// which case the generic parser is invoked. The parsed Type is
896  /// populated in `result`.
897  template <typename TypeT>
900  llvm::SMLoc loc = getCurrentLocation();
901 
902  // Parse any kind of Type.
903  Type type;
904  if (parseCustomTypeWithFallback(type, [&](Type &result) -> ParseResult {
905  result = TypeT::parse(*this);
906  return success(!!result);
907  }))
908  return failure();
909 
910  // Check for the right kind of Type.
911  result = type.dyn_cast<TypeT>();
912  if (!result)
913  return emitError(loc, "invalid kind of Type specified");
914  return success();
915  }
916 
917  /// SFINAE parsing method for Type that don't implement a parse method.
918  template <typename TypeT>
921  return parseType(result);
922  }
923 
924  /// Parse a type list.
926  do {
927  Type type;
928  if (parseType(type))
929  return failure();
930  result.push_back(type);
931  } while (succeeded(parseOptionalComma()));
932  return success();
933  }
934 
935  /// Parse an arrow followed by a type list.
936  virtual ParseResult parseArrowTypeList(SmallVectorImpl<Type> &result) = 0;
937 
938  /// Parse an optional arrow followed by a type list.
939  virtual ParseResult
940  parseOptionalArrowTypeList(SmallVectorImpl<Type> &result) = 0;
941 
942  /// Parse a colon followed by a type.
943  virtual ParseResult parseColonType(Type &result) = 0;
944 
945  /// Parse a colon followed by a type of a specific kind, e.g. a FunctionType.
946  template <typename TypeType>
947  ParseResult parseColonType(TypeType &result) {
948  llvm::SMLoc loc = getCurrentLocation();
949 
950  // Parse any kind of type.
951  Type type;
952  if (parseColonType(type))
953  return failure();
954 
955  // Check for the right kind of type.
956  result = type.dyn_cast<TypeType>();
957  if (!result)
958  return emitError(loc, "invalid kind of type specified");
959 
960  return success();
961  }
962 
963  /// Parse a colon followed by a type list, which must have at least one type.
964  virtual ParseResult parseColonTypeList(SmallVectorImpl<Type> &result) = 0;
965 
966  /// Parse an optional colon followed by a type list, which if present must
967  /// have at least one type.
968  virtual ParseResult
969  parseOptionalColonTypeList(SmallVectorImpl<Type> &result) = 0;
970 
971  /// Parse a keyword followed by a type.
972  ParseResult parseKeywordType(const char *keyword, Type &result) {
973  return failure(parseKeyword(keyword) || parseType(result));
974  }
975 
976  /// Add the specified type to the end of the specified type list and return
977  /// success. This is a helper designed to allow parse methods to be simple
978  /// and chain through || operators.
980  result.push_back(type);
981  return success();
982  }
983 
984  /// Add the specified types to the end of the specified type list and return
985  /// success. This is a helper designed to allow parse methods to be simple
986  /// and chain through || operators.
988  SmallVectorImpl<Type> &result) {
989  result.append(types.begin(), types.end());
990  return success();
991  }
992 
993  /// Parse a 'x' separated dimension list. This populates the dimension list,
994  /// using -1 for the `?` dimensions if `allowDynamic` is set and errors out on
995  /// `?` otherwise.
996  ///
997  /// dimension-list ::= (dimension `x`)*
998  /// dimension ::= `?` | integer
999  ///
1000  /// When `allowDynamic` is not set, this is used to parse:
1001  ///
1002  /// static-dimension-list ::= (integer `x`)*
1003  virtual ParseResult parseDimensionList(SmallVectorImpl<int64_t> &dimensions,
1004  bool allowDynamic = true) = 0;
1005 
1006  /// Parse an 'x' token in a dimension list, handling the case where the x is
1007  /// juxtaposed with an element type, as in "xf32", leaving the "f32" as the
1008  /// next token.
1009  virtual ParseResult parseXInDimensionList() = 0;
1010 
1011 private:
1012  AsmParser(const AsmParser &) = delete;
1013  void operator=(const AsmParser &) = delete;
1014 };
1015 
1016 //===----------------------------------------------------------------------===//
1017 // OpAsmParser
1018 //===----------------------------------------------------------------------===//
1019 
1020 /// The OpAsmParser has methods for interacting with the asm parser: parsing
1021 /// things from it, emitting errors etc. It has an intentionally high-level API
1022 /// that is designed to reduce/constrain syntax innovation in individual
1023 /// operations.
1024 ///
1025 /// For example, consider an op like this:
1026 ///
1027 /// %x = load %p[%1, %2] : memref<...>
1028 ///
1029 /// The "%x = load" tokens are already parsed and therefore invisible to the
1030 /// custom op parser. This can be supported by calling `parseOperandList` to
1031 /// parse the %p, then calling `parseOperandList` with a `SquareDelimiter` to
1032 /// parse the indices, then calling `parseColonTypeList` to parse the result
1033 /// type.
1034 ///
1035 class OpAsmParser : public AsmParser {
1036 public:
1037  using AsmParser::AsmParser;
1038  ~OpAsmParser() override;
1039 
1040  /// Parse a loc(...) specifier if present, filling in result if so.
1041  /// Location for BlockArgument and Operation may be deferred with an alias, in
1042  /// which case an OpaqueLoc is set and will be resolved when parsing
1043  /// completes.
1044  virtual ParseResult
1045  parseOptionalLocationSpecifier(Optional<Location> &result) = 0;
1046 
1047  /// Return the name of the specified result in the specified syntax, as well
1048  /// as the sub-element in the name. It returns an empty string and ~0U for
1049  /// invalid result numbers. For example, in this operation:
1050  ///
1051  /// %x, %y:2, %z = foo.op
1052  ///
1053  /// getResultName(0) == {"x", 0 }
1054  /// getResultName(1) == {"y", 0 }
1055  /// getResultName(2) == {"y", 1 }
1056  /// getResultName(3) == {"z", 0 }
1057  /// getResultName(4) == {"", ~0U }
1058  virtual std::pair<StringRef, unsigned>
1059  getResultName(unsigned resultNo) const = 0;
1060 
1061  /// Return the number of declared SSA results. This returns 4 for the foo.op
1062  /// example in the comment for `getResultName`.
1063  virtual size_t getNumResults() const = 0;
1064 
1065  // These methods emit an error and return failure or success. This allows
1066  // these to be chained together into a linear sequence of || expressions in
1067  // many cases.
1068 
1069  /// Parse an operation in its generic form.
1070  /// The parsed operation is parsed in the current context and inserted in the
1071  /// provided block and insertion point. The results produced by this operation
1072  /// aren't mapped to any named value in the parser. Returns nullptr on
1073  /// failure.
1074  virtual Operation *parseGenericOperation(Block *insertBlock,
1075  Block::iterator insertPt) = 0;
1076 
1077  /// Parse the name of an operation, in the custom form. On success, return a
1078  /// an object of type 'OperationName'. Otherwise, failure is returned.
1079  virtual FailureOr<OperationName> parseCustomOperationName() = 0;
1080 
1081  //===--------------------------------------------------------------------===//
1082  // Operand Parsing
1083  //===--------------------------------------------------------------------===//
1084 
1085  /// This is the representation of an operand reference.
1086  struct OperandType {
1087  llvm::SMLoc location; // Location of the token.
1088  StringRef name; // Value name, e.g. %42 or %abc
1089  unsigned number; // Number, e.g. 12 for an operand like %xyz#12
1090  };
1091 
1092  /// Parse different components, viz., use-info of operand(s), successor(s),
1093  /// region(s), attribute(s) and function-type, of the generic form of an
1094  /// operation instance and populate the input operation-state 'result' with
1095  /// those components. If any of the components is explicitly provided, then
1096  /// skip parsing that component.
1097  virtual ParseResult parseGenericOperationAfterOpName(
1098  OperationState &result,
1099  Optional<ArrayRef<OperandType>> parsedOperandType = llvm::None,
1100  Optional<ArrayRef<Block *>> parsedSuccessors = llvm::None,
1101  Optional<MutableArrayRef<std::unique_ptr<Region>>> parsedRegions =
1102  llvm::None,
1103  Optional<ArrayRef<NamedAttribute>> parsedAttributes = llvm::None,
1104  Optional<FunctionType> parsedFnType = llvm::None) = 0;
1105 
1106  /// Parse a single operand.
1107  virtual ParseResult parseOperand(OperandType &result) = 0;
1108 
1109  /// Parse a single operand if present.
1111 
1112  /// Parse zero or more SSA comma-separated operand references with a specified
1113  /// surrounding delimiter, and an optional required operand count.
1114  virtual ParseResult
1116  int requiredOperandCount = -1,
1117  Delimiter delimiter = Delimiter::None) = 0;
1119  Delimiter delimiter) {
1120  return parseOperandList(result, /*requiredOperandCount=*/-1, delimiter);
1121  }
1122 
1123  /// Parse zero or more trailing SSA comma-separated trailing operand
1124  /// references with a specified surrounding delimiter, and an optional
1125  /// required operand count. A leading comma is expected before the operands.
1126  virtual ParseResult
1127  parseTrailingOperandList(SmallVectorImpl<OperandType> &result,
1128  int requiredOperandCount = -1,
1129  Delimiter delimiter = Delimiter::None) = 0;
1131  Delimiter delimiter) {
1132  return parseTrailingOperandList(result, /*requiredOperandCount=*/-1,
1133  delimiter);
1134  }
1135 
1136  /// Resolve an operand to an SSA value, emitting an error on failure.
1137  virtual ParseResult resolveOperand(const OperandType &operand, Type type,
1138  SmallVectorImpl<Value> &result) = 0;
1139 
1140  /// Resolve a list of operands to SSA values, emitting an error on failure, or
1141  /// appending the results to the list on success. This method should be used
1142  /// when all operands have the same type.
1144  SmallVectorImpl<Value> &result) {
1145  for (auto elt : operands)
1146  if (resolveOperand(elt, type, result))
1147  return failure();
1148  return success();
1149  }
1150 
1151  /// Resolve a list of operands and a list of operand types to SSA values,
1152  /// emitting an error and returning failure, or appending the results
1153  /// to the list on success.
1155  ArrayRef<Type> types, llvm::SMLoc loc,
1156  SmallVectorImpl<Value> &result) {
1157  if (operands.size() != types.size())
1158  return emitError(loc)
1159  << operands.size() << " operands present, but expected "
1160  << types.size();
1161 
1162  for (unsigned i = 0, e = operands.size(); i != e; ++i)
1163  if (resolveOperand(operands[i], types[i], result))
1164  return failure();
1165  return success();
1166  }
1167  template <typename Operands>
1168  ParseResult resolveOperands(Operands &&operands, Type type, llvm::SMLoc loc,
1169  SmallVectorImpl<Value> &result) {
1170  return resolveOperands(std::forward<Operands>(operands),
1171  ArrayRef<Type>(type), loc, result);
1172  }
1173  template <typename Operands, typename Types>
1175  resolveOperands(Operands &&operands, Types &&types, llvm::SMLoc loc,
1176  SmallVectorImpl<Value> &result) {
1177  size_t operandSize = std::distance(operands.begin(), operands.end());
1178  size_t typeSize = std::distance(types.begin(), types.end());
1179  if (operandSize != typeSize)
1180  return emitError(loc)
1181  << operandSize << " operands present, but expected " << typeSize;
1182 
1183  for (auto it : llvm::zip(operands, types))
1184  if (resolveOperand(std::get<0>(it), std::get<1>(it), result))
1185  return failure();
1186  return success();
1187  }
1188 
1189  /// Parses an affine map attribute where dims and symbols are SSA operands.
1190  /// Operand values must come from single-result sources, and be valid
1191  /// dimensions/symbol identifiers according to mlir::isValidDim/Symbol.
1192  virtual ParseResult
1193  parseAffineMapOfSSAIds(SmallVectorImpl<OperandType> &operands, Attribute &map,
1194  StringRef attrName, NamedAttrList &attrs,
1195  Delimiter delimiter = Delimiter::Square) = 0;
1196 
1197  /// Parses an affine expression where dims and symbols are SSA operands.
1198  /// Operand values must come from single-result sources, and be valid
1199  /// dimensions/symbol identifiers according to mlir::isValidDim/Symbol.
1200  virtual ParseResult
1201  parseAffineExprOfSSAIds(SmallVectorImpl<OperandType> &dimOperands,
1202  SmallVectorImpl<OperandType> &symbOperands,
1203  AffineExpr &expr) = 0;
1204 
1205  //===--------------------------------------------------------------------===//
1206  // Region Parsing
1207  //===--------------------------------------------------------------------===//
1208 
1209  /// Parses a region. Any parsed blocks are appended to 'region' and must be
1210  /// moved to the op regions after the op is created. The first block of the
1211  /// region takes 'arguments' of types 'argTypes'. If `argLocations` is
1212  /// non-empty it contains a location to be attached to each argument. If
1213  /// 'enableNameShadowing' is set to true, the argument names are allowed to
1214  /// shadow the names of other existing SSA values defined above the region
1215  /// scope. 'enableNameShadowing' can only be set to true for regions attached
1216  /// to operations that are 'IsolatedFromAbove'.
1217  virtual ParseResult parseRegion(Region &region,
1218  ArrayRef<OperandType> arguments = {},
1219  ArrayRef<Type> argTypes = {},
1220  ArrayRef<Location> argLocations = {},
1221  bool enableNameShadowing = false) = 0;
1222 
1223  /// Parses a region if present.
1224  virtual OptionalParseResult
1225  parseOptionalRegion(Region &region, ArrayRef<OperandType> arguments = {},
1226  ArrayRef<Type> argTypes = {},
1227  ArrayRef<Location> argLocations = {},
1228  bool enableNameShadowing = false) = 0;
1229 
1230  /// Parses a region if present. If the region is present, a new region is
1231  /// allocated and placed in `region`. If no region is present or on failure,
1232  /// `region` remains untouched.
1233  virtual OptionalParseResult parseOptionalRegion(
1234  std::unique_ptr<Region> &region, ArrayRef<OperandType> arguments = {},
1235  ArrayRef<Type> argTypes = {}, bool enableNameShadowing = false) = 0;
1236 
1237  /// Parse a region argument, this argument is resolved when calling
1238  /// 'parseRegion'.
1239  virtual ParseResult parseRegionArgument(OperandType &argument) = 0;
1240 
1241  /// Parse zero or more region arguments with a specified surrounding
1242  /// delimiter, and an optional required argument count. Region arguments
1243  /// define new values; so this also checks if values with the same names have
1244  /// not been defined yet.
1245  virtual ParseResult
1246  parseRegionArgumentList(SmallVectorImpl<OperandType> &result,
1247  int requiredOperandCount = -1,
1248  Delimiter delimiter = Delimiter::None) = 0;
1249  virtual ParseResult
1251  Delimiter delimiter) {
1252  return parseRegionArgumentList(result, /*requiredOperandCount=*/-1,
1253  delimiter);
1254  }
1255 
1256  /// Parse a region argument if present.
1257  virtual ParseResult parseOptionalRegionArgument(OperandType &argument) = 0;
1258 
1259  //===--------------------------------------------------------------------===//
1260  // Successor Parsing
1261  //===--------------------------------------------------------------------===//
1262 
1263  /// Parse a single operation successor.
1264  virtual ParseResult parseSuccessor(Block *&dest) = 0;
1265 
1266  /// Parse an optional operation successor.
1267  virtual OptionalParseResult parseOptionalSuccessor(Block *&dest) = 0;
1268 
1269  /// Parse a single operation successor and its operand list.
1270  virtual ParseResult
1271  parseSuccessorAndUseList(Block *&dest, SmallVectorImpl<Value> &operands) = 0;
1272 
1273  //===--------------------------------------------------------------------===//
1274  // Type Parsing
1275  //===--------------------------------------------------------------------===//
1276 
1277  /// Parse a list of assignments of the form
1278  /// (%x1 = %y1, %x2 = %y2, ...)
1281  OptionalParseResult result = parseOptionalAssignmentList(lhs, rhs);
1282  if (!result.hasValue())
1283  return emitError(getCurrentLocation(), "expected '('");
1284  return result.getValue();
1285  }
1286 
1287  virtual OptionalParseResult
1288  parseOptionalAssignmentList(SmallVectorImpl<OperandType> &lhs,
1289  SmallVectorImpl<OperandType> &rhs) = 0;
1290 
1291  /// Parse a list of assignments of the form
1292  /// (%x1 = %y1 : type1, %x2 = %y2 : type2, ...)
1295  SmallVectorImpl<Type> &types) {
1296  OptionalParseResult result =
1297  parseOptionalAssignmentListWithTypes(lhs, rhs, types);
1298  if (!result.hasValue())
1299  return emitError(getCurrentLocation(), "expected '('");
1300  return result.getValue();
1301  }
1302 
1303  virtual OptionalParseResult
1304  parseOptionalAssignmentListWithTypes(SmallVectorImpl<OperandType> &lhs,
1306  SmallVectorImpl<Type> &types) = 0;
1307 
1308 private:
1309  /// Parse either an operand list or a region argument list depending on
1310  /// whether isOperandList is true.
1311  ParseResult parseOperandOrRegionArgList(SmallVectorImpl<OperandType> &result,
1312  bool isOperandList,
1313  int requiredOperandCount,
1314  Delimiter delimiter);
1315 };
1316 
1317 //===--------------------------------------------------------------------===//
1318 // Dialect OpAsm interface.
1319 //===--------------------------------------------------------------------===//
1320 
1321 /// A functor used to set the name of the start of a result group of an
1322 /// operation. See 'getAsmResultNames' below for more details.
1324 
1326  : public DialectInterface::Base<OpAsmDialectInterface> {
1327 public:
1328  /// Holds the result of `getAlias` hook call.
1329  enum class AliasResult {
1330  /// The object (type or attribute) is not supported by the hook
1331  /// and an alias was not provided.
1332  NoAlias,
1333  /// An alias was provided, but it might be overriden by other hook.
1334  OverridableAlias,
1335  /// An alias was provided and it should be used
1336  /// (no other hooks will be checked).
1337  FinalAlias
1338  };
1339 
1340  OpAsmDialectInterface(Dialect *dialect) : Base(dialect) {}
1341 
1342  /// Hooks for getting an alias identifier alias for a given symbol, that is
1343  /// not necessarily a part of this dialect. The identifier is used in place of
1344  /// the symbol when printing textual IR. These aliases must not contain `.` or
1345  /// end with a numeric digit([0-9]+).
1346  virtual AliasResult getAlias(Attribute attr, raw_ostream &os) const {
1347  return AliasResult::NoAlias;
1348  }
1349  virtual AliasResult getAlias(Type type, raw_ostream &os) const {
1350  return AliasResult::NoAlias;
1351  }
1352 
1353 };
1354 } // namespace mlir
1355 
1356 //===--------------------------------------------------------------------===//
1357 // Operation OpAsm interface.
1358 //===--------------------------------------------------------------------===//
1359 
1360 /// The OpAsmOpInterface, see OpAsmInterface.td for more details.
1361 #include "mlir/IR/OpAsmInterface.h.inc"
1362 
1363 #endif
ParseResult parseAttribute(AttrType &result, Type type={})
Parse an attribute of a specific kind and type.
virtual void printSymbolName(StringRef symbolRef)
Print the given string as a symbol reference, i.e.
This is the representation of an operand reference.
virtual AliasResult getAlias(Type type, raw_ostream &os) const
virtual ParseResult parseRegionArgumentList(SmallVectorImpl< OperandType > &result, Delimiter delimiter)
Include the generated interface declarations.
ParseResult resolveOperands(ArrayRef< OperandType > operands, ArrayRef< Type > types, llvm::SMLoc loc, SmallVectorImpl< Value > &result)
Resolve a list of operands and a list of operand types to SSA values, emitting an error and returning...
ParseResult parseColonType(TypeType &result)
Parse a colon followed by a type of a specific kind, e.g. a FunctionType.
Attribute parseAttribute(llvm::StringRef attrStr, MLIRContext *context)
This parses a single MLIR attribute to an MLIR context if it was valid.
This class contains a list of basic blocks and a link to the parent operation it is attached to...
Definition: Region.h:26
ParseResult resolveOperands(ArrayRef< OperandType > operands, Type type, SmallVectorImpl< Value > &result)
Resolve a list of operands to SSA values, emitting an error on failure, or appending the results to t...
virtual raw_ostream & getStream() const
Return the raw output stream used by this printer.
ParseResult parseTrailingOperandList(SmallVectorImpl< OperandType > &result, Delimiter delimiter)
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
The base class used for all derived interface types.
std::enable_if_t< detect_has_parse_method< AttrType >::value, ParseResult > parseCustomAttributeWithFallback(AttrType &result)
Parse a custom attribute of a given type unless the next token is #, in which case the generic parser...
virtual void printType(Type type)
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:301
ParseResult parseKeywordOrString(std::string *result)
Parse a keyword or a quoted string.
Block represents an ordered list of Operations.
Definition: Block.h:29
ParseResult parseInteger(IntT &result)
Parse an integer value from the stream.
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value...
Definition: LogicalResult.h:72
ParseResult parseType(TypeT &result)
Parse a type of a specific type.
void print(OpAsmPrinter &p, FunctionLibraryOp op)
Definition: Shape.cpp:1112
ParseResult parseAssignmentList(SmallVectorImpl< OperandType > &lhs, SmallVectorImpl< OperandType > &rhs)
Parse a list of assignments of the form (x1 = y1, x2 = y2, ...)
ParseResult addTypeToList(Type type, SmallVectorImpl< Type > &result)
Add the specified type to the end of the specified type list and return success.
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value...
Definition: LogicalResult.h:68
IteratorType
Typed representation for loop type strings.
The OpAsmParser has methods for interacting with the asm parser: parsing things from it...
ParseResult parseAttribute(AttrType &result, Type type, StringRef attrName, NamedAttrList &attrs)
Parse an arbitrary attribute of a given type and populate it in result.
void printOperands(IteratorType it, IteratorType end)
Print a comma separated list of operands.
std::enable_if_t< detect_has_parse_method< AttrType >::value, ParseResult > parseCustomAttributeWithFallback(AttrType &result, Type type, StringRef attrName, NamedAttrList &attrs)
Parse a custom attribute of a given type unless the next token is #, in which case the generic parser...
llvm::is_detected< has_print_method, AttrOrType > detect_has_print_method
void printArrowTypeList(TypeRange &&types)
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
Definition: AliasAnalysis.h:78
void printOperands(const ContainerType &container)
Print a comma separated list of operands.
static constexpr const bool value
ParseResult parseSymbolName(StringAttr &result, StringRef attrName, NamedAttrList &attrs)
Parse an -identifier and store it (without the &#39;@&#39; symbol) in a string attribute named &#39;attrName&#39;...
ParseResult parseCommaSeparatedList(function_ref< ParseResult()> parseElementFn)
Parse a comma separated list of elements that must have at least one entry in it. ...
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:48
OptionalParseResult parseOptionalAttribute(AttrType &result, Type type, StringRef attrName, NamedAttrList &attrs)
Parse an optional attribute of a specific type and add it to the list with the specified name...
virtual void printAttributeWithoutType(Attribute attr)
Print the given attribute without its type.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
void printFunctionalType(InputRangeT &&inputs, ResultRangeT &&results)
Print the two given type ranges in a functional form.
AliasResult
Holds the result of getAlias hook call.
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
static ParseResult parseOperandList(OpAsmParser &parser, StringRef keyword, SmallVectorImpl< OpAsmParser::OperandType > &args, SmallVectorImpl< Type > &argTypes, OperationState &result)
Definition: OpenACC.cpp:57
OpListType::iterator iterator
Definition: Block.h:131
This class provides support for representing a failure result, or a valid value of type T...
Definition: LogicalResult.h:77
void printOptionalArrowTypeList(TypeRange &&types)
Print an optional arrow followed by a type list.
U dyn_cast() const
Definition: Types.h:244
decltype(TypeT::parse(std::declval< AsmParser & >())) type_has_parse_method
Trait to check if TypeT provides a parse method.
void printStrippedAttrOrType(AttrOrType attrOrType)
Print the provided attribute in the context of an operation custom printer/parser: this will invoke d...
ParseResult parseKeywordType(const char *keyword, Type &result)
Parse a keyword followed by a type.
Attributes are known-constant values of operations.
Definition: Attributes.h:24
virtual AliasResult getAlias(Attribute attr, raw_ostream &os) const
Hooks for getting an alias identifier alias for a given symbol, that is not necessarily a part of thi...
std::enable_if_t<!detect_type_has_parse_method< TypeT >::value, ParseResult > parseCustomTypeWithFallback(TypeT &result)
SFINAE parsing method for Type that don&#39;t implement a parse method.
Base type for affine expression.
Definition: AffineExpr.h:68
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:42
This class provides an abstraction over the various different ranges of value types.
Definition: TypeRange.h:38
ParseResult parseKeyword(StringRef keyword, const Twine &msg="")
Parse a given keyword.
MLIR_CRUNNERUTILS_EXPORT void printNewline()
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
This represents an operation in an abstracted form, suitable for use with the builder APIs...
T getChecked(ParamsT &&... params)
A variant of getChecked that uses the result of getNameLoc to emit errors.
A multi-dimensional affine map Affine map&#39;s are immutable like Type&#39;s, and they are uniqued...
Definition: AffineMap.h:38
static ParseResult parseOptionalOperand(OpAsmParser &parser, StringRef keyword, OpAsmParser::OperandType &operand, Type type, bool &hasOptional, OperationState &result)
Definition: OpenACC.cpp:100
ParseResult parseString(std::string *string)
Parse a quoted string token.
This class represents an argument of a Block.
Definition: Value.h:298
Type parseType(llvm::StringRef typeStr, MLIRContext *context)
This parses a single MLIR type to an MLIR context if it was valid.
This base class exposes generic asm parser hooks, usable across the various derived parsers...
std::enable_if_t<!detect_has_parse_method< AttrType >::value, ParseResult > parseCustomAttributeWithFallback(AttrType &result)
SFINAE parsing method for Attribute that don&#39;t implement a parse method.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:72
llvm::is_detected< has_parse_method, AttrType > detect_has_parse_method
llvm::is_detected< type_has_parse_method, TypeT > detect_type_has_parse_method
ParseResult parseOperandList(SmallVectorImpl< OperandType > &result, Delimiter delimiter)
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:84
ParseResult getValue() const
Access the internal ParseResult value.
Definition: OpDefinition.h:65
T getChecked(llvm::SMLoc loc, ParamsT &&... params)
Invoke the getChecked method of the given Attribute or Type class, using the provided location to emi...
This class implements Optional functionality for ParseResult.
Definition: OpDefinition.h:52
The two locations do not alias at all.
Definition: AliasAnalysis.h:34
std::enable_if_t<!detect_has_parse_method< AttrType >::value, ParseResult > parseCustomAttributeWithFallback(AttrType &result, Type type, StringRef attrName, NamedAttrList &attrs)
SFINAE parsing method for Attribute that don&#39;t implement a parse method.
OpAsmDialectInterface(Dialect *dialect)
ParseResult parseAssignmentListWithTypes(SmallVectorImpl< OperandType > &lhs, SmallVectorImpl< OperandType > &rhs, SmallVectorImpl< Type > &types)
Parse a list of assignments of the form (x1 = y1 : type1, x2 = y2 : type2, ...)
virtual void printSuccessor(Block *successor)=0
Print the given successor.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
This class is a general helper class for creating context-global objects like types, attributes, and affine expressions.
Definition: Builders.h:49
U dyn_cast() const
Definition: Attributes.h:117
decltype(std::declval< AttrOrType >().print(std::declval< AsmPrinter & >())) has_print_method
Trait to check if AttrType provides a print method.
virtual void printOperand(Value value)=0
Print implementations for various things an operation contains.
ParseResult parseKeyword(StringRef *keyword)
Parse a keyword into &#39;keyword&#39;.
void append(StringRef name, Attribute attr)
Add an attribute with the specified name.
Delimiter
These are the supported delimiters around operand lists and region argument lists, used by parseOperandList and parseRegionArgumentList.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:55
OptionalParseResult parseOptionalAttribute(AttrType &result, StringRef attrName, NamedAttrList &attrs)
Parse an optional attribute of a specific type and add it to the list with the specified name...
ParseResult parseAttribute(Attribute &result, StringRef attrName, NamedAttrList &attrs)
Parse an arbitrary attribute and return it in result.
AsmPrinter()
Initialize the printer with no internal implementation.
virtual void printFloat(const APFloat &value)
Print the given floating point value in a stabilized form that can be roundtripped through the IR...
This base class exposes generic asm printer hooks, usable across the various derived printers...
bool hasValue() const
Returns true if we contain a valid ParseResult value.
Definition: OpDefinition.h:62
virtual void printAttribute(Attribute attr)
ParseResult resolveOperands(Operands &&operands, Type type, llvm::SMLoc loc, SmallVectorImpl< Value > &result)
std::enable_if_t<!std::is_convertible< Types, Type >::value, ParseResult > resolveOperands(Operands &&operands, Types &&types, llvm::SMLoc loc, SmallVectorImpl< Value > &result)
This class represents success/failure for operation parsing.
Definition: OpDefinition.h:36
ParseResult getCurrentLocation(llvm::SMLoc *loc)
decltype(AttrType::parse(std::declval< AsmParser & >(), std::declval< Type >())) has_parse_method
Trait to check if AttrType provides a parse method.
AsmPrinter(Impl &impl)
Initialize the printer with the given internal implementation.
This class provides an abstraction over the different types of ranges over Values.
AsmParser()=default
virtual ~AsmPrinter()
OptionalParseResult parseOptionalInteger(IntT &result)
ParseResult addTypesToList(ArrayRef< Type > types, SmallVectorImpl< Type > &result)
Add the specified types to the end of the specified type list and return success. ...
std::enable_if_t< detect_type_has_parse_method< TypeT >::value, ParseResult > parseCustomTypeWithFallback(TypeT &result)
Parse a custom Type of a given type unless the next token is #, in which case the generic parser is i...
ParseResult parseTypeList(SmallVectorImpl< Type > &result)
Parse a type list.
ParseResult parseAttribute(AttrType &result, StringRef attrName, NamedAttrList &attrs)
Parse an attribute of a specific kind and type.
virtual void printKeywordOrString(StringRef keyword)
Print the given string as a keyword, or a quoted and escaped string if it has any special or non-prin...
An integer set representing a conjunction of one or more affine equalities and inequalities.
Definition: IntegerSet.h:44