MLIR  22.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/OpAsmSupport.h"
19 #include "mlir/IR/OpDefinition.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/Support/SMLoc.h"
22 #include <optional>
23 
24 namespace {
25 // reference https://stackoverflow.com/a/16000226
26 template <typename T, typename = void>
27 struct HasStaticName : std::false_type {};
28 
29 template <typename T>
30 struct HasStaticName<T,
31  typename std::enable_if<
32  std::is_same<::llvm::StringLiteral,
33  std::decay_t<decltype(T::name)>>::value,
34  void>::type> : std::true_type {};
35 } // namespace
36 
37 namespace mlir {
38 class AsmParsedResourceEntry;
39 class AsmResourceBuilder;
40 class Builder;
41 
42 //===----------------------------------------------------------------------===//
43 // AsmDialectResourceHandle
44 //===----------------------------------------------------------------------===//
45 
46 /// This class represents an opaque handle to a dialect resource entry.
48 public:
50  AsmDialectResourceHandle(void *resource, TypeID resourceID, Dialect *dialect)
51  : resource(resource), opaqueID(resourceID), dialect(dialect) {}
52  bool operator==(const AsmDialectResourceHandle &other) const {
53  return resource == other.resource;
54  }
55 
56  /// Return an opaque pointer to the referenced resource.
57  void *getResource() const { return resource; }
58 
59  /// Return the type ID of the resource.
60  TypeID getTypeID() const { return opaqueID; }
61 
62  /// Return the dialect that owns the resource.
63  Dialect *getDialect() const { return dialect; }
64 
65 private:
66  /// The opaque handle to the dialect resource.
67  void *resource = nullptr;
68  /// The type of the resource referenced.
69  TypeID opaqueID;
70  /// The dialect owning the given resource.
71  Dialect *dialect;
72 };
73 
74 /// This class represents a CRTP base class for dialect resource handles. It
75 /// abstracts away various utilities necessary for defined derived resource
76 /// handles.
77 template <typename DerivedT, typename ResourceT, typename DialectT>
79 public:
80  using Dialect = DialectT;
81 
82  /// Construct a handle from a pointer to the resource. The given pointer
83  /// should be guaranteed to live beyond the life of this handle.
84  AsmDialectResourceHandleBase(ResourceT *resource, DialectT *dialect)
85  : AsmDialectResourceHandle(resource, TypeID::get<DerivedT>(), dialect) {}
87  : AsmDialectResourceHandle(handle) {
88  assert(handle.getTypeID() == TypeID::get<DerivedT>());
89  }
90 
91  /// Return the resource referenced by this handle.
92  ResourceT *getResource() {
93  return static_cast<ResourceT *>(AsmDialectResourceHandle::getResource());
94  }
95  const ResourceT *getResource() const {
96  return const_cast<AsmDialectResourceHandleBase *>(this)->getResource();
97  }
98 
99  /// Return the dialect that owns the resource.
100  DialectT *getDialect() const {
101  return static_cast<DialectT *>(AsmDialectResourceHandle::getDialect());
102  }
103 
104  /// Support llvm style casting.
105  static bool classof(const AsmDialectResourceHandle *handle) {
106  return handle->getTypeID() == TypeID::get<DerivedT>();
107  }
108 };
109 
110 inline llvm::hash_code hash_value(const AsmDialectResourceHandle &param) {
111  return llvm::hash_value(param.getResource());
112 }
113 
114 //===----------------------------------------------------------------------===//
115 // AsmPrinter
116 //===----------------------------------------------------------------------===//
117 
118 /// This base class exposes generic asm printer hooks, usable across the various
119 /// derived printers.
120 class AsmPrinter {
121 public:
122  /// This class contains the internal default implementation of the base
123  /// printer methods.
124  class Impl;
125 
126  /// Initialize the printer with the given internal implementation.
128  virtual ~AsmPrinter();
129 
130  /// Return the raw output stream used by this printer.
131  virtual raw_ostream &getStream() const;
132 
133  /// Print the given floating point value in a stabilized form that can be
134  /// roundtripped through the IR. This is the companion to the 'parseFloat'
135  /// hook on the AsmParser.
136  virtual void printFloat(const APFloat &value);
137 
138  /// Print the given integer value. This is useful to force a uint8_t/int8_t to
139  /// be printed as an integer instead of a char.
140  template <typename IntT>
141  std::enable_if_t<std::is_integral_v<IntT>, void> printInteger(IntT value) {
142  // Handle int8_t/uint8_t specially to avoid printing as char
143  if constexpr (std::is_same_v<IntT, int8_t> ||
144  std::is_same_v<IntT, uint8_t>) {
145  getStream() << static_cast<int>(value);
146  } else {
147  getStream() << value;
148  }
149  }
150 
151  virtual void printType(Type type);
152  virtual void printAttribute(Attribute attr);
153 
154  /// Trait to check if `AttrType` provides a `print` method.
155  template <typename AttrOrType>
157  decltype(std::declval<AttrOrType>().print(std::declval<AsmPrinter &>()));
158  template <typename AttrOrType>
160  llvm::is_detected<has_print_method, AttrOrType>;
161 
162  /// Print the provided attribute in the context of an operation custom
163  /// printer/parser: this will invoke directly the print method on the
164  /// attribute class and skip the `#dialect.mnemonic` prefix in most cases.
165  template <typename AttrOrType,
166  std::enable_if_t<detect_has_print_method<AttrOrType>::value>
167  *sfinae = nullptr>
168  void printStrippedAttrOrType(AttrOrType attrOrType) {
169  if (succeeded(printAlias(attrOrType)))
170  return;
171 
172  raw_ostream &os = getStream();
173  uint64_t posPrior = os.tell();
174  attrOrType.print(*this);
175  if (posPrior != os.tell())
176  return;
177 
178  // Fallback to printing with prefix if the above failed to write anything
179  // to the output stream.
180  *this << attrOrType;
181  }
182 
183  /// Print the provided array of attributes or types in the context of an
184  /// operation custom printer/parser: this will invoke directly the print
185  /// method on the attribute class and skip the `#dialect.mnemonic` prefix in
186  /// most cases.
187  template <typename AttrOrType,
188  std::enable_if_t<detect_has_print_method<AttrOrType>::value>
189  *sfinae = nullptr>
191  llvm::interleaveComma(
192  attrOrTypes, getStream(),
193  [this](AttrOrType attrOrType) { printStrippedAttrOrType(attrOrType); });
194  }
195 
196  /// SFINAE for printing the provided attribute in the context of an operation
197  /// custom printer in the case where the attribute does not define a print
198  /// method.
199  template <typename AttrOrType,
200  std::enable_if_t<!detect_has_print_method<AttrOrType>::value>
201  *sfinae = nullptr>
202  void printStrippedAttrOrType(AttrOrType attrOrType) {
203  *this << attrOrType;
204  }
205 
206  /// Print the given attribute without its type. The corresponding parser must
207  /// provide a valid type for the attribute.
208  virtual void printAttributeWithoutType(Attribute attr);
209 
210  /// Print the given named attribute.
211  virtual void printNamedAttribute(NamedAttribute attr);
212 
213  /// Print the alias for the given attribute, return failure if no alias could
214  /// be printed.
215  virtual LogicalResult printAlias(Attribute attr);
216 
217  /// Print the alias for the given type, return failure if no alias could
218  /// be printed.
219  virtual LogicalResult printAlias(Type type);
220 
221  /// Print the given string as a keyword, or a quoted and escaped string if it
222  /// has any special or non-printable characters in it.
223  virtual void printKeywordOrString(StringRef keyword);
224 
225  /// Print the given string as a quoted string, escaping any special or
226  /// non-printable characters in it.
227  virtual void printString(StringRef string);
228 
229  /// Print the given string as a symbol reference, i.e. a form representable by
230  /// a SymbolRefAttr. A symbol reference is represented as a string prefixed
231  /// with '@'. The reference is surrounded with ""'s and escaped if it has any
232  /// special or non-printable characters in it.
233  virtual void printSymbolName(StringRef symbolRef);
234 
235  /// Print a handle to the given dialect resource. The handle key is quoted and
236  /// escaped if it has any special or non-printable characters in it.
237  virtual void printResourceHandle(const AsmDialectResourceHandle &resource);
238 
239  /// Print an optional arrow followed by a type list.
240  template <typename TypeRange>
242  if (types.begin() != types.end())
243  printArrowTypeList(types);
244  }
245  template <typename TypeRange>
247  auto &os = getStream() << " -> ";
248 
249  bool wrapped = !llvm::hasSingleElement(types) ||
250  llvm::isa<FunctionType>((*types.begin()));
251  if (wrapped)
252  os << '(';
253  llvm::interleaveComma(types, *this);
254  if (wrapped)
255  os << ')';
256  }
257 
258  /// Print the two given type ranges in a functional form.
259  template <typename InputRangeT, typename ResultRangeT>
260  void printFunctionalType(InputRangeT &&inputs, ResultRangeT &&results) {
261  auto &os = getStream();
262  os << '(';
263  llvm::interleaveComma(inputs, *this);
264  os << ')';
265  printArrowTypeList(results);
266  }
267 
269 
270  /// Class used to automatically end a cyclic region on destruction.
272  public:
273  explicit CyclicPrintReset(AsmPrinter *printer) : printer(printer) {}
274 
276  if (printer)
277  printer->popCyclicPrinting();
278  }
279 
281 
283 
285  : printer(std::exchange(rhs.printer, nullptr)) {}
286 
288  printer = std::exchange(rhs.printer, nullptr);
289  return *this;
290  }
291 
292  private:
293  AsmPrinter *printer;
294  };
295 
296  /// Attempts to start a cyclic printing region for `attrOrType`.
297  /// A cyclic printing region starts with this call and ends with the
298  /// destruction of the returned `CyclicPrintReset`. During this time,
299  /// calling `tryStartCyclicPrint` with the same attribute in any printer
300  /// will lead to returning failure.
301  ///
302  /// This makes it possible to break infinite recursions when trying to print
303  /// cyclic attributes or types by printing only immutable parameters if nested
304  /// within itself.
305  template <class AttrOrTypeT>
306  FailureOr<CyclicPrintReset> tryStartCyclicPrint(AttrOrTypeT attrOrType) {
307  static_assert(
308  std::is_base_of_v<AttributeTrait::IsMutable<AttrOrTypeT>,
309  AttrOrTypeT> ||
310  std::is_base_of_v<TypeTrait::IsMutable<AttrOrTypeT>, AttrOrTypeT>,
311  "Only mutable attributes or types can be cyclic");
312  if (failed(pushCyclicPrinting(attrOrType.getAsOpaquePointer())))
313  return failure();
314  return CyclicPrintReset(this);
315  }
316 
317 protected:
318  /// Initialize the printer with no internal implementation. In this case, all
319  /// virtual methods of this class must be overriden.
320  AsmPrinter() = default;
321 
322  /// Pushes a new attribute or type in the form of a type erased pointer
323  /// into an internal set.
324  /// Returns success if the type or attribute was inserted in the set or
325  /// failure if it was already contained.
326  virtual LogicalResult pushCyclicPrinting(const void *opaquePointer);
327 
328  /// Removes the element that was last inserted with a successful call to
329  /// `pushCyclicPrinting`. There must be exactly one `popCyclicPrinting` call
330  /// in reverse order of all successful `pushCyclicPrinting`.
331  virtual void popCyclicPrinting();
332 
333 private:
334  AsmPrinter(const AsmPrinter &) = delete;
335  void operator=(const AsmPrinter &) = delete;
336 
337  /// The internal implementation of the printer.
338  Impl *impl{nullptr};
339 };
340 
341 template <typename AsmPrinterT>
342 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
343  AsmPrinterT &>
344 operator<<(AsmPrinterT &p, Type type) {
345  p.printType(type);
346  return p;
347 }
348 
349 template <typename AsmPrinterT>
350 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
351  AsmPrinterT &>
352 operator<<(AsmPrinterT &p, Attribute attr) {
353  p.printAttribute(attr);
354  return p;
355 }
356 
357 template <typename AsmPrinterT>
358 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
359  AsmPrinterT &>
360 operator<<(AsmPrinterT &p, const APFloat &value) {
361  p.printFloat(value);
362  return p;
363 }
364 template <typename AsmPrinterT>
365 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
366  AsmPrinterT &>
367 operator<<(AsmPrinterT &p, float value) {
368  return p << APFloat(value);
369 }
370 template <typename AsmPrinterT>
371 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
372  AsmPrinterT &>
373 operator<<(AsmPrinterT &p, double value) {
374  return p << APFloat(value);
375 }
376 
377 // Support printing anything that isn't convertible to one of the other
378 // streamable types, even if it isn't exactly one of them. For example, we want
379 // to print FunctionType with the Type version above, not have it match this.
380 template <typename AsmPrinterT, typename T,
381  std::enable_if_t<!std::is_convertible<T &, Value &>::value &&
382  !std::is_convertible<T &, Type &>::value &&
383  !std::is_convertible<T &, Attribute &>::value &&
384  !std::is_convertible<T &, ValueRange>::value &&
385  !std::is_convertible<T &, APFloat &>::value &&
386  !llvm::is_one_of<T, bool, float, double>::value,
387  T> * = nullptr>
388 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
389  AsmPrinterT &>
390 operator<<(AsmPrinterT &p, const T &other) {
391  p.getStream() << other;
392  return p;
393 }
394 
395 template <typename AsmPrinterT>
396 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
397  AsmPrinterT &>
398 operator<<(AsmPrinterT &p, bool value) {
399  return p << (value ? StringRef("true") : "false");
400 }
401 
402 template <typename AsmPrinterT, typename ValueRangeT>
403 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
404  AsmPrinterT &>
405 operator<<(AsmPrinterT &p, const ValueTypeRange<ValueRangeT> &types) {
406  llvm::interleaveComma(types, p);
407  return p;
408 }
409 
410 template <typename AsmPrinterT>
411 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
412  AsmPrinterT &>
413 operator<<(AsmPrinterT &p, const TypeRange &types) {
414  llvm::interleaveComma(types, p);
415  return p;
416 }
417 
418 // Prevent matching the TypeRange version above for ValueRange
419 // printing through base AsmPrinter. This is needed so that the
420 // ValueRange printing behaviour does not change from printing
421 // the SSA values to printing the types for the operands when
422 // using AsmPrinter instead of OpAsmPrinter.
423 template <typename AsmPrinterT, typename T>
424 inline std::enable_if_t<std::is_same<AsmPrinter, AsmPrinterT>::value &&
425  std::is_convertible<T &, ValueRange>::value,
426  AsmPrinterT &>
427 operator<<(AsmPrinterT &p, const T &other) = delete;
428 
429 template <typename AsmPrinterT, typename ElementT>
430 inline std::enable_if_t<std::is_base_of<AsmPrinter, AsmPrinterT>::value,
431  AsmPrinterT &>
432 operator<<(AsmPrinterT &p, ArrayRef<ElementT> types) {
433  llvm::interleaveComma(types, p);
434  return p;
435 }
436 
437 //===----------------------------------------------------------------------===//
438 // OpAsmPrinter
439 //===----------------------------------------------------------------------===//
440 
441 /// This is a pure-virtual base class that exposes the asmprinter hooks
442 /// necessary to implement a custom print() method.
443 class OpAsmPrinter : public AsmPrinter {
444 public:
446  ~OpAsmPrinter() override;
447 
448  /// Print a loc(...) specifier if printing debug info is enabled.
450 
451  /// Print a newline and indent the printer to the start of the current
452  /// operation.
453  virtual void printNewline() = 0;
454 
455  /// Increase indentation.
456  virtual void increaseIndent() = 0;
457 
458  /// Decrease indentation.
459  virtual void decreaseIndent() = 0;
460 
461  /// Print a block argument in the usual format of:
462  /// %ssaName : type {attr1=42} loc("here")
463  /// where location printing is controlled by the standard internal option.
464  /// You may pass omitType=true to not print a type, and pass an empty
465  /// attribute list if you don't care for attributes.
467  ArrayRef<NamedAttribute> argAttrs = {},
468  bool omitType = false) = 0;
469 
470  /// Print implementations for various things an operation contains.
471  virtual void printOperand(Value value) = 0;
472  virtual void printOperand(Value value, raw_ostream &os) = 0;
473 
474  /// Print a comma separated list of operands.
475  template <typename ContainerType>
476  void printOperands(const ContainerType &container) {
477  printOperands(container.begin(), container.end());
478  }
479 
480  /// Print a comma separated list of operands.
481  template <typename IteratorType>
482  void printOperands(IteratorType it, IteratorType end) {
483  llvm::interleaveComma(llvm::make_range(it, end), getStream(),
484  [this](Value value) { printOperand(value); });
485  }
486 
487  /// Print the given successor.
488  virtual void printSuccessor(Block *successor) = 0;
489 
490  /// Print the successor and its operands.
491  virtual void printSuccessorAndUseList(Block *successor,
492  ValueRange succOperands) = 0;
493 
494  /// If the specified operation has attributes, print out an attribute
495  /// dictionary with their values. elidedAttrs allows the client to ignore
496  /// specific well known attributes, commonly used if the attribute value is
497  /// printed some other way (like as a fixed operand).
499  ArrayRef<StringRef> elidedAttrs = {}) = 0;
500 
501  /// If the specified operation has attributes, print out an attribute
502  /// dictionary prefixed with 'attributes'.
503  virtual void
505  ArrayRef<StringRef> elidedAttrs = {}) = 0;
506 
507  /// Prints the entire operation with the custom assembly form, if available,
508  /// or the generic assembly form, otherwise.
509  virtual void printCustomOrGenericOp(Operation *op) = 0;
510 
511  /// Print the entire operation with the default generic assembly form.
512  /// If `printOpName` is true, then the operation name is printed (the default)
513  /// otherwise it is omitted and the print will start with the operand list.
514  virtual void printGenericOp(Operation *op, bool printOpName = true) = 0;
515 
516  /// Prints a region.
517  /// If 'printEntryBlockArgs' is false, the arguments of the
518  /// block are not printed. If 'printBlockTerminator' is false, the terminator
519  /// operation of the block is not printed. If printEmptyBlock is true, then
520  /// the block header is printed even if the block is empty.
521  virtual void printRegion(Region &blocks, bool printEntryBlockArgs = true,
522  bool printBlockTerminators = true,
523  bool printEmptyBlock = false) = 0;
524 
525  /// Renumber the arguments for the specified region to the same names as the
526  /// SSA values in namesToUse. This may only be used for IsolatedFromAbove
527  /// operations. If any entry in namesToUse is null, the corresponding
528  /// argument name is left alone.
529  virtual void shadowRegionArgs(Region &region, ValueRange namesToUse) = 0;
530 
531  /// Prints an affine map of SSA ids, where SSA id names are used in place
532  /// of dims/symbols.
533  /// Operand values must come from single-result sources, and be valid
534  /// dimensions/symbol identifiers according to mlir::isValidDim/Symbol.
535  virtual void printAffineMapOfSSAIds(AffineMapAttr mapAttr,
536  ValueRange operands) = 0;
537 
538  /// Prints an affine expression of SSA ids with SSA id names used instead of
539  /// dims and symbols.
540  /// Operand values must come from single-result sources, and be valid
541  /// dimensions/symbol identifiers according to mlir::isValidDim/Symbol.
542  virtual void printAffineExprOfSSAIds(AffineExpr expr, ValueRange dimOperands,
543  ValueRange symOperands) = 0;
544 
545  /// Print the complete type of an operation in functional form.
546  void printFunctionalType(Operation *op);
548 };
549 
550 // Make the implementations convenient to use.
552  p.printOperand(value);
553  return p;
554 }
555 
556 template <typename T,
557  std::enable_if_t<std::is_convertible<T &, ValueRange>::value &&
558  !std::is_convertible<T &, Value &>::value,
559  T> * = nullptr>
560 inline OpAsmPrinter &operator<<(OpAsmPrinter &p, const T &values) {
561  p.printOperands(values);
562  return p;
563 }
564 
566  p.printSuccessor(value);
567  return p;
568 }
569 
570 //===----------------------------------------------------------------------===//
571 // AsmParser
572 //===----------------------------------------------------------------------===//
573 
574 /// This base class exposes generic asm parser hooks, usable across the various
575 /// derived parsers.
576 class AsmParser {
577 public:
578  AsmParser() = default;
579  virtual ~AsmParser();
580 
581  MLIRContext *getContext() const;
582 
583  /// Return the location of the original name token.
584  virtual SMLoc getNameLoc() const = 0;
585 
586  //===--------------------------------------------------------------------===//
587  // Utilities
588  //===--------------------------------------------------------------------===//
589 
590  /// Emit a diagnostic at the specified location and return failure.
591  virtual InFlightDiagnostic emitError(SMLoc loc,
592  const Twine &message = {}) = 0;
593 
594  /// Return a builder which provides useful access to MLIRContext, global
595  /// objects like types and attributes.
596  virtual Builder &getBuilder() const = 0;
597 
598  /// Get the location of the next token and store it into the argument. This
599  /// always succeeds.
600  virtual SMLoc getCurrentLocation() = 0;
601  ParseResult getCurrentLocation(SMLoc *loc) {
602  *loc = getCurrentLocation();
603  return success();
604  }
605 
606  /// Re-encode the given source location as an MLIR location and return it.
607  /// Note: This method should only be used when a `Location` is necessary, as
608  /// the encoding process is not efficient.
609  virtual Location getEncodedSourceLoc(SMLoc loc) = 0;
610 
611  //===--------------------------------------------------------------------===//
612  // Token Parsing
613  //===--------------------------------------------------------------------===//
614 
615  /// Parse a '->' token.
616  virtual ParseResult parseArrow() = 0;
617 
618  /// Parse a '->' token if present
619  virtual ParseResult parseOptionalArrow() = 0;
620 
621  /// Parse a `{` token.
622  virtual ParseResult parseLBrace() = 0;
623 
624  /// Parse a `{` token if present.
625  virtual ParseResult parseOptionalLBrace() = 0;
626 
627  /// Parse a `}` token.
628  virtual ParseResult parseRBrace() = 0;
629 
630  /// Parse a `}` token if present.
631  virtual ParseResult parseOptionalRBrace() = 0;
632 
633  /// Parse a `:` token.
634  virtual ParseResult parseColon() = 0;
635 
636  /// Parse a `:` token if present.
637  virtual ParseResult parseOptionalColon() = 0;
638 
639  /// Parse a `,` token.
640  virtual ParseResult parseComma() = 0;
641 
642  /// Parse a `,` token if present.
643  virtual ParseResult parseOptionalComma() = 0;
644 
645  /// Parse a `=` token.
646  virtual ParseResult parseEqual() = 0;
647 
648  /// Parse a `=` token if present.
649  virtual ParseResult parseOptionalEqual() = 0;
650 
651  /// Parse a '<' token.
652  virtual ParseResult parseLess() = 0;
653 
654  /// Parse a '<' token if present.
655  virtual ParseResult parseOptionalLess() = 0;
656 
657  /// Parse a '>' token.
658  virtual ParseResult parseGreater() = 0;
659 
660  /// Parse a '>' token if present.
661  virtual ParseResult parseOptionalGreater() = 0;
662 
663  /// Parse a '?' token.
664  virtual ParseResult parseQuestion() = 0;
665 
666  /// Parse a '?' token if present.
667  virtual ParseResult parseOptionalQuestion() = 0;
668 
669  /// Parse a '+' token.
670  virtual ParseResult parsePlus() = 0;
671 
672  /// Parse a '+' token if present.
673  virtual ParseResult parseOptionalPlus() = 0;
674 
675  /// Parse a '/' token.
676  virtual ParseResult parseSlash() = 0;
677 
678  /// Parse a '/' token if present.
679  virtual ParseResult parseOptionalSlash() = 0;
680 
681  /// Parse a '-' token.
682  virtual ParseResult parseMinus() = 0;
683 
684  /// Parse a '-' token if present.
685  virtual ParseResult parseOptionalMinus() = 0;
686 
687  /// Parse a '*' token.
688  virtual ParseResult parseStar() = 0;
689 
690  /// Parse a '*' token if present.
691  virtual ParseResult parseOptionalStar() = 0;
692 
693  /// Parse a '|' token.
694  virtual ParseResult parseVerticalBar() = 0;
695 
696  /// Parse a '|' token if present.
697  virtual ParseResult parseOptionalVerticalBar() = 0;
698 
699  /// Parse a quoted string token.
700  ParseResult parseString(std::string *string) {
701  auto loc = getCurrentLocation();
702  if (parseOptionalString(string))
703  return emitError(loc, "expected string");
704  return success();
705  }
706 
707  /// Parse a quoted string token if present.
708  virtual ParseResult parseOptionalString(std::string *string) = 0;
709 
710  /// Parses a Base64 encoded string of bytes.
711  virtual ParseResult parseBase64Bytes(std::vector<char> *bytes) = 0;
712 
713  /// Parse a `(` token.
714  virtual ParseResult parseLParen() = 0;
715 
716  /// Parse a `(` token if present.
717  virtual ParseResult parseOptionalLParen() = 0;
718 
719  /// Parse a `)` token.
720  virtual ParseResult parseRParen() = 0;
721 
722  /// Parse a `)` token if present.
723  virtual ParseResult parseOptionalRParen() = 0;
724 
725  /// Parse a `[` token.
726  virtual ParseResult parseLSquare() = 0;
727 
728  /// Parse a `[` token if present.
729  virtual ParseResult parseOptionalLSquare() = 0;
730 
731  /// Parse a `]` token.
732  virtual ParseResult parseRSquare() = 0;
733 
734  /// Parse a `]` token if present.
735  virtual ParseResult parseOptionalRSquare() = 0;
736 
737  /// Parse a `...` token.
738  virtual ParseResult parseEllipsis() = 0;
739 
740  /// Parse a `...` token if present;
741  virtual ParseResult parseOptionalEllipsis() = 0;
742 
743  /// Parse a floating point value from the stream.
744  virtual ParseResult parseFloat(double &result) = 0;
745 
746  /// Parse a floating point value into APFloat from the stream.
747  virtual ParseResult parseFloat(const llvm::fltSemantics &semantics,
748  APFloat &result) = 0;
749 
750  /// Parse an integer value from the stream.
751  template <typename IntT>
752  ParseResult parseInteger(IntT &result) {
753  auto loc = getCurrentLocation();
754  OptionalParseResult parseResult = parseOptionalInteger(result);
755  if (!parseResult.has_value())
756  return emitError(loc, "expected integer value");
757  return *parseResult;
758  }
759 
760  /// Parse a decimal integer value from the stream.
761  template <typename IntT>
762  ParseResult parseDecimalInteger(IntT &result) {
763  auto loc = getCurrentLocation();
764  OptionalParseResult parseResult = parseOptionalDecimalInteger(result);
765  if (!parseResult.has_value())
766  return emitError(loc, "expected decimal integer value");
767  return *parseResult;
768  }
769 
770  /// Parse an optional integer value from the stream.
771  virtual OptionalParseResult parseOptionalInteger(APInt &result) = 0;
773 
774 private:
775  template <typename IntT, typename ParseFn>
776  OptionalParseResult parseOptionalIntegerAndCheck(IntT &result,
777  ParseFn &&parseFn) {
778  auto loc = getCurrentLocation();
779  APInt uintResult;
780  OptionalParseResult parseResult = parseFn(uintResult);
781  if (!parseResult.has_value() || failed(*parseResult))
782  return parseResult;
783 
784  // Try to convert to the provided integer type. sextOrTrunc is correct even
785  // for unsigned types because parseOptionalInteger ensures the sign bit is
786  // zero for non-negated integers.
787  result =
788  (IntT)uintResult.sextOrTrunc(sizeof(IntT) * CHAR_BIT).getLimitedValue();
789  if (APInt(uintResult.getBitWidth(), result,
790  /*isSigned=*/std::is_signed_v<IntT>,
791  /*implicitTrunc=*/true) != uintResult)
792  return emitError(loc, "integer value too large");
793  return success();
794  }
795 
796 public:
797  template <typename IntT>
799  return parseOptionalIntegerAndCheck(
800  result, [&](APInt &result) { return parseOptionalInteger(result); });
801  }
802 
803  template <typename IntT>
805  return parseOptionalIntegerAndCheck(result, [&](APInt &result) {
806  return parseOptionalDecimalInteger(result);
807  });
808  }
809 
810  /// These are the supported delimiters around operand lists and region
811  /// argument lists, used by parseOperandList.
812  enum class Delimiter {
813  /// Zero or more operands with no delimiters.
814  None,
815  /// Parens surrounding zero or more operands.
816  Paren,
817  /// Square brackets surrounding zero or more operands.
818  Square,
819  /// <> brackets surrounding zero or more operands.
820  LessGreater,
821  /// {} brackets surrounding zero or more operands.
822  Braces,
823  /// Parens supporting zero or more operands, or nothing.
825  /// Square brackets supporting zero or more ops, or nothing.
827  /// <> brackets supporting zero or more ops, or nothing.
829  /// {} brackets surrounding zero or more operands, or nothing.
831  };
832 
833  /// Parse a list of comma-separated items with an optional delimiter. If a
834  /// delimiter is provided, then an empty list is allowed. If not, then at
835  /// least one element will be parsed.
836  ///
837  /// contextMessage is an optional message appended to "expected '('" sorts of
838  /// diagnostics when parsing the delimeters.
839  virtual ParseResult
841  function_ref<ParseResult()> parseElementFn,
842  StringRef contextMessage = StringRef()) = 0;
843 
844  /// Parse a comma separated list of elements that must have at least one entry
845  /// in it.
846  ParseResult
847  parseCommaSeparatedList(function_ref<ParseResult()> parseElementFn) {
848  return parseCommaSeparatedList(Delimiter::None, parseElementFn);
849  }
850 
851  //===--------------------------------------------------------------------===//
852  // Keyword Parsing
853  //===--------------------------------------------------------------------===//
854 
855  /// This class represents a StringSwitch like class that is useful for parsing
856  /// expected keywords. On construction, unless a non-empty keyword is
857  /// provided, it invokes `parseKeyword` and processes each of the provided
858  /// cases statements until a match is hit. The provided `ResultT` must be
859  /// assignable from `failure()`.
860  template <typename ResultT = ParseResult>
862  public:
863  KeywordSwitch(AsmParser &parser, StringRef *keyword = nullptr)
864  : parser(parser), loc(parser.getCurrentLocation()) {
865  if (keyword && !keyword->empty())
866  this->keyword = *keyword;
867  else if (failed(parser.parseKeywordOrCompletion(&this->keyword)))
868  result = failure();
869  }
870  /// Case that uses the provided value when true.
871  KeywordSwitch &Case(StringLiteral str, ResultT value) {
872  return Case(str, [&](StringRef, SMLoc) { return std::move(value); });
873  }
874  KeywordSwitch &Default(ResultT value) {
875  return Default([&](StringRef, SMLoc) { return std::move(value); });
876  }
877  /// Case that invokes the provided functor when true. The parameters passed
878  /// to the functor are the keyword, and the location of the keyword (in case
879  /// any errors need to be emitted).
880  template <typename FnT>
881  std::enable_if_t<!std::is_convertible<FnT, ResultT>::value, KeywordSwitch &>
882  Case(StringLiteral str, FnT &&fn) {
883  if (result)
884  return *this;
885 
886  // If the word was empty, record this as a completion.
887  if (keyword.empty())
888  parser.codeCompleteExpectedTokens(str);
889  else if (keyword == str)
890  result.emplace(std::move(fn(keyword, loc)));
891  return *this;
892  }
893  template <typename FnT>
894  std::enable_if_t<!std::is_convertible<FnT, ResultT>::value, KeywordSwitch &>
895  Default(FnT &&fn) {
896  if (!result)
897  result.emplace(fn(keyword, loc));
898  return *this;
899  }
900 
901  /// Returns true if this switch has a value yet.
902  bool hasValue() const { return result.has_value(); }
903 
904  /// Return the result of the switch.
905  [[nodiscard]] operator ResultT() {
906  if (!result)
907  return parser.emitError(loc, "unexpected keyword: ") << keyword;
908  return std::move(*result);
909  }
910 
911  private:
912  /// The parser used to construct this switch.
913  AsmParser &parser;
914 
915  /// The location of the keyword, used to emit errors as necessary.
916  SMLoc loc;
917 
918  /// The parsed keyword itself.
919  StringRef keyword;
920 
921  /// The result of the switch statement or std::nullopt if currently unknown.
922  std::optional<ResultT> result;
923  };
924 
925  /// Parse a given keyword.
926  ParseResult parseKeyword(StringRef keyword) {
927  return parseKeyword(keyword, "");
928  }
929  virtual ParseResult parseKeyword(StringRef keyword, const Twine &msg) = 0;
930 
931  /// Parse a keyword into 'keyword'.
932  ParseResult parseKeyword(StringRef *keyword) {
933  auto loc = getCurrentLocation();
934  if (parseOptionalKeyword(keyword))
935  return emitError(loc, "expected valid keyword");
936  return success();
937  }
938 
939  /// Parse the given keyword if present.
940  virtual ParseResult parseOptionalKeyword(StringRef keyword) = 0;
941 
942  /// Parse a keyword, if present, into 'keyword'.
943  virtual ParseResult parseOptionalKeyword(StringRef *keyword) = 0;
944 
945  /// Parse a keyword, if present, and if one of the 'allowedValues',
946  /// into 'keyword'
947  virtual ParseResult
948  parseOptionalKeyword(StringRef *keyword,
949  ArrayRef<StringRef> allowedValues) = 0;
950 
951  /// Parse a keyword or a quoted string.
952  ParseResult parseKeywordOrString(std::string *result) {
953  if (failed(parseOptionalKeywordOrString(result)))
954  return emitError(getCurrentLocation())
955  << "expected valid keyword or string";
956  return success();
957  }
958 
959  /// Parse an optional keyword or string.
960  virtual ParseResult parseOptionalKeywordOrString(std::string *result) = 0;
961 
962  //===--------------------------------------------------------------------===//
963  // Attribute/Type Parsing
964  //===--------------------------------------------------------------------===//
965 
966  /// Invoke the `getChecked` method of the given Attribute or Type class, using
967  /// the provided location to emit errors in the case of failure. Note that
968  /// unlike `OpBuilder::getType`, this method does not implicitly insert a
969  /// context parameter.
970  template <typename T, typename... ParamsT>
971  auto getChecked(SMLoc loc, ParamsT &&...params) {
972  return T::getChecked([&] { return emitError(loc); },
973  std::forward<ParamsT>(params)...);
974  }
975  /// A variant of `getChecked` that uses the result of `getNameLoc` to emit
976  /// errors.
977  template <typename T, typename... ParamsT>
978  auto getChecked(ParamsT &&...params) {
979  return T::getChecked([&] { return emitError(getNameLoc()); },
980  std::forward<ParamsT>(params)...);
981  }
982 
983  //===--------------------------------------------------------------------===//
984  // Attribute Parsing
985  //===--------------------------------------------------------------------===//
986 
987  /// Parse an arbitrary attribute of a given type and return it in result.
988  virtual ParseResult parseAttribute(Attribute &result, Type type = {}) = 0;
989 
990  /// Parse a custom attribute with the provided callback, unless the next
991  /// token is `#`, in which case the generic parser is invoked.
992  virtual ParseResult parseCustomAttributeWithFallback(
993  Attribute &result, Type type,
994  function_ref<ParseResult(Attribute &result, Type type)>
995  parseAttribute) = 0;
996 
997  /// Parse an attribute of a specific kind and type.
998  template <typename AttrType>
999  ParseResult parseAttribute(AttrType &result, Type type = {}) {
1000  SMLoc loc = getCurrentLocation();
1001 
1002  // Parse any kind of attribute.
1003  Attribute attr;
1004  if (parseAttribute(attr, type))
1005  return failure();
1006 
1007  // Check for the right kind of attribute.
1008  if (!(result = llvm::dyn_cast<AttrType>(attr)))
1009  return emitError(loc, "invalid kind of attribute specified");
1010 
1011  return success();
1012  }
1013 
1014  /// Parse an arbitrary attribute and return it in result. This also adds the
1015  /// attribute to the specified attribute list with the specified name.
1016  ParseResult parseAttribute(Attribute &result, StringRef attrName,
1017  NamedAttrList &attrs) {
1018  return parseAttribute(result, Type(), attrName, attrs);
1019  }
1020 
1021  /// Parse an attribute of a specific kind and type.
1022  template <typename AttrType>
1023  ParseResult parseAttribute(AttrType &result, StringRef attrName,
1024  NamedAttrList &attrs) {
1025  return parseAttribute(result, Type(), attrName, attrs);
1026  }
1027 
1028  /// Parse an arbitrary attribute of a given type and populate it in `result`.
1029  /// This also adds the attribute to the specified attribute list with the
1030  /// specified name.
1031  template <typename AttrType>
1032  ParseResult parseAttribute(AttrType &result, Type type, StringRef attrName,
1033  NamedAttrList &attrs) {
1034  SMLoc loc = getCurrentLocation();
1035 
1036  // Parse any kind of attribute.
1037  Attribute attr;
1038  if (parseAttribute(attr, type))
1039  return failure();
1040 
1041  // Check for the right kind of attribute.
1042  result = llvm::dyn_cast<AttrType>(attr);
1043  if (!result)
1044  return emitError(loc, "invalid kind of attribute specified");
1045 
1046  attrs.append(attrName, result);
1047  return success();
1048  }
1049 
1050  /// Trait to check if `AttrType` provides a `parse` method.
1051  template <typename AttrType>
1052  using has_parse_method = decltype(AttrType::parse(std::declval<AsmParser &>(),
1053  std::declval<Type>()));
1054  template <typename AttrType>
1055  using detect_has_parse_method = llvm::is_detected<has_parse_method, AttrType>;
1056 
1057  /// Parse a custom attribute of a given type unless the next token is `#`, in
1058  /// which case the generic parser is invoked. The parsed attribute is
1059  /// populated in `result` and also added to the specified attribute list with
1060  /// the specified name.
1061  template <typename AttrType>
1062  std::enable_if_t<detect_has_parse_method<AttrType>::value, ParseResult>
1063  parseCustomAttributeWithFallback(AttrType &result, Type type,
1064  StringRef attrName, NamedAttrList &attrs) {
1065  SMLoc loc = getCurrentLocation();
1066 
1067  // Parse any kind of attribute.
1068  Attribute attr;
1070  attr, type, [&](Attribute &result, Type type) -> ParseResult {
1071  result = AttrType::parse(*this, type);
1072  if (!result)
1073  return failure();
1074  return success();
1075  }))
1076  return failure();
1077 
1078  // Check for the right kind of attribute.
1079  result = llvm::dyn_cast<AttrType>(attr);
1080  if (!result)
1081  return emitError(loc, "invalid kind of attribute specified");
1082 
1083  attrs.append(attrName, result);
1084  return success();
1085  }
1086 
1087  /// SFINAE parsing method for Attribute that don't implement a parse method.
1088  template <typename AttrType>
1089  std::enable_if_t<!detect_has_parse_method<AttrType>::value, ParseResult>
1090  parseCustomAttributeWithFallback(AttrType &result, Type type,
1091  StringRef attrName, NamedAttrList &attrs) {
1092  return parseAttribute(result, type, attrName, attrs);
1093  }
1094 
1095  /// Parse a custom attribute of a given type unless the next token is `#`, in
1096  /// which case the generic parser is invoked. The parsed attribute is
1097  /// populated in `result`.
1098  template <typename AttrType>
1099  std::enable_if_t<detect_has_parse_method<AttrType>::value, ParseResult>
1100  parseCustomAttributeWithFallback(AttrType &result, Type type = {}) {
1101  SMLoc loc = getCurrentLocation();
1102 
1103  // Parse any kind of attribute.
1104  Attribute attr;
1106  attr, type, [&](Attribute &result, Type type) -> ParseResult {
1107  result = AttrType::parse(*this, type);
1108  return success(!!result);
1109  }))
1110  return failure();
1111 
1112  // Check for the right kind of attribute.
1113  result = llvm::dyn_cast<AttrType>(attr);
1114  if (!result)
1115  return emitError(loc, "invalid kind of attribute specified");
1116  return success();
1117  }
1118 
1119  /// SFINAE parsing method for Attribute that don't implement a parse method.
1120  template <typename AttrType>
1121  std::enable_if_t<!detect_has_parse_method<AttrType>::value, ParseResult>
1122  parseCustomAttributeWithFallback(AttrType &result, Type type = {}) {
1123  return parseAttribute(result, type);
1124  }
1125 
1126  /// Parse an arbitrary optional attribute of a given type and return it in
1127  /// result.
1129  Type type = {}) = 0;
1130 
1131  /// Parse an optional array attribute and return it in result.
1132  virtual OptionalParseResult parseOptionalAttribute(ArrayAttr &result,
1133  Type type = {}) = 0;
1134 
1135  /// Parse an optional string attribute and return it in result.
1136  virtual OptionalParseResult parseOptionalAttribute(StringAttr &result,
1137  Type type = {}) = 0;
1138 
1139  /// Parse an optional symbol ref attribute and return it in result.
1140  virtual OptionalParseResult parseOptionalAttribute(SymbolRefAttr &result,
1141  Type type = {}) = 0;
1142 
1143  /// Parse an optional attribute of a specific type and add it to the list with
1144  /// the specified name.
1145  template <typename AttrType>
1147  StringRef attrName,
1148  NamedAttrList &attrs) {
1149  return parseOptionalAttribute(result, Type(), attrName, attrs);
1150  }
1151 
1152  /// Parse an optional attribute of a specific type and add it to the list with
1153  /// the specified name.
1154  template <typename AttrType>
1156  StringRef attrName,
1157  NamedAttrList &attrs) {
1158  OptionalParseResult parseResult = parseOptionalAttribute(result, type);
1159  if (parseResult.has_value() && succeeded(*parseResult))
1160  attrs.append(attrName, result);
1161  return parseResult;
1162  }
1163 
1164  /// Parse a named dictionary into 'result' if it is present.
1165  virtual ParseResult parseOptionalAttrDict(NamedAttrList &result) = 0;
1166 
1167  /// Parse a named dictionary into 'result' if the `attributes` keyword is
1168  /// present.
1169  virtual ParseResult
1171 
1172  /// Parse an affine map instance into 'map'.
1173  virtual ParseResult parseAffineMap(AffineMap &map) = 0;
1174 
1175  /// Parse an affine expr instance into 'expr' using the already computed
1176  /// mapping from symbols to affine expressions in 'symbolSet'.
1177  virtual ParseResult
1178  parseAffineExpr(ArrayRef<std::pair<StringRef, AffineExpr>> symbolSet,
1179  AffineExpr &expr) = 0;
1180 
1181  /// Parse an integer set instance into 'set'.
1182  virtual ParseResult parseIntegerSet(IntegerSet &set) = 0;
1183 
1184  //===--------------------------------------------------------------------===//
1185  // Identifier Parsing
1186  //===--------------------------------------------------------------------===//
1187 
1188  /// Parse an @-identifier and store it (without the '@' symbol) in a string
1189  /// attribute.
1190  ParseResult parseSymbolName(StringAttr &result) {
1191  if (failed(parseOptionalSymbolName(result)))
1192  return emitError(getCurrentLocation())
1193  << "expected valid '@'-identifier for symbol name";
1194  return success();
1195  }
1196 
1197  /// Parse an @-identifier and store it (without the '@' symbol) in a string
1198  /// attribute named 'attrName'.
1199  ParseResult parseSymbolName(StringAttr &result, StringRef attrName,
1200  NamedAttrList &attrs) {
1201  if (parseSymbolName(result))
1202  return failure();
1203  attrs.append(attrName, result);
1204  return success();
1205  }
1206 
1207  /// Parse an optional @-identifier and store it (without the '@' symbol) in a
1208  /// string attribute.
1209  virtual ParseResult parseOptionalSymbolName(StringAttr &result) = 0;
1210 
1211  /// Parse an optional @-identifier and store it (without the '@' symbol) in a
1212  /// string attribute named 'attrName'.
1213  ParseResult parseOptionalSymbolName(StringAttr &result, StringRef attrName,
1214  NamedAttrList &attrs) {
1215  if (succeeded(parseOptionalSymbolName(result))) {
1216  attrs.append(attrName, result);
1217  return success();
1218  }
1219  return failure();
1220  }
1221 
1222  //===--------------------------------------------------------------------===//
1223  // Resource Parsing
1224  //===--------------------------------------------------------------------===//
1225 
1226  /// Parse a handle to a resource within the assembly format.
1227  template <typename ResourceT>
1228  FailureOr<ResourceT> parseResourceHandle() {
1229  SMLoc handleLoc = getCurrentLocation();
1230 
1231  // Try to load the dialect that owns the handle.
1232  auto *dialect =
1233  getContext()->getOrLoadDialect<typename ResourceT::Dialect>();
1234  if (!dialect) {
1235  return emitError(handleLoc)
1236  << "dialect '" << ResourceT::Dialect::getDialectNamespace()
1237  << "' is unknown";
1238  }
1239 
1240  FailureOr<AsmDialectResourceHandle> handle = parseResourceHandle(dialect);
1241  if (failed(handle))
1242  return failure();
1243  if (auto *result = dyn_cast<ResourceT>(&*handle))
1244  return std::move(*result);
1245  return emitError(handleLoc) << "provided resource handle differs from the "
1246  "expected resource type";
1247  }
1248 
1249  //===--------------------------------------------------------------------===//
1250  // Type Parsing
1251  //===--------------------------------------------------------------------===//
1252 
1253  /// Parse a type.
1254  virtual ParseResult parseType(Type &result) = 0;
1255 
1256  /// Parse a custom type with the provided callback, unless the next
1257  /// token is `#`, in which case the generic parser is invoked.
1258  virtual ParseResult parseCustomTypeWithFallback(
1259  Type &result, function_ref<ParseResult(Type &result)> parseType) = 0;
1260 
1261  /// Parse an optional type.
1263 
1264  /// Parse a type of a specific type.
1265  template <typename TypeT>
1266  ParseResult parseType(TypeT &result) {
1267  SMLoc loc = getCurrentLocation();
1268 
1269  // Parse any kind of type.
1270  Type type;
1271  if (parseType(type))
1272  return failure();
1273 
1274  // Check for the right kind of type.
1275  result = llvm::dyn_cast<TypeT>(type);
1276  if (!result) {
1278  emitError(loc, "invalid kind of type specified");
1279  if constexpr (HasStaticName<TypeT>::value)
1280  diag << ": expected " << TypeT::name << ", but found " << type;
1281  return diag;
1282  }
1283 
1284  return success();
1285  }
1286 
1287  /// Trait to check if `TypeT` provides a `parse` method.
1288  template <typename TypeT>
1290  decltype(TypeT::parse(std::declval<AsmParser &>()));
1291  template <typename TypeT>
1293  llvm::is_detected<type_has_parse_method, TypeT>;
1294 
1295  /// Parse a custom Type of a given type unless the next token is `#`, in
1296  /// which case the generic parser is invoked. The parsed Type is
1297  /// populated in `result`.
1298  template <typename TypeT>
1299  std::enable_if_t<detect_type_has_parse_method<TypeT>::value, ParseResult>
1301  SMLoc loc = getCurrentLocation();
1302 
1303  // Parse any kind of Type.
1304  Type type;
1305  if (parseCustomTypeWithFallback(type, [&](Type &result) -> ParseResult {
1306  result = TypeT::parse(*this);
1307  return success(!!result);
1308  }))
1309  return failure();
1310 
1311  // Check for the right kind of Type.
1312  result = llvm::dyn_cast<TypeT>(type);
1313  if (!result) {
1315  emitError(loc, "invalid kind of type specified");
1316  if constexpr (HasStaticName<TypeT>::value)
1317  diag << ": expected " << TypeT::name << ", but found " << type;
1318  return diag;
1319  }
1320  return success();
1321  }
1322 
1323  /// SFINAE parsing method for Type that don't implement a parse method.
1324  template <typename TypeT>
1325  std::enable_if_t<!detect_type_has_parse_method<TypeT>::value, ParseResult>
1327  return parseType(result);
1328  }
1329 
1330  /// Parse a type list.
1331  ParseResult parseTypeList(SmallVectorImpl<Type> &result);
1332 
1333  /// Parse an arrow followed by a type list.
1334  virtual ParseResult parseArrowTypeList(SmallVectorImpl<Type> &result) = 0;
1335 
1336  /// Parse an optional arrow followed by a type list.
1337  virtual ParseResult
1339 
1340  /// Parse a colon followed by a type.
1341  virtual ParseResult parseColonType(Type &result) = 0;
1342 
1343  /// Parse a colon followed by a type of a specific kind, e.g. a FunctionType.
1344  template <typename TypeType>
1345  ParseResult parseColonType(TypeType &result) {
1346  SMLoc loc = getCurrentLocation();
1347 
1348  // Parse any kind of type.
1349  Type type;
1350  if (parseColonType(type))
1351  return failure();
1352 
1353  // Check for the right kind of type.
1354  result = llvm::dyn_cast<TypeType>(type);
1355  if (!result) {
1357  emitError(loc, "invalid kind of type specified");
1358  if constexpr (HasStaticName<TypeType>::value)
1359  diag << ": expected " << TypeType::name << ", but found " << type;
1360  return diag;
1361  }
1362 
1363  return success();
1364  }
1365 
1366  /// Parse a colon followed by a type list, which must have at least one type.
1367  virtual ParseResult parseColonTypeList(SmallVectorImpl<Type> &result) = 0;
1368 
1369  /// Parse an optional colon followed by a type list, which if present must
1370  /// have at least one type.
1371  virtual ParseResult
1373 
1374  /// Parse a keyword followed by a type.
1375  ParseResult parseKeywordType(const char *keyword, Type &result) {
1376  return failure(parseKeyword(keyword) || parseType(result));
1377  }
1378 
1379  /// Add the specified type to the end of the specified type list and return
1380  /// success. This is a helper designed to allow parse methods to be simple
1381  /// and chain through || operators.
1382  ParseResult addTypeToList(Type type, SmallVectorImpl<Type> &result) {
1383  result.push_back(type);
1384  return success();
1385  }
1386 
1387  /// Add the specified types to the end of the specified type list and return
1388  /// success. This is a helper designed to allow parse methods to be simple
1389  /// and chain through || operators.
1390  ParseResult addTypesToList(ArrayRef<Type> types,
1391  SmallVectorImpl<Type> &result) {
1392  result.append(types.begin(), types.end());
1393  return success();
1394  }
1395 
1396  /// Parse a dimension list of a tensor or memref type. This populates the
1397  /// dimension list, using ShapedType::kDynamic for the `?` dimensions if
1398  /// `allowDynamic` is set and errors out on `?` otherwise. Parsing the
1399  /// trailing `x` is configurable.
1400  ///
1401  /// dimension-list ::= eps | dimension (`x` dimension)*
1402  /// dimension-list-with-trailing-x ::= (dimension `x`)*
1403  /// dimension ::= `?` | decimal-literal
1404  ///
1405  /// When `allowDynamic` is not set, this is used to parse:
1406  ///
1407  /// static-dimension-list ::= eps | decimal-literal (`x` decimal-literal)*
1408  /// static-dimension-list-with-trailing-x ::= (dimension `x`)*
1409  virtual ParseResult parseDimensionList(SmallVectorImpl<int64_t> &dimensions,
1410  bool allowDynamic = true,
1411  bool withTrailingX = true) = 0;
1412 
1413  /// Parse an 'x' token in a dimension list, handling the case where the x is
1414  /// juxtaposed with an element type, as in "xf32", leaving the "f32" as the
1415  /// next token.
1416  virtual ParseResult parseXInDimensionList() = 0;
1417 
1418  /// Class used to automatically end a cyclic region on destruction.
1420  public:
1421  explicit CyclicParseReset(AsmParser *parser) : parser(parser) {}
1422 
1424  if (parser)
1425  parser->popCyclicParsing();
1426  }
1427 
1431  : parser(std::exchange(rhs.parser, nullptr)) {}
1433  parser = std::exchange(rhs.parser, nullptr);
1434  return *this;
1435  }
1436 
1437  private:
1438  AsmParser *parser;
1439  };
1440 
1441  /// Attempts to start a cyclic parsing region for `attrOrType`.
1442  /// A cyclic parsing region starts with this call and ends with the
1443  /// destruction of the returned `CyclicParseReset`. During this time,
1444  /// calling `tryStartCyclicParse` with the same attribute in any parser
1445  /// will lead to returning failure.
1446  ///
1447  /// This makes it possible to parse cyclic attributes or types by parsing a
1448  /// short from if nested within itself.
1449  template <class AttrOrTypeT>
1450  FailureOr<CyclicParseReset> tryStartCyclicParse(AttrOrTypeT attrOrType) {
1451  static_assert(
1452  std::is_base_of_v<AttributeTrait::IsMutable<AttrOrTypeT>,
1453  AttrOrTypeT> ||
1454  std::is_base_of_v<TypeTrait::IsMutable<AttrOrTypeT>, AttrOrTypeT>,
1455  "Only mutable attributes or types can be cyclic");
1456  if (failed(pushCyclicParsing(attrOrType.getAsOpaquePointer())))
1457  return failure();
1458 
1459  return CyclicParseReset(this);
1460  }
1461 
1462 protected:
1463  /// Parse a handle to a resource within the assembly format for the given
1464  /// dialect.
1465  virtual FailureOr<AsmDialectResourceHandle>
1467 
1468  /// Pushes a new attribute or type in the form of a type erased pointer
1469  /// into an internal set.
1470  /// Returns success if the type or attribute was inserted in the set or
1471  /// failure if it was already contained.
1472  virtual LogicalResult pushCyclicParsing(const void *opaquePointer) = 0;
1473 
1474  /// Removes the element that was last inserted with a successful call to
1475  /// `pushCyclicParsing`. There must be exactly one `popCyclicParsing` call
1476  /// in reverse order of all successful `pushCyclicParsing`.
1477  virtual void popCyclicParsing() = 0;
1478 
1479  //===--------------------------------------------------------------------===//
1480  // Code Completion
1481  //===--------------------------------------------------------------------===//
1482 
1483  /// Parse a keyword, or an empty string if the current location signals a code
1484  /// completion.
1485  virtual ParseResult parseKeywordOrCompletion(StringRef *keyword) = 0;
1486 
1487  /// Signal the code completion of a set of expected tokens.
1489 
1490 private:
1491  AsmParser(const AsmParser &) = delete;
1492  void operator=(const AsmParser &) = delete;
1493 };
1494 
1495 //===----------------------------------------------------------------------===//
1496 // OpAsmParser
1497 //===----------------------------------------------------------------------===//
1498 
1499 /// The OpAsmParser has methods for interacting with the asm parser: parsing
1500 /// things from it, emitting errors etc. It has an intentionally high-level API
1501 /// that is designed to reduce/constrain syntax innovation in individual
1502 /// operations.
1503 ///
1504 /// For example, consider an op like this:
1505 ///
1506 /// %x = load %p[%1, %2] : memref<...>
1507 ///
1508 /// The "%x = load" tokens are already parsed and therefore invisible to the
1509 /// custom op parser. This can be supported by calling `parseOperandList` to
1510 /// parse the %p, then calling `parseOperandList` with a `SquareDelimiter` to
1511 /// parse the indices, then calling `parseColonTypeList` to parse the result
1512 /// type.
1513 ///
1514 class OpAsmParser : public AsmParser {
1515 public:
1516  using AsmParser::AsmParser;
1517  ~OpAsmParser() override;
1518 
1519  /// Parse a loc(...) specifier if present, filling in result if so.
1520  /// Location for BlockArgument and Operation may be deferred with an alias, in
1521  /// which case an OpaqueLoc is set and will be resolved when parsing
1522  /// completes.
1523  virtual ParseResult
1524  parseOptionalLocationSpecifier(std::optional<Location> &result) = 0;
1525 
1526  /// Return the name of the specified result in the specified syntax, as well
1527  /// as the sub-element in the name. It returns an empty string and ~0U for
1528  /// invalid result numbers. For example, in this operation:
1529  ///
1530  /// %x, %y:2, %z = foo.op
1531  ///
1532  /// getResultName(0) == {"x", 0 }
1533  /// getResultName(1) == {"y", 0 }
1534  /// getResultName(2) == {"y", 1 }
1535  /// getResultName(3) == {"z", 0 }
1536  /// getResultName(4) == {"", ~0U }
1537  virtual std::pair<StringRef, unsigned>
1538  getResultName(unsigned resultNo) const = 0;
1539 
1540  /// Return the number of declared SSA results. This returns 4 for the foo.op
1541  /// example in the comment for `getResultName`.
1542  virtual size_t getNumResults() const = 0;
1543 
1544  // These methods emit an error and return failure or success. This allows
1545  // these to be chained together into a linear sequence of || expressions in
1546  // many cases.
1547 
1548  /// Parse an operation in its generic form.
1549  /// The parsed operation is parsed in the current context and inserted in the
1550  /// provided block and insertion point. The results produced by this operation
1551  /// aren't mapped to any named value in the parser. Returns nullptr on
1552  /// failure.
1553  virtual Operation *parseGenericOperation(Block *insertBlock,
1554  Block::iterator insertPt) = 0;
1555 
1556  /// Parse the name of an operation, in the custom form. On success, return a
1557  /// an object of type 'OperationName'. Otherwise, failure is returned.
1558  virtual FailureOr<OperationName> parseCustomOperationName() = 0;
1559 
1560  //===--------------------------------------------------------------------===//
1561  // Operand Parsing
1562  //===--------------------------------------------------------------------===//
1563 
1564  /// This is the representation of an operand reference.
1566  SMLoc location; // Location of the token.
1567  StringRef name; // Value name, e.g. %42 or %abc
1568  unsigned number; // Number, e.g. 12 for an operand like %xyz#12
1569  };
1570 
1571  /// Parse different components, viz., use-info of operand(s), successor(s),
1572  /// region(s), attribute(s) and function-type, of the generic form of an
1573  /// operation instance and populate the input operation-state 'result' with
1574  /// those components. If any of the components is explicitly provided, then
1575  /// skip parsing that component.
1577  OperationState &result,
1578  std::optional<ArrayRef<UnresolvedOperand>> parsedOperandType =
1579  std::nullopt,
1580  std::optional<ArrayRef<Block *>> parsedSuccessors = std::nullopt,
1581  std::optional<MutableArrayRef<std::unique_ptr<Region>>> parsedRegions =
1582  std::nullopt,
1583  std::optional<ArrayRef<NamedAttribute>> parsedAttributes = std::nullopt,
1584  std::optional<Attribute> parsedPropertiesAttribute = std::nullopt,
1585  std::optional<FunctionType> parsedFnType = std::nullopt) = 0;
1586 
1587  /// Parse a single SSA value operand name along with a result number if
1588  /// `allowResultNumber` is true.
1589  virtual ParseResult parseOperand(UnresolvedOperand &result,
1590  bool allowResultNumber = true) = 0;
1591 
1592  /// Parse a single operand if present.
1593  virtual OptionalParseResult
1595  bool allowResultNumber = true) = 0;
1596 
1597  /// Parse zero or more SSA comma-separated operand references with a specified
1598  /// surrounding delimiter, and an optional required operand count.
1599  virtual ParseResult
1601  Delimiter delimiter = Delimiter::None,
1602  bool allowResultNumber = true,
1603  int requiredOperandCount = -1) = 0;
1604 
1605  /// Parse a specified number of comma separated operands.
1607  int requiredOperandCount,
1608  Delimiter delimiter = Delimiter::None) {
1609  return parseOperandList(result, delimiter,
1610  /*allowResultNumber=*/true, requiredOperandCount);
1611  }
1612 
1613  /// Parse zero or more trailing SSA comma-separated trailing operand
1614  /// references with a specified surrounding delimiter, and an optional
1615  /// required operand count. A leading comma is expected before the
1616  /// operands.
1617  ParseResult
1619  Delimiter delimiter = Delimiter::None) {
1620  if (failed(parseOptionalComma()))
1621  return success(); // The comma is optional.
1622  return parseOperandList(result, delimiter);
1623  }
1624 
1625  /// Resolve an operand to an SSA value, emitting an error on failure.
1626  virtual ParseResult resolveOperand(const UnresolvedOperand &operand,
1627  Type type,
1628  SmallVectorImpl<Value> &result) = 0;
1629 
1630  /// Resolve a list of operands to SSA values, emitting an error on failure, or
1631  /// appending the results to the list on success. This method should be used
1632  /// when all operands have the same type.
1633  template <typename Operands = ArrayRef<UnresolvedOperand>>
1634  ParseResult resolveOperands(Operands &&operands, Type type,
1635  SmallVectorImpl<Value> &result) {
1636  for (const UnresolvedOperand &operand : operands)
1637  if (resolveOperand(operand, type, result))
1638  return failure();
1639  return success();
1640  }
1641  template <typename Operands = ArrayRef<UnresolvedOperand>>
1642  ParseResult resolveOperands(Operands &&operands, Type type, SMLoc loc,
1643  SmallVectorImpl<Value> &result) {
1644  return resolveOperands(std::forward<Operands>(operands), type, result);
1645  }
1646 
1647  /// Resolve a list of operands and a list of operand types to SSA values,
1648  /// emitting an error and returning failure, or appending the results
1649  /// to the list on success.
1650  template <typename Operands = ArrayRef<UnresolvedOperand>,
1651  typename Types = ArrayRef<Type>>
1652  std::enable_if_t<!std::is_convertible<Types, Type>::value, ParseResult>
1653  resolveOperands(Operands &&operands, Types &&types, SMLoc loc,
1654  SmallVectorImpl<Value> &result) {
1655  size_t operandSize = llvm::range_size(operands);
1656  size_t typeSize = llvm::range_size(types);
1657  if (operandSize != typeSize) {
1658  // If no location was provided, report errors at the beginning of the op.
1659  return emitError(loc.isValid() ? loc : getNameLoc())
1660  << "number of operands and types do not match: got " << operandSize
1661  << " operands and " << typeSize << " types";
1662  }
1663 
1664  for (auto [operand, type] : llvm::zip_equal(operands, types))
1665  if (resolveOperand(operand, type, result))
1666  return failure();
1667  return success();
1668  }
1669 
1670  /// Parses an affine map attribute where dims and symbols are SSA operands.
1671  /// Operand values must come from single-result sources, and be valid
1672  /// dimensions/symbol identifiers according to mlir::isValidDim/Symbol.
1673  virtual ParseResult
1675  Attribute &map, StringRef attrName,
1676  NamedAttrList &attrs,
1677  Delimiter delimiter = Delimiter::Square) = 0;
1678 
1679  /// Parses an affine expression where dims and symbols are SSA operands.
1680  /// Operand values must come from single-result sources, and be valid
1681  /// dimensions/symbol identifiers according to mlir::isValidDim/Symbol.
1682  virtual ParseResult
1684  SmallVectorImpl<UnresolvedOperand> &symbOperands,
1685  AffineExpr &expr) = 0;
1686 
1687  //===--------------------------------------------------------------------===//
1688  // Argument Parsing
1689  //===--------------------------------------------------------------------===//
1690 
1691  struct Argument {
1692  UnresolvedOperand ssaName; // SourceLoc, SSA name, result #.
1693  Type type; // Type.
1694  DictionaryAttr attrs; // Attributes if present.
1695  std::optional<Location> sourceLoc; // Source location specifier if present.
1696  };
1697 
1698  /// Parse a single argument with the following syntax:
1699  ///
1700  /// `%ssaName : !type { optionalAttrDict} loc(optionalSourceLoc)`
1701  ///
1702  /// If `allowType` is false or `allowAttrs` are false then the respective
1703  /// parts of the grammar are not parsed.
1704  virtual ParseResult parseArgument(Argument &result, bool allowType = false,
1705  bool allowAttrs = false) = 0;
1706 
1707  /// Parse a single argument if present.
1708  virtual OptionalParseResult
1709  parseOptionalArgument(Argument &result, bool allowType = false,
1710  bool allowAttrs = false) = 0;
1711 
1712  /// Parse zero or more arguments with a specified surrounding delimiter.
1713  virtual ParseResult parseArgumentList(SmallVectorImpl<Argument> &result,
1714  Delimiter delimiter = Delimiter::None,
1715  bool allowType = false,
1716  bool allowAttrs = false) = 0;
1717 
1718  //===--------------------------------------------------------------------===//
1719  // Region Parsing
1720  //===--------------------------------------------------------------------===//
1721 
1722  /// Parses a region. Any parsed blocks are appended to 'region' and must be
1723  /// moved to the op regions after the op is created. The first block of the
1724  /// region takes 'arguments'.
1725  ///
1726  /// If 'enableNameShadowing' is set to true, the argument names are allowed to
1727  /// shadow the names of other existing SSA values defined above the region
1728  /// scope. 'enableNameShadowing' can only be set to true for regions attached
1729  /// to operations that are 'IsolatedFromAbove'.
1730  virtual ParseResult parseRegion(Region &region,
1731  ArrayRef<Argument> arguments = {},
1732  bool enableNameShadowing = false) = 0;
1733 
1734  /// Parses a region if present.
1735  virtual OptionalParseResult
1737  bool enableNameShadowing = false) = 0;
1738 
1739  /// Parses a region if present. If the region is present, a new region is
1740  /// allocated and placed in `region`. If no region is present or on failure,
1741  /// `region` remains untouched.
1742  virtual OptionalParseResult
1743  parseOptionalRegion(std::unique_ptr<Region> &region,
1744  ArrayRef<Argument> arguments = {},
1745  bool enableNameShadowing = false) = 0;
1746 
1747  //===--------------------------------------------------------------------===//
1748  // Successor Parsing
1749  //===--------------------------------------------------------------------===//
1750 
1751  /// Parse a single operation successor.
1752  virtual ParseResult parseSuccessor(Block *&dest) = 0;
1753 
1754  /// Parse an optional operation successor.
1756 
1757  /// Parse a single operation successor and its operand list.
1758  virtual ParseResult
1760 
1761  //===--------------------------------------------------------------------===//
1762  // Type Parsing
1763  //===--------------------------------------------------------------------===//
1764 
1765  /// Parse a list of assignments of the form
1766  /// (%x1 = %y1, %x2 = %y2, ...)
1770  if (!result.has_value())
1771  return emitError(getCurrentLocation(), "expected '('");
1772  return result.value();
1773  }
1774 
1775  virtual OptionalParseResult
1778 };
1779 
1780 //===--------------------------------------------------------------------===//
1781 // Dialect OpAsm interface.
1782 //===--------------------------------------------------------------------===//
1783 
1785  : public DialectInterface::Base<OpAsmDialectInterface> {
1786 public:
1787  OpAsmDialectInterface(Dialect *dialect) : Base(dialect) {}
1788 
1790 
1791  /// Hooks for getting an alias identifier alias for a given symbol, that is
1792  /// not necessarily a part of this dialect. The identifier is used in place of
1793  /// the symbol when printing textual IR. These aliases must not contain `.` or
1794  /// end with a numeric digit([0-9]+).
1795  virtual AliasResult getAlias(Attribute attr, raw_ostream &os) const {
1796  return AliasResult::NoAlias;
1797  }
1798  virtual AliasResult getAlias(Type type, raw_ostream &os) const {
1799  return AliasResult::NoAlias;
1800  }
1801 
1802  //===--------------------------------------------------------------------===//
1803  // Resources
1804  //===--------------------------------------------------------------------===//
1805 
1806  /// Declare a resource with the given key, returning a handle to use for any
1807  /// references of this resource key within the IR during parsing. The result
1808  /// of `getResourceKey` on the returned handle is permitted to be different
1809  /// than `key`.
1810  virtual FailureOr<AsmDialectResourceHandle>
1811  declareResource(StringRef key) const {
1812  return failure();
1813  }
1814 
1815  /// Return a key to use for the given resource. This key should uniquely
1816  /// identify this resource within the dialect.
1817  virtual std::string
1819  llvm_unreachable(
1820  "Dialect must implement `getResourceKey` when defining resources");
1821  }
1822 
1823  /// Hook for parsing resource entries. Returns failure if the entry was not
1824  /// valid, or could otherwise not be processed correctly. Any necessary errors
1825  /// can be emitted via the provided entry.
1826  virtual LogicalResult parseResource(AsmParsedResourceEntry &entry) const;
1827 
1828  /// Hook for building resources to use during printing. The given `op` may be
1829  /// inspected to help determine what information to include.
1830  /// `referencedResources` contains all of the resources detected when printing
1831  /// 'op'.
1832  virtual void
1834  const SetVector<AsmDialectResourceHandle> &referencedResources,
1835  AsmResourceBuilder &builder) const {}
1836 };
1837 
1838 //===--------------------------------------------------------------------===//
1839 // Custom printers and parsers.
1840 //===--------------------------------------------------------------------===//
1841 
1842 // Handles custom<DimensionList>(...) in TableGen.
1843 void printDimensionList(OpAsmPrinter &printer, Operation *op,
1844  ArrayRef<int64_t> dimensions);
1845 ParseResult parseDimensionList(OpAsmParser &parser,
1846  DenseI64ArrayAttr &dimensions);
1847 
1848 } // namespace mlir
1849 
1850 //===--------------------------------------------------------------------===//
1851 // Operation OpAsm interface.
1852 //===--------------------------------------------------------------------===//
1853 
1854 /// The OpAsmOpInterface, see OpAsmInterface.td for more details.
1855 #include "mlir/IR/OpAsmOpInterface.h.inc"
1856 
1857 namespace llvm {
1858 template <>
1859 struct DenseMapInfo<mlir::AsmDialectResourceHandle> {
1863  }
1867  }
1868  static unsigned getHashValue(const mlir::AsmDialectResourceHandle &handle) {
1870  }
1871  static bool isEqual(const mlir::AsmDialectResourceHandle &lhs,
1872  const mlir::AsmDialectResourceHandle &rhs) {
1873  return lhs.getResource() == rhs.getResource();
1874  }
1875 };
1876 } // namespace llvm
1877 
1878 #endif
static std::string diag(const llvm::Value &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:46
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:291
Class used to automatically end a cyclic region on destruction.
CyclicParseReset & operator=(CyclicParseReset &&rhs)
CyclicParseReset & operator=(const CyclicParseReset &)=delete
CyclicParseReset(const CyclicParseReset &)=delete
CyclicParseReset(CyclicParseReset &&rhs)
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)
KeywordSwitch(AsmParser &parser, StringRef *keyword=nullptr)
This base class exposes generic asm parser hooks, usable across the various derived parsers.
virtual ParseResult parseMinus()=0
Parse a '-' token.
llvm::is_detected< has_parse_method, AttrType > detect_has_parse_method
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 parseIntegerSet(IntegerSet &set)=0
Parse an integer set instance into 'set'.
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.
FailureOr< CyclicParseReset > tryStartCyclicParse(AttrOrTypeT attrOrType)
Attempts to start a cyclic parsing region for attrOrType.
virtual ParseResult parseOptionalRBrace()=0
Parse a } token if present.
ParseResult parseDecimalInteger(IntT &result)
Parse a decimal integer value from the stream.
virtual ParseResult parseOptionalMinus()=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 void popCyclicParsing()=0
Removes the element that was last inserted with a successful call to pushCyclicParsing.
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:72
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...
virtual OptionalParseResult parseOptionalDecimalInteger(APInt &result)=0
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 ParseResult parseFloat(const llvm::fltSemantics &semantics, APFloat &result)=0
Parse a floating point value into APFloat from the stream.
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.
virtual ParseResult parseSlash()=0
Parse a '/' token.
std::enable_if_t< detect_has_parse_method< AttrType >::value, ParseResult > parseCustomAttributeWithFallback(AttrType &result, Type type={})
Parse a custom attribute of a given type unless the next token is #, in which case the generic parser...
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.
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 OptionalParseResult parseOptionalAttribute(SymbolRefAttr &result, Type type={})=0
Parse an optional symbol ref attribute and return it in result.
virtual ParseResult parseQuestion()=0
Parse a '?' token.
virtual ParseResult parseOptionalSlash()=0
Parse a '/' token if present.
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.
OptionalParseResult parseOptionalDecimalInteger(IntT &result)
virtual ParseResult parseLParen()=0
Parse a ( token.
virtual ParseResult parseOptionalEllipsis()=0
Parse a ... token if present;.
std::enable_if_t<!detect_has_parse_method< AttrType >::value, ParseResult > parseCustomAttributeWithFallback(AttrType &result, Type type={})
SFINAE parsing method for Attribute that don't implement a parse method.
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 parseAffineExpr(ArrayRef< std::pair< StringRef, AffineExpr >> symbolSet, AffineExpr &expr)=0
Parse an affine expr instance into 'expr' using the already computed mapping from symbols to affine e...
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.
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.
ParseResult parseTypeList(SmallVectorImpl< Type > &result)
Parse a type list.
Definition: AsmPrinter.cpp:77
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 LogicalResult pushCyclicParsing(const void *opaquePointer)=0
Pushes a new attribute or type in the form of a type erased pointer into an internal set.
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
Class used to automatically end a cyclic region on destruction.
CyclicPrintReset & operator=(const CyclicPrintReset &)=delete
CyclicPrintReset(const CyclicPrintReset &)=delete
CyclicPrintReset & operator=(CyclicPrintReset &&rhs)
CyclicPrintReset(CyclicPrintReset &&rhs)
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:...
FailureOr< CyclicPrintReset > tryStartCyclicPrint(AttrOrTypeT attrOrType)
Attempts to start a cyclic printing region for attrOrType.
virtual void printAttributeWithoutType(Attribute attr)
Print the given attribute without its type.
virtual LogicalResult printAlias(Attribute attr)
Print the alias for the given attribute, return failure if no alias could be printed.
virtual void popCyclicPrinting()
Removes the element that was last inserted with a successful call to pushCyclicPrinting.
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 LogicalResult pushCyclicPrinting(const void *opaquePointer)
Pushes a new attribute or type in the form of a type erased pointer into an internal set.
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.
virtual void printString(StringRef string)
Print the given string as a quoted string, escaping any special or non-printable characters in it.
void printOptionalArrowTypeList(TypeRange &&types)
Print an optional arrow followed by a type list.
virtual void printAttribute(Attribute attr)
std::enable_if_t< std::is_integral_v< IntT >, void > printInteger(IntT value)
Print the given integer value.
void printDimensionList(ArrayRef< int64_t > shape)
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.
virtual void printNamedAttribute(NamedAttribute attr)
Print the given named attribute.
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:247
Attributes are known-constant values of operations.
Definition: Attributes.h:25
This class represents an argument of a Block.
Definition: Value.h:309
Block represents an ordered list of Operations.
Definition: Block.h:33
OpListType::iterator iterator
Definition: Block.h:140
This class is a general helper class for creating context-global objects like types,...
Definition: Builders.h:50
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:38
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:314
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:76
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
T * getOrLoadDialect()
Get (or create) a dialect for the given derived dialect type.
Definition: MLIRContext.h:97
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.
NamedAttribute represents a combination of a name and an Attribute value.
Definition: Attributes.h:164
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:132
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.
~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:
virtual ParseResult parseGenericOperationAfterOpName(OperationState &result, std::optional< ArrayRef< UnresolvedOperand >> parsedOperandType=std::nullopt, std::optional< ArrayRef< Block * >> parsedSuccessors=std::nullopt, std::optional< MutableArrayRef< std::unique_ptr< Region >>> parsedRegions=std::nullopt, std::optional< ArrayRef< NamedAttribute >> parsedAttributes=std::nullopt, std::optional< Attribute > parsedPropertiesAttribute=std::nullopt, std::optional< FunctionType > parsedFnType=std::nullopt)=0
Parse different components, viz., use-info of operand(s), successor(s), region(s),...
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.
virtual ParseResult parseOptionalLocationSpecifier(std::optional< Location > &result)=0
Parse a loc(...) specifier if present, filling in result if so.
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 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:94
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 the basic unit of execution within MLIR.
Definition: Operation.h:88
This class implements Optional functionality for ParseResult.
Definition: OpDefinition.h:40
ParseResult value() const
Access the internal ParseResult value.
Definition: OpDefinition.h:53
bool has_value() const
Returns true if we contain a valid ParseResult value.
Definition: OpDefinition.h:50
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:107
This class provides an abstraction over the various different ranges of value types.
Definition: TypeRange.h:37
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:387
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:96
The base class used for all derived interface types.
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:229
QueryRef parse(llvm::StringRef line, const QuerySession &qs)
Definition: Query.cpp:21
Include the generated interface declarations.
ParseResult parseDimensionList(OpAsmParser &parser, DenseI64ArrayAttr &dimensions)
void printDimensionList(OpAsmPrinter &printer, Operation *op, ArrayRef< int64_t > dimensions)
detail::DenseArrayAttrImpl< int64_t > DenseI64ArrayAttr
OpAsmAliasResult
Holds the result of OpAsm{Dialect,Attr,Type}Interface::getAlias hook call.
Definition: OpAsmSupport.h:39
@ NoAlias
The object (type or attribute) is not supported by the hook and an alias was not provided.
llvm::hash_code hash_value(const AsmDialectResourceHandle &param)
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
inline ::llvm::hash_code hash_value(AffineExpr arg)
Make AffineExpr hashable.
Definition: AffineExpr.h:247
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)
std::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.
This trait is used to determine if a storage user, like Type, is mutable or not.