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