MLIR  16.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 class AsmParsedResourceEntry;
24 class AsmResourceBuilder;
25 class Builder;
26 
27 //===----------------------------------------------------------------------===//
28 // AsmDialectResourceHandle
29 //===----------------------------------------------------------------------===//
30 
31 /// This class represents an opaque handle to a dialect resource entry.
33 public:
35  AsmDialectResourceHandle(void *resource, TypeID resourceID, Dialect *dialect)
36  : resource(resource), opaqueID(resourceID), dialect(dialect) {}
37  bool operator==(const AsmDialectResourceHandle &other) const {
38  return resource == other.resource;
39  }
40 
41  /// Return an opaque pointer to the referenced resource.
42  void *getResource() const { return resource; }
43 
44  /// Return the type ID of the resource.
45  TypeID getTypeID() const { return opaqueID; }
46 
47  /// Return the dialect that owns the resource.
48  Dialect *getDialect() const { return dialect; }
49 
50 private:
51  /// The opaque handle to the dialect resource.
52  void *resource = nullptr;
53  /// The type of the resource referenced.
54  TypeID opaqueID;
55  /// The dialect owning the given resource.
56  Dialect *dialect;
57 };
58 
59 /// This class represents a CRTP base class for dialect resource handles. It
60 /// abstracts away various utilities necessary for defined derived resource
61 /// handles.
62 template <typename DerivedT, typename ResourceT, typename DialectT>
64 public:
65  using Dialect = DialectT;
66 
67  /// Construct a handle from a pointer to the resource. The given pointer
68  /// should be guaranteed to live beyond the life of this handle.
69  AsmDialectResourceHandleBase(ResourceT *resource, DialectT *dialect)
70  : AsmDialectResourceHandle(resource, TypeID::get<DerivedT>(), dialect) {}
72  : AsmDialectResourceHandle(handle) {
73  assert(handle.getTypeID() == TypeID::get<DerivedT>());
74  }
75 
76  /// Return the resource referenced by this handle.
77  ResourceT *getResource() {
78  return static_cast<ResourceT *>(AsmDialectResourceHandle::getResource());
79  }
80  const ResourceT *getResource() const {
81  return const_cast<AsmDialectResourceHandleBase *>(this)->getResource();
82  }
83 
84  /// Return the dialect that owns the resource.
85  DialectT *getDialect() const {
86  return static_cast<DialectT *>(AsmDialectResourceHandle::getDialect());
87  }
88 
89  /// Support llvm style casting.
90  static bool classof(const AsmDialectResourceHandle *handle) {
91  return handle->getTypeID() == TypeID::get<DerivedT>();
92  }
93 };
94 
95 inline llvm::hash_code hash_value(const AsmDialectResourceHandle &param) {
96  return llvm::hash_value(param.getResource());
97 }
98 
99 //===----------------------------------------------------------------------===//
100 // AsmPrinter
101 //===----------------------------------------------------------------------===//
102 
103 /// This base class exposes generic asm printer hooks, usable across the various
104 /// derived printers.
105 class AsmPrinter {
106 public:
107  /// This class contains the internal default implementation of the base
108  /// printer methods.
109  class Impl;
110 
111  /// Initialize the printer with the given internal implementation.
113  virtual ~AsmPrinter();
114 
115  /// Return the raw output stream used by this printer.
116  virtual raw_ostream &getStream() const;
117 
118  /// Print the given floating point value in a stabilized form that can be
119  /// roundtripped through the IR. This is the companion to the 'parseFloat'
120  /// hook on the AsmParser.
121  virtual void printFloat(const APFloat &value);
122 
123  virtual void printType(Type type);
124  virtual void printAttribute(Attribute attr);
125 
126  /// Trait to check if `AttrType` provides a `print` method.
127  template <typename AttrOrType>
129  decltype(std::declval<AttrOrType>().print(std::declval<AsmPrinter &>()));
130  template <typename AttrOrType>
132  llvm::is_detected<has_print_method, AttrOrType>;
133 
134  /// Print the provided attribute in the context of an operation custom
135  /// printer/parser: this will invoke directly the print method on the
136  /// attribute class and skip the `#dialect.mnemonic` prefix in most cases.
137  template <typename AttrOrType,
139  *sfinae = nullptr>
140  void printStrippedAttrOrType(AttrOrType attrOrType) {
141  if (succeeded(printAlias(attrOrType)))
142  return;
143  attrOrType.print(*this);
144  }
145 
146  /// Print the provided array of attributes or types in the context of an
147  /// operation custom printer/parser: this will invoke directly the print
148  /// method on the attribute class and skip the `#dialect.mnemonic` prefix in
149  /// most cases.
150  template <typename AttrOrType,
152  *sfinae = nullptr>
154  llvm::interleaveComma(
155  attrOrTypes, getStream(),
156  [this](AttrOrType attrOrType) { printStrippedAttrOrType(attrOrType); });
157  }
158 
159  /// SFINAE for printing the provided attribute in the context of an operation
160  /// custom printer in the case where the attribute does not define a print
161  /// method.
162  template <typename AttrOrType,
164  *sfinae = nullptr>
165  void printStrippedAttrOrType(AttrOrType attrOrType) {
166  *this << attrOrType;
167  }
168 
169  /// Print the given attribute without its type. The corresponding parser must
170  /// provide a valid type for the attribute.
171  virtual void printAttributeWithoutType(Attribute attr);
172 
173  /// Print the given string as a keyword, or a quoted and escaped string if it
174  /// has any special or non-printable characters in it.
175  virtual void printKeywordOrString(StringRef keyword);
176 
177  /// Print the given string as a symbol reference, i.e. a form representable by
178  /// a SymbolRefAttr. A symbol reference is represented as a string prefixed
179  /// with '@'. The reference is surrounded with ""'s and escaped if it has any
180  /// special or non-printable characters in it.
181  virtual void printSymbolName(StringRef symbolRef);
182 
183  /// Print a handle to the given dialect resource.
184  virtual void printResourceHandle(const AsmDialectResourceHandle &resource);
185 
186  /// Print an optional arrow followed by a type list.
187  template <typename TypeRange>
189  if (types.begin() != types.end())
190  printArrowTypeList(types);
191  }
192  template <typename TypeRange>
194  auto &os = getStream() << " -> ";
195 
196  bool wrapped = !llvm::hasSingleElement(types) ||
197  (*types.begin()).template isa<FunctionType>();
198  if (wrapped)
199  os << '(';
200  llvm::interleaveComma(types, *this);
201  if (wrapped)
202  os << ')';
203  }
204 
205  /// Print the two given type ranges in a functional form.
206  template <typename InputRangeT, typename ResultRangeT>
207  void printFunctionalType(InputRangeT &&inputs, ResultRangeT &&results) {
208  auto &os = getStream();
209  os << '(';
210  llvm::interleaveComma(inputs, *this);
211  os << ')';
212  printArrowTypeList(results);
213  }
214 
215 protected:
216  /// Initialize the printer with no internal implementation. In this case, all
217  /// virtual methods of this class must be overriden.
218  AsmPrinter() = default;
219 
220 private:
221  AsmPrinter(const AsmPrinter &) = delete;
222  void operator=(const AsmPrinter &) = delete;
223 
224  /// Print the alias for the given attribute, return failure if no alias could
225  /// be printed.
226  virtual LogicalResult printAlias(Attribute attr);
227 
228  /// Print the alias for the given type, return failure if no alias could
229  /// be printed.
230  virtual LogicalResult printAlias(Type type);
231 
232  /// The internal implementation of the printer.
233  Impl *impl{nullptr};
234 };
235 
236 template <typename AsmPrinterT>
238  AsmPrinterT &>
239 operator<<(AsmPrinterT &p, Type type) {
240  p.printType(type);
241  return p;
242 }
243 
244 template <typename AsmPrinterT>
246  AsmPrinterT &>
247 operator<<(AsmPrinterT &p, Attribute attr) {
248  p.printAttribute(attr);
249  return p;
250 }
251 
252 template <typename AsmPrinterT>
254  AsmPrinterT &>
255 operator<<(AsmPrinterT &p, const APFloat &value) {
256  p.printFloat(value);
257  return p;
258 }
259 template <typename AsmPrinterT>
261  AsmPrinterT &>
262 operator<<(AsmPrinterT &p, float value) {
263  return p << APFloat(value);
264 }
265 template <typename AsmPrinterT>
267  AsmPrinterT &>
268 operator<<(AsmPrinterT &p, double value) {
269  return p << APFloat(value);
270 }
271 
272 // Support printing anything that isn't convertible to one of the other
273 // streamable types, even if it isn't exactly one of them. For example, we want
274 // to print FunctionType with the Type version above, not have it match this.
275 template <typename AsmPrinterT, typename T,
282  T> * = nullptr>
284  AsmPrinterT &>
285 operator<<(AsmPrinterT &p, const T &other) {
286  p.getStream() << other;
287  return p;
288 }
289 
290 template <typename AsmPrinterT>
292  AsmPrinterT &>
293 operator<<(AsmPrinterT &p, bool value) {
294  return p << (value ? StringRef("true") : "false");
295 }
296 
297 template <typename AsmPrinterT, typename ValueRangeT>
299  AsmPrinterT &>
300 operator<<(AsmPrinterT &p, const ValueTypeRange<ValueRangeT> &types) {
301  llvm::interleaveComma(types, p);
302  return p;
303 }
304 template <typename AsmPrinterT>
306  AsmPrinterT &>
307 operator<<(AsmPrinterT &p, const TypeRange &types) {
308  llvm::interleaveComma(types, p);
309  return p;
310 }
311 template <typename AsmPrinterT, typename ElementT>
313  AsmPrinterT &>
314 operator<<(AsmPrinterT &p, ArrayRef<ElementT> types) {
315  llvm::interleaveComma(types, p);
316  return p;
317 }
318 
319 //===----------------------------------------------------------------------===//
320 // OpAsmPrinter
321 //===----------------------------------------------------------------------===//
322 
323 /// This is a pure-virtual base class that exposes the asmprinter hooks
324 /// necessary to implement a custom print() method.
325 class OpAsmPrinter : public AsmPrinter {
326 public:
328  ~OpAsmPrinter() override;
329 
330  /// Print a loc(...) specifier if printing debug info is enabled.
332 
333  /// Print a newline and indent the printer to the start of the current
334  /// operation.
335  virtual void printNewline() = 0;
336 
337  /// Increase indentation.
338  virtual void increaseIndent() = 0;
339 
340  /// Decrease indentation.
341  virtual void decreaseIndent() = 0;
342 
343  /// Print a block argument in the usual format of:
344  /// %ssaName : type {attr1=42} loc("here")
345  /// where location printing is controlled by the standard internal option.
346  /// You may pass omitType=true to not print a type, and pass an empty
347  /// attribute list if you don't care for attributes.
349  ArrayRef<NamedAttribute> argAttrs = {},
350  bool omitType = false) = 0;
351 
352  /// Print implementations for various things an operation contains.
353  virtual void printOperand(Value value) = 0;
354  virtual void printOperand(Value value, raw_ostream &os) = 0;
355 
356  /// Print a comma separated list of operands.
357  template <typename ContainerType>
358  void printOperands(const ContainerType &container) {
359  printOperands(container.begin(), container.end());
360  }
361 
362  /// Print a comma separated list of operands.
363  template <typename IteratorType>
364  void printOperands(IteratorType it, IteratorType end) {
365  llvm::interleaveComma(llvm::make_range(it, end), getStream(),
366  [this](Value value) { printOperand(value); });
367  }
368 
369  /// Print the given successor.
370  virtual void printSuccessor(Block *successor) = 0;
371 
372  /// Print the successor and its operands.
373  virtual void printSuccessorAndUseList(Block *successor,
374  ValueRange succOperands) = 0;
375 
376  /// If the specified operation has attributes, print out an attribute
377  /// dictionary with their values. elidedAttrs allows the client to ignore
378  /// specific well known attributes, commonly used if the attribute value is
379  /// printed some other way (like as a fixed operand).
381  ArrayRef<StringRef> elidedAttrs = {}) = 0;
382 
383  /// If the specified operation has attributes, print out an attribute
384  /// dictionary prefixed with 'attributes'.
385  virtual void
387  ArrayRef<StringRef> elidedAttrs = {}) = 0;
388 
389  /// Prints the entire operation with the custom assembly form, if available,
390  /// or the generic assembly form, otherwise.
391  virtual void printCustomOrGenericOp(Operation *op) = 0;
392 
393  /// Print the entire operation with the default generic assembly form.
394  /// If `printOpName` is true, then the operation name is printed (the default)
395  /// otherwise it is omitted and the print will start with the operand list.
396  virtual void printGenericOp(Operation *op, bool printOpName = true) = 0;
397 
398  /// Prints a region.
399  /// If 'printEntryBlockArgs' is false, the arguments of the
400  /// block are not printed. If 'printBlockTerminator' is false, the terminator
401  /// operation of the block is not printed. If printEmptyBlock is true, then
402  /// the block header is printed even if the block is empty.
403  virtual void printRegion(Region &blocks, bool printEntryBlockArgs = true,
404  bool printBlockTerminators = true,
405  bool printEmptyBlock = false) = 0;
406 
407  /// Renumber the arguments for the specified region to the same names as the
408  /// SSA values in namesToUse. This may only be used for IsolatedFromAbove
409  /// operations. If any entry in namesToUse is null, the corresponding
410  /// argument name is left alone.
411  virtual void shadowRegionArgs(Region &region, ValueRange namesToUse) = 0;
412 
413  /// Prints an affine map of SSA ids, where SSA id names are used in place
414  /// of dims/symbols.
415  /// Operand values must come from single-result sources, and be valid
416  /// dimensions/symbol identifiers according to mlir::isValidDim/Symbol.
417  virtual void printAffineMapOfSSAIds(AffineMapAttr mapAttr,
418  ValueRange operands) = 0;
419 
420  /// Prints an affine expression of SSA ids with SSA id names used instead of
421  /// dims and symbols.
422  /// Operand values must come from single-result sources, and be valid
423  /// dimensions/symbol identifiers according to mlir::isValidDim/Symbol.
424  virtual void printAffineExprOfSSAIds(AffineExpr expr, ValueRange dimOperands,
425  ValueRange symOperands) = 0;
426 
427  /// Print the complete type of an operation in functional form.
428  void printFunctionalType(Operation *op);
430 };
431 
432 // Make the implementations convenient to use.
434  p.printOperand(value);
435  return p;
436 }
437 
438 template <typename T,
441  T> * = nullptr>
442 inline OpAsmPrinter &operator<<(OpAsmPrinter &p, const T &values) {
443  p.printOperands(values);
444  return p;
445 }
446 
449  return p;
450 }
451 
452 //===----------------------------------------------------------------------===//
453 // AsmParser
454 //===----------------------------------------------------------------------===//
455 
456 /// This base class exposes generic asm parser hooks, usable across the various
457 /// derived parsers.
458 class AsmParser {
459 public:
460  AsmParser() = default;
461  virtual ~AsmParser();
462 
463  MLIRContext *getContext() const;
464 
465  /// Return the location of the original name token.
466  virtual SMLoc getNameLoc() const = 0;
467 
468  //===--------------------------------------------------------------------===//
469  // Utilities
470  //===--------------------------------------------------------------------===//
471 
472  /// Emit a diagnostic at the specified location and return failure.
473  virtual InFlightDiagnostic emitError(SMLoc loc,
474  const Twine &message = {}) = 0;
475 
476  /// Return a builder which provides useful access to MLIRContext, global
477  /// objects like types and attributes.
478  virtual Builder &getBuilder() const = 0;
479 
480  /// Get the location of the next token and store it into the argument. This
481  /// always succeeds.
482  virtual SMLoc getCurrentLocation() = 0;
484  *loc = getCurrentLocation();
485  return success();
486  }
487 
488  /// Re-encode the given source location as an MLIR location and return it.
489  /// Note: This method should only be used when a `Location` is necessary, as
490  /// the encoding process is not efficient.
491  virtual Location getEncodedSourceLoc(SMLoc loc) = 0;
492 
493  //===--------------------------------------------------------------------===//
494  // Token Parsing
495  //===--------------------------------------------------------------------===//
496 
497  /// Parse a '->' token.
498  virtual ParseResult parseArrow() = 0;
499 
500  /// Parse a '->' token if present
502 
503  /// Parse a `{` token.
504  virtual ParseResult parseLBrace() = 0;
505 
506  /// Parse a `{` token if present.
508 
509  /// Parse a `}` token.
510  virtual ParseResult parseRBrace() = 0;
511 
512  /// Parse a `}` token if present.
514 
515  /// Parse a `:` token.
516  virtual ParseResult parseColon() = 0;
517 
518  /// Parse a `:` token if present.
520 
521  /// Parse a `,` token.
522  virtual ParseResult parseComma() = 0;
523 
524  /// Parse a `,` token if present.
526 
527  /// Parse a `=` token.
528  virtual ParseResult parseEqual() = 0;
529 
530  /// Parse a `=` token if present.
532 
533  /// Parse a '<' token.
534  virtual ParseResult parseLess() = 0;
535 
536  /// Parse a '<' token if present.
538 
539  /// Parse a '>' token.
540  virtual ParseResult parseGreater() = 0;
541 
542  /// Parse a '>' token if present.
544 
545  /// Parse a '?' token.
546  virtual ParseResult parseQuestion() = 0;
547 
548  /// Parse a '?' token if present.
550 
551  /// Parse a '+' token.
552  virtual ParseResult parsePlus() = 0;
553 
554  /// Parse a '+' token if present.
556 
557  /// Parse a '*' token.
558  virtual ParseResult parseStar() = 0;
559 
560  /// Parse a '*' token if present.
562 
563  /// Parse a '|' token.
565 
566  /// Parse a '|' token if present.
568 
569  /// Parse a quoted string token.
570  ParseResult parseString(std::string *string) {
571  auto loc = getCurrentLocation();
572  if (parseOptionalString(string))
573  return emitError(loc, "expected string");
574  return success();
575  }
576 
577  /// Parse a quoted string token if present.
578  virtual ParseResult parseOptionalString(std::string *string) = 0;
579 
580  /// Parses a Base64 encoded string of bytes.
581  virtual ParseResult parseBase64Bytes(std::vector<char> *bytes) = 0;
582 
583  /// Parse a `(` token.
584  virtual ParseResult parseLParen() = 0;
585 
586  /// Parse a `(` token if present.
588 
589  /// Parse a `)` token.
590  virtual ParseResult parseRParen() = 0;
591 
592  /// Parse a `)` token if present.
594 
595  /// Parse a `[` token.
596  virtual ParseResult parseLSquare() = 0;
597 
598  /// Parse a `[` token if present.
600 
601  /// Parse a `]` token.
602  virtual ParseResult parseRSquare() = 0;
603 
604  /// Parse a `]` token if present.
606 
607  /// Parse a `...` token.
608  virtual ParseResult parseEllipsis() = 0;
609 
610  /// Parse a `...` token if present;
612 
613  /// Parse a floating point value from the stream.
614  virtual ParseResult parseFloat(double &result) = 0;
615 
616  /// Parse an integer value from the stream.
617  template <typename IntT>
618  ParseResult parseInteger(IntT &result) {
619  auto loc = getCurrentLocation();
620  OptionalParseResult parseResult = parseOptionalInteger(result);
621  if (!parseResult.has_value())
622  return emitError(loc, "expected integer value");
623  return *parseResult;
624  }
625 
626  /// Parse an optional integer value from the stream.
627  virtual OptionalParseResult parseOptionalInteger(APInt &result) = 0;
628 
629  template <typename IntT>
631  auto loc = getCurrentLocation();
632 
633  // Parse the unsigned variant.
634  APInt uintResult;
635  OptionalParseResult parseResult = parseOptionalInteger(uintResult);
636  if (!parseResult.has_value() || failed(*parseResult))
637  return parseResult;
638 
639  // Try to convert to the provided integer type. sextOrTrunc is correct even
640  // for unsigned types because parseOptionalInteger ensures the sign bit is
641  // zero for non-negated integers.
642  result =
643  (IntT)uintResult.sextOrTrunc(sizeof(IntT) * CHAR_BIT).getLimitedValue();
644  if (APInt(uintResult.getBitWidth(), result) != uintResult)
645  return emitError(loc, "integer value too large");
646  return success();
647  }
648 
649  /// These are the supported delimiters around operand lists and region
650  /// argument lists, used by parseOperandList.
651  enum class Delimiter {
652  /// Zero or more operands with no delimiters.
653  None,
654  /// Parens surrounding zero or more operands.
655  Paren,
656  /// Square brackets surrounding zero or more operands.
657  Square,
658  /// <> brackets surrounding zero or more operands.
659  LessGreater,
660  /// {} brackets surrounding zero or more operands.
661  Braces,
662  /// Parens supporting zero or more operands, or nothing.
664  /// Square brackets supporting zero or more ops, or nothing.
666  /// <> brackets supporting zero or more ops, or nothing.
668  /// {} brackets surrounding zero or more operands, or nothing.
670  };
671 
672  /// Parse a list of comma-separated items with an optional delimiter. If a
673  /// delimiter is provided, then an empty list is allowed. If not, then at
674  /// least one element will be parsed.
675  ///
676  /// contextMessage is an optional message appended to "expected '('" sorts of
677  /// diagnostics when parsing the delimeters.
678  virtual ParseResult
680  function_ref<ParseResult()> parseElementFn,
681  StringRef contextMessage = StringRef()) = 0;
682 
683  /// Parse a comma separated list of elements that must have at least one entry
684  /// in it.
687  return parseCommaSeparatedList(Delimiter::None, parseElementFn);
688  }
689 
690  //===--------------------------------------------------------------------===//
691  // Keyword Parsing
692  //===--------------------------------------------------------------------===//
693 
694  /// This class represents a StringSwitch like class that is useful for parsing
695  /// expected keywords. On construction, it invokes `parseKeyword` and
696  /// processes each of the provided cases statements until a match is hit. The
697  /// provided `ResultT` must be assignable from `failure()`.
698  template <typename ResultT = ParseResult>
700  public:
702  : parser(parser), loc(parser.getCurrentLocation()) {
703  if (failed(parser.parseKeywordOrCompletion(&keyword)))
704  result = failure();
705  }
706 
707  /// Case that uses the provided value when true.
708  KeywordSwitch &Case(StringLiteral str, ResultT value) {
709  return Case(str, [&](StringRef, SMLoc) { return std::move(value); });
710  }
712  return Default([&](StringRef, SMLoc) { return std::move(value); });
713  }
714  /// Case that invokes the provided functor when true. The parameters passed
715  /// to the functor are the keyword, and the location of the keyword (in case
716  /// any errors need to be emitted).
717  template <typename FnT>
719  Case(StringLiteral str, FnT &&fn) {
720  if (result)
721  return *this;
722 
723  // If the word was empty, record this as a completion.
724  if (keyword.empty())
725  parser.codeCompleteExpectedTokens(str);
726  else if (keyword == str)
727  result.emplace(std::move(fn(keyword, loc)));
728  return *this;
729  }
730  template <typename FnT>
732  Default(FnT &&fn) {
733  if (!result)
734  result.emplace(fn(keyword, loc));
735  return *this;
736  }
737 
738  /// Returns true if this switch has a value yet.
739  bool hasValue() const { return result.has_value(); }
740 
741  /// Return the result of the switch.
742  [[nodiscard]] operator ResultT() {
743  if (!result)
744  return parser.emitError(loc, "unexpected keyword: ") << keyword;
745  return std::move(*result);
746  }
747 
748  private:
749  /// The parser used to construct this switch.
750  AsmParser &parser;
751 
752  /// The location of the keyword, used to emit errors as necessary.
753  SMLoc loc;
754 
755  /// The parsed keyword itself.
756  StringRef keyword;
757 
758  /// The result of the switch statement or none if currently unknown.
759  Optional<ResultT> result;
760  };
761 
762  /// Parse a given keyword.
763  ParseResult parseKeyword(StringRef keyword) {
764  return parseKeyword(keyword, "");
765  }
766  virtual ParseResult parseKeyword(StringRef keyword, const Twine &msg) = 0;
767 
768  /// Parse a keyword into 'keyword'.
769  ParseResult parseKeyword(StringRef *keyword) {
770  auto loc = getCurrentLocation();
771  if (parseOptionalKeyword(keyword))
772  return emitError(loc, "expected valid keyword");
773  return success();
774  }
775 
776  /// Parse the given keyword if present.
777  virtual ParseResult parseOptionalKeyword(StringRef keyword) = 0;
778 
779  /// Parse a keyword, if present, into 'keyword'.
780  virtual ParseResult parseOptionalKeyword(StringRef *keyword) = 0;
781 
782  /// Parse a keyword, if present, and if one of the 'allowedValues',
783  /// into 'keyword'
784  virtual ParseResult
785  parseOptionalKeyword(StringRef *keyword,
786  ArrayRef<StringRef> allowedValues) = 0;
787 
788  /// Parse a keyword or a quoted string.
789  ParseResult parseKeywordOrString(std::string *result) {
791  return emitError(getCurrentLocation())
792  << "expected valid keyword or string";
793  return success();
794  }
795 
796  /// Parse an optional keyword or string.
797  virtual ParseResult parseOptionalKeywordOrString(std::string *result) = 0;
798 
799  //===--------------------------------------------------------------------===//
800  // Attribute/Type Parsing
801  //===--------------------------------------------------------------------===//
802 
803  /// Invoke the `getChecked` method of the given Attribute or Type class, using
804  /// the provided location to emit errors in the case of failure. Note that
805  /// unlike `OpBuilder::getType`, this method does not implicitly insert a
806  /// context parameter.
807  template <typename T, typename... ParamsT>
808  auto getChecked(SMLoc loc, ParamsT &&...params) {
809  return T::getChecked([&] { return emitError(loc); },
810  std::forward<ParamsT>(params)...);
811  }
812  /// A variant of `getChecked` that uses the result of `getNameLoc` to emit
813  /// errors.
814  template <typename T, typename... ParamsT>
815  auto getChecked(ParamsT &&...params) {
816  return T::getChecked([&] { return emitError(getNameLoc()); },
817  std::forward<ParamsT>(params)...);
818  }
819 
820  //===--------------------------------------------------------------------===//
821  // Attribute Parsing
822  //===--------------------------------------------------------------------===//
823 
824  /// Parse an arbitrary attribute of a given type and return it in result.
825  virtual ParseResult parseAttribute(Attribute &result, Type type = {}) = 0;
826 
827  /// Parse a custom attribute with the provided callback, unless the next
828  /// token is `#`, in which case the generic parser is invoked.
830  Attribute &result, Type type,
831  function_ref<ParseResult(Attribute &result, Type type)>
832  parseAttribute) = 0;
833 
834  /// Parse an attribute of a specific kind and type.
835  template <typename AttrType>
836  ParseResult parseAttribute(AttrType &result, Type type = {}) {
837  SMLoc loc = getCurrentLocation();
838 
839  // Parse any kind of attribute.
840  Attribute attr;
841  if (parseAttribute(attr, type))
842  return failure();
843 
844  // Check for the right kind of attribute.
845  if (!(result = attr.dyn_cast<AttrType>()))
846  return emitError(loc, "invalid kind of attribute specified");
847 
848  return success();
849  }
850 
851  /// Parse an arbitrary attribute and return it in result. This also adds the
852  /// attribute to the specified attribute list with the specified name.
853  ParseResult parseAttribute(Attribute &result, StringRef attrName,
854  NamedAttrList &attrs) {
855  return parseAttribute(result, Type(), attrName, attrs);
856  }
857 
858  /// Parse an attribute of a specific kind and type.
859  template <typename AttrType>
860  ParseResult parseAttribute(AttrType &result, StringRef attrName,
861  NamedAttrList &attrs) {
862  return parseAttribute(result, Type(), attrName, attrs);
863  }
864 
865  /// Parse an arbitrary attribute of a given type and populate it in `result`.
866  /// This also adds the attribute to the specified attribute list with the
867  /// specified name.
868  template <typename AttrType>
869  ParseResult parseAttribute(AttrType &result, Type type, StringRef attrName,
870  NamedAttrList &attrs) {
871  SMLoc loc = getCurrentLocation();
872 
873  // Parse any kind of attribute.
874  Attribute attr;
875  if (parseAttribute(attr, type))
876  return failure();
877 
878  // Check for the right kind of attribute.
879  result = attr.dyn_cast<AttrType>();
880  if (!result)
881  return emitError(loc, "invalid kind of attribute specified");
882 
883  attrs.append(attrName, result);
884  return success();
885  }
886 
887  /// Trait to check if `AttrType` provides a `parse` method.
888  template <typename AttrType>
889  using has_parse_method = decltype(AttrType::parse(std::declval<AsmParser &>(),
890  std::declval<Type>()));
891  template <typename AttrType>
892  using detect_has_parse_method = llvm::is_detected<has_parse_method, AttrType>;
893 
894  /// Parse a custom attribute of a given type unless the next token is `#`, in
895  /// which case the generic parser is invoked. The parsed attribute is
896  /// populated in `result` and also added to the specified attribute list with
897  /// the specified name.
898  template <typename AttrType>
900  parseCustomAttributeWithFallback(AttrType &result, Type type,
901  StringRef attrName, NamedAttrList &attrs) {
902  SMLoc loc = getCurrentLocation();
903 
904  // Parse any kind of attribute.
905  Attribute attr;
907  attr, type, [&](Attribute &result, Type type) -> ParseResult {
908  result = AttrType::parse(*this, type);
909  if (!result)
910  return failure();
911  return success();
912  }))
913  return failure();
914 
915  // Check for the right kind of attribute.
916  result = attr.dyn_cast<AttrType>();
917  if (!result)
918  return emitError(loc, "invalid kind of attribute specified");
919 
920  attrs.append(attrName, result);
921  return success();
922  }
923 
924  /// SFINAE parsing method for Attribute that don't implement a parse method.
925  template <typename AttrType>
927  parseCustomAttributeWithFallback(AttrType &result, Type type,
928  StringRef attrName, NamedAttrList &attrs) {
929  return parseAttribute(result, type, attrName, attrs);
930  }
931 
932  /// Parse a custom attribute of a given type unless the next token is `#`, in
933  /// which case the generic parser is invoked. The parsed attribute is
934  /// populated in `result`.
935  template <typename AttrType>
938  SMLoc loc = getCurrentLocation();
939 
940  // Parse any kind of attribute.
941  Attribute attr;
943  attr, {}, [&](Attribute &result, Type type) -> ParseResult {
944  result = AttrType::parse(*this, type);
945  return success(!!result);
946  }))
947  return failure();
948 
949  // Check for the right kind of attribute.
950  result = attr.dyn_cast<AttrType>();
951  if (!result)
952  return emitError(loc, "invalid kind of attribute specified");
953  return success();
954  }
955 
956  /// SFINAE parsing method for Attribute that don't implement a parse method.
957  template <typename AttrType>
960  return parseAttribute(result);
961  }
962 
963  /// Parse an arbitrary optional attribute of a given type and return it in
964  /// result.
966  Type type = {}) = 0;
967 
968  /// Parse an optional array attribute and return it in result.
969  virtual OptionalParseResult parseOptionalAttribute(ArrayAttr &result,
970  Type type = {}) = 0;
971 
972  /// Parse an optional string attribute and return it in result.
973  virtual OptionalParseResult parseOptionalAttribute(StringAttr &result,
974  Type type = {}) = 0;
975 
976  /// Parse an optional attribute of a specific type and add it to the list with
977  /// the specified name.
978  template <typename AttrType>
980  StringRef attrName,
981  NamedAttrList &attrs) {
982  return parseOptionalAttribute(result, Type(), attrName, attrs);
983  }
984 
985  /// Parse an optional attribute of a specific type and add it to the list with
986  /// the specified name.
987  template <typename AttrType>
989  StringRef attrName,
990  NamedAttrList &attrs) {
991  OptionalParseResult parseResult = parseOptionalAttribute(result, type);
992  if (parseResult.has_value() && succeeded(*parseResult))
993  attrs.append(attrName, result);
994  return parseResult;
995  }
996 
997  /// Parse a named dictionary into 'result' if it is present.
999 
1000  /// Parse a named dictionary into 'result' if the `attributes` keyword is
1001  /// present.
1002  virtual ParseResult
1004 
1005  /// Parse an affine map instance into 'map'.
1007 
1008  /// Parse an integer set instance into 'set'.
1010 
1011  //===--------------------------------------------------------------------===//
1012  // Identifier Parsing
1013  //===--------------------------------------------------------------------===//
1014 
1015  /// Parse an @-identifier and store it (without the '@' symbol) in a string
1016  /// attribute.
1017  ParseResult parseSymbolName(StringAttr &result) {
1018  if (failed(parseOptionalSymbolName(result)))
1019  return emitError(getCurrentLocation())
1020  << "expected valid '@'-identifier for symbol name";
1021  return success();
1022  }
1023 
1024  /// Parse an @-identifier and store it (without the '@' symbol) in a string
1025  /// attribute named 'attrName'.
1026  ParseResult parseSymbolName(StringAttr &result, StringRef attrName,
1027  NamedAttrList &attrs) {
1028  if (parseSymbolName(result))
1029  return failure();
1030  attrs.append(attrName, result);
1031  return success();
1032  }
1033 
1034  /// Parse an optional @-identifier and store it (without the '@' symbol) in a
1035  /// string attribute.
1036  virtual ParseResult parseOptionalSymbolName(StringAttr &result) = 0;
1037 
1038  /// Parse an optional @-identifier and store it (without the '@' symbol) in a
1039  /// string attribute named 'attrName'.
1040  ParseResult parseOptionalSymbolName(StringAttr &result, StringRef attrName,
1041  NamedAttrList &attrs) {
1042  if (succeeded(parseOptionalSymbolName(result))) {
1043  attrs.append(attrName, result);
1044  return success();
1045  }
1046  return failure();
1047  }
1048 
1049  //===--------------------------------------------------------------------===//
1050  // Resource Parsing
1051  //===--------------------------------------------------------------------===//
1052 
1053  /// Parse a handle to a resource within the assembly format.
1054  template <typename ResourceT>
1056  SMLoc handleLoc = getCurrentLocation();
1057 
1058  // Try to load the dialect that owns the handle.
1059  auto *dialect =
1060  getContext()->getOrLoadDialect<typename ResourceT::Dialect>();
1061  if (!dialect) {
1062  return emitError(handleLoc)
1063  << "dialect '" << ResourceT::Dialect::getDialectNamespace()
1064  << "' is unknown";
1065  }
1066 
1068  if (failed(handle))
1069  return failure();
1070  if (auto *result = dyn_cast<ResourceT>(&*handle))
1071  return std::move(*result);
1072  return emitError(handleLoc) << "provided resource handle differs from the "
1073  "expected resource type";
1074  }
1075 
1076  //===--------------------------------------------------------------------===//
1077  // Type Parsing
1078  //===--------------------------------------------------------------------===//
1079 
1080  /// Parse a type.
1081  virtual ParseResult parseType(Type &result) = 0;
1082 
1083  /// Parse a custom type with the provided callback, unless the next
1084  /// token is `#`, in which case the generic parser is invoked.
1086  Type &result, function_ref<ParseResult(Type &result)> parseType) = 0;
1087 
1088  /// Parse an optional type.
1090 
1091  /// Parse a type of a specific type.
1092  template <typename TypeT>
1093  ParseResult parseType(TypeT &result) {
1094  SMLoc loc = getCurrentLocation();
1095 
1096  // Parse any kind of type.
1097  Type type;
1098  if (parseType(type))
1099  return failure();
1100 
1101  // Check for the right kind of type.
1102  result = type.dyn_cast<TypeT>();
1103  if (!result)
1104  return emitError(loc, "invalid kind of type specified");
1105 
1106  return success();
1107  }
1108 
1109  /// Trait to check if `TypeT` provides a `parse` method.
1110  template <typename TypeT>
1112  decltype(TypeT::parse(std::declval<AsmParser &>()));
1113  template <typename TypeT>
1115  llvm::is_detected<type_has_parse_method, TypeT>;
1116 
1117  /// Parse a custom Type of a given type unless the next token is `#`, in
1118  /// which case the generic parser is invoked. The parsed Type is
1119  /// populated in `result`.
1120  template <typename TypeT>
1123  SMLoc loc = getCurrentLocation();
1124 
1125  // Parse any kind of Type.
1126  Type type;
1127  if (parseCustomTypeWithFallback(type, [&](Type &result) -> ParseResult {
1128  result = TypeT::parse(*this);
1129  return success(!!result);
1130  }))
1131  return failure();
1132 
1133  // Check for the right kind of Type.
1134  result = type.dyn_cast<TypeT>();
1135  if (!result)
1136  return emitError(loc, "invalid kind of Type specified");
1137  return success();
1138  }
1139 
1140  /// SFINAE parsing method for Type that don't implement a parse method.
1141  template <typename TypeT>
1144  return parseType(result);
1145  }
1146 
1147  /// Parse a type list.
1149  return parseCommaSeparatedList(
1150  [&]() { return parseType(result.emplace_back()); });
1151  }
1152 
1153  /// Parse an arrow followed by a type list.
1155 
1156  /// Parse an optional arrow followed by a type list.
1157  virtual ParseResult
1159 
1160  /// Parse a colon followed by a type.
1161  virtual ParseResult parseColonType(Type &result) = 0;
1162 
1163  /// Parse a colon followed by a type of a specific kind, e.g. a FunctionType.
1164  template <typename TypeType>
1165  ParseResult parseColonType(TypeType &result) {
1166  SMLoc loc = getCurrentLocation();
1167 
1168  // Parse any kind of type.
1169  Type type;
1170  if (parseColonType(type))
1171  return failure();
1172 
1173  // Check for the right kind of type.
1174  result = type.dyn_cast<TypeType>();
1175  if (!result)
1176  return emitError(loc, "invalid kind of type specified");
1177 
1178  return success();
1179  }
1180 
1181  /// Parse a colon followed by a type list, which must have at least one type.
1183 
1184  /// Parse an optional colon followed by a type list, which if present must
1185  /// have at least one type.
1186  virtual ParseResult
1188 
1189  /// Parse a keyword followed by a type.
1190  ParseResult parseKeywordType(const char *keyword, Type &result) {
1191  return failure(parseKeyword(keyword) || parseType(result));
1192  }
1193 
1194  /// Add the specified type to the end of the specified type list and return
1195  /// success. This is a helper designed to allow parse methods to be simple
1196  /// and chain through || operators.
1198  result.push_back(type);
1199  return success();
1200  }
1201 
1202  /// Add the specified types to the end of the specified type list and return
1203  /// success. This is a helper designed to allow parse methods to be simple
1204  /// and chain through || operators.
1206  SmallVectorImpl<Type> &result) {
1207  result.append(types.begin(), types.end());
1208  return success();
1209  }
1210 
1211  /// Parse a dimension list of a tensor or memref type. This populates the
1212  /// dimension list, using -1 for the `?` dimensions if `allowDynamic` is set
1213  /// and errors out on `?` otherwise. Parsing the trailing `x` is configurable.
1214  ///
1215  /// dimension-list ::= eps | dimension (`x` dimension)*
1216  /// dimension-list-with-trailing-x ::= (dimension `x`)*
1217  /// dimension ::= `?` | decimal-literal
1218  ///
1219  /// When `allowDynamic` is not set, this is used to parse:
1220  ///
1221  /// static-dimension-list ::= eps | decimal-literal (`x` decimal-literal)*
1222  /// static-dimension-list-with-trailing-x ::= (dimension `x`)*
1224  bool allowDynamic = true,
1225  bool withTrailingX = true) = 0;
1226 
1227  /// Parse an 'x' token in a dimension list, handling the case where the x is
1228  /// juxtaposed with an element type, as in "xf32", leaving the "f32" as the
1229  /// next token.
1231 
1232 protected:
1233  /// Parse a handle to a resource within the assembly format for the given
1234  /// dialect.
1237 
1238  //===--------------------------------------------------------------------===//
1239  // Code Completion
1240  //===--------------------------------------------------------------------===//
1241 
1242  /// Parse a keyword, or an empty string if the current location signals a code
1243  /// completion.
1244  virtual ParseResult parseKeywordOrCompletion(StringRef *keyword) = 0;
1245 
1246  /// Signal the code completion of a set of expected tokens.
1248 
1249 private:
1250  AsmParser(const AsmParser &) = delete;
1251  void operator=(const AsmParser &) = delete;
1252 };
1253 
1254 //===----------------------------------------------------------------------===//
1255 // OpAsmParser
1256 //===----------------------------------------------------------------------===//
1257 
1258 /// The OpAsmParser has methods for interacting with the asm parser: parsing
1259 /// things from it, emitting errors etc. It has an intentionally high-level API
1260 /// that is designed to reduce/constrain syntax innovation in individual
1261 /// operations.
1262 ///
1263 /// For example, consider an op like this:
1264 ///
1265 /// %x = load %p[%1, %2] : memref<...>
1266 ///
1267 /// The "%x = load" tokens are already parsed and therefore invisible to the
1268 /// custom op parser. This can be supported by calling `parseOperandList` to
1269 /// parse the %p, then calling `parseOperandList` with a `SquareDelimiter` to
1270 /// parse the indices, then calling `parseColonTypeList` to parse the result
1271 /// type.
1272 ///
1273 class OpAsmParser : public AsmParser {
1274 public:
1275  using AsmParser::AsmParser;
1276  ~OpAsmParser() override;
1277 
1278  /// Parse a loc(...) specifier if present, filling in result if so.
1279  /// Location for BlockArgument and Operation may be deferred with an alias, in
1280  /// which case an OpaqueLoc is set and will be resolved when parsing
1281  /// completes.
1282  virtual ParseResult
1284 
1285  /// Return the name of the specified result in the specified syntax, as well
1286  /// as the sub-element in the name. It returns an empty string and ~0U for
1287  /// invalid result numbers. For example, in this operation:
1288  ///
1289  /// %x, %y:2, %z = foo.op
1290  ///
1291  /// getResultName(0) == {"x", 0 }
1292  /// getResultName(1) == {"y", 0 }
1293  /// getResultName(2) == {"y", 1 }
1294  /// getResultName(3) == {"z", 0 }
1295  /// getResultName(4) == {"", ~0U }
1296  virtual std::pair<StringRef, unsigned>
1297  getResultName(unsigned resultNo) const = 0;
1298 
1299  /// Return the number of declared SSA results. This returns 4 for the foo.op
1300  /// example in the comment for `getResultName`.
1301  virtual size_t getNumResults() const = 0;
1302 
1303  // These methods emit an error and return failure or success. This allows
1304  // these to be chained together into a linear sequence of || expressions in
1305  // many cases.
1306 
1307  /// Parse an operation in its generic form.
1308  /// The parsed operation is parsed in the current context and inserted in the
1309  /// provided block and insertion point. The results produced by this operation
1310  /// aren't mapped to any named value in the parser. Returns nullptr on
1311  /// failure.
1312  virtual Operation *parseGenericOperation(Block *insertBlock,
1313  Block::iterator insertPt) = 0;
1314 
1315  /// Parse the name of an operation, in the custom form. On success, return a
1316  /// an object of type 'OperationName'. Otherwise, failure is returned.
1318 
1319  //===--------------------------------------------------------------------===//
1320  // Operand Parsing
1321  //===--------------------------------------------------------------------===//
1322 
1323  /// This is the representation of an operand reference.
1325  SMLoc location; // Location of the token.
1326  StringRef name; // Value name, e.g. %42 or %abc
1327  unsigned number; // Number, e.g. 12 for an operand like %xyz#12
1328  };
1329 
1330  /// Parse different components, viz., use-info of operand(s), successor(s),
1331  /// region(s), attribute(s) and function-type, of the generic form of an
1332  /// operation instance and populate the input operation-state 'result' with
1333  /// those components. If any of the components is explicitly provided, then
1334  /// skip parsing that component.
1336  OperationState &result,
1337  Optional<ArrayRef<UnresolvedOperand>> parsedOperandType = std::nullopt,
1338  Optional<ArrayRef<Block *>> parsedSuccessors = std::nullopt,
1339  Optional<MutableArrayRef<std::unique_ptr<Region>>> parsedRegions =
1340  std::nullopt,
1341  Optional<ArrayRef<NamedAttribute>> parsedAttributes = std::nullopt,
1342  Optional<FunctionType> parsedFnType = std::nullopt) = 0;
1343 
1344  /// Parse a single SSA value operand name along with a result number if
1345  /// `allowResultNumber` is true.
1347  bool allowResultNumber = true) = 0;
1348 
1349  /// Parse a single operand if present.
1350  virtual OptionalParseResult
1352  bool allowResultNumber = true) = 0;
1353 
1354  /// Parse zero or more SSA comma-separated operand references with a specified
1355  /// surrounding delimiter, and an optional required operand count.
1356  virtual ParseResult
1358  Delimiter delimiter = Delimiter::None,
1359  bool allowResultNumber = true,
1360  int requiredOperandCount = -1) = 0;
1361 
1362  /// Parse a specified number of comma separated operands.
1364  int requiredOperandCount,
1365  Delimiter delimiter = Delimiter::None) {
1366  return parseOperandList(result, delimiter,
1367  /*allowResultNumber=*/true, requiredOperandCount);
1368  }
1369 
1370  /// Parse zero or more trailing SSA comma-separated trailing operand
1371  /// references with a specified surrounding delimiter, and an optional
1372  /// required operand count. A leading comma is expected before the
1373  /// operands.
1374  ParseResult
1376  Delimiter delimiter = Delimiter::None) {
1377  if (failed(parseOptionalComma()))
1378  return success(); // The comma is optional.
1379  return parseOperandList(result, delimiter);
1380  }
1381 
1382  /// Resolve an operand to an SSA value, emitting an error on failure.
1384  Type type,
1385  SmallVectorImpl<Value> &result) = 0;
1386 
1387  /// Resolve a list of operands to SSA values, emitting an error on failure, or
1388  /// appending the results to the list on success. This method should be used
1389  /// when all operands have the same type.
1390  template <typename Operands = ArrayRef<UnresolvedOperand>>
1391  ParseResult resolveOperands(Operands &&operands, Type type,
1392  SmallVectorImpl<Value> &result) {
1393  for (const UnresolvedOperand &operand : operands)
1394  if (resolveOperand(operand, type, result))
1395  return failure();
1396  return success();
1397  }
1398  template <typename Operands = ArrayRef<UnresolvedOperand>>
1399  ParseResult resolveOperands(Operands &&operands, Type type, SMLoc loc,
1400  SmallVectorImpl<Value> &result) {
1401  return resolveOperands(std::forward<Operands>(operands), type, result);
1402  }
1403 
1404  /// Resolve a list of operands and a list of operand types to SSA values,
1405  /// emitting an error and returning failure, or appending the results
1406  /// to the list on success.
1407  template <typename Operands = ArrayRef<UnresolvedOperand>,
1408  typename Types = ArrayRef<Type>>
1410  resolveOperands(Operands &&operands, Types &&types, SMLoc loc,
1411  SmallVectorImpl<Value> &result) {
1412  size_t operandSize = std::distance(operands.begin(), operands.end());
1413  size_t typeSize = std::distance(types.begin(), types.end());
1414  if (operandSize != typeSize)
1415  return emitError(loc)
1416  << operandSize << " operands present, but expected " << typeSize;
1417 
1418  for (auto [operand, type] : llvm::zip(operands, types))
1419  if (resolveOperand(operand, type, result))
1420  return failure();
1421  return success();
1422  }
1423 
1424  /// Parses an affine map attribute where dims and symbols are SSA operands.
1425  /// Operand values must come from single-result sources, and be valid
1426  /// dimensions/symbol identifiers according to mlir::isValidDim/Symbol.
1427  virtual ParseResult
1429  Attribute &map, StringRef attrName,
1430  NamedAttrList &attrs,
1431  Delimiter delimiter = Delimiter::Square) = 0;
1432 
1433  /// Parses an affine expression where dims and symbols are SSA operands.
1434  /// Operand values must come from single-result sources, and be valid
1435  /// dimensions/symbol identifiers according to mlir::isValidDim/Symbol.
1436  virtual ParseResult
1438  SmallVectorImpl<UnresolvedOperand> &symbOperands,
1439  AffineExpr &expr) = 0;
1440 
1441  //===--------------------------------------------------------------------===//
1442  // Argument Parsing
1443  //===--------------------------------------------------------------------===//
1444 
1445  struct Argument {
1446  UnresolvedOperand ssaName; // SourceLoc, SSA name, result #.
1447  Type type; // Type.
1448  DictionaryAttr attrs; // Attributes if present.
1449  Optional<Location> sourceLoc; // Source location specifier if present.
1450  };
1451 
1452  /// Parse a single argument with the following syntax:
1453  ///
1454  /// `%ssaName : !type { optionalAttrDict} loc(optionalSourceLoc)`
1455  ///
1456  /// If `allowType` is false or `allowAttrs` are false then the respective
1457  /// parts of the grammar are not parsed.
1458  virtual ParseResult parseArgument(Argument &result, bool allowType = false,
1459  bool allowAttrs = false) = 0;
1460 
1461  /// Parse a single argument if present.
1462  virtual OptionalParseResult
1463  parseOptionalArgument(Argument &result, bool allowType = false,
1464  bool allowAttrs = false) = 0;
1465 
1466  /// Parse zero or more arguments with a specified surrounding delimiter.
1468  Delimiter delimiter = Delimiter::None,
1469  bool allowType = false,
1470  bool allowAttrs = false) = 0;
1471 
1472  //===--------------------------------------------------------------------===//
1473  // Region Parsing
1474  //===--------------------------------------------------------------------===//
1475 
1476  /// Parses a region. Any parsed blocks are appended to 'region' and must be
1477  /// moved to the op regions after the op is created. The first block of the
1478  /// region takes 'arguments'.
1479  ///
1480  /// If 'enableNameShadowing' is set to true, the argument names are allowed to
1481  /// shadow the names of other existing SSA values defined above the region
1482  /// scope. 'enableNameShadowing' can only be set to true for regions attached
1483  /// to operations that are 'IsolatedFromAbove'.
1484  virtual ParseResult parseRegion(Region &region,
1485  ArrayRef<Argument> arguments = {},
1486  bool enableNameShadowing = false) = 0;
1487 
1488  /// Parses a region if present.
1489  virtual OptionalParseResult
1491  bool enableNameShadowing = false) = 0;
1492 
1493  /// Parses a region if present. If the region is present, a new region is
1494  /// allocated and placed in `region`. If no region is present or on failure,
1495  /// `region` remains untouched.
1496  virtual OptionalParseResult
1497  parseOptionalRegion(std::unique_ptr<Region> &region,
1498  ArrayRef<Argument> arguments = {},
1499  bool enableNameShadowing = false) = 0;
1500 
1501  //===--------------------------------------------------------------------===//
1502  // Successor Parsing
1503  //===--------------------------------------------------------------------===//
1504 
1505  /// Parse a single operation successor.
1506  virtual ParseResult parseSuccessor(Block *&dest) = 0;
1507 
1508  /// Parse an optional operation successor.
1510 
1511  /// Parse a single operation successor and its operand list.
1512  virtual ParseResult
1514 
1515  //===--------------------------------------------------------------------===//
1516  // Type Parsing
1517  //===--------------------------------------------------------------------===//
1518 
1519  /// Parse a list of assignments of the form
1520  /// (%x1 = %y1, %x2 = %y2, ...)
1524  if (!result.has_value())
1525  return emitError(getCurrentLocation(), "expected '('");
1526  return result.value();
1527  }
1528 
1529  virtual OptionalParseResult
1532 };
1533 
1534 //===--------------------------------------------------------------------===//
1535 // Dialect OpAsm interface.
1536 //===--------------------------------------------------------------------===//
1537 
1538 /// A functor used to set the name of the start of a result group of an
1539 /// operation. See 'getAsmResultNames' below for more details.
1540 using OpAsmSetValueNameFn = function_ref<void(Value, StringRef)>;
1541 
1542 /// A functor used to set the name of blocks in regions directly nested under
1543 /// an operation.
1544 using OpAsmSetBlockNameFn = function_ref<void(Block *, StringRef)>;
1545 
1547  : public DialectInterface::Base<OpAsmDialectInterface> {
1548 public:
1549  OpAsmDialectInterface(Dialect *dialect) : Base(dialect) {}
1550 
1551  //===------------------------------------------------------------------===//
1552  // Aliases
1553  //===------------------------------------------------------------------===//
1554 
1555  /// Holds the result of `getAlias` hook call.
1556  enum class AliasResult {
1557  /// The object (type or attribute) is not supported by the hook
1558  /// and an alias was not provided.
1559  NoAlias,
1560  /// An alias was provided, but it might be overriden by other hook.
1562  /// An alias was provided and it should be used
1563  /// (no other hooks will be checked).
1564  FinalAlias
1565  };
1566 
1567  /// Hooks for getting an alias identifier alias for a given symbol, that is
1568  /// not necessarily a part of this dialect. The identifier is used in place of
1569  /// the symbol when printing textual IR. These aliases must not contain `.` or
1570  /// end with a numeric digit([0-9]+).
1571  virtual AliasResult getAlias(Attribute attr, raw_ostream &os) const {
1572  return AliasResult::NoAlias;
1573  }
1574  virtual AliasResult getAlias(Type type, raw_ostream &os) const {
1575  return AliasResult::NoAlias;
1576  }
1577 
1578  //===--------------------------------------------------------------------===//
1579  // Resources
1580  //===--------------------------------------------------------------------===//
1581 
1582  /// Declare a resource with the given key, returning a handle to use for any
1583  /// references of this resource key within the IR during parsing. The result
1584  /// of `getResourceKey` on the returned handle is permitted to be different
1585  /// than `key`.
1587  declareResource(StringRef key) const {
1588  return failure();
1589  }
1590 
1591  /// Return a key to use for the given resource. This key should uniquely
1592  /// identify this resource within the dialect.
1593  virtual std::string
1595  llvm_unreachable(
1596  "Dialect must implement `getResourceKey` when defining resources");
1597  }
1598 
1599  /// Hook for parsing resource entries. Returns failure if the entry was not
1600  /// valid, or could otherwise not be processed correctly. Any necessary errors
1601  /// can be emitted via the provided entry.
1602  virtual LogicalResult parseResource(AsmParsedResourceEntry &entry) const;
1603 
1604  /// Hook for building resources to use during printing. The given `op` may be
1605  /// inspected to help determine what information to include.
1606  /// `referencedResources` contains all of the resources detected when printing
1607  /// 'op'.
1608  virtual void
1610  const SetVector<AsmDialectResourceHandle> &referencedResources,
1611  AsmResourceBuilder &builder) const {}
1612 };
1613 } // namespace mlir
1614 
1615 //===--------------------------------------------------------------------===//
1616 // Operation OpAsm interface.
1617 //===--------------------------------------------------------------------===//
1618 
1619 /// The OpAsmOpInterface, see OpAsmInterface.td for more details.
1620 #include "mlir/IR/OpAsmInterface.h.inc"
1621 
1622 namespace llvm {
1623 template <>
1624 struct DenseMapInfo<mlir::AsmDialectResourceHandle> {
1628  }
1632  }
1633  static unsigned getHashValue(const mlir::AsmDialectResourceHandle &handle) {
1635  }
1636  static bool isEqual(const mlir::AsmDialectResourceHandle &lhs,
1637  const mlir::AsmDialectResourceHandle &rhs) {
1638  return lhs.getResource() == rhs.getResource();
1639  }
1640 };
1641 } // namespace llvm
1642 
1643 #endif
static constexpr const bool value
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
Base type for affine expression.
Definition: AffineExpr.h:68
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
Definition: AffineMap.h:42
This class represents a CRTP base class for dialect resource handles.
const ResourceT * getResource() const
AsmDialectResourceHandleBase(AsmDialectResourceHandle handle)
ResourceT * getResource()
Return the resource referenced by this handle.
static bool classof(const AsmDialectResourceHandle *handle)
Support llvm style casting.
AsmDialectResourceHandleBase(ResourceT *resource, DialectT *dialect)
Construct a handle from a pointer to the resource.
DialectT * getDialect() const
Return the dialect that owns the resource.
This class represents an opaque handle to a dialect resource entry.
Dialect * getDialect() const
Return the dialect that owns the resource.
TypeID getTypeID() const
Return the type ID of the resource.
bool operator==(const AsmDialectResourceHandle &other) const
AsmDialectResourceHandle(void *resource, TypeID resourceID, Dialect *dialect)
void * getResource() const
Return an opaque pointer to the referenced resource.
This class represents a single parsed resource entry.
Definition: AsmState.h:280
This class represents a StringSwitch like class that is useful for parsing expected keywords.
std::enable_if_t<!std::is_convertible< FnT, ResultT >::value, KeywordSwitch & > Default(FnT &&fn)
KeywordSwitch & Case(StringLiteral str, ResultT value)
Case that uses the provided value when true.
bool hasValue() const
Returns true if this switch has a value yet.
std::enable_if_t<!std::is_convertible< FnT, ResultT >::value, KeywordSwitch & > Case(StringLiteral str, FnT &&fn)
Case that invokes the provided functor when true.
KeywordSwitch & Default(ResultT value)
This base class exposes generic asm parser hooks, usable across the various derived parsers.
llvm::is_detected< has_parse_method, AttrType > detect_has_parse_method
virtual ParseResult printIntegerSet(IntegerSet &set)=0
Parse an integer set instance into 'set'.
ParseResult parseSymbolName(StringAttr &result)
Parse an -identifier and store it (without the '@' symbol) in a string attribute.
virtual ParseResult parseLBrace()=0
Parse a { token.
Delimiter
These are the supported delimiters around operand lists and region argument lists,...
@ Paren
Parens surrounding zero or more operands.
@ None
Zero or more operands with no delimiters.
@ OptionalLessGreater
<> brackets supporting zero or more ops, or nothing.
@ Braces
{} brackets surrounding zero or more operands.
@ OptionalBraces
{} brackets surrounding zero or more operands, or nothing.
@ OptionalParen
Parens supporting zero or more operands, or nothing.
@ Square
Square brackets surrounding zero or more operands.
@ LessGreater
<> brackets surrounding zero or more operands.
@ OptionalSquare
Square brackets supporting zero or more ops, or nothing.
virtual OptionalParseResult parseOptionalInteger(APInt &result)=0
Parse an optional integer value from the stream.
AsmParser()=default
virtual ParseResult parseColonTypeList(SmallVectorImpl< Type > &result)=0
Parse a colon followed by a type list, which must have at least one type.
virtual ParseResult parseOptionalKeywordOrString(std::string *result)=0
Parse an optional keyword or string.
virtual ParseResult parseOptionalSymbolName(StringAttr &result)=0
Parse an optional -identifier and store it (without the '@' symbol) in a string attribute.
virtual ParseResult parseOptionalRBrace()=0
Parse a } token if present.
virtual ParseResult parsePlus()=0
Parse a '+' token.
ParseResult parseKeyword(StringRef *keyword)
Parse a keyword into 'keyword'.
virtual ParseResult parseCommaSeparatedList(Delimiter delimiter, function_ref< ParseResult()> parseElementFn, StringRef contextMessage=StringRef())=0
Parse a list of comma-separated items with an optional delimiter.
decltype(AttrType::parse(std::declval< AsmParser & >(), std::declval< Type >())) has_parse_method
Trait to check if AttrType provides a parse method.
virtual Builder & getBuilder() const =0
Return a builder which provides useful access to MLIRContext, global objects like types and attribute...
virtual ParseResult parseOptionalAttrDict(NamedAttrList &result)=0
Parse a named dictionary into 'result' if it is present.
virtual ParseResult parseOptionalEqual()=0
Parse a = token if present.
virtual ParseResult parseOptionalKeyword(StringRef keyword)=0
Parse the given keyword if present.
virtual OptionalParseResult parseOptionalType(Type &result)=0
Parse an optional type.
MLIRContext * getContext() const
Definition: AsmPrinter.cpp:67
virtual Location getEncodedSourceLoc(SMLoc loc)=0
Re-encode the given source location as an MLIR location and return it.
std::enable_if_t<!detect_type_has_parse_method< TypeT >::value, ParseResult > parseCustomTypeWithFallback(TypeT &result)
SFINAE parsing method for Type that don't implement a parse method.
virtual ParseResult parseRParen()=0
Parse a ) token.
virtual InFlightDiagnostic emitError(SMLoc loc, const Twine &message={})=0
Emit a diagnostic at the specified location and return failure.
virtual ParseResult parseOptionalColon()=0
Parse a : token if present.
virtual ParseResult parseLSquare()=0
Parse a [ token.
virtual ParseResult parseRSquare()=0
Parse a ] token.
virtual ParseResult parseOptionalColonTypeList(SmallVectorImpl< Type > &result)=0
Parse an optional colon followed by a type list, which if present must have at least one type.
ParseResult parseInteger(IntT &result)
Parse an integer value from the stream.
virtual ParseResult parseOptionalArrow()=0
Parse a '->' token if present.
ParseResult parseOptionalSymbolName(StringAttr &result, StringRef attrName, NamedAttrList &attrs)
Parse an optional -identifier and store it (without the '@' symbol) in a string attribute named 'attr...
ParseResult parseAttribute(AttrType &result, Type type, StringRef attrName, NamedAttrList &attrs)
Parse an arbitrary attribute of a given type and populate it in result.
ParseResult parseAttribute(AttrType &result, Type type={})
Parse an attribute of a specific kind and type.
ParseResult parseKeywordOrString(std::string *result)
Parse a keyword or a quoted string.
virtual void codeCompleteExpectedTokens(ArrayRef< StringRef > tokens)=0
Signal the code completion of a set of expected tokens.
virtual ParseResult parseRBrace()=0
Parse a } token.
virtual ParseResult parseAffineMap(AffineMap &map)=0
Parse an affine map instance into 'map'.
ParseResult addTypeToList(Type type, SmallVectorImpl< Type > &result)
Add the specified type to the end of the specified type list and return success.
virtual ParseResult parseOptionalRParen()=0
Parse a ) token if present.
virtual ParseResult parseCustomAttributeWithFallback(Attribute &result, Type type, function_ref< ParseResult(Attribute &result, Type type)> parseAttribute)=0
Parse a custom attribute with the provided callback, unless the next token is #, in which case the ge...
virtual ParseResult parseLess()=0
Parse a '<' token.
virtual ParseResult parseDimensionList(SmallVectorImpl< int64_t > &dimensions, bool allowDynamic=true, bool withTrailingX=true)=0
Parse a dimension list of a tensor or memref type.
ParseResult parseString(std::string *string)
Parse a quoted string token.
virtual ParseResult parseOptionalPlus()=0
Parse a '+' token if present.
virtual ParseResult parseOptionalKeyword(StringRef *keyword, ArrayRef< StringRef > allowedValues)=0
Parse a keyword, if present, and if one of the 'allowedValues', into 'keyword'.
virtual ParseResult parseOptionalGreater()=0
Parse a '>' token if present.
virtual ParseResult parseEqual()=0
Parse a = token.
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't implement a parse method.
virtual ParseResult parseCustomTypeWithFallback(Type &result, function_ref< ParseResult(Type &result)> parseType)=0
Parse a custom type with the provided callback, unless the next token is #, in which case the generic...
virtual OptionalParseResult parseOptionalAttribute(ArrayAttr &result, Type type={})=0
Parse an optional array attribute and return it in result.
virtual ParseResult parseStar()=0
Parse a '*' token.
virtual ParseResult parseOptionalAttrDictWithKeyword(NamedAttrList &result)=0
Parse a named dictionary into 'result' if the attributes keyword is present.
virtual ParseResult parseColonType(Type &result)=0
Parse a colon followed by a type.
virtual OptionalParseResult parseOptionalAttribute(Attribute &result, Type type={})=0
Parse an arbitrary optional attribute of a given type and return it in result.
ParseResult parseCommaSeparatedList(function_ref< ParseResult()> parseElementFn)
Parse a comma separated list of elements that must have at least one entry in it.
virtual ParseResult parseVerticalBar()=0
Parse a '|' token.
ParseResult parseTypeList(SmallVectorImpl< Type > &result)
Parse a type list.
virtual SMLoc getCurrentLocation()=0
Get the location of the next token and store it into the argument.
virtual ParseResult parseOptionalComma()=0
Parse a , token if present.
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.
auto getChecked(SMLoc loc, ParamsT &&...params)
Invoke the getChecked method of the given Attribute or Type class, using the provided location to emi...
virtual ParseResult parseColon()=0
Parse a : token.
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 parseAttribute(Attribute &result, StringRef attrName, NamedAttrList &attrs)
Parse an arbitrary attribute and return it in result.
virtual OptionalParseResult parseOptionalAttribute(StringAttr &result, Type type={})=0
Parse an optional string attribute and return it in result.
virtual SMLoc getNameLoc() const =0
Return the location of the original name token.
virtual ParseResult parseOptionalString(std::string *string)=0
Parse a quoted string token if present.
OptionalParseResult parseOptionalInteger(IntT &result)
ParseResult getCurrentLocation(SMLoc *loc)
virtual ParseResult parseOptionalLess()=0
Parse a '<' token if present.
virtual ParseResult parseOptionalStar()=0
Parse a '*' token if present.
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 ParseResult parseQuestion()=0
Parse a '?' token.
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...
ParseResult parseType(TypeT &result)
Parse a type of a specific type.
virtual ParseResult parseOptionalRSquare()=0
Parse a ] token if present.
virtual ParseResult parseArrow()=0
Parse a '->' token.
ParseResult parseColonType(TypeType &result)
Parse a colon followed by a type of a specific kind, e.g. a FunctionType.
virtual ParseResult parseGreater()=0
Parse a '>' token.
virtual ParseResult parseLParen()=0
Parse a ( token.
virtual ParseResult parseOptionalEllipsis()=0
Parse a ... token if present;.
virtual ParseResult parseType(Type &result)=0
Parse a type.
ParseResult parseAttribute(AttrType &result, StringRef attrName, NamedAttrList &attrs)
Parse an attribute of a specific kind and type.
virtual ParseResult parseEllipsis()=0
Parse a ... token.
auto getChecked(ParamsT &&...params)
A variant of getChecked that uses the result of getNameLoc to emit errors.
virtual ParseResult parseComma()=0
Parse a , token.
virtual ParseResult parseOptionalArrowTypeList(SmallVectorImpl< Type > &result)=0
Parse an optional arrow followed by a type list.
virtual ParseResult parseOptionalLParen()=0
Parse a ( token if present.
ParseResult parseKeywordType(const char *keyword, Type &result)
Parse a keyword followed by a type.
std::enable_if_t<!detect_has_parse_method< AttrType >::value, ParseResult > parseCustomAttributeWithFallback(AttrType &result)
SFINAE parsing method for Attribute that don't implement a parse method.
virtual ParseResult parseArrowTypeList(SmallVectorImpl< Type > &result)=0
Parse an arrow followed by a type list.
virtual ~AsmParser()
virtual ParseResult parseOptionalVerticalBar()=0
Parse a '|' token if present.
virtual ParseResult parseBase64Bytes(std::vector< char > *bytes)=0
Parses a Base64 encoded string of bytes.
llvm::is_detected< type_has_parse_method, TypeT > detect_type_has_parse_method
virtual ParseResult parseKeywordOrCompletion(StringRef *keyword)=0
Parse a keyword, or an empty string if the current location signals a code completion.
virtual ParseResult parseFloat(double &result)=0
Parse a floating point value from the stream.
ParseResult parseSymbolName(StringAttr &result, StringRef attrName, NamedAttrList &attrs)
Parse an -identifier and store it (without the '@' symbol) in a string attribute named 'attrName'.
virtual ParseResult parseOptionalKeyword(StringRef *keyword)=0
Parse a keyword, if present, into 'keyword'.
decltype(TypeT::parse(std::declval< AsmParser & >())) type_has_parse_method
Trait to check if TypeT provides a parse method.
ParseResult parseKeyword(StringRef keyword)
Parse a given keyword.
virtual ParseResult parseOptionalLSquare()=0
Parse a [ token if present.
virtual FailureOr< AsmDialectResourceHandle > parseResourceHandle(Dialect *dialect)=0
Parse a handle to a resource within the assembly format for the given dialect.
virtual ParseResult parseOptionalQuestion()=0
Parse a '?' token if present.
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...
FailureOr< ResourceT > parseResourceHandle()
Parse a handle to a resource within the assembly format.
virtual ParseResult parseAttribute(Attribute &result, Type type={})=0
Parse an arbitrary attribute of a given type and return it in result.
virtual ParseResult parseXInDimensionList()=0
Parse an 'x' token in a dimension list, handling the case where the x is juxtaposed with an element t...
virtual ParseResult parseOptionalLBrace()=0
Parse a { token if present.
virtual ParseResult parseKeyword(StringRef keyword, const Twine &msg)=0
This base class exposes generic asm printer hooks, usable across the various derived printers.
void printStrippedAttrOrType(ArrayRef< AttrOrType > attrOrTypes)
Print the provided array of attributes or types in the context of an operation custom printer/parser:...
virtual void printAttributeWithoutType(Attribute attr)
Print the given attribute without its type.
AsmPrinter()=default
Initialize the printer with no internal implementation.
void printFunctionalType(InputRangeT &&inputs, ResultRangeT &&results)
Print the two given type ranges in a functional form.
virtual void printType(Type 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...
llvm::is_detected< has_print_method, AttrOrType > detect_has_print_method
virtual void printSymbolName(StringRef symbolRef)
Print the given string as a symbol reference, i.e.
void printOptionalArrowTypeList(TypeRange &&types)
Print an optional arrow followed by a type list.
virtual void printAttribute(Attribute attr)
void printArrowTypeList(TypeRange &&types)
virtual ~AsmPrinter()
virtual raw_ostream & getStream() const
Return the raw output stream used by this printer.
virtual void printResourceHandle(const AsmDialectResourceHandle &resource)
Print a handle to the given dialect resource.
decltype(std::declval< AttrOrType >().print(std::declval< AsmPrinter & >())) has_print_method
Trait to check if AttrType provides a print method.
virtual void printFloat(const APFloat &value)
Print the given floating point value in a stabilized form that can be roundtripped through the IR.
void printStrippedAttrOrType(AttrOrType attrOrType)
Print the provided attribute in the context of an operation custom printer/parser: this will invoke d...
AsmPrinter(Impl &impl)
Initialize the printer with the given internal implementation.
This class is used to build resource entries for use by the printer.
Definition: AsmState.h:236
Attributes are known-constant values of operations.
Definition: Attributes.h:25
U dyn_cast() const
Definition: Attributes.h:127
This class represents an argument of a Block.
Definition: Value.h:296
Block represents an ordered list of Operations.
Definition: Block.h:30
OpListType::iterator iterator
Definition: Block.h:129
This class is a general helper class for creating context-global objects like types,...
Definition: Builders.h:49
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:41
This class provides support for representing a failure result, or a valid value of type T.
Definition: LogicalResult.h:78
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:307
An integer set representing a conjunction of one or more affine equalities and inequalities.
Definition: IntegerSet.h:44
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:64
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:56
T * getOrLoadDialect()
Get (or create) a dialect for the given derived dialect type.
Definition: MLIRContext.h:93
NamedAttrList is array of NamedAttributes that tracks whether it is sorted and does some basic work t...
void append(StringRef name, Attribute attr)
Add an attribute with the specified name.
virtual void buildResources(Operation *op, const SetVector< AsmDialectResourceHandle > &referencedResources, AsmResourceBuilder &builder) const
Hook for building resources to use during printing.
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...
OpAsmDialectInterface(Dialect *dialect)
virtual AliasResult getAlias(Type type, raw_ostream &os) const
virtual std::string getResourceKey(const AsmDialectResourceHandle &handle) const
Return a key to use for the given resource.
virtual FailureOr< AsmDialectResourceHandle > declareResource(StringRef key) const
Declare a resource with the given key, returning a handle to use for any references of this resource ...
virtual LogicalResult parseResource(AsmParsedResourceEntry &entry) const
Hook for parsing resource entries.
Definition: AsmPrinter.cpp:117
AliasResult
Holds the result of getAlias hook call.
@ FinalAlias
An alias was provided and it should be used (no other hooks will be checked).
@ NoAlias
The object (type or attribute) is not supported by the hook and an alias was not provided.
@ OverridableAlias
An alias was provided, but it might be overriden by other hook.
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
virtual std::pair< StringRef, unsigned > getResultName(unsigned resultNo) const =0
Return the name of the specified result in the specified syntax, as well as the sub-element in the na...
virtual size_t getNumResults() const =0
Return the number of declared SSA results.
virtual OptionalParseResult parseOptionalAssignmentList(SmallVectorImpl< Argument > &lhs, SmallVectorImpl< UnresolvedOperand > &rhs)=0
virtual ParseResult parseRegion(Region &region, ArrayRef< Argument > arguments={}, bool enableNameShadowing=false)=0
Parses a region.
virtual ParseResult parseGenericOperationAfterOpName(OperationState &result, Optional< ArrayRef< UnresolvedOperand >> parsedOperandType=std::nullopt, Optional< ArrayRef< Block * >> parsedSuccessors=std::nullopt, Optional< MutableArrayRef< std::unique_ptr< Region >>> parsedRegions=std::nullopt, Optional< ArrayRef< NamedAttribute >> parsedAttributes=std::nullopt, Optional< FunctionType > parsedFnType=std::nullopt)=0
Parse different components, viz., use-info of operand(s), successor(s), region(s),...
~OpAsmParser() override
virtual ParseResult parseSuccessor(Block *&dest)=0
Parse a single operation successor.
virtual ParseResult parseArgument(Argument &result, bool allowType=false, bool allowAttrs=false)=0
Parse a single argument with the following syntax:
ParseResult parseTrailingOperandList(SmallVectorImpl< UnresolvedOperand > &result, Delimiter delimiter=Delimiter::None)
Parse zero or more trailing SSA comma-separated trailing operand references with a specified surround...
ParseResult resolveOperands(Operands &&operands, Type type, SMLoc loc, SmallVectorImpl< Value > &result)
virtual ParseResult parseArgumentList(SmallVectorImpl< Argument > &result, Delimiter delimiter=Delimiter::None, bool allowType=false, bool allowAttrs=false)=0
Parse zero or more arguments with a specified surrounding delimiter.
virtual ParseResult parseAffineMapOfSSAIds(SmallVectorImpl< UnresolvedOperand > &operands, Attribute &map, StringRef attrName, NamedAttrList &attrs, Delimiter delimiter=Delimiter::Square)=0
Parses an affine map attribute where dims and symbols are SSA operands.
virtual OptionalParseResult parseOptionalArgument(Argument &result, bool allowType=false, bool allowAttrs=false)=0
Parse a single argument if present.
ParseResult parseAssignmentList(SmallVectorImpl< Argument > &lhs, SmallVectorImpl< UnresolvedOperand > &rhs)
Parse a list of assignments of the form (x1 = y1, x2 = y2, ...)
virtual ParseResult resolveOperand(const UnresolvedOperand &operand, Type type, SmallVectorImpl< Value > &result)=0
Resolve an operand to an SSA value, emitting an error on failure.
virtual OptionalParseResult parseOptionalOperand(UnresolvedOperand &result, bool allowResultNumber=true)=0
Parse a single operand if present.
virtual ParseResult parseSuccessorAndUseList(Block *&dest, SmallVectorImpl< Value > &operands)=0
Parse a single operation successor and its operand list.
virtual OptionalParseResult parseOptionalRegion(Region &region, ArrayRef< Argument > arguments={}, bool enableNameShadowing=false)=0
Parses a region if present.
virtual FailureOr< OperationName > parseCustomOperationName()=0
Parse the name of an operation, in the custom form.
ParseResult parseOperandList(SmallVectorImpl< UnresolvedOperand > &result, int requiredOperandCount, Delimiter delimiter=Delimiter::None)
Parse a specified number of comma separated operands.
ParseResult resolveOperands(Operands &&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 Operation * parseGenericOperation(Block *insertBlock, Block::iterator insertPt)=0
Parse an operation in its generic form.
virtual ParseResult parseOperand(UnresolvedOperand &result, bool allowResultNumber=true)=0
Parse a single SSA value operand name along with a result number if allowResultNumber is true.
virtual ParseResult parseAffineExprOfSSAIds(SmallVectorImpl< UnresolvedOperand > &dimOperands, SmallVectorImpl< UnresolvedOperand > &symbOperands, AffineExpr &expr)=0
Parses an affine expression where dims and symbols are SSA operands.
virtual OptionalParseResult parseOptionalSuccessor(Block *&dest)=0
Parse an optional operation successor.
std::enable_if_t<!std::is_convertible< Types, Type >::value, ParseResult > resolveOperands(Operands &&operands, Types &&types, SMLoc loc, SmallVectorImpl< Value > &result)
Resolve a list of operands and a list of operand types to SSA values, emitting an error and returning...
virtual ParseResult parseOptionalLocationSpecifier(Optional< Location > &result)=0
Parse a loc(...) specifier if present, filling in result if so.
virtual OptionalParseResult parseOptionalRegion(std::unique_ptr< Region > &region, ArrayRef< Argument > arguments={}, bool enableNameShadowing=false)=0
Parses a region if present.
virtual ParseResult parseOperandList(SmallVectorImpl< UnresolvedOperand > &result, Delimiter delimiter=Delimiter::None, bool allowResultNumber=true, int requiredOperandCount=-1)=0
Parse zero or more SSA comma-separated operand references with a specified surrounding delimiter,...
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
void printOperands(IteratorType it, IteratorType end)
Print a comma separated list of operands.
virtual void shadowRegionArgs(Region &region, ValueRange namesToUse)=0
Renumber the arguments for the specified region to the same names as the SSA values in namesToUse.
virtual void printNewline()=0
Print a newline and indent the printer to the start of the current operation.
virtual void increaseIndent()=0
Increase indentation.
virtual void printSuccessorAndUseList(Block *successor, ValueRange succOperands)=0
Print the successor and its operands.
void printOperands(const ContainerType &container)
Print a comma separated list of operands.
virtual void printOptionalAttrDictWithKeyword(ArrayRef< NamedAttribute > attrs, ArrayRef< StringRef > elidedAttrs={})=0
If the specified operation has attributes, print out an attribute dictionary prefixed with 'attribute...
virtual void printOptionalAttrDict(ArrayRef< NamedAttribute > attrs, ArrayRef< StringRef > elidedAttrs={})=0
If the specified operation has attributes, print out an attribute dictionary with their values.
virtual void printOptionalLocationSpecifier(Location loc)=0
Print a loc(...) specifier if printing debug info is enabled.
virtual void printCustomOrGenericOp(Operation *op)=0
Prints the entire operation with the custom assembly form, if available, or the generic assembly form...
virtual void decreaseIndent()=0
Decrease indentation.
virtual void printOperand(Value value, raw_ostream &os)=0
virtual void printSuccessor(Block *successor)=0
Print the given successor.
virtual void printAffineExprOfSSAIds(AffineExpr expr, ValueRange dimOperands, ValueRange symOperands)=0
Prints an affine expression of SSA ids with SSA id names used instead of dims and symbols.
void printFunctionalType(Operation *op)
Print the complete type of an operation in functional form.
Definition: AsmPrinter.cpp:81
virtual void printAffineMapOfSSAIds(AffineMapAttr mapAttr, ValueRange operands)=0
Prints an affine map of SSA ids, where SSA id names are used in place of dims/symbols.
virtual void printGenericOp(Operation *op, bool printOpName=true)=0
Print the entire operation with the default generic assembly form.
~OpAsmPrinter() override
virtual void printRegion(Region &blocks, bool printEntryBlockArgs=true, bool printBlockTerminators=true, bool printEmptyBlock=false)=0
Prints a region.
virtual void printRegionArgument(BlockArgument arg, ArrayRef< NamedAttribute > argAttrs={}, bool omitType=false)=0
Print a block argument in the usual format of: ssaName : type {attr1=42} loc("here") where location p...
virtual void printOperand(Value value)=0
Print implementations for various things an operation contains.
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:31
This class implements Optional functionality for ParseResult.
Definition: OpDefinition.h:37
ParseResult value() const
Access the internal ParseResult value.
Definition: OpDefinition.h:50
bool has_value() const
Returns true if we contain a valid ParseResult value.
Definition: OpDefinition.h:47
This class represents success/failure for parsing-like operations that find it important to chain tog...
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Definition: Region.h:26
This class provides an efficient unique identifier for a specific C++ type.
Definition: TypeID.h:104
This class provides an abstraction over the various different ranges of value types.
Definition: TypeRange.h:36
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
U dyn_cast() const
Definition: Types.h:270
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:349
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:85
The base class used for all derived interface types.
Include the generated interface declarations.
Definition: CallGraph.h:229
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value.
Definition: LogicalResult.h:68
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
llvm::hash_code hash_value(const AsmDialectResourceHandle &param)
inline ::llvm::hash_code hash_value(AffineExpr arg)
Make AffineExpr hashable.
Definition: AffineExpr.h:240
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
Definition: LogicalResult.h:72
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
Definition: AliasAnalysis.h:78
static mlir::AsmDialectResourceHandle getTombstoneKey()
static unsigned getHashValue(const mlir::AsmDialectResourceHandle &handle)
static mlir::AsmDialectResourceHandle getEmptyKey()
static bool isEqual(const mlir::AsmDialectResourceHandle &lhs, const mlir::AsmDialectResourceHandle &rhs)
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
Optional< Location > sourceLoc
This is the representation of an operand reference.
This represents an operation in an abstracted form, suitable for use with the builder APIs.