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