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