Bug Summary

File:build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/mlir/lib/Parser/Parser.cpp
Warning:line 1642, column 24
Although the value stored to 'dialect' is used in the enclosing expression, the value is never actually read from 'dialect'

Annotated Source Code

Press '?' to see keyboard shortcuts

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