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