MLIR 22.0.0git
LocationParser.cpp
Go to the documentation of this file.
1//===- LocationParser.cpp - MLIR Location Parser -------------------------===//
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#include "Parser.h"
10#include "Token.h"
11#include "mlir/IR/Attributes.h"
13#include "mlir/IR/Location.h"
14#include "mlir/Support/LLVM.h"
15#include <optional>
16
17using namespace mlir;
18using namespace mlir::detail;
19
20/// Specific location instances.
21///
22/// location-inst ::= filelinecol-location |
23/// name-location |
24/// callsite-location |
25/// fused-location |
26/// unknown-location
27/// filelinecol-location ::= string-literal ':' integer-literal
28/// ':' integer-literal
29/// name-location ::= string-literal
30/// callsite-location ::= 'callsite' '(' location-inst 'at' location-inst ')'
31/// fused-location ::= fused ('<' attribute-value '>')?
32/// '[' location-inst (location-inst ',')* ']'
33/// unknown-location ::= 'unknown'
34///
36 consumeToken(Token::bare_identifier);
37
38 // Parse the '('.
39 if (parseToken(Token::l_paren, "expected '(' in callsite location"))
40 return failure();
41
42 // Parse the callee location.
43 LocationAttr calleeLoc;
44 if (parseLocationInstance(calleeLoc))
45 return failure();
46
47 // Parse the 'at'.
48 if (getToken().isNot(Token::bare_identifier) ||
49 getToken().getSpelling() != "at")
50 return emitWrongTokenError("expected 'at' in callsite location");
51 consumeToken(Token::bare_identifier);
52
53 // Parse the caller location.
54 LocationAttr callerLoc;
55 if (parseLocationInstance(callerLoc))
56 return failure();
57
58 // Parse the ')'.
59 if (parseToken(Token::r_paren, "expected ')' in callsite location"))
60 return failure();
61
62 // Return the callsite location.
63 loc = CallSiteLoc::get(calleeLoc, callerLoc);
64 return success();
65}
66
68 consumeToken(Token::bare_identifier);
69
70 // Try to parse the optional metadata.
71 Attribute metadata;
72 if (consumeIf(Token::less)) {
73 metadata = parseAttribute();
74 if (!metadata)
75 return failure();
76
77 // Parse the '>' token.
78 if (parseToken(Token::greater,
79 "expected '>' after fused location metadata"))
80 return failure();
81 }
82
84 auto parseElt = [&] {
85 LocationAttr newLoc;
86 if (parseLocationInstance(newLoc))
87 return failure();
88 locations.push_back(newLoc);
89 return success();
90 };
91
92 if (parseCommaSeparatedList(Delimiter::Square, parseElt,
93 " in fused location"))
94 return failure();
95
96 // Return the fused location.
97 loc = FusedLoc::get(locations, metadata, getContext());
98 return success();
99}
100
102 auto *ctx = getContext();
103 auto str = getToken().getStringValue();
104 consumeToken(Token::string);
105
106 std::optional<unsigned> startLine, startColumn, endLine, endColumn;
107
108 // If the next token is ':' this is a filelinecol location.
109 if (consumeIf(Token::colon)) {
110 // Parse the line number.
111 if (getToken().isNot(Token::integer))
112 return emitWrongTokenError(
113 "expected integer line number in FileLineColRange");
114 startLine = getToken().getUnsignedIntegerValue();
115 if (!startLine)
116 return emitWrongTokenError(
117 "expected integer line number in FileLineColRange");
118 consumeToken(Token::integer);
119
120 // Parse the ':'.
121 if (getToken().isNot(Token::colon)) {
122 loc = FileLineColRange::get(StringAttr::get(ctx, str), *startLine);
123 return success();
124 }
125 consumeToken(Token::colon);
126
127 // Parse the column number.
128 if (getToken().isNot(Token::integer)) {
129 return emitWrongTokenError(
130 "expected integer column number in FileLineColRange");
131 }
132 startColumn = getToken().getUnsignedIntegerValue();
133 if (!startColumn.has_value())
134 return emitError("expected integer column number in FileLineColRange");
135 consumeToken(Token::integer);
136
137 if (!isCurrentTokenAKeyword() || getTokenSpelling() != "to") {
138 loc = FileLineColLoc::get(ctx, str, *startLine, *startColumn);
139 return success();
140 }
141 consumeToken();
142
143 // Parse the line number.
144 if (getToken().is(Token::integer)) {
145 endLine = getToken().getUnsignedIntegerValue();
146 if (!endLine) {
147 return emitWrongTokenError(
148 "expected integer line number in FileLineColRange");
149 }
150 consumeToken(Token::integer);
151 }
152
153 // Parse the ':'.
154 if (getToken().isNot(Token::colon)) {
155 return emitWrongTokenError(
156 "expected either integer or `:` post `to` in FileLineColRange");
157 }
158 consumeToken(Token::colon);
159
160 // Parse the column number.
161 if (getToken().isNot(Token::integer)) {
162 return emitWrongTokenError(
163 "expected integer column number in FileLineColRange");
164 }
165 endColumn = getToken().getUnsignedIntegerValue();
166 if (!endColumn.has_value())
167 return emitError("expected integer column number in FileLineColRange");
168 consumeToken(Token::integer);
169
170 if (endLine.has_value()) {
171 loc = FileLineColRange::get(StringAttr::get(ctx, str), *startLine,
172 *startColumn, *endLine, *endColumn);
173 } else {
174 loc = FileLineColRange::get(StringAttr::get(ctx, str), *startLine,
175 *startColumn, *endColumn);
176 }
177 return success();
178 }
179
180 // Otherwise, this is a NameLoc.
181
182 // Check for a child location.
183 if (consumeIf(Token::l_paren)) {
184 // Parse the child location.
185 LocationAttr childLoc;
186 if (parseLocationInstance(childLoc))
187 return failure();
188
189 loc = NameLoc::get(StringAttr::get(ctx, str), childLoc);
190
191 // Parse the closing ')'.
192 if (parseToken(Token::r_paren,
193 "expected ')' after child location of NameLoc"))
194 return failure();
195 } else {
196 loc = NameLoc::get(StringAttr::get(ctx, str));
197 }
198
199 return success();
200}
201
203 // Handle aliases.
204 if (getToken().is(Token::hash_identifier)) {
205 Attribute locAttr = parseExtendedAttr(Type());
206 if (!locAttr)
207 return failure();
208 if (!(loc = dyn_cast<LocationAttr>(locAttr)))
209 return emitError("expected location attribute, but got") << locAttr;
210 return success();
211 }
212
213 // Handle either name or filelinecol locations.
214 if (getToken().is(Token::string))
215 return parseNameOrFileLineColRange(loc);
216
217 // Bare tokens required for other cases.
218 if (!getToken().is(Token::bare_identifier))
219 return emitWrongTokenError("expected location instance");
220
221 // Check for the 'callsite' signifying a callsite location.
222 if (getToken().getSpelling() == "callsite")
223 return parseCallSiteLocation(loc);
224
225 // If the token is 'fused', then this is a fused location.
226 if (getToken().getSpelling() == "fused")
227 return parseFusedLocation(loc);
228
229 // Check for a 'unknown' for an unknown location.
230 if (getToken().getSpelling() == "unknown") {
231 consumeToken(Token::bare_identifier);
232 loc = UnknownLoc::get(getContext());
233 return success();
234 }
235
236 return emitWrongTokenError("expected location instance");
237}
return success()
Attributes are known-constant values of operations.
Definition Attributes.h:25
static FileLineColLoc get(StringAttr filename, unsigned line, unsigned column)
Definition Location.cpp:157
Location objects represent source locations information in MLIR.
Definition Location.h:32
std::string getStringValue() const
Given a token containing a string literal, return its value, including removing the quote characters ...
Definition Token.cpp:86
std::optional< unsigned > getUnsignedIntegerValue() const
For an integer token, return its value as an unsigned.
Definition Token.cpp:34
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
ParseResult parseToken(Token::Kind expectedToken, const Twine &message)
Consume the specified token if present and return success.
Definition Parser.cpp:267
InFlightDiagnostic emitError(const Twine &message={})
Emit an error and return failure.
Definition Parser.cpp:192
Attribute parseAttribute(Type type={})
Parse an arbitrary attribute with an optional type.
StringRef getTokenSpelling() const
Definition Parser.h:104
ParseResult parseLocationInstance(LocationAttr &loc)
Parse a raw location instance.
void consumeToken()
Advance the current lexer onto the next token.
Definition Parser.h:119
InFlightDiagnostic emitWrongTokenError(const Twine &message={})
Emit an error about a "wrong token".
Definition Parser.cpp:215
ParseResult parseCommaSeparatedList(Delimiter delimiter, function_ref< ParseResult()> parseElementFn, StringRef contextMessage=StringRef())
Parse a list of comma-separated items with an optional delimiter.
Definition Parser.cpp:84
ParseResult parseNameOrFileLineColRange(LocationAttr &loc)
Parse a name or FileLineCol location instance.
ParseResult parseFusedLocation(LocationAttr &loc)
Parse a fused location instance.
bool isCurrentTokenAKeyword() const
Returns true if the current token corresponds to a keyword.
Definition Parser.h:169
ParseResult parseCallSiteLocation(LocationAttr &loc)
Parse a callsite location instance.
const Token & getToken() const
Return the current token the parser is inspecting.
Definition Parser.h:103
Attribute parseExtendedAttr(Type type)
Parse an extended attribute.
MLIRContext * getContext() const
Definition Parser.h:38
bool consumeIf(Token::Kind kind)
If the current token has the specified kind, consume it and return true.
Definition Parser.h:111
AttrTypeReplacer.
Include the generated interface declarations.