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