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