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