xref: /llvm-project/mlir/lib/AsmParser/Parser.cpp (revision 4f4e2abb1a5ff1225d32410fd02b732d077aa056)
1 //===- Parser.cpp - MLIR Parser Implementation ----------------------------===//
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 file implements the parser for the MLIR textual form.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "Parser.h"
14 #include "AsmParserImpl.h"
15 #include "mlir/AsmParser/AsmParser.h"
16 #include "mlir/AsmParser/AsmParserState.h"
17 #include "mlir/AsmParser/CodeComplete.h"
18 #include "mlir/IR/AffineExpr.h"
19 #include "mlir/IR/AffineMap.h"
20 #include "mlir/IR/AsmState.h"
21 #include "mlir/IR/Attributes.h"
22 #include "mlir/IR/BuiltinAttributes.h"
23 #include "mlir/IR/BuiltinOps.h"
24 #include "mlir/IR/BuiltinTypes.h"
25 #include "mlir/IR/Diagnostics.h"
26 #include "mlir/IR/Dialect.h"
27 #include "mlir/IR/Location.h"
28 #include "mlir/IR/OpDefinition.h"
29 #include "mlir/IR/OpImplementation.h"
30 #include "mlir/IR/OperationSupport.h"
31 #include "mlir/IR/OwningOpRef.h"
32 #include "mlir/IR/Region.h"
33 #include "mlir/IR/Value.h"
34 #include "mlir/IR/Verifier.h"
35 #include "mlir/IR/Visitors.h"
36 #include "mlir/Support/LLVM.h"
37 #include "mlir/Support/TypeID.h"
38 #include "llvm/ADT/APFloat.h"
39 #include "llvm/ADT/DenseMap.h"
40 #include "llvm/ADT/PointerUnion.h"
41 #include "llvm/ADT/STLExtras.h"
42 #include "llvm/ADT/ScopeExit.h"
43 #include "llvm/ADT/Sequence.h"
44 #include "llvm/ADT/StringExtras.h"
45 #include "llvm/ADT/StringMap.h"
46 #include "llvm/ADT/StringSet.h"
47 #include "llvm/Support/Alignment.h"
48 #include "llvm/Support/Casting.h"
49 #include "llvm/Support/Endian.h"
50 #include "llvm/Support/ErrorHandling.h"
51 #include "llvm/Support/MathExtras.h"
52 #include "llvm/Support/PrettyStackTrace.h"
53 #include "llvm/Support/SourceMgr.h"
54 #include "llvm/Support/raw_ostream.h"
55 #include <algorithm>
56 #include <cassert>
57 #include <cstddef>
58 #include <cstdint>
59 #include <cstring>
60 #include <memory>
61 #include <optional>
62 #include <string>
63 #include <tuple>
64 #include <utility>
65 #include <vector>
66 
67 using namespace mlir;
68 using namespace mlir::detail;
69 
70 //===----------------------------------------------------------------------===//
71 // CodeComplete
72 //===----------------------------------------------------------------------===//
73 
74 AsmParserCodeCompleteContext::~AsmParserCodeCompleteContext() = default;
75 
76 //===----------------------------------------------------------------------===//
77 // Parser
78 //===----------------------------------------------------------------------===//
79 
80 /// Parse a list of comma-separated items with an optional delimiter.  If a
81 /// delimiter is provided, then an empty list is allowed.  If not, then at
82 /// least one element will be parsed.
83 ParseResult
84 Parser::parseCommaSeparatedList(Delimiter delimiter,
85                                 function_ref<ParseResult()> parseElementFn,
86                                 StringRef contextMessage) {
87   switch (delimiter) {
88   case Delimiter::None:
89     break;
90   case Delimiter::OptionalParen:
91     if (getToken().isNot(Token::l_paren))
92       return success();
93     [[fallthrough]];
94   case Delimiter::Paren:
95     if (parseToken(Token::l_paren, "expected '('" + contextMessage))
96       return failure();
97     // Check for empty list.
98     if (consumeIf(Token::r_paren))
99       return success();
100     break;
101   case Delimiter::OptionalLessGreater:
102     // Check for absent list.
103     if (getToken().isNot(Token::less))
104       return success();
105     [[fallthrough]];
106   case Delimiter::LessGreater:
107     if (parseToken(Token::less, "expected '<'" + contextMessage))
108       return success();
109     // Check for empty list.
110     if (consumeIf(Token::greater))
111       return success();
112     break;
113   case Delimiter::OptionalSquare:
114     if (getToken().isNot(Token::l_square))
115       return success();
116     [[fallthrough]];
117   case Delimiter::Square:
118     if (parseToken(Token::l_square, "expected '['" + contextMessage))
119       return failure();
120     // Check for empty list.
121     if (consumeIf(Token::r_square))
122       return success();
123     break;
124   case Delimiter::OptionalBraces:
125     if (getToken().isNot(Token::l_brace))
126       return success();
127     [[fallthrough]];
128   case Delimiter::Braces:
129     if (parseToken(Token::l_brace, "expected '{'" + contextMessage))
130       return failure();
131     // Check for empty list.
132     if (consumeIf(Token::r_brace))
133       return success();
134     break;
135   }
136 
137   // Non-empty case starts with an element.
138   if (parseElementFn())
139     return failure();
140 
141   // Otherwise we have a list of comma separated elements.
142   while (consumeIf(Token::comma)) {
143     if (parseElementFn())
144       return failure();
145   }
146 
147   switch (delimiter) {
148   case Delimiter::None:
149     return success();
150   case Delimiter::OptionalParen:
151   case Delimiter::Paren:
152     return parseToken(Token::r_paren, "expected ')'" + contextMessage);
153   case Delimiter::OptionalLessGreater:
154   case Delimiter::LessGreater:
155     return parseToken(Token::greater, "expected '>'" + contextMessage);
156   case Delimiter::OptionalSquare:
157   case Delimiter::Square:
158     return parseToken(Token::r_square, "expected ']'" + contextMessage);
159   case Delimiter::OptionalBraces:
160   case Delimiter::Braces:
161     return parseToken(Token::r_brace, "expected '}'" + contextMessage);
162   }
163   llvm_unreachable("Unknown delimiter");
164 }
165 
166 /// Parse a comma-separated list of elements, terminated with an arbitrary
167 /// token.  This allows empty lists if allowEmptyList is true.
168 ///
169 ///   abstract-list ::= rightToken                  // if allowEmptyList == true
170 ///   abstract-list ::= element (',' element)* rightToken
171 ///
172 ParseResult
173 Parser::parseCommaSeparatedListUntil(Token::Kind rightToken,
174                                      function_ref<ParseResult()> parseElement,
175                                      bool allowEmptyList) {
176   // Handle the empty case.
177   if (getToken().is(rightToken)) {
178     if (!allowEmptyList)
179       return emitWrongTokenError("expected list element");
180     consumeToken(rightToken);
181     return success();
182   }
183 
184   if (parseCommaSeparatedList(parseElement) ||
185       parseToken(rightToken, "expected ',' or '" +
186                                  Token::getTokenSpelling(rightToken) + "'"))
187     return failure();
188 
189   return success();
190 }
191 
192 InFlightDiagnostic Parser::emitError(const Twine &message) {
193   auto loc = state.curToken.getLoc();
194   if (state.curToken.isNot(Token::eof))
195     return emitError(loc, message);
196 
197   // If the error is to be emitted at EOF, move it back one character.
198   return emitError(SMLoc::getFromPointer(loc.getPointer() - 1), message);
199 }
200 
201 InFlightDiagnostic Parser::emitError(SMLoc loc, const Twine &message) {
202   auto diag = mlir::emitError(getEncodedSourceLocation(loc), message);
203 
204   // If we hit a parse error in response to a lexer error, then the lexer
205   // already reported the error.
206   if (getToken().is(Token::error))
207     diag.abandon();
208   return diag;
209 }
210 
211 /// Emit an error about a "wrong token".  If the current token is at the
212 /// start of a source line, this will apply heuristics to back up and report
213 /// the error at the end of the previous line, which is where the expected
214 /// token is supposed to be.
215 InFlightDiagnostic Parser::emitWrongTokenError(const Twine &message) {
216   auto loc = state.curToken.getLoc();
217 
218   // If the error is to be emitted at EOF, move it back one character.
219   if (state.curToken.is(Token::eof))
220     loc = SMLoc::getFromPointer(loc.getPointer() - 1);
221 
222   // This is the location we were originally asked to report the error at.
223   auto originalLoc = loc;
224 
225   // Determine if the token is at the start of the current line.
226   const char *bufferStart = state.lex.getBufferBegin();
227   const char *curPtr = loc.getPointer();
228 
229   // Use this StringRef to keep track of what we are going to back up through,
230   // it provides nicer string search functions etc.
231   StringRef startOfBuffer(bufferStart, curPtr - bufferStart);
232 
233   // Back up over entirely blank lines.
234   while (true) {
235     // Back up until we see a \n, but don't look past the buffer start.
236     startOfBuffer = startOfBuffer.rtrim(" \t");
237 
238     // For tokens with no preceding source line, just emit at the original
239     // location.
240     if (startOfBuffer.empty())
241       return emitError(originalLoc, message);
242 
243     // If we found something that isn't the end of line, then we're done.
244     if (startOfBuffer.back() != '\n' && startOfBuffer.back() != '\r')
245       return emitError(SMLoc::getFromPointer(startOfBuffer.end()), message);
246 
247     // Drop the \n so we emit the diagnostic at the end of the line.
248     startOfBuffer = startOfBuffer.drop_back();
249 
250     // Check to see if the preceding line has a comment on it.  We assume that a
251     // `//` is the start of a comment, which is mostly correct.
252     // TODO: This will do the wrong thing for // in a string literal.
253     auto prevLine = startOfBuffer;
254     size_t newLineIndex = prevLine.find_last_of("\n\r");
255     if (newLineIndex != StringRef::npos)
256       prevLine = prevLine.drop_front(newLineIndex);
257 
258     // If we find a // in the current line, then emit the diagnostic before it.
259     size_t commentStart = prevLine.find("//");
260     if (commentStart != StringRef::npos)
261       startOfBuffer = startOfBuffer.drop_back(prevLine.size() - commentStart);
262   }
263 }
264 
265 /// Consume the specified token if present and return success.  On failure,
266 /// output a diagnostic and return failure.
267 ParseResult Parser::parseToken(Token::Kind expectedToken,
268                                const Twine &message) {
269   if (consumeIf(expectedToken))
270     return success();
271   return emitWrongTokenError(message);
272 }
273 
274 /// Parse an optional integer value from the stream.
275 OptionalParseResult Parser::parseOptionalInteger(APInt &result) {
276   // Parse `false` and `true` keywords as 0 and 1 respectively.
277   if (consumeIf(Token::kw_false)) {
278     result = false;
279     return success();
280   }
281   if (consumeIf(Token::kw_true)) {
282     result = true;
283     return success();
284   }
285 
286   Token curToken = getToken();
287   if (curToken.isNot(Token::integer, Token::minus))
288     return std::nullopt;
289 
290   bool negative = consumeIf(Token::minus);
291   Token curTok = getToken();
292   if (parseToken(Token::integer, "expected integer value"))
293     return failure();
294 
295   StringRef spelling = curTok.getSpelling();
296   bool isHex = spelling.size() > 1 && spelling[1] == 'x';
297   if (spelling.getAsInteger(isHex ? 0 : 10, result))
298     return emitError(curTok.getLoc(), "integer value too large");
299 
300   // Make sure we have a zero at the top so we return the right signedness.
301   if (result.isNegative())
302     result = result.zext(result.getBitWidth() + 1);
303 
304   // Process the negative sign if present.
305   if (negative)
306     result.negate();
307 
308   return success();
309 }
310 
311 /// Parse an optional integer value only in decimal format from the stream.
312 OptionalParseResult Parser::parseOptionalDecimalInteger(APInt &result) {
313   Token curToken = getToken();
314   if (curToken.isNot(Token::integer, Token::minus)) {
315     return std::nullopt;
316   }
317 
318   bool negative = consumeIf(Token::minus);
319   Token curTok = getToken();
320   if (parseToken(Token::integer, "expected integer value")) {
321     return failure();
322   }
323 
324   StringRef spelling = curTok.getSpelling();
325   // If the integer is in hexadecimal return only the 0. The lexer has already
326   // moved past the entire hexidecimal encoded integer so we reset the lex
327   // pointer to just past the 0 we actualy want to consume.
328   if (spelling[0] == '0' && spelling.size() > 1 &&
329       llvm::toLower(spelling[1]) == 'x') {
330     result = 0;
331     state.lex.resetPointer(spelling.data() + 1);
332     consumeToken();
333     return success();
334   }
335 
336   if (spelling.getAsInteger(10, result))
337     return emitError(curTok.getLoc(), "integer value too large");
338 
339   // Make sure we have a zero at the top so we return the right signedness.
340   if (result.isNegative())
341     result = result.zext(result.getBitWidth() + 1);
342 
343   // Process the negative sign if present.
344   if (negative)
345     result.negate();
346 
347   return success();
348 }
349 
350 ParseResult Parser::parseFloatFromLiteral(std::optional<APFloat> &result,
351                                           const Token &tok, bool isNegative,
352                                           const llvm::fltSemantics &semantics) {
353   // Check for a floating point value.
354   if (tok.is(Token::floatliteral)) {
355     auto val = tok.getFloatingPointValue();
356     if (!val)
357       return emitError(tok.getLoc()) << "floating point value too large";
358 
359     result.emplace(isNegative ? -*val : *val);
360     bool unused;
361     result->convert(semantics, APFloat::rmNearestTiesToEven, &unused);
362     return success();
363   }
364 
365   // Check for a hexadecimal float value.
366   if (tok.is(Token::integer))
367     return parseFloatFromIntegerLiteral(result, tok, isNegative, semantics);
368 
369   return emitError(tok.getLoc()) << "expected floating point literal";
370 }
371 
372 /// Parse a floating point value from an integer literal token.
373 ParseResult
374 Parser::parseFloatFromIntegerLiteral(std::optional<APFloat> &result,
375                                      const Token &tok, bool isNegative,
376                                      const llvm::fltSemantics &semantics) {
377   StringRef spelling = tok.getSpelling();
378   bool isHex = spelling.size() > 1 && spelling[1] == 'x';
379   if (!isHex) {
380     return emitError(tok.getLoc(), "unexpected decimal integer literal for a "
381                                    "floating point value")
382                .attachNote()
383            << "add a trailing dot to make the literal a float";
384   }
385   if (isNegative) {
386     return emitError(tok.getLoc(),
387                      "hexadecimal float literal should not have a "
388                      "leading minus");
389   }
390 
391   APInt intValue;
392   tok.getSpelling().getAsInteger(isHex ? 0 : 10, intValue);
393   auto typeSizeInBits = APFloat::semanticsSizeInBits(semantics);
394   if (intValue.getActiveBits() > typeSizeInBits) {
395     return emitError(tok.getLoc(),
396                      "hexadecimal float constant out of range for type");
397   }
398 
399   APInt truncatedValue(typeSizeInBits, intValue.getNumWords(),
400                        intValue.getRawData());
401   result.emplace(semantics, truncatedValue);
402   return success();
403 }
404 
405 ParseResult Parser::parseOptionalKeyword(StringRef *keyword) {
406   // Check that the current token is a keyword.
407   if (!isCurrentTokenAKeyword())
408     return failure();
409 
410   *keyword = getTokenSpelling();
411   consumeToken();
412   return success();
413 }
414 
415 //===----------------------------------------------------------------------===//
416 // Resource Parsing
417 
418 FailureOr<AsmDialectResourceHandle>
419 Parser::parseResourceHandle(const OpAsmDialectInterface *dialect,
420                             StringRef &name) {
421   assert(dialect && "expected valid dialect interface");
422   SMLoc nameLoc = getToken().getLoc();
423   if (failed(parseOptionalKeyword(&name)))
424     return emitError("expected identifier key for 'resource' entry");
425   auto &resources = getState().symbols.dialectResources;
426 
427   // If this is the first time encountering this handle, ask the dialect to
428   // resolve a reference to this handle. This allows for us to remap the name of
429   // the handle if necessary.
430   std::pair<std::string, AsmDialectResourceHandle> &entry =
431       resources[dialect][name];
432   if (entry.first.empty()) {
433     FailureOr<AsmDialectResourceHandle> result = dialect->declareResource(name);
434     if (failed(result)) {
435       return emitError(nameLoc)
436              << "unknown 'resource' key '" << name << "' for dialect '"
437              << dialect->getDialect()->getNamespace() << "'";
438     }
439     entry.first = dialect->getResourceKey(*result);
440     entry.second = *result;
441   }
442 
443   name = entry.first;
444   return entry.second;
445 }
446 
447 FailureOr<AsmDialectResourceHandle>
448 Parser::parseResourceHandle(Dialect *dialect) {
449   const auto *interface = dyn_cast<OpAsmDialectInterface>(dialect);
450   if (!interface) {
451     return emitError() << "dialect '" << dialect->getNamespace()
452                        << "' does not expect resource handles";
453   }
454   StringRef resourceName;
455   return parseResourceHandle(interface, resourceName);
456 }
457 
458 //===----------------------------------------------------------------------===//
459 // Code Completion
460 
461 ParseResult Parser::codeCompleteDialectName() {
462   state.codeCompleteContext->completeDialectName();
463   return failure();
464 }
465 
466 ParseResult Parser::codeCompleteOperationName(StringRef dialectName) {
467   // Perform some simple validation on the dialect name. This doesn't need to be
468   // extensive, it's more of an optimization (to avoid checking completion
469   // results when we know they will fail).
470   if (dialectName.empty() || dialectName.contains('.'))
471     return failure();
472   state.codeCompleteContext->completeOperationName(dialectName);
473   return failure();
474 }
475 
476 ParseResult Parser::codeCompleteDialectOrElidedOpName(SMLoc loc) {
477   // Check to see if there is anything else on the current line. This check
478   // isn't strictly necessary, but it does avoid unnecessarily triggering
479   // completions for operations and dialects in situations where we don't want
480   // them (e.g. at the end of an operation).
481   auto shouldIgnoreOpCompletion = [&]() {
482     const char *bufBegin = state.lex.getBufferBegin();
483     const char *it = loc.getPointer() - 1;
484     for (; it > bufBegin && *it != '\n'; --it)
485       if (!StringRef(" \t\r").contains(*it))
486         return true;
487     return false;
488   };
489   if (shouldIgnoreOpCompletion())
490     return failure();
491 
492   // The completion here is either for a dialect name, or an operation name
493   // whose dialect prefix was elided. For this we simply invoke both of the
494   // individual completion methods.
495   (void)codeCompleteDialectName();
496   return codeCompleteOperationName(state.defaultDialectStack.back());
497 }
498 
499 ParseResult Parser::codeCompleteStringDialectOrOperationName(StringRef name) {
500   // If the name is empty, this is the start of the string and contains the
501   // dialect.
502   if (name.empty())
503     return codeCompleteDialectName();
504 
505   // Otherwise, we treat this as completing an operation name. The current name
506   // is used as the dialect namespace.
507   if (name.consume_back("."))
508     return codeCompleteOperationName(name);
509   return failure();
510 }
511 
512 ParseResult Parser::codeCompleteExpectedTokens(ArrayRef<StringRef> tokens) {
513   state.codeCompleteContext->completeExpectedTokens(tokens, /*optional=*/false);
514   return failure();
515 }
516 ParseResult Parser::codeCompleteOptionalTokens(ArrayRef<StringRef> tokens) {
517   state.codeCompleteContext->completeExpectedTokens(tokens, /*optional=*/true);
518   return failure();
519 }
520 
521 Attribute Parser::codeCompleteAttribute() {
522   state.codeCompleteContext->completeAttribute(
523       state.symbols.attributeAliasDefinitions);
524   return {};
525 }
526 Type Parser::codeCompleteType() {
527   state.codeCompleteContext->completeType(state.symbols.typeAliasDefinitions);
528   return {};
529 }
530 
531 Attribute
532 Parser::codeCompleteDialectSymbol(const llvm::StringMap<Attribute> &aliases) {
533   state.codeCompleteContext->completeDialectAttributeOrAlias(aliases);
534   return {};
535 }
536 Type Parser::codeCompleteDialectSymbol(const llvm::StringMap<Type> &aliases) {
537   state.codeCompleteContext->completeDialectTypeOrAlias(aliases);
538   return {};
539 }
540 
541 //===----------------------------------------------------------------------===//
542 // OperationParser
543 //===----------------------------------------------------------------------===//
544 
545 namespace {
546 /// This class provides support for parsing operations and regions of
547 /// operations.
548 class OperationParser : public Parser {
549 public:
550   OperationParser(ParserState &state, ModuleOp topLevelOp);
551   ~OperationParser();
552 
553   /// After parsing is finished, this function must be called to see if there
554   /// are any remaining issues.
555   ParseResult finalize();
556 
557   //===--------------------------------------------------------------------===//
558   // SSA Value Handling
559   //===--------------------------------------------------------------------===//
560 
561   using UnresolvedOperand = OpAsmParser::UnresolvedOperand;
562   using Argument = OpAsmParser::Argument;
563 
564   struct DeferredLocInfo {
565     SMLoc loc;
566     StringRef identifier;
567   };
568 
569   /// Push a new SSA name scope to the parser.
570   void pushSSANameScope(bool isIsolated);
571 
572   /// Pop the last SSA name scope from the parser.
573   ParseResult popSSANameScope();
574 
575   /// Register a definition of a value with the symbol table.
576   ParseResult addDefinition(UnresolvedOperand useInfo, Value value);
577 
578   /// Parse an optional list of SSA uses into 'results'.
579   ParseResult
580   parseOptionalSSAUseList(SmallVectorImpl<UnresolvedOperand> &results);
581 
582   /// Parse a single SSA use into 'result'.  If 'allowResultNumber' is true then
583   /// we allow #42 syntax.
584   ParseResult parseSSAUse(UnresolvedOperand &result,
585                           bool allowResultNumber = true);
586 
587   /// Given a reference to an SSA value and its type, return a reference. This
588   /// returns null on failure.
589   Value resolveSSAUse(UnresolvedOperand useInfo, Type type);
590 
591   ParseResult parseSSADefOrUseAndType(
592       function_ref<ParseResult(UnresolvedOperand, Type)> action);
593 
594   ParseResult parseOptionalSSAUseAndTypeList(SmallVectorImpl<Value> &results);
595 
596   /// Return the location of the value identified by its name and number if it
597   /// has been already reference.
598   std::optional<SMLoc> getReferenceLoc(StringRef name, unsigned number) {
599     auto &values = isolatedNameScopes.back().values;
600     if (!values.count(name) || number >= values[name].size())
601       return {};
602     if (values[name][number].value)
603       return values[name][number].loc;
604     return {};
605   }
606 
607   //===--------------------------------------------------------------------===//
608   // Operation Parsing
609   //===--------------------------------------------------------------------===//
610 
611   /// Parse an operation instance.
612   ParseResult parseOperation();
613 
614   /// Parse a single operation successor.
615   ParseResult parseSuccessor(Block *&dest);
616 
617   /// Parse a comma-separated list of operation successors in brackets.
618   ParseResult parseSuccessors(SmallVectorImpl<Block *> &destinations);
619 
620   /// Parse an operation instance that is in the generic form.
621   Operation *parseGenericOperation();
622 
623   /// Parse different components, viz., use-info of operand(s), successor(s),
624   /// region(s), attribute(s) and function-type, of the generic form of an
625   /// operation instance and populate the input operation-state 'result' with
626   /// those components. If any of the components is explicitly provided, then
627   /// skip parsing that component.
628   ParseResult parseGenericOperationAfterOpName(
629       OperationState &result,
630       std::optional<ArrayRef<UnresolvedOperand>> parsedOperandUseInfo =
631           std::nullopt,
632       std::optional<ArrayRef<Block *>> parsedSuccessors = std::nullopt,
633       std::optional<MutableArrayRef<std::unique_ptr<Region>>> parsedRegions =
634           std::nullopt,
635       std::optional<ArrayRef<NamedAttribute>> parsedAttributes = std::nullopt,
636       std::optional<Attribute> propertiesAttribute = std::nullopt,
637       std::optional<FunctionType> parsedFnType = std::nullopt);
638 
639   /// Parse an operation instance that is in the generic form and insert it at
640   /// the provided insertion point.
641   Operation *parseGenericOperation(Block *insertBlock,
642                                    Block::iterator insertPt);
643 
644   /// This type is used to keep track of things that are either an Operation or
645   /// a BlockArgument.  We cannot use Value for this, because not all Operations
646   /// have results.
647   using OpOrArgument = llvm::PointerUnion<Operation *, BlockArgument>;
648 
649   /// Parse an optional trailing location and add it to the specifier Operation
650   /// or `UnresolvedOperand` if present.
651   ///
652   ///   trailing-location ::= (`loc` (`(` location `)` | attribute-alias))?
653   ///
654   ParseResult parseTrailingLocationSpecifier(OpOrArgument opOrArgument);
655 
656   /// Parse a location alias, that is a sequence looking like: #loc42
657   /// The alias may have already be defined or may be defined later, in which
658   /// case an OpaqueLoc is used a placeholder. The caller must ensure that the
659   /// token is actually an alias, which means it must not contain a dot.
660   ParseResult parseLocationAlias(LocationAttr &loc);
661 
662   /// This is the structure of a result specifier in the assembly syntax,
663   /// including the name, number of results, and location.
664   using ResultRecord = std::tuple<StringRef, unsigned, SMLoc>;
665 
666   /// Parse an operation instance that is in the op-defined custom form.
667   /// resultInfo specifies information about the "%name =" specifiers.
668   Operation *parseCustomOperation(ArrayRef<ResultRecord> resultIDs);
669 
670   /// Parse the name of an operation, in the custom form. On success, return a
671   /// an object of type 'OperationName'. Otherwise, failure is returned.
672   FailureOr<OperationName> parseCustomOperationName();
673 
674   //===--------------------------------------------------------------------===//
675   // Region Parsing
676   //===--------------------------------------------------------------------===//
677 
678   /// Parse a region into 'region' with the provided entry block arguments.
679   /// 'isIsolatedNameScope' indicates if the naming scope of this region is
680   /// isolated from those above.
681   ParseResult parseRegion(Region &region, ArrayRef<Argument> entryArguments,
682                           bool isIsolatedNameScope = false);
683 
684   /// Parse a region body into 'region'.
685   ParseResult parseRegionBody(Region &region, SMLoc startLoc,
686                               ArrayRef<Argument> entryArguments,
687                               bool isIsolatedNameScope);
688 
689   //===--------------------------------------------------------------------===//
690   // Block Parsing
691   //===--------------------------------------------------------------------===//
692 
693   /// Parse a new block into 'block'.
694   ParseResult parseBlock(Block *&block);
695 
696   /// Parse a list of operations into 'block'.
697   ParseResult parseBlockBody(Block *block);
698 
699   /// Parse a (possibly empty) list of block arguments.
700   ParseResult parseOptionalBlockArgList(Block *owner);
701 
702   /// Get the block with the specified name, creating it if it doesn't
703   /// already exist.  The location specified is the point of use, which allows
704   /// us to diagnose references to blocks that are not defined precisely.
705   Block *getBlockNamed(StringRef name, SMLoc loc);
706 
707   //===--------------------------------------------------------------------===//
708   // Code Completion
709   //===--------------------------------------------------------------------===//
710 
711   /// The set of various code completion methods. Every completion method
712   /// returns `failure` to stop the parsing process after providing completion
713   /// results.
714 
715   ParseResult codeCompleteSSAUse();
716   ParseResult codeCompleteBlock();
717 
718 private:
719   /// This class represents a definition of a Block.
720   struct BlockDefinition {
721     /// A pointer to the defined Block.
722     Block *block;
723     /// The location that the Block was defined at.
724     SMLoc loc;
725   };
726   /// This class represents a definition of a Value.
727   struct ValueDefinition {
728     /// A pointer to the defined Value.
729     Value value;
730     /// The location that the Value was defined at.
731     SMLoc loc;
732   };
733 
734   /// Returns the info for a block at the current scope for the given name.
735   BlockDefinition &getBlockInfoByName(StringRef name) {
736     return blocksByName.back()[name];
737   }
738 
739   /// Insert a new forward reference to the given block.
740   void insertForwardRef(Block *block, SMLoc loc) {
741     forwardRef.back().try_emplace(block, loc);
742   }
743 
744   /// Erase any forward reference to the given block.
745   bool eraseForwardRef(Block *block) { return forwardRef.back().erase(block); }
746 
747   /// Record that a definition was added at the current scope.
748   void recordDefinition(StringRef def);
749 
750   /// Get the value entry for the given SSA name.
751   SmallVectorImpl<ValueDefinition> &getSSAValueEntry(StringRef name);
752 
753   /// Create a forward reference placeholder value with the given location and
754   /// result type.
755   Value createForwardRefPlaceholder(SMLoc loc, Type type);
756 
757   /// Return true if this is a forward reference.
758   bool isForwardRefPlaceholder(Value value) {
759     return forwardRefPlaceholders.count(value);
760   }
761 
762   /// This struct represents an isolated SSA name scope. This scope may contain
763   /// other nested non-isolated scopes. These scopes are used for operations
764   /// that are known to be isolated to allow for reusing names within their
765   /// regions, even if those names are used above.
766   struct IsolatedSSANameScope {
767     /// Record that a definition was added at the current scope.
768     void recordDefinition(StringRef def) {
769       definitionsPerScope.back().insert(def);
770     }
771 
772     /// Push a nested name scope.
773     void pushSSANameScope() { definitionsPerScope.push_back({}); }
774 
775     /// Pop a nested name scope.
776     void popSSANameScope() {
777       for (auto &def : definitionsPerScope.pop_back_val())
778         values.erase(def.getKey());
779     }
780 
781     /// This keeps track of all of the SSA values we are tracking for each name
782     /// scope, indexed by their name. This has one entry per result number.
783     llvm::StringMap<SmallVector<ValueDefinition, 1>> values;
784 
785     /// This keeps track of all of the values defined by a specific name scope.
786     SmallVector<llvm::StringSet<>, 2> definitionsPerScope;
787   };
788 
789   /// A list of isolated name scopes.
790   SmallVector<IsolatedSSANameScope, 2> isolatedNameScopes;
791 
792   /// This keeps track of the block names as well as the location of the first
793   /// reference for each nested name scope. This is used to diagnose invalid
794   /// block references and memorize them.
795   SmallVector<DenseMap<StringRef, BlockDefinition>, 2> blocksByName;
796   SmallVector<DenseMap<Block *, SMLoc>, 2> forwardRef;
797 
798   /// These are all of the placeholders we've made along with the location of
799   /// their first reference, to allow checking for use of undefined values.
800   DenseMap<Value, SMLoc> forwardRefPlaceholders;
801 
802   /// Deffered locations: when parsing `loc(#loc42)` we add an entry to this
803   /// map. After parsing the definition `#loc42 = ...` we'll patch back users
804   /// of this location.
805   std::vector<DeferredLocInfo> deferredLocsReferences;
806 
807   /// The builder used when creating parsed operation instances.
808   OpBuilder opBuilder;
809 
810   /// The top level operation that holds all of the parsed operations.
811   Operation *topLevelOp;
812 };
813 } // namespace
814 
815 MLIR_DECLARE_EXPLICIT_TYPE_ID(OperationParser::DeferredLocInfo *)
816 MLIR_DEFINE_EXPLICIT_TYPE_ID(OperationParser::DeferredLocInfo *)
817 
818 OperationParser::OperationParser(ParserState &state, ModuleOp topLevelOp)
819     : Parser(state), opBuilder(topLevelOp.getRegion()), topLevelOp(topLevelOp) {
820   // The top level operation starts a new name scope.
821   pushSSANameScope(/*isIsolated=*/true);
822 
823   // If we are populating the parser state, prepare it for parsing.
824   if (state.asmState)
825     state.asmState->initialize(topLevelOp);
826 }
827 
828 OperationParser::~OperationParser() {
829   for (auto &fwd : forwardRefPlaceholders) {
830     // Drop all uses of undefined forward declared reference and destroy
831     // defining operation.
832     fwd.first.dropAllUses();
833     fwd.first.getDefiningOp()->destroy();
834   }
835   for (const auto &scope : forwardRef) {
836     for (const auto &fwd : scope) {
837       // Delete all blocks that were created as forward references but never
838       // included into a region.
839       fwd.first->dropAllUses();
840       delete fwd.first;
841     }
842   }
843 }
844 
845 /// After parsing is finished, this function must be called to see if there are
846 /// any remaining issues.
847 ParseResult OperationParser::finalize() {
848   // Check for any forward references that are left.  If we find any, error
849   // out.
850   if (!forwardRefPlaceholders.empty()) {
851     SmallVector<const char *, 4> errors;
852     // Iteration over the map isn't deterministic, so sort by source location.
853     for (auto entry : forwardRefPlaceholders)
854       errors.push_back(entry.second.getPointer());
855     llvm::array_pod_sort(errors.begin(), errors.end());
856 
857     for (const char *entry : errors) {
858       auto loc = SMLoc::getFromPointer(entry);
859       emitError(loc, "use of undeclared SSA value name");
860     }
861     return failure();
862   }
863 
864   // Resolve the locations of any deferred operations.
865   auto &attributeAliases = state.symbols.attributeAliasDefinitions;
866   auto locID = TypeID::get<DeferredLocInfo *>();
867   auto resolveLocation = [&, this](auto &opOrArgument) -> LogicalResult {
868     auto fwdLoc = dyn_cast<OpaqueLoc>(opOrArgument.getLoc());
869     if (!fwdLoc || fwdLoc.getUnderlyingTypeID() != locID)
870       return success();
871     auto locInfo = deferredLocsReferences[fwdLoc.getUnderlyingLocation()];
872     Attribute attr = attributeAliases.lookup(locInfo.identifier);
873     if (!attr)
874       return this->emitError(locInfo.loc)
875              << "operation location alias was never defined";
876     auto locAttr = dyn_cast<LocationAttr>(attr);
877     if (!locAttr)
878       return this->emitError(locInfo.loc)
879              << "expected location, but found '" << attr << "'";
880     opOrArgument.setLoc(locAttr);
881     return success();
882   };
883 
884   auto walkRes = topLevelOp->walk([&](Operation *op) {
885     if (failed(resolveLocation(*op)))
886       return WalkResult::interrupt();
887     for (Region &region : op->getRegions())
888       for (Block &block : region.getBlocks())
889         for (BlockArgument arg : block.getArguments())
890           if (failed(resolveLocation(arg)))
891             return WalkResult::interrupt();
892     return WalkResult::advance();
893   });
894   if (walkRes.wasInterrupted())
895     return failure();
896 
897   // Pop the top level name scope.
898   if (failed(popSSANameScope()))
899     return failure();
900 
901   // Verify that the parsed operations are valid.
902   if (state.config.shouldVerifyAfterParse() && failed(verify(topLevelOp)))
903     return failure();
904 
905   // If we are populating the parser state, finalize the top-level operation.
906   if (state.asmState)
907     state.asmState->finalize(topLevelOp);
908   return success();
909 }
910 
911 //===----------------------------------------------------------------------===//
912 // SSA Value Handling
913 //===----------------------------------------------------------------------===//
914 
915 void OperationParser::pushSSANameScope(bool isIsolated) {
916   blocksByName.push_back(DenseMap<StringRef, BlockDefinition>());
917   forwardRef.push_back(DenseMap<Block *, SMLoc>());
918 
919   // Push back a new name definition scope.
920   if (isIsolated)
921     isolatedNameScopes.push_back({});
922   isolatedNameScopes.back().pushSSANameScope();
923 }
924 
925 ParseResult OperationParser::popSSANameScope() {
926   auto forwardRefInCurrentScope = forwardRef.pop_back_val();
927 
928   // Verify that all referenced blocks were defined.
929   if (!forwardRefInCurrentScope.empty()) {
930     SmallVector<std::pair<const char *, Block *>, 4> errors;
931     // Iteration over the map isn't deterministic, so sort by source location.
932     for (auto entry : forwardRefInCurrentScope) {
933       errors.push_back({entry.second.getPointer(), entry.first});
934       // Add this block to the top-level region to allow for automatic cleanup.
935       topLevelOp->getRegion(0).push_back(entry.first);
936     }
937     llvm::array_pod_sort(errors.begin(), errors.end());
938 
939     for (auto entry : errors) {
940       auto loc = SMLoc::getFromPointer(entry.first);
941       emitError(loc, "reference to an undefined block");
942     }
943     return failure();
944   }
945 
946   // Pop the next nested namescope. If there is only one internal namescope,
947   // just pop the isolated scope.
948   auto &currentNameScope = isolatedNameScopes.back();
949   if (currentNameScope.definitionsPerScope.size() == 1)
950     isolatedNameScopes.pop_back();
951   else
952     currentNameScope.popSSANameScope();
953 
954   blocksByName.pop_back();
955   return success();
956 }
957 
958 /// Register a definition of a value with the symbol table.
959 ParseResult OperationParser::addDefinition(UnresolvedOperand useInfo,
960                                            Value value) {
961   auto &entries = getSSAValueEntry(useInfo.name);
962 
963   // Make sure there is a slot for this value.
964   if (entries.size() <= useInfo.number)
965     entries.resize(useInfo.number + 1);
966 
967   // If we already have an entry for this, check to see if it was a definition
968   // or a forward reference.
969   if (auto existing = entries[useInfo.number].value) {
970     if (!isForwardRefPlaceholder(existing)) {
971       return emitError(useInfo.location)
972           .append("redefinition of SSA value '", useInfo.name, "'")
973           .attachNote(getEncodedSourceLocation(entries[useInfo.number].loc))
974           .append("previously defined here");
975     }
976 
977     if (existing.getType() != value.getType()) {
978       return emitError(useInfo.location)
979           .append("definition of SSA value '", useInfo.name, "#",
980                   useInfo.number, "' has type ", value.getType())
981           .attachNote(getEncodedSourceLocation(entries[useInfo.number].loc))
982           .append("previously used here with type ", existing.getType());
983     }
984 
985     // If it was a forward reference, update everything that used it to use
986     // the actual definition instead, delete the forward ref, and remove it
987     // from our set of forward references we track.
988     existing.replaceAllUsesWith(value);
989     existing.getDefiningOp()->destroy();
990     forwardRefPlaceholders.erase(existing);
991 
992     // If a definition of the value already exists, replace it in the assembly
993     // state.
994     if (state.asmState)
995       state.asmState->refineDefinition(existing, value);
996   }
997 
998   /// Record this definition for the current scope.
999   entries[useInfo.number] = {value, useInfo.location};
1000   recordDefinition(useInfo.name);
1001   return success();
1002 }
1003 
1004 /// Parse a (possibly empty) list of SSA operands.
1005 ///
1006 ///   ssa-use-list ::= ssa-use (`,` ssa-use)*
1007 ///   ssa-use-list-opt ::= ssa-use-list?
1008 ///
1009 ParseResult OperationParser::parseOptionalSSAUseList(
1010     SmallVectorImpl<UnresolvedOperand> &results) {
1011   if (!getToken().isOrIsCodeCompletionFor(Token::percent_identifier))
1012     return success();
1013   return parseCommaSeparatedList([&]() -> ParseResult {
1014     UnresolvedOperand result;
1015     if (parseSSAUse(result))
1016       return failure();
1017     results.push_back(result);
1018     return success();
1019   });
1020 }
1021 
1022 /// Parse a SSA operand for an operation.
1023 ///
1024 ///   ssa-use ::= ssa-id
1025 ///
1026 ParseResult OperationParser::parseSSAUse(UnresolvedOperand &result,
1027                                          bool allowResultNumber) {
1028   if (getToken().isCodeCompletion())
1029     return codeCompleteSSAUse();
1030 
1031   result.name = getTokenSpelling();
1032   result.number = 0;
1033   result.location = getToken().getLoc();
1034   if (parseToken(Token::percent_identifier, "expected SSA operand"))
1035     return failure();
1036 
1037   // If we have an attribute ID, it is a result number.
1038   if (getToken().is(Token::hash_identifier)) {
1039     if (!allowResultNumber)
1040       return emitError("result number not allowed in argument list");
1041 
1042     if (auto value = getToken().getHashIdentifierNumber())
1043       result.number = *value;
1044     else
1045       return emitError("invalid SSA value result number");
1046     consumeToken(Token::hash_identifier);
1047   }
1048 
1049   return success();
1050 }
1051 
1052 /// Given an unbound reference to an SSA value and its type, return the value
1053 /// it specifies.  This returns null on failure.
1054 Value OperationParser::resolveSSAUse(UnresolvedOperand useInfo, Type type) {
1055   auto &entries = getSSAValueEntry(useInfo.name);
1056 
1057   // Functor used to record the use of the given value if the assembly state
1058   // field is populated.
1059   auto maybeRecordUse = [&](Value value) {
1060     if (state.asmState)
1061       state.asmState->addUses(value, useInfo.location);
1062     return value;
1063   };
1064 
1065   // If we have already seen a value of this name, return it.
1066   if (useInfo.number < entries.size() && entries[useInfo.number].value) {
1067     Value result = entries[useInfo.number].value;
1068     // Check that the type matches the other uses.
1069     if (result.getType() == type)
1070       return maybeRecordUse(result);
1071 
1072     emitError(useInfo.location, "use of value '")
1073         .append(useInfo.name,
1074                 "' expects different type than prior uses: ", type, " vs ",
1075                 result.getType())
1076         .attachNote(getEncodedSourceLocation(entries[useInfo.number].loc))
1077         .append("prior use here");
1078     return nullptr;
1079   }
1080 
1081   // Make sure we have enough slots for this.
1082   if (entries.size() <= useInfo.number)
1083     entries.resize(useInfo.number + 1);
1084 
1085   // If the value has already been defined and this is an overly large result
1086   // number, diagnose that.
1087   if (entries[0].value && !isForwardRefPlaceholder(entries[0].value))
1088     return (emitError(useInfo.location, "reference to invalid result number"),
1089             nullptr);
1090 
1091   // Otherwise, this is a forward reference.  Create a placeholder and remember
1092   // that we did so.
1093   Value result = createForwardRefPlaceholder(useInfo.location, type);
1094   entries[useInfo.number] = {result, useInfo.location};
1095   return maybeRecordUse(result);
1096 }
1097 
1098 /// Parse an SSA use with an associated type.
1099 ///
1100 ///   ssa-use-and-type ::= ssa-use `:` type
1101 ParseResult OperationParser::parseSSADefOrUseAndType(
1102     function_ref<ParseResult(UnresolvedOperand, Type)> action) {
1103   UnresolvedOperand useInfo;
1104   if (parseSSAUse(useInfo) ||
1105       parseToken(Token::colon, "expected ':' and type for SSA operand"))
1106     return failure();
1107 
1108   auto type = parseType();
1109   if (!type)
1110     return failure();
1111 
1112   return action(useInfo, type);
1113 }
1114 
1115 /// Parse a (possibly empty) list of SSA operands, followed by a colon, then
1116 /// followed by a type list.
1117 ///
1118 ///   ssa-use-and-type-list
1119 ///     ::= ssa-use-list ':' type-list-no-parens
1120 ///
1121 ParseResult OperationParser::parseOptionalSSAUseAndTypeList(
1122     SmallVectorImpl<Value> &results) {
1123   SmallVector<UnresolvedOperand, 4> valueIDs;
1124   if (parseOptionalSSAUseList(valueIDs))
1125     return failure();
1126 
1127   // If there were no operands, then there is no colon or type lists.
1128   if (valueIDs.empty())
1129     return success();
1130 
1131   SmallVector<Type, 4> types;
1132   if (parseToken(Token::colon, "expected ':' in operand list") ||
1133       parseTypeListNoParens(types))
1134     return failure();
1135 
1136   if (valueIDs.size() != types.size())
1137     return emitError("expected ")
1138            << valueIDs.size() << " types to match operand list";
1139 
1140   results.reserve(valueIDs.size());
1141   for (unsigned i = 0, e = valueIDs.size(); i != e; ++i) {
1142     if (auto value = resolveSSAUse(valueIDs[i], types[i]))
1143       results.push_back(value);
1144     else
1145       return failure();
1146   }
1147 
1148   return success();
1149 }
1150 
1151 /// Record that a definition was added at the current scope.
1152 void OperationParser::recordDefinition(StringRef def) {
1153   isolatedNameScopes.back().recordDefinition(def);
1154 }
1155 
1156 /// Get the value entry for the given SSA name.
1157 auto OperationParser::getSSAValueEntry(StringRef name)
1158     -> SmallVectorImpl<ValueDefinition> & {
1159   return isolatedNameScopes.back().values[name];
1160 }
1161 
1162 /// Create and remember a new placeholder for a forward reference.
1163 Value OperationParser::createForwardRefPlaceholder(SMLoc loc, Type type) {
1164   // Forward references are always created as operations, because we just need
1165   // something with a def/use chain.
1166   //
1167   // We create these placeholders as having an empty name, which we know
1168   // cannot be created through normal user input, allowing us to distinguish
1169   // them.
1170   auto name = OperationName("builtin.unrealized_conversion_cast", getContext());
1171   auto *op = Operation::create(
1172       getEncodedSourceLocation(loc), name, type, /*operands=*/{},
1173       /*attributes=*/std::nullopt, /*properties=*/nullptr, /*successors=*/{},
1174       /*numRegions=*/0);
1175   forwardRefPlaceholders[op->getResult(0)] = loc;
1176   return op->getResult(0);
1177 }
1178 
1179 //===----------------------------------------------------------------------===//
1180 // Operation Parsing
1181 //===----------------------------------------------------------------------===//
1182 
1183 /// Parse an operation.
1184 ///
1185 ///  operation         ::= op-result-list?
1186 ///                        (generic-operation | custom-operation)
1187 ///                        trailing-location?
1188 ///  generic-operation ::= string-literal `(` ssa-use-list? `)`
1189 ///                        successor-list? (`(` region-list `)`)?
1190 ///                        attribute-dict? `:` function-type
1191 ///  custom-operation  ::= bare-id custom-operation-format
1192 ///  op-result-list    ::= op-result (`,` op-result)* `=`
1193 ///  op-result         ::= ssa-id (`:` integer-literal)
1194 ///
1195 ParseResult OperationParser::parseOperation() {
1196   auto loc = getToken().getLoc();
1197   SmallVector<ResultRecord, 1> resultIDs;
1198   size_t numExpectedResults = 0;
1199   if (getToken().is(Token::percent_identifier)) {
1200     // Parse the group of result ids.
1201     auto parseNextResult = [&]() -> ParseResult {
1202       // Parse the next result id.
1203       Token nameTok = getToken();
1204       if (parseToken(Token::percent_identifier,
1205                      "expected valid ssa identifier"))
1206         return failure();
1207 
1208       // If the next token is a ':', we parse the expected result count.
1209       size_t expectedSubResults = 1;
1210       if (consumeIf(Token::colon)) {
1211         // Check that the next token is an integer.
1212         if (!getToken().is(Token::integer))
1213           return emitWrongTokenError("expected integer number of results");
1214 
1215         // Check that number of results is > 0.
1216         auto val = getToken().getUInt64IntegerValue();
1217         if (!val || *val < 1)
1218           return emitError(
1219               "expected named operation to have at least 1 result");
1220         consumeToken(Token::integer);
1221         expectedSubResults = *val;
1222       }
1223 
1224       resultIDs.emplace_back(nameTok.getSpelling(), expectedSubResults,
1225                              nameTok.getLoc());
1226       numExpectedResults += expectedSubResults;
1227       return success();
1228     };
1229     if (parseCommaSeparatedList(parseNextResult))
1230       return failure();
1231 
1232     if (parseToken(Token::equal, "expected '=' after SSA name"))
1233       return failure();
1234   }
1235 
1236   Operation *op;
1237   Token nameTok = getToken();
1238   if (nameTok.is(Token::bare_identifier) || nameTok.isKeyword())
1239     op = parseCustomOperation(resultIDs);
1240   else if (nameTok.is(Token::string))
1241     op = parseGenericOperation();
1242   else if (nameTok.isCodeCompletionFor(Token::string))
1243     return codeCompleteStringDialectOrOperationName(nameTok.getStringValue());
1244   else if (nameTok.isCodeCompletion())
1245     return codeCompleteDialectOrElidedOpName(loc);
1246   else
1247     return emitWrongTokenError("expected operation name in quotes");
1248 
1249   // If parsing of the basic operation failed, then this whole thing fails.
1250   if (!op)
1251     return failure();
1252 
1253   // If the operation had a name, register it.
1254   if (!resultIDs.empty()) {
1255     if (op->getNumResults() == 0)
1256       return emitError(loc, "cannot name an operation with no results");
1257     if (numExpectedResults != op->getNumResults())
1258       return emitError(loc, "operation defines ")
1259              << op->getNumResults() << " results but was provided "
1260              << numExpectedResults << " to bind";
1261 
1262     // Add this operation to the assembly state if it was provided to populate.
1263     if (state.asmState) {
1264       unsigned resultIt = 0;
1265       SmallVector<std::pair<unsigned, SMLoc>> asmResultGroups;
1266       asmResultGroups.reserve(resultIDs.size());
1267       for (ResultRecord &record : resultIDs) {
1268         asmResultGroups.emplace_back(resultIt, std::get<2>(record));
1269         resultIt += std::get<1>(record);
1270       }
1271       state.asmState->finalizeOperationDefinition(
1272           op, nameTok.getLocRange(), /*endLoc=*/getLastToken().getEndLoc(),
1273           asmResultGroups);
1274     }
1275 
1276     // Add definitions for each of the result groups.
1277     unsigned opResI = 0;
1278     for (ResultRecord &resIt : resultIDs) {
1279       for (unsigned subRes : llvm::seq<unsigned>(0, std::get<1>(resIt))) {
1280         if (addDefinition({std::get<2>(resIt), std::get<0>(resIt), subRes},
1281                           op->getResult(opResI++)))
1282           return failure();
1283       }
1284     }
1285 
1286     // Add this operation to the assembly state if it was provided to populate.
1287   } else if (state.asmState) {
1288     state.asmState->finalizeOperationDefinition(
1289         op, nameTok.getLocRange(),
1290         /*endLoc=*/getLastToken().getEndLoc());
1291   }
1292 
1293   return success();
1294 }
1295 
1296 /// Parse a single operation successor.
1297 ///
1298 ///   successor ::= block-id
1299 ///
1300 ParseResult OperationParser::parseSuccessor(Block *&dest) {
1301   if (getToken().isCodeCompletion())
1302     return codeCompleteBlock();
1303 
1304   // Verify branch is identifier and get the matching block.
1305   if (!getToken().is(Token::caret_identifier))
1306     return emitWrongTokenError("expected block name");
1307   dest = getBlockNamed(getTokenSpelling(), getToken().getLoc());
1308   consumeToken();
1309   return success();
1310 }
1311 
1312 /// Parse a comma-separated list of operation successors in brackets.
1313 ///
1314 ///   successor-list ::= `[` successor (`,` successor )* `]`
1315 ///
1316 ParseResult
1317 OperationParser::parseSuccessors(SmallVectorImpl<Block *> &destinations) {
1318   if (parseToken(Token::l_square, "expected '['"))
1319     return failure();
1320 
1321   auto parseElt = [this, &destinations] {
1322     Block *dest;
1323     ParseResult res = parseSuccessor(dest);
1324     destinations.push_back(dest);
1325     return res;
1326   };
1327   return parseCommaSeparatedListUntil(Token::r_square, parseElt,
1328                                       /*allowEmptyList=*/false);
1329 }
1330 
1331 namespace {
1332 // RAII-style guard for cleaning up the regions in the operation state before
1333 // deleting them.  Within the parser, regions may get deleted if parsing failed,
1334 // and other errors may be present, in particular undominated uses.  This makes
1335 // sure such uses are deleted.
1336 struct CleanupOpStateRegions {
1337   ~CleanupOpStateRegions() {
1338     SmallVector<Region *, 4> regionsToClean;
1339     regionsToClean.reserve(state.regions.size());
1340     for (auto &region : state.regions)
1341       if (region)
1342         for (auto &block : *region)
1343           block.dropAllDefinedValueUses();
1344   }
1345   OperationState &state;
1346 };
1347 } // namespace
1348 
1349 ParseResult OperationParser::parseGenericOperationAfterOpName(
1350     OperationState &result,
1351     std::optional<ArrayRef<UnresolvedOperand>> parsedOperandUseInfo,
1352     std::optional<ArrayRef<Block *>> parsedSuccessors,
1353     std::optional<MutableArrayRef<std::unique_ptr<Region>>> parsedRegions,
1354     std::optional<ArrayRef<NamedAttribute>> parsedAttributes,
1355     std::optional<Attribute> propertiesAttribute,
1356     std::optional<FunctionType> parsedFnType) {
1357 
1358   // Parse the operand list, if not explicitly provided.
1359   SmallVector<UnresolvedOperand, 8> opInfo;
1360   if (!parsedOperandUseInfo) {
1361     if (parseToken(Token::l_paren, "expected '(' to start operand list") ||
1362         parseOptionalSSAUseList(opInfo) ||
1363         parseToken(Token::r_paren, "expected ')' to end operand list")) {
1364       return failure();
1365     }
1366     parsedOperandUseInfo = opInfo;
1367   }
1368 
1369   // Parse the successor list, if not explicitly provided.
1370   if (!parsedSuccessors) {
1371     if (getToken().is(Token::l_square)) {
1372       // Check if the operation is not a known terminator.
1373       if (!result.name.mightHaveTrait<OpTrait::IsTerminator>())
1374         return emitError("successors in non-terminator");
1375 
1376       SmallVector<Block *, 2> successors;
1377       if (parseSuccessors(successors))
1378         return failure();
1379       result.addSuccessors(successors);
1380     }
1381   } else {
1382     result.addSuccessors(*parsedSuccessors);
1383   }
1384 
1385   // Parse the properties, if not explicitly provided.
1386   if (propertiesAttribute) {
1387     result.propertiesAttr = *propertiesAttribute;
1388   } else if (consumeIf(Token::less)) {
1389     result.propertiesAttr = parseAttribute();
1390     if (!result.propertiesAttr)
1391       return failure();
1392     if (parseToken(Token::greater, "expected '>' to close properties"))
1393       return failure();
1394   }
1395   // Parse the region list, if not explicitly provided.
1396   if (!parsedRegions) {
1397     if (consumeIf(Token::l_paren)) {
1398       do {
1399         // Create temporary regions with the top level region as parent.
1400         result.regions.emplace_back(new Region(topLevelOp));
1401         if (parseRegion(*result.regions.back(), /*entryArguments=*/{}))
1402           return failure();
1403       } while (consumeIf(Token::comma));
1404       if (parseToken(Token::r_paren, "expected ')' to end region list"))
1405         return failure();
1406     }
1407   } else {
1408     result.addRegions(*parsedRegions);
1409   }
1410 
1411   // Parse the attributes, if not explicitly provided.
1412   if (!parsedAttributes) {
1413     if (getToken().is(Token::l_brace)) {
1414       if (parseAttributeDict(result.attributes))
1415         return failure();
1416     }
1417   } else {
1418     result.addAttributes(*parsedAttributes);
1419   }
1420 
1421   // Parse the operation type, if not explicitly provided.
1422   Location typeLoc = result.location;
1423   if (!parsedFnType) {
1424     if (parseToken(Token::colon, "expected ':' followed by operation type"))
1425       return failure();
1426 
1427     typeLoc = getEncodedSourceLocation(getToken().getLoc());
1428     auto type = parseType();
1429     if (!type)
1430       return failure();
1431     auto fnType = dyn_cast<FunctionType>(type);
1432     if (!fnType)
1433       return mlir::emitError(typeLoc, "expected function type");
1434 
1435     parsedFnType = fnType;
1436   }
1437 
1438   result.addTypes(parsedFnType->getResults());
1439 
1440   // Check that we have the right number of types for the operands.
1441   ArrayRef<Type> operandTypes = parsedFnType->getInputs();
1442   if (operandTypes.size() != parsedOperandUseInfo->size()) {
1443     auto plural = "s"[parsedOperandUseInfo->size() == 1];
1444     return mlir::emitError(typeLoc, "expected ")
1445            << parsedOperandUseInfo->size() << " operand type" << plural
1446            << " but had " << operandTypes.size();
1447   }
1448 
1449   // Resolve all of the operands.
1450   for (unsigned i = 0, e = parsedOperandUseInfo->size(); i != e; ++i) {
1451     result.operands.push_back(
1452         resolveSSAUse((*parsedOperandUseInfo)[i], operandTypes[i]));
1453     if (!result.operands.back())
1454       return failure();
1455   }
1456 
1457   return success();
1458 }
1459 
1460 Operation *OperationParser::parseGenericOperation() {
1461   // Get location information for the operation.
1462   auto srcLocation = getEncodedSourceLocation(getToken().getLoc());
1463 
1464   std::string name = getToken().getStringValue();
1465   if (name.empty())
1466     return (emitError("empty operation name is invalid"), nullptr);
1467   if (name.find('\0') != StringRef::npos)
1468     return (emitError("null character not allowed in operation name"), nullptr);
1469 
1470   consumeToken(Token::string);
1471 
1472   OperationState result(srcLocation, name);
1473   CleanupOpStateRegions guard{result};
1474 
1475   // Lazy load dialects in the context as needed.
1476   if (!result.name.isRegistered()) {
1477     StringRef dialectName = StringRef(name).split('.').first;
1478     if (!getContext()->getLoadedDialect(dialectName) &&
1479         !getContext()->getOrLoadDialect(dialectName)) {
1480       if (!getContext()->allowsUnregisteredDialects()) {
1481         // Emit an error if the dialect couldn't be loaded (i.e., it was not
1482         // registered) and unregistered dialects aren't allowed.
1483         emitError("operation being parsed with an unregistered dialect. If "
1484                   "this is intended, please use -allow-unregistered-dialect "
1485                   "with the MLIR tool used");
1486         return nullptr;
1487       }
1488     } else {
1489       // Reload the OperationName now that the dialect is loaded.
1490       result.name = OperationName(name, getContext());
1491     }
1492   }
1493 
1494   // If we are populating the parser state, start a new operation definition.
1495   if (state.asmState)
1496     state.asmState->startOperationDefinition(result.name);
1497 
1498   if (parseGenericOperationAfterOpName(result))
1499     return nullptr;
1500 
1501   // Operation::create() is not allowed to fail, however setting the properties
1502   // from an attribute is a failable operation. So we save the attribute here
1503   // and set it on the operation post-parsing.
1504   Attribute properties;
1505   std::swap(properties, result.propertiesAttr);
1506 
1507   // If we don't have properties in the textual IR, but the operation now has
1508   // support for properties, we support some backward-compatible generic syntax
1509   // for the operation and as such we accept inherent attributes mixed in the
1510   // dictionary of discardable attributes. We pre-validate these here because
1511   // invalid attributes can't be casted to the properties storage and will be
1512   // silently dropped. For example an attribute { foo = 0 : i32 } that is
1513   // declared as F32Attr in ODS would have a C++ type of FloatAttr in the
1514   // properties array. When setting it we would do something like:
1515   //
1516   //   properties.foo = dyn_cast<FloatAttr>(fooAttr);
1517   //
1518   // which would end up with a null Attribute. The diagnostic from the verifier
1519   // would be "missing foo attribute" instead of something like "expects a 32
1520   // bits float attribute but got a 32 bits integer attribute".
1521   if (!properties && !result.getRawProperties()) {
1522     std::optional<RegisteredOperationName> info =
1523         result.name.getRegisteredInfo();
1524     if (info) {
1525       if (failed(info->verifyInherentAttrs(result.attributes, [&]() {
1526             return mlir::emitError(srcLocation) << "'" << name << "' op ";
1527           })))
1528         return nullptr;
1529     }
1530   }
1531 
1532   // Create the operation and try to parse a location for it.
1533   Operation *op = opBuilder.create(result);
1534   if (parseTrailingLocationSpecifier(op))
1535     return nullptr;
1536 
1537   // Try setting the properties for the operation, using a diagnostic to print
1538   // errors.
1539   if (properties) {
1540     auto emitError = [&]() {
1541       return mlir::emitError(srcLocation, "invalid properties ")
1542              << properties << " for op " << name << ": ";
1543     };
1544     if (failed(op->setPropertiesFromAttribute(properties, emitError)))
1545       return nullptr;
1546   }
1547 
1548   return op;
1549 }
1550 
1551 Operation *OperationParser::parseGenericOperation(Block *insertBlock,
1552                                                   Block::iterator insertPt) {
1553   Token nameToken = getToken();
1554 
1555   OpBuilder::InsertionGuard restoreInsertionPoint(opBuilder);
1556   opBuilder.setInsertionPoint(insertBlock, insertPt);
1557   Operation *op = parseGenericOperation();
1558   if (!op)
1559     return nullptr;
1560 
1561   // If we are populating the parser asm state, finalize this operation
1562   // definition.
1563   if (state.asmState)
1564     state.asmState->finalizeOperationDefinition(
1565         op, nameToken.getLocRange(),
1566         /*endLoc=*/getLastToken().getEndLoc());
1567   return op;
1568 }
1569 
1570 namespace {
1571 class CustomOpAsmParser : public AsmParserImpl<OpAsmParser> {
1572 public:
1573   CustomOpAsmParser(
1574       SMLoc nameLoc, ArrayRef<OperationParser::ResultRecord> resultIDs,
1575       function_ref<ParseResult(OpAsmParser &, OperationState &)> parseAssembly,
1576       bool isIsolatedFromAbove, StringRef opName, OperationParser &parser)
1577       : AsmParserImpl<OpAsmParser>(nameLoc, parser), resultIDs(resultIDs),
1578         parseAssembly(parseAssembly), isIsolatedFromAbove(isIsolatedFromAbove),
1579         opName(opName), parser(parser) {
1580     (void)isIsolatedFromAbove; // Only used in assert, silence unused warning.
1581   }
1582 
1583   /// Parse an instance of the operation described by 'opDefinition' into the
1584   /// provided operation state.
1585   ParseResult parseOperation(OperationState &opState) {
1586     if (parseAssembly(*this, opState))
1587       return failure();
1588     // Verify that the parsed attributes does not have duplicate attributes.
1589     // This can happen if an attribute set during parsing is also specified in
1590     // the attribute dictionary in the assembly, or the attribute is set
1591     // multiple during parsing.
1592     std::optional<NamedAttribute> duplicate =
1593         opState.attributes.findDuplicate();
1594     if (duplicate)
1595       return emitError(getNameLoc(), "attribute '")
1596              << duplicate->getName().getValue()
1597              << "' occurs more than once in the attribute list";
1598     return success();
1599   }
1600 
1601   Operation *parseGenericOperation(Block *insertBlock,
1602                                    Block::iterator insertPt) final {
1603     return parser.parseGenericOperation(insertBlock, insertPt);
1604   }
1605 
1606   FailureOr<OperationName> parseCustomOperationName() final {
1607     return parser.parseCustomOperationName();
1608   }
1609 
1610   ParseResult parseGenericOperationAfterOpName(
1611       OperationState &result,
1612       std::optional<ArrayRef<UnresolvedOperand>> parsedUnresolvedOperands,
1613       std::optional<ArrayRef<Block *>> parsedSuccessors,
1614       std::optional<MutableArrayRef<std::unique_ptr<Region>>> parsedRegions,
1615       std::optional<ArrayRef<NamedAttribute>> parsedAttributes,
1616       std::optional<Attribute> parsedPropertiesAttribute,
1617       std::optional<FunctionType> parsedFnType) final {
1618     return parser.parseGenericOperationAfterOpName(
1619         result, parsedUnresolvedOperands, parsedSuccessors, parsedRegions,
1620         parsedAttributes, parsedPropertiesAttribute, parsedFnType);
1621   }
1622   //===--------------------------------------------------------------------===//
1623   // Utilities
1624   //===--------------------------------------------------------------------===//
1625 
1626   /// Return the name of the specified result in the specified syntax, as well
1627   /// as the subelement in the name.  For example, in this operation:
1628   ///
1629   ///  %x, %y:2, %z = foo.op
1630   ///
1631   ///    getResultName(0) == {"x", 0 }
1632   ///    getResultName(1) == {"y", 0 }
1633   ///    getResultName(2) == {"y", 1 }
1634   ///    getResultName(3) == {"z", 0 }
1635   std::pair<StringRef, unsigned>
1636   getResultName(unsigned resultNo) const override {
1637     // Scan for the resultID that contains this result number.
1638     for (const auto &entry : resultIDs) {
1639       if (resultNo < std::get<1>(entry)) {
1640         // Don't pass on the leading %.
1641         StringRef name = std::get<0>(entry).drop_front();
1642         return {name, resultNo};
1643       }
1644       resultNo -= std::get<1>(entry);
1645     }
1646 
1647     // Invalid result number.
1648     return {"", ~0U};
1649   }
1650 
1651   /// Return the number of declared SSA results.  This returns 4 for the foo.op
1652   /// example in the comment for getResultName.
1653   size_t getNumResults() const override {
1654     size_t count = 0;
1655     for (auto &entry : resultIDs)
1656       count += std::get<1>(entry);
1657     return count;
1658   }
1659 
1660   /// Emit a diagnostic at the specified location and return failure.
1661   InFlightDiagnostic emitError(SMLoc loc, const Twine &message) override {
1662     return AsmParserImpl<OpAsmParser>::emitError(loc, "custom op '" + opName +
1663                                                           "' " + message);
1664   }
1665 
1666   //===--------------------------------------------------------------------===//
1667   // Operand Parsing
1668   //===--------------------------------------------------------------------===//
1669 
1670   /// Parse a single operand.
1671   ParseResult parseOperand(UnresolvedOperand &result,
1672                            bool allowResultNumber = true) override {
1673     OperationParser::UnresolvedOperand useInfo;
1674     if (parser.parseSSAUse(useInfo, allowResultNumber))
1675       return failure();
1676 
1677     result = {useInfo.location, useInfo.name, useInfo.number};
1678     return success();
1679   }
1680 
1681   /// Parse a single operand if present.
1682   OptionalParseResult
1683   parseOptionalOperand(UnresolvedOperand &result,
1684                        bool allowResultNumber = true) override {
1685     if (parser.getToken().isOrIsCodeCompletionFor(Token::percent_identifier))
1686       return parseOperand(result, allowResultNumber);
1687     return std::nullopt;
1688   }
1689 
1690   /// Parse zero or more SSA comma-separated operand references with a specified
1691   /// surrounding delimiter, and an optional required operand count.
1692   ParseResult parseOperandList(SmallVectorImpl<UnresolvedOperand> &result,
1693                                Delimiter delimiter = Delimiter::None,
1694                                bool allowResultNumber = true,
1695                                int requiredOperandCount = -1) override {
1696     // The no-delimiter case has some special handling for better diagnostics.
1697     if (delimiter == Delimiter::None) {
1698       // parseCommaSeparatedList doesn't handle the missing case for "none",
1699       // so we handle it custom here.
1700       Token tok = parser.getToken();
1701       if (!tok.isOrIsCodeCompletionFor(Token::percent_identifier)) {
1702         // If we didn't require any operands or required exactly zero (weird)
1703         // then this is success.
1704         if (requiredOperandCount == -1 || requiredOperandCount == 0)
1705           return success();
1706 
1707         // Otherwise, try to produce a nice error message.
1708         if (tok.isAny(Token::l_paren, Token::l_square))
1709           return parser.emitError("unexpected delimiter");
1710         return parser.emitWrongTokenError("expected operand");
1711       }
1712     }
1713 
1714     auto parseOneOperand = [&]() -> ParseResult {
1715       return parseOperand(result.emplace_back(), allowResultNumber);
1716     };
1717 
1718     auto startLoc = parser.getToken().getLoc();
1719     if (parseCommaSeparatedList(delimiter, parseOneOperand, " in operand list"))
1720       return failure();
1721 
1722     // Check that we got the expected # of elements.
1723     if (requiredOperandCount != -1 &&
1724         result.size() != static_cast<size_t>(requiredOperandCount))
1725       return emitError(startLoc, "expected ")
1726              << requiredOperandCount << " operands";
1727     return success();
1728   }
1729 
1730   /// Resolve an operand to an SSA value, emitting an error on failure.
1731   ParseResult resolveOperand(const UnresolvedOperand &operand, Type type,
1732                              SmallVectorImpl<Value> &result) override {
1733     if (auto value = parser.resolveSSAUse(operand, type)) {
1734       result.push_back(value);
1735       return success();
1736     }
1737     return failure();
1738   }
1739 
1740   /// Parse an AffineMap of SSA ids.
1741   ParseResult
1742   parseAffineMapOfSSAIds(SmallVectorImpl<UnresolvedOperand> &operands,
1743                          Attribute &mapAttr, StringRef attrName,
1744                          NamedAttrList &attrs, Delimiter delimiter) override {
1745     SmallVector<UnresolvedOperand, 2> dimOperands;
1746     SmallVector<UnresolvedOperand, 1> symOperands;
1747 
1748     auto parseElement = [&](bool isSymbol) -> ParseResult {
1749       UnresolvedOperand operand;
1750       if (parseOperand(operand))
1751         return failure();
1752       if (isSymbol)
1753         symOperands.push_back(operand);
1754       else
1755         dimOperands.push_back(operand);
1756       return success();
1757     };
1758 
1759     AffineMap map;
1760     if (parser.parseAffineMapOfSSAIds(map, parseElement, delimiter))
1761       return failure();
1762     // Add AffineMap attribute.
1763     if (map) {
1764       mapAttr = AffineMapAttr::get(map);
1765       attrs.push_back(parser.builder.getNamedAttr(attrName, mapAttr));
1766     }
1767 
1768     // Add dim operands before symbol operands in 'operands'.
1769     operands.assign(dimOperands.begin(), dimOperands.end());
1770     operands.append(symOperands.begin(), symOperands.end());
1771     return success();
1772   }
1773 
1774   /// Parse an AffineExpr of SSA ids.
1775   ParseResult
1776   parseAffineExprOfSSAIds(SmallVectorImpl<UnresolvedOperand> &dimOperands,
1777                           SmallVectorImpl<UnresolvedOperand> &symbOperands,
1778                           AffineExpr &expr) override {
1779     auto parseElement = [&](bool isSymbol) -> ParseResult {
1780       UnresolvedOperand operand;
1781       if (parseOperand(operand))
1782         return failure();
1783       if (isSymbol)
1784         symbOperands.push_back(operand);
1785       else
1786         dimOperands.push_back(operand);
1787       return success();
1788     };
1789 
1790     return parser.parseAffineExprOfSSAIds(expr, parseElement);
1791   }
1792 
1793   //===--------------------------------------------------------------------===//
1794   // Argument Parsing
1795   //===--------------------------------------------------------------------===//
1796 
1797   /// Parse a single argument with the following syntax:
1798   ///
1799   ///   `%ssaname : !type { optionalAttrDict} loc(optionalSourceLoc)`
1800   ///
1801   /// If `allowType` is false or `allowAttrs` are false then the respective
1802   /// parts of the grammar are not parsed.
1803   ParseResult parseArgument(Argument &result, bool allowType = false,
1804                             bool allowAttrs = false) override {
1805     NamedAttrList attrs;
1806     if (parseOperand(result.ssaName, /*allowResultNumber=*/false) ||
1807         (allowType && parseColonType(result.type)) ||
1808         (allowAttrs && parseOptionalAttrDict(attrs)) ||
1809         parseOptionalLocationSpecifier(result.sourceLoc))
1810       return failure();
1811     result.attrs = attrs.getDictionary(getContext());
1812     return success();
1813   }
1814 
1815   /// Parse a single argument if present.
1816   OptionalParseResult parseOptionalArgument(Argument &result, bool allowType,
1817                                             bool allowAttrs) override {
1818     if (parser.getToken().is(Token::percent_identifier))
1819       return parseArgument(result, allowType, allowAttrs);
1820     return std::nullopt;
1821   }
1822 
1823   ParseResult parseArgumentList(SmallVectorImpl<Argument> &result,
1824                                 Delimiter delimiter, bool allowType,
1825                                 bool allowAttrs) override {
1826     // The no-delimiter case has some special handling for the empty case.
1827     if (delimiter == Delimiter::None &&
1828         parser.getToken().isNot(Token::percent_identifier))
1829       return success();
1830 
1831     auto parseOneArgument = [&]() -> ParseResult {
1832       return parseArgument(result.emplace_back(), allowType, allowAttrs);
1833     };
1834     return parseCommaSeparatedList(delimiter, parseOneArgument,
1835                                    " in argument list");
1836   }
1837 
1838   //===--------------------------------------------------------------------===//
1839   // Region Parsing
1840   //===--------------------------------------------------------------------===//
1841 
1842   /// Parse a region that takes `arguments` of `argTypes` types.  This
1843   /// effectively defines the SSA values of `arguments` and assigns their type.
1844   ParseResult parseRegion(Region &region, ArrayRef<Argument> arguments,
1845                           bool enableNameShadowing) override {
1846     // Try to parse the region.
1847     (void)isIsolatedFromAbove;
1848     assert((!enableNameShadowing || isIsolatedFromAbove) &&
1849            "name shadowing is only allowed on isolated regions");
1850     if (parser.parseRegion(region, arguments, enableNameShadowing))
1851       return failure();
1852     return success();
1853   }
1854 
1855   /// Parses a region if present.
1856   OptionalParseResult parseOptionalRegion(Region &region,
1857                                           ArrayRef<Argument> arguments,
1858                                           bool enableNameShadowing) override {
1859     if (parser.getToken().isNot(Token::l_brace))
1860       return std::nullopt;
1861     return parseRegion(region, arguments, enableNameShadowing);
1862   }
1863 
1864   /// Parses a region if present. If the region is present, a new region is
1865   /// allocated and placed in `region`. If no region is present, `region`
1866   /// remains untouched.
1867   OptionalParseResult
1868   parseOptionalRegion(std::unique_ptr<Region> &region,
1869                       ArrayRef<Argument> arguments,
1870                       bool enableNameShadowing = false) override {
1871     if (parser.getToken().isNot(Token::l_brace))
1872       return std::nullopt;
1873     std::unique_ptr<Region> newRegion = std::make_unique<Region>();
1874     if (parseRegion(*newRegion, arguments, enableNameShadowing))
1875       return failure();
1876 
1877     region = std::move(newRegion);
1878     return success();
1879   }
1880 
1881   //===--------------------------------------------------------------------===//
1882   // Successor Parsing
1883   //===--------------------------------------------------------------------===//
1884 
1885   /// Parse a single operation successor.
1886   ParseResult parseSuccessor(Block *&dest) override {
1887     return parser.parseSuccessor(dest);
1888   }
1889 
1890   /// Parse an optional operation successor and its operand list.
1891   OptionalParseResult parseOptionalSuccessor(Block *&dest) override {
1892     if (!parser.getToken().isOrIsCodeCompletionFor(Token::caret_identifier))
1893       return std::nullopt;
1894     return parseSuccessor(dest);
1895   }
1896 
1897   /// Parse a single operation successor and its operand list.
1898   ParseResult
1899   parseSuccessorAndUseList(Block *&dest,
1900                            SmallVectorImpl<Value> &operands) override {
1901     if (parseSuccessor(dest))
1902       return failure();
1903 
1904     // Handle optional arguments.
1905     if (succeeded(parseOptionalLParen()) &&
1906         (parser.parseOptionalSSAUseAndTypeList(operands) || parseRParen())) {
1907       return failure();
1908     }
1909     return success();
1910   }
1911 
1912   //===--------------------------------------------------------------------===//
1913   // Type Parsing
1914   //===--------------------------------------------------------------------===//
1915 
1916   /// Parse a list of assignments of the form
1917   ///   (%x1 = %y1, %x2 = %y2, ...).
1918   OptionalParseResult parseOptionalAssignmentList(
1919       SmallVectorImpl<Argument> &lhs,
1920       SmallVectorImpl<UnresolvedOperand> &rhs) override {
1921     if (failed(parseOptionalLParen()))
1922       return std::nullopt;
1923 
1924     auto parseElt = [&]() -> ParseResult {
1925       if (parseArgument(lhs.emplace_back()) || parseEqual() ||
1926           parseOperand(rhs.emplace_back()))
1927         return failure();
1928       return success();
1929     };
1930     return parser.parseCommaSeparatedListUntil(Token::r_paren, parseElt);
1931   }
1932 
1933   /// Parse a loc(...) specifier if present, filling in result if so.
1934   ParseResult
1935   parseOptionalLocationSpecifier(std::optional<Location> &result) override {
1936     // If there is a 'loc' we parse a trailing location.
1937     if (!parser.consumeIf(Token::kw_loc))
1938       return success();
1939     LocationAttr directLoc;
1940     if (parser.parseToken(Token::l_paren, "expected '(' in location"))
1941       return failure();
1942 
1943     Token tok = parser.getToken();
1944 
1945     // Check to see if we are parsing a location alias. We are parsing a
1946     // location alias if the token is a hash identifier *without* a dot in it -
1947     // the dot signifies a dialect attribute. Otherwise, we parse the location
1948     // directly.
1949     if (tok.is(Token::hash_identifier) && !tok.getSpelling().contains('.')) {
1950       if (parser.parseLocationAlias(directLoc))
1951         return failure();
1952     } else if (parser.parseLocationInstance(directLoc)) {
1953       return failure();
1954     }
1955 
1956     if (parser.parseToken(Token::r_paren, "expected ')' in location"))
1957       return failure();
1958 
1959     result = directLoc;
1960     return success();
1961   }
1962 
1963 private:
1964   /// Information about the result name specifiers.
1965   ArrayRef<OperationParser::ResultRecord> resultIDs;
1966 
1967   /// The abstract information of the operation.
1968   function_ref<ParseResult(OpAsmParser &, OperationState &)> parseAssembly;
1969   bool isIsolatedFromAbove;
1970   StringRef opName;
1971 
1972   /// The backing operation parser.
1973   OperationParser &parser;
1974 };
1975 } // namespace
1976 
1977 FailureOr<OperationName> OperationParser::parseCustomOperationName() {
1978   Token nameTok = getToken();
1979   StringRef opName = nameTok.getSpelling();
1980   if (opName.empty())
1981     return (emitError("empty operation name is invalid"), failure());
1982   consumeToken();
1983 
1984   // Check to see if this operation name is already registered.
1985   std::optional<RegisteredOperationName> opInfo =
1986       RegisteredOperationName::lookup(opName, getContext());
1987   if (opInfo)
1988     return *opInfo;
1989 
1990   // If the operation doesn't have a dialect prefix try using the default
1991   // dialect.
1992   auto opNameSplit = opName.split('.');
1993   StringRef dialectName = opNameSplit.first;
1994   std::string opNameStorage;
1995   if (opNameSplit.second.empty()) {
1996     // If the name didn't have a prefix, check for a code completion request.
1997     if (getToken().isCodeCompletion() && opName.back() == '.')
1998       return codeCompleteOperationName(dialectName);
1999 
2000     dialectName = getState().defaultDialectStack.back();
2001     opNameStorage = (dialectName + "." + opName).str();
2002     opName = opNameStorage;
2003   }
2004 
2005   // Try to load the dialect before returning the operation name to make sure
2006   // the operation has a chance to be registered.
2007   getContext()->getOrLoadDialect(dialectName);
2008   return OperationName(opName, getContext());
2009 }
2010 
2011 Operation *
2012 OperationParser::parseCustomOperation(ArrayRef<ResultRecord> resultIDs) {
2013   SMLoc opLoc = getToken().getLoc();
2014   StringRef originalOpName = getTokenSpelling();
2015 
2016   FailureOr<OperationName> opNameInfo = parseCustomOperationName();
2017   if (failed(opNameInfo))
2018     return nullptr;
2019   StringRef opName = opNameInfo->getStringRef();
2020 
2021   // This is the actual hook for the custom op parsing, usually implemented by
2022   // the op itself (`Op::parse()`). We retrieve it either from the
2023   // RegisteredOperationName or from the Dialect.
2024   OperationName::ParseAssemblyFn parseAssemblyFn;
2025   bool isIsolatedFromAbove = false;
2026 
2027   StringRef defaultDialect = "";
2028   if (auto opInfo = opNameInfo->getRegisteredInfo()) {
2029     parseAssemblyFn = opInfo->getParseAssemblyFn();
2030     isIsolatedFromAbove = opInfo->hasTrait<OpTrait::IsIsolatedFromAbove>();
2031     auto *iface = opInfo->getInterface<OpAsmOpInterface>();
2032     if (iface && !iface->getDefaultDialect().empty())
2033       defaultDialect = iface->getDefaultDialect();
2034   } else {
2035     std::optional<Dialect::ParseOpHook> dialectHook;
2036     Dialect *dialect = opNameInfo->getDialect();
2037     if (!dialect) {
2038       InFlightDiagnostic diag =
2039           emitError(opLoc) << "Dialect `" << opNameInfo->getDialectNamespace()
2040                            << "' not found for custom op '" << originalOpName
2041                            << "' ";
2042       if (originalOpName != opName)
2043         diag << " (tried '" << opName << "' as well)";
2044       auto &note = diag.attachNote();
2045       note << "Registered dialects: ";
2046       llvm::interleaveComma(getContext()->getAvailableDialects(), note,
2047                             [&](StringRef dialect) { note << dialect; });
2048       note << " ; for more info on dialect registration see "
2049               "https://mlir.llvm.org/getting_started/Faq/"
2050               "#registered-loaded-dependent-whats-up-with-dialects-management";
2051       return nullptr;
2052     }
2053     dialectHook = dialect->getParseOperationHook(opName);
2054     if (!dialectHook) {
2055       InFlightDiagnostic diag =
2056           emitError(opLoc) << "custom op '" << originalOpName << "' is unknown";
2057       if (originalOpName != opName)
2058         diag << " (tried '" << opName << "' as well)";
2059       return nullptr;
2060     }
2061     parseAssemblyFn = *dialectHook;
2062   }
2063   getState().defaultDialectStack.push_back(defaultDialect);
2064   auto restoreDefaultDialect = llvm::make_scope_exit(
2065       [&]() { getState().defaultDialectStack.pop_back(); });
2066 
2067   // If the custom op parser crashes, produce some indication to help
2068   // debugging.
2069   llvm::PrettyStackTraceFormat fmt("MLIR Parser: custom op parser '%s'",
2070                                    opNameInfo->getIdentifier().data());
2071 
2072   // Get location information for the operation.
2073   auto srcLocation = getEncodedSourceLocation(opLoc);
2074   OperationState opState(srcLocation, *opNameInfo);
2075 
2076   // If we are populating the parser state, start a new operation definition.
2077   if (state.asmState)
2078     state.asmState->startOperationDefinition(opState.name);
2079 
2080   // Have the op implementation take a crack and parsing this.
2081   CleanupOpStateRegions guard{opState};
2082   CustomOpAsmParser opAsmParser(opLoc, resultIDs, parseAssemblyFn,
2083                                 isIsolatedFromAbove, opName, *this);
2084   if (opAsmParser.parseOperation(opState))
2085     return nullptr;
2086 
2087   // If it emitted an error, we failed.
2088   if (opAsmParser.didEmitError())
2089     return nullptr;
2090 
2091   Attribute properties = opState.propertiesAttr;
2092   opState.propertiesAttr = Attribute{};
2093 
2094   // Otherwise, create the operation and try to parse a location for it.
2095   Operation *op = opBuilder.create(opState);
2096   if (parseTrailingLocationSpecifier(op))
2097     return nullptr;
2098 
2099   // Try setting the properties for the operation.
2100   if (properties) {
2101     auto emitError = [&]() {
2102       return mlir::emitError(srcLocation, "invalid properties ")
2103              << properties << " for op " << op->getName().getStringRef()
2104              << ": ";
2105     };
2106     if (failed(op->setPropertiesFromAttribute(properties, emitError)))
2107       return nullptr;
2108   }
2109   return op;
2110 }
2111 
2112 ParseResult OperationParser::parseLocationAlias(LocationAttr &loc) {
2113   Token tok = getToken();
2114   consumeToken(Token::hash_identifier);
2115   StringRef identifier = tok.getSpelling().drop_front();
2116   assert(!identifier.contains('.') &&
2117          "unexpected dialect attribute token, expected alias");
2118 
2119   if (state.asmState)
2120     state.asmState->addAttrAliasUses(identifier, tok.getLocRange());
2121 
2122   // If this alias can be resolved, do it now.
2123   Attribute attr = state.symbols.attributeAliasDefinitions.lookup(identifier);
2124   if (attr) {
2125     if (!(loc = dyn_cast<LocationAttr>(attr)))
2126       return emitError(tok.getLoc())
2127              << "expected location, but found '" << attr << "'";
2128   } else {
2129     // Otherwise, remember this operation and resolve its location later.
2130     // In the meantime, use a special OpaqueLoc as a marker.
2131     loc = OpaqueLoc::get(deferredLocsReferences.size(),
2132                          TypeID::get<DeferredLocInfo *>(),
2133                          UnknownLoc::get(getContext()));
2134     deferredLocsReferences.push_back(DeferredLocInfo{tok.getLoc(), identifier});
2135   }
2136   return success();
2137 }
2138 
2139 ParseResult
2140 OperationParser::parseTrailingLocationSpecifier(OpOrArgument opOrArgument) {
2141   // If there is a 'loc' we parse a trailing location.
2142   if (!consumeIf(Token::kw_loc))
2143     return success();
2144   if (parseToken(Token::l_paren, "expected '(' in location"))
2145     return failure();
2146   Token tok = getToken();
2147 
2148   // Check to see if we are parsing a location alias. We are parsing a location
2149   // alias if the token is a hash identifier *without* a dot in it - the dot
2150   // signifies a dialect attribute. Otherwise, we parse the location directly.
2151   LocationAttr directLoc;
2152   if (tok.is(Token::hash_identifier) && !tok.getSpelling().contains('.')) {
2153     if (parseLocationAlias(directLoc))
2154       return failure();
2155   } else if (parseLocationInstance(directLoc)) {
2156     return failure();
2157   }
2158 
2159   if (parseToken(Token::r_paren, "expected ')' in location"))
2160     return failure();
2161 
2162   if (auto *op = llvm::dyn_cast_if_present<Operation *>(opOrArgument))
2163     op->setLoc(directLoc);
2164   else
2165     cast<BlockArgument>(opOrArgument).setLoc(directLoc);
2166   return success();
2167 }
2168 
2169 //===----------------------------------------------------------------------===//
2170 // Region Parsing
2171 //===----------------------------------------------------------------------===//
2172 
2173 ParseResult OperationParser::parseRegion(Region &region,
2174                                          ArrayRef<Argument> entryArguments,
2175                                          bool isIsolatedNameScope) {
2176   // Parse the '{'.
2177   Token lBraceTok = getToken();
2178   if (parseToken(Token::l_brace, "expected '{' to begin a region"))
2179     return failure();
2180 
2181   // If we are populating the parser state, start a new region definition.
2182   if (state.asmState)
2183     state.asmState->startRegionDefinition();
2184 
2185   // Parse the region body.
2186   if ((!entryArguments.empty() || getToken().isNot(Token::r_brace)) &&
2187       parseRegionBody(region, lBraceTok.getLoc(), entryArguments,
2188                       isIsolatedNameScope)) {
2189     return failure();
2190   }
2191   consumeToken(Token::r_brace);
2192 
2193   // If we are populating the parser state, finalize this region.
2194   if (state.asmState)
2195     state.asmState->finalizeRegionDefinition();
2196 
2197   return success();
2198 }
2199 
2200 ParseResult OperationParser::parseRegionBody(Region &region, SMLoc startLoc,
2201                                              ArrayRef<Argument> entryArguments,
2202                                              bool isIsolatedNameScope) {
2203   auto currentPt = opBuilder.saveInsertionPoint();
2204 
2205   // Push a new named value scope.
2206   pushSSANameScope(isIsolatedNameScope);
2207 
2208   // Parse the first block directly to allow for it to be unnamed.
2209   auto owningBlock = std::make_unique<Block>();
2210   Block *block = owningBlock.get();
2211 
2212   // If this block is not defined in the source file, add a definition for it
2213   // now in the assembly state. Blocks with a name will be defined when the name
2214   // is parsed.
2215   if (state.asmState && getToken().isNot(Token::caret_identifier))
2216     state.asmState->addDefinition(block, startLoc);
2217 
2218   // Add arguments to the entry block if we had the form with explicit names.
2219   if (!entryArguments.empty() && !entryArguments[0].ssaName.name.empty()) {
2220     // If we had named arguments, then don't allow a block name.
2221     if (getToken().is(Token::caret_identifier))
2222       return emitError("invalid block name in region with named arguments");
2223 
2224     for (auto &entryArg : entryArguments) {
2225       auto &argInfo = entryArg.ssaName;
2226 
2227       // Ensure that the argument was not already defined.
2228       if (auto defLoc = getReferenceLoc(argInfo.name, argInfo.number)) {
2229         return emitError(argInfo.location, "region entry argument '" +
2230                                                argInfo.name +
2231                                                "' is already in use")
2232                    .attachNote(getEncodedSourceLocation(*defLoc))
2233                << "previously referenced here";
2234       }
2235       Location loc = entryArg.sourceLoc.has_value()
2236                          ? *entryArg.sourceLoc
2237                          : getEncodedSourceLocation(argInfo.location);
2238       BlockArgument arg = block->addArgument(entryArg.type, loc);
2239 
2240       // Add a definition of this arg to the assembly state if provided.
2241       if (state.asmState)
2242         state.asmState->addDefinition(arg, argInfo.location);
2243 
2244       // Record the definition for this argument.
2245       if (addDefinition(argInfo, arg))
2246         return failure();
2247     }
2248   }
2249 
2250   if (parseBlock(block))
2251     return failure();
2252 
2253   // Verify that no other arguments were parsed.
2254   if (!entryArguments.empty() &&
2255       block->getNumArguments() > entryArguments.size()) {
2256     return emitError("entry block arguments were already defined");
2257   }
2258 
2259   // Parse the rest of the region.
2260   region.push_back(owningBlock.release());
2261   while (getToken().isNot(Token::r_brace)) {
2262     Block *newBlock = nullptr;
2263     if (parseBlock(newBlock))
2264       return failure();
2265     region.push_back(newBlock);
2266   }
2267 
2268   // Pop the SSA value scope for this region.
2269   if (popSSANameScope())
2270     return failure();
2271 
2272   // Reset the original insertion point.
2273   opBuilder.restoreInsertionPoint(currentPt);
2274   return success();
2275 }
2276 
2277 //===----------------------------------------------------------------------===//
2278 // Block Parsing
2279 //===----------------------------------------------------------------------===//
2280 
2281 /// Block declaration.
2282 ///
2283 ///   block ::= block-label? operation*
2284 ///   block-label    ::= block-id block-arg-list? `:`
2285 ///   block-id       ::= caret-id
2286 ///   block-arg-list ::= `(` ssa-id-and-type-list? `)`
2287 ///
2288 ParseResult OperationParser::parseBlock(Block *&block) {
2289   // The first block of a region may already exist, if it does the caret
2290   // identifier is optional.
2291   if (block && getToken().isNot(Token::caret_identifier))
2292     return parseBlockBody(block);
2293 
2294   SMLoc nameLoc = getToken().getLoc();
2295   auto name = getTokenSpelling();
2296   if (parseToken(Token::caret_identifier, "expected block name"))
2297     return failure();
2298 
2299   // Define the block with the specified name.
2300   auto &blockAndLoc = getBlockInfoByName(name);
2301   blockAndLoc.loc = nameLoc;
2302 
2303   // Use a unique pointer for in-flight block being parsed. Release ownership
2304   // only in the case of a successful parse. This ensures that the Block
2305   // allocated is released if the parse fails and control returns early.
2306   std::unique_ptr<Block> inflightBlock;
2307   auto cleanupOnFailure = llvm::make_scope_exit([&] {
2308     if (inflightBlock)
2309       inflightBlock->dropAllDefinedValueUses();
2310   });
2311 
2312   // If a block has yet to be set, this is a new definition. If the caller
2313   // provided a block, use it. Otherwise create a new one.
2314   if (!blockAndLoc.block) {
2315     if (block) {
2316       blockAndLoc.block = block;
2317     } else {
2318       inflightBlock = std::make_unique<Block>();
2319       blockAndLoc.block = inflightBlock.get();
2320     }
2321 
2322     // Otherwise, the block has a forward declaration. Forward declarations are
2323     // removed once defined, so if we are defining a existing block and it is
2324     // not a forward declaration, then it is a redeclaration. Fail if the block
2325     // was already defined.
2326   } else if (!eraseForwardRef(blockAndLoc.block)) {
2327     return emitError(nameLoc, "redefinition of block '") << name << "'";
2328   } else {
2329     // This was a forward reference block that is now floating. Keep track of it
2330     // as inflight in case of error, so that it gets cleaned up properly.
2331     inflightBlock.reset(blockAndLoc.block);
2332   }
2333 
2334   // Populate the high level assembly state if necessary.
2335   if (state.asmState)
2336     state.asmState->addDefinition(blockAndLoc.block, nameLoc);
2337   block = blockAndLoc.block;
2338 
2339   // If an argument list is present, parse it.
2340   if (getToken().is(Token::l_paren))
2341     if (parseOptionalBlockArgList(block))
2342       return failure();
2343   if (parseToken(Token::colon, "expected ':' after block name"))
2344     return failure();
2345 
2346   // Parse the body of the block.
2347   ParseResult res = parseBlockBody(block);
2348 
2349   // If parsing was successful, drop the inflight block. We relinquish ownership
2350   // back up to the caller.
2351   if (succeeded(res))
2352     (void)inflightBlock.release();
2353   return res;
2354 }
2355 
2356 ParseResult OperationParser::parseBlockBody(Block *block) {
2357   // Set the insertion point to the end of the block to parse.
2358   opBuilder.setInsertionPointToEnd(block);
2359 
2360   // Parse the list of operations that make up the body of the block.
2361   while (getToken().isNot(Token::caret_identifier, Token::r_brace))
2362     if (parseOperation())
2363       return failure();
2364 
2365   return success();
2366 }
2367 
2368 /// Get the block with the specified name, creating it if it doesn't already
2369 /// exist.  The location specified is the point of use, which allows
2370 /// us to diagnose references to blocks that are not defined precisely.
2371 Block *OperationParser::getBlockNamed(StringRef name, SMLoc loc) {
2372   BlockDefinition &blockDef = getBlockInfoByName(name);
2373   if (!blockDef.block) {
2374     blockDef = {new Block(), loc};
2375     insertForwardRef(blockDef.block, blockDef.loc);
2376   }
2377 
2378   // Populate the high level assembly state if necessary.
2379   if (state.asmState)
2380     state.asmState->addUses(blockDef.block, loc);
2381 
2382   return blockDef.block;
2383 }
2384 
2385 /// Parse a (possibly empty) list of SSA operands with types as block arguments
2386 /// enclosed in parentheses.
2387 ///
2388 ///   value-id-and-type-list ::= value-id-and-type (`,` ssa-id-and-type)*
2389 ///   block-arg-list ::= `(` value-id-and-type-list? `)`
2390 ///
2391 ParseResult OperationParser::parseOptionalBlockArgList(Block *owner) {
2392   if (getToken().is(Token::r_brace))
2393     return success();
2394 
2395   // If the block already has arguments, then we're handling the entry block.
2396   // Parse and register the names for the arguments, but do not add them.
2397   bool definingExistingArgs = owner->getNumArguments() != 0;
2398   unsigned nextArgument = 0;
2399 
2400   return parseCommaSeparatedList(Delimiter::Paren, [&]() -> ParseResult {
2401     return parseSSADefOrUseAndType(
2402         [&](UnresolvedOperand useInfo, Type type) -> ParseResult {
2403           BlockArgument arg;
2404 
2405           // If we are defining existing arguments, ensure that the argument
2406           // has already been created with the right type.
2407           if (definingExistingArgs) {
2408             // Otherwise, ensure that this argument has already been created.
2409             if (nextArgument >= owner->getNumArguments())
2410               return emitError("too many arguments specified in argument list");
2411 
2412             // Finally, make sure the existing argument has the correct type.
2413             arg = owner->getArgument(nextArgument++);
2414             if (arg.getType() != type)
2415               return emitError("argument and block argument type mismatch");
2416           } else {
2417             auto loc = getEncodedSourceLocation(useInfo.location);
2418             arg = owner->addArgument(type, loc);
2419           }
2420 
2421           // If the argument has an explicit loc(...) specifier, parse and apply
2422           // it.
2423           if (parseTrailingLocationSpecifier(arg))
2424             return failure();
2425 
2426           // Mark this block argument definition in the parser state if it was
2427           // provided.
2428           if (state.asmState)
2429             state.asmState->addDefinition(arg, useInfo.location);
2430 
2431           return addDefinition(useInfo, arg);
2432         });
2433   });
2434 }
2435 
2436 //===----------------------------------------------------------------------===//
2437 // Code Completion
2438 //===----------------------------------------------------------------------===//
2439 
2440 ParseResult OperationParser::codeCompleteSSAUse() {
2441   for (IsolatedSSANameScope &scope : isolatedNameScopes) {
2442     for (auto &it : scope.values) {
2443       if (it.second.empty())
2444         continue;
2445       Value frontValue = it.second.front().value;
2446 
2447       std::string detailData;
2448       llvm::raw_string_ostream detailOS(detailData);
2449 
2450       // If the value isn't a forward reference, we also add the name of the op
2451       // to the detail.
2452       if (auto result = dyn_cast<OpResult>(frontValue)) {
2453         if (!forwardRefPlaceholders.count(result))
2454           detailOS << result.getOwner()->getName() << ": ";
2455       } else {
2456         detailOS << "arg #" << cast<BlockArgument>(frontValue).getArgNumber()
2457                  << ": ";
2458       }
2459 
2460       // Emit the type of the values to aid with completion selection.
2461       detailOS << frontValue.getType();
2462 
2463       // FIXME: We should define a policy for packed values, e.g. with a limit
2464       // on the detail size, but it isn't clear what would be useful right now.
2465       // For now we just only emit the first type.
2466       if (it.second.size() > 1)
2467         detailOS << ", ...";
2468 
2469       state.codeCompleteContext->appendSSAValueCompletion(
2470           it.getKey(), std::move(detailData));
2471     }
2472   }
2473 
2474   return failure();
2475 }
2476 
2477 ParseResult OperationParser::codeCompleteBlock() {
2478   // Don't provide completions if the token isn't empty, e.g. this avoids
2479   // weirdness when we encounter a `.` within the identifier.
2480   StringRef spelling = getTokenSpelling();
2481   if (!(spelling.empty() || spelling == "^"))
2482     return failure();
2483 
2484   for (const auto &it : blocksByName.back())
2485     state.codeCompleteContext->appendBlockCompletion(it.getFirst());
2486   return failure();
2487 }
2488 
2489 //===----------------------------------------------------------------------===//
2490 // Top-level entity parsing.
2491 //===----------------------------------------------------------------------===//
2492 
2493 namespace {
2494 /// This parser handles entities that are only valid at the top level of the
2495 /// file.
2496 class TopLevelOperationParser : public Parser {
2497 public:
2498   explicit TopLevelOperationParser(ParserState &state) : Parser(state) {}
2499 
2500   /// Parse a set of operations into the end of the given Block.
2501   ParseResult parse(Block *topLevelBlock, Location parserLoc);
2502 
2503 private:
2504   /// Parse an attribute alias declaration.
2505   ///
2506   ///   attribute-alias-def ::= '#' alias-name `=` attribute-value
2507   ///
2508   ParseResult parseAttributeAliasDef();
2509 
2510   /// Parse a type alias declaration.
2511   ///
2512   ///   type-alias-def ::= '!' alias-name `=` type
2513   ///
2514   ParseResult parseTypeAliasDef();
2515 
2516   /// Parse a top-level file metadata dictionary.
2517   ///
2518   ///   file-metadata-dict ::= '{-#' file-metadata-entry* `#-}'
2519   ///
2520   ParseResult parseFileMetadataDictionary();
2521 
2522   /// Parse a resource metadata dictionary.
2523   ParseResult parseResourceFileMetadata(
2524       function_ref<ParseResult(StringRef, SMLoc)> parseBody);
2525   ParseResult parseDialectResourceFileMetadata();
2526   ParseResult parseExternalResourceFileMetadata();
2527 };
2528 
2529 /// This class represents an implementation of a resource entry for the MLIR
2530 /// textual format.
2531 class ParsedResourceEntry : public AsmParsedResourceEntry {
2532 public:
2533   ParsedResourceEntry(StringRef key, SMLoc keyLoc, Token value, Parser &p)
2534       : key(key), keyLoc(keyLoc), value(value), p(p) {}
2535   ~ParsedResourceEntry() override = default;
2536 
2537   StringRef getKey() const final { return key; }
2538 
2539   InFlightDiagnostic emitError() const final { return p.emitError(keyLoc); }
2540 
2541   AsmResourceEntryKind getKind() const final {
2542     if (value.isAny(Token::kw_true, Token::kw_false))
2543       return AsmResourceEntryKind::Bool;
2544     return value.getSpelling().starts_with("\"0x")
2545                ? AsmResourceEntryKind::Blob
2546                : AsmResourceEntryKind::String;
2547   }
2548 
2549   FailureOr<bool> parseAsBool() const final {
2550     if (value.is(Token::kw_true))
2551       return true;
2552     if (value.is(Token::kw_false))
2553       return false;
2554     return p.emitError(value.getLoc(),
2555                        "expected 'true' or 'false' value for key '" + key +
2556                            "'");
2557   }
2558 
2559   FailureOr<std::string> parseAsString() const final {
2560     if (value.isNot(Token::string))
2561       return p.emitError(value.getLoc(),
2562                          "expected string value for key '" + key + "'");
2563     return value.getStringValue();
2564   }
2565 
2566   FailureOr<AsmResourceBlob>
2567   parseAsBlob(BlobAllocatorFn allocator) const final {
2568     // Blob data within then textual format is represented as a hex string.
2569     // TODO: We could avoid an additional alloc+copy here if we pre-allocated
2570     // the buffer to use during hex processing.
2571     std::optional<std::string> blobData =
2572         value.is(Token::string) ? value.getHexStringValue() : std::nullopt;
2573     if (!blobData)
2574       return p.emitError(value.getLoc(),
2575                          "expected hex string blob for key '" + key + "'");
2576 
2577     // Extract the alignment of the blob data, which gets stored at the
2578     // beginning of the string.
2579     if (blobData->size() < sizeof(uint32_t)) {
2580       return p.emitError(value.getLoc(),
2581                          "expected hex string blob for key '" + key +
2582                              "' to encode alignment in first 4 bytes");
2583     }
2584     llvm::support::ulittle32_t align;
2585     memcpy(&align, blobData->data(), sizeof(uint32_t));
2586     if (align && !llvm::isPowerOf2_32(align)) {
2587       return p.emitError(value.getLoc(),
2588                          "expected hex string blob for key '" + key +
2589                              "' to encode alignment in first 4 bytes, but got "
2590                              "non-power-of-2 value: " +
2591                              Twine(align));
2592     }
2593 
2594     // Get the data portion of the blob.
2595     StringRef data = StringRef(*blobData).drop_front(sizeof(uint32_t));
2596     if (data.empty())
2597       return AsmResourceBlob();
2598 
2599     // Allocate memory for the blob using the provided allocator and copy the
2600     // data into it.
2601     AsmResourceBlob blob = allocator(data.size(), align);
2602     assert(llvm::isAddrAligned(llvm::Align(align), blob.getData().data()) &&
2603            blob.isMutable() &&
2604            "blob allocator did not return a properly aligned address");
2605     memcpy(blob.getMutableData().data(), data.data(), data.size());
2606     return blob;
2607   }
2608 
2609 private:
2610   StringRef key;
2611   SMLoc keyLoc;
2612   Token value;
2613   Parser &p;
2614 };
2615 } // namespace
2616 
2617 ParseResult TopLevelOperationParser::parseAttributeAliasDef() {
2618   assert(getToken().is(Token::hash_identifier));
2619   StringRef aliasName = getTokenSpelling().drop_front();
2620 
2621   // Check for redefinitions.
2622   if (state.symbols.attributeAliasDefinitions.count(aliasName) > 0)
2623     return emitError("redefinition of attribute alias id '" + aliasName + "'");
2624 
2625   // Make sure this isn't invading the dialect attribute namespace.
2626   if (aliasName.contains('.'))
2627     return emitError("attribute names with a '.' are reserved for "
2628                      "dialect-defined names");
2629 
2630   SMRange location = getToken().getLocRange();
2631   consumeToken(Token::hash_identifier);
2632 
2633   // Parse the '='.
2634   if (parseToken(Token::equal, "expected '=' in attribute alias definition"))
2635     return failure();
2636 
2637   // Parse the attribute value.
2638   Attribute attr = parseAttribute();
2639   if (!attr)
2640     return failure();
2641 
2642   // Register this alias with the parser state.
2643   if (state.asmState)
2644     state.asmState->addAttrAliasDefinition(aliasName, location, attr);
2645   state.symbols.attributeAliasDefinitions[aliasName] = attr;
2646   return success();
2647 }
2648 
2649 ParseResult TopLevelOperationParser::parseTypeAliasDef() {
2650   assert(getToken().is(Token::exclamation_identifier));
2651   StringRef aliasName = getTokenSpelling().drop_front();
2652 
2653   // Check for redefinitions.
2654   if (state.symbols.typeAliasDefinitions.count(aliasName) > 0)
2655     return emitError("redefinition of type alias id '" + aliasName + "'");
2656 
2657   // Make sure this isn't invading the dialect type namespace.
2658   if (aliasName.contains('.'))
2659     return emitError("type names with a '.' are reserved for "
2660                      "dialect-defined names");
2661 
2662   SMRange location = getToken().getLocRange();
2663   consumeToken(Token::exclamation_identifier);
2664 
2665   // Parse the '='.
2666   if (parseToken(Token::equal, "expected '=' in type alias definition"))
2667     return failure();
2668 
2669   // Parse the type.
2670   Type aliasedType = parseType();
2671   if (!aliasedType)
2672     return failure();
2673 
2674   // Register this alias with the parser state.
2675   if (state.asmState)
2676     state.asmState->addTypeAliasDefinition(aliasName, location, aliasedType);
2677   state.symbols.typeAliasDefinitions.try_emplace(aliasName, aliasedType);
2678   return success();
2679 }
2680 
2681 ParseResult TopLevelOperationParser::parseFileMetadataDictionary() {
2682   consumeToken(Token::file_metadata_begin);
2683   return parseCommaSeparatedListUntil(
2684       Token::file_metadata_end, [&]() -> ParseResult {
2685         // Parse the key of the metadata dictionary.
2686         SMLoc keyLoc = getToken().getLoc();
2687         StringRef key;
2688         if (failed(parseOptionalKeyword(&key)))
2689           return emitError("expected identifier key in file "
2690                            "metadata dictionary");
2691         if (parseToken(Token::colon, "expected ':'"))
2692           return failure();
2693 
2694         // Process the metadata entry.
2695         if (key == "dialect_resources")
2696           return parseDialectResourceFileMetadata();
2697         if (key == "external_resources")
2698           return parseExternalResourceFileMetadata();
2699         return emitError(keyLoc, "unknown key '" + key +
2700                                      "' in file metadata dictionary");
2701       });
2702 }
2703 
2704 ParseResult TopLevelOperationParser::parseResourceFileMetadata(
2705     function_ref<ParseResult(StringRef, SMLoc)> parseBody) {
2706   if (parseToken(Token::l_brace, "expected '{'"))
2707     return failure();
2708 
2709   return parseCommaSeparatedListUntil(Token::r_brace, [&]() -> ParseResult {
2710     // Parse the top-level name entry.
2711     SMLoc nameLoc = getToken().getLoc();
2712     StringRef name;
2713     if (failed(parseOptionalKeyword(&name)))
2714       return emitError("expected identifier key for 'resource' entry");
2715 
2716     if (parseToken(Token::colon, "expected ':'") ||
2717         parseToken(Token::l_brace, "expected '{'"))
2718       return failure();
2719     return parseBody(name, nameLoc);
2720   });
2721 }
2722 
2723 ParseResult TopLevelOperationParser::parseDialectResourceFileMetadata() {
2724   return parseResourceFileMetadata([&](StringRef name,
2725                                        SMLoc nameLoc) -> ParseResult {
2726     // Lookup the dialect and check that it can handle a resource entry.
2727     Dialect *dialect = getContext()->getOrLoadDialect(name);
2728     if (!dialect)
2729       return emitError(nameLoc, "dialect '" + name + "' is unknown");
2730     const auto *handler = dyn_cast<OpAsmDialectInterface>(dialect);
2731     if (!handler) {
2732       return emitError() << "unexpected 'resource' section for dialect '"
2733                          << dialect->getNamespace() << "'";
2734     }
2735 
2736     return parseCommaSeparatedListUntil(Token::r_brace, [&]() -> ParseResult {
2737       // Parse the name of the resource entry.
2738       SMLoc keyLoc = getToken().getLoc();
2739       StringRef key;
2740       if (failed(parseResourceHandle(handler, key)) ||
2741           parseToken(Token::colon, "expected ':'"))
2742         return failure();
2743       Token valueTok = getToken();
2744       consumeToken();
2745 
2746       ParsedResourceEntry entry(key, keyLoc, valueTok, *this);
2747       return handler->parseResource(entry);
2748     });
2749   });
2750 }
2751 
2752 ParseResult TopLevelOperationParser::parseExternalResourceFileMetadata() {
2753   return parseResourceFileMetadata([&](StringRef name,
2754                                        SMLoc nameLoc) -> ParseResult {
2755     AsmResourceParser *handler = state.config.getResourceParser(name);
2756 
2757     // TODO: Should we require handling external resources in some scenarios?
2758     if (!handler) {
2759       emitWarning(getEncodedSourceLocation(nameLoc))
2760           << "ignoring unknown external resources for '" << name << "'";
2761     }
2762 
2763     return parseCommaSeparatedListUntil(Token::r_brace, [&]() -> ParseResult {
2764       // Parse the name of the resource entry.
2765       SMLoc keyLoc = getToken().getLoc();
2766       StringRef key;
2767       if (failed(parseOptionalKeyword(&key)))
2768         return emitError(
2769             "expected identifier key for 'external_resources' entry");
2770       if (parseToken(Token::colon, "expected ':'"))
2771         return failure();
2772       Token valueTok = getToken();
2773       consumeToken();
2774 
2775       if (!handler)
2776         return success();
2777       ParsedResourceEntry entry(key, keyLoc, valueTok, *this);
2778       return handler->parseResource(entry);
2779     });
2780   });
2781 }
2782 
2783 ParseResult TopLevelOperationParser::parse(Block *topLevelBlock,
2784                                            Location parserLoc) {
2785   // Create a top-level operation to contain the parsed state.
2786   OwningOpRef<ModuleOp> topLevelOp(ModuleOp::create(parserLoc));
2787   OperationParser opParser(state, topLevelOp.get());
2788   while (true) {
2789     switch (getToken().getKind()) {
2790     default:
2791       // Parse a top-level operation.
2792       if (opParser.parseOperation())
2793         return failure();
2794       break;
2795 
2796     // If we got to the end of the file, then we're done.
2797     case Token::eof: {
2798       if (opParser.finalize())
2799         return failure();
2800 
2801       // Splice the blocks of the parsed operation over to the provided
2802       // top-level block.
2803       auto &parsedOps = topLevelOp->getBody()->getOperations();
2804       auto &destOps = topLevelBlock->getOperations();
2805       destOps.splice(destOps.end(), parsedOps, parsedOps.begin(),
2806                      parsedOps.end());
2807       return success();
2808     }
2809 
2810     // If we got an error token, then the lexer already emitted an error, just
2811     // stop.  Someday we could introduce error recovery if there was demand
2812     // for it.
2813     case Token::error:
2814       return failure();
2815 
2816     // Parse an attribute alias.
2817     case Token::hash_identifier:
2818       if (parseAttributeAliasDef())
2819         return failure();
2820       break;
2821 
2822     // Parse a type alias.
2823     case Token::exclamation_identifier:
2824       if (parseTypeAliasDef())
2825         return failure();
2826       break;
2827 
2828       // Parse a file-level metadata dictionary.
2829     case Token::file_metadata_begin:
2830       if (parseFileMetadataDictionary())
2831         return failure();
2832       break;
2833     }
2834   }
2835 }
2836 
2837 //===----------------------------------------------------------------------===//
2838 
2839 LogicalResult
2840 mlir::parseAsmSourceFile(const llvm::SourceMgr &sourceMgr, Block *block,
2841                          const ParserConfig &config, AsmParserState *asmState,
2842                          AsmParserCodeCompleteContext *codeCompleteContext) {
2843   const auto *sourceBuf = sourceMgr.getMemoryBuffer(sourceMgr.getMainFileID());
2844 
2845   Location parserLoc =
2846       FileLineColLoc::get(config.getContext(), sourceBuf->getBufferIdentifier(),
2847                           /*line=*/0, /*column=*/0);
2848 
2849   SymbolState aliasState;
2850   ParserState state(sourceMgr, config, aliasState, asmState,
2851                     codeCompleteContext);
2852   return TopLevelOperationParser(state).parse(block, parserLoc);
2853 }
2854