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