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