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