MLIR  20.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 
16 using namespace mlir;
17 using namespace mlir::detail;
18 
19 /// Specific location instances.
20 ///
21 /// location-inst ::= filelinecol-location |
22 /// name-location |
23 /// callsite-location |
24 /// fused-location |
25 /// unknown-location
26 /// filelinecol-location ::= string-literal ':' integer-literal
27 /// ':' integer-literal
28 /// name-location ::= string-literal
29 /// callsite-location ::= 'callsite' '(' location-inst 'at' location-inst ')'
30 /// fused-location ::= fused ('<' attribute-value '>')?
31 /// '[' location-inst (location-inst ',')* ']'
32 /// unknown-location ::= 'unknown'
33 ///
35  consumeToken(Token::bare_identifier);
36 
37  // Parse the '('.
38  if (parseToken(Token::l_paren, "expected '(' in callsite location"))
39  return failure();
40 
41  // Parse the callee location.
42  LocationAttr calleeLoc;
43  if (parseLocationInstance(calleeLoc))
44  return failure();
45 
46  // Parse the 'at'.
47  if (getToken().isNot(Token::bare_identifier) ||
48  getToken().getSpelling() != "at")
49  return emitWrongTokenError("expected 'at' in callsite location");
50  consumeToken(Token::bare_identifier);
51 
52  // Parse the caller location.
53  LocationAttr callerLoc;
54  if (parseLocationInstance(callerLoc))
55  return failure();
56 
57  // Parse the ')'.
58  if (parseToken(Token::r_paren, "expected ')' in callsite location"))
59  return failure();
60 
61  // Return the callsite location.
62  loc = CallSiteLoc::get(calleeLoc, callerLoc);
63  return success();
64 }
65 
67  consumeToken(Token::bare_identifier);
68 
69  // Try to parse the optional metadata.
70  Attribute metadata;
71  if (consumeIf(Token::less)) {
72  metadata = parseAttribute();
73  if (!metadata)
74  return failure();
75 
76  // Parse the '>' token.
77  if (parseToken(Token::greater,
78  "expected '>' after fused location metadata"))
79  return failure();
80  }
81 
82  SmallVector<Location, 4> locations;
83  auto parseElt = [&] {
84  LocationAttr newLoc;
85  if (parseLocationInstance(newLoc))
86  return failure();
87  locations.push_back(newLoc);
88  return success();
89  };
90 
92  " in fused location"))
93  return failure();
94 
95  // Return the fused location.
96  loc = FusedLoc::get(locations, metadata, getContext());
97  return success();
98 }
99 
101  auto *ctx = getContext();
102  auto str = getToken().getStringValue();
103  consumeToken(Token::string);
104 
105  // If the next token is ':' this is a filelinecol location.
106  if (consumeIf(Token::colon)) {
107  // Parse the line number.
108  if (getToken().isNot(Token::integer))
109  return emitWrongTokenError(
110  "expected integer line number in FileLineColLoc");
111  auto line = getToken().getUnsignedIntegerValue();
112  if (!line)
113  return emitWrongTokenError(
114  "expected integer line number in FileLineColLoc");
115  consumeToken(Token::integer);
116 
117  // Parse the ':'.
118  if (parseToken(Token::colon, "expected ':' in FileLineColLoc"))
119  return failure();
120 
121  // Parse the column number.
122  if (getToken().isNot(Token::integer))
123  return emitWrongTokenError(
124  "expected integer column number in FileLineColLoc");
125  auto column = getToken().getUnsignedIntegerValue();
126  if (!column.has_value())
127  return emitError("expected integer column number in FileLineColLoc");
128  consumeToken(Token::integer);
129 
130  loc = FileLineColLoc::get(ctx, str, *line, *column);
131  return success();
132  }
133 
134  // Otherwise, this is a NameLoc.
135 
136  // Check for a child location.
137  if (consumeIf(Token::l_paren)) {
138  // Parse the child location.
139  LocationAttr childLoc;
140  if (parseLocationInstance(childLoc))
141  return failure();
142 
143  loc = NameLoc::get(StringAttr::get(ctx, str), childLoc);
144 
145  // Parse the closing ')'.
146  if (parseToken(Token::r_paren,
147  "expected ')' after child location of NameLoc"))
148  return failure();
149  } else {
150  loc = NameLoc::get(StringAttr::get(ctx, str));
151  }
152 
153  return success();
154 }
155 
157  // Handle aliases.
158  if (getToken().is(Token::hash_identifier)) {
159  Attribute locAttr = parseExtendedAttr(Type());
160  if (!locAttr)
161  return failure();
162  if (!(loc = dyn_cast<LocationAttr>(locAttr)))
163  return emitError("expected location attribute, but got") << locAttr;
164  return success();
165  }
166 
167  // Handle either name or filelinecol locations.
168  if (getToken().is(Token::string))
169  return parseNameOrFileLineColLocation(loc);
170 
171  // Bare tokens required for other cases.
172  if (!getToken().is(Token::bare_identifier))
173  return emitWrongTokenError("expected location instance");
174 
175  // Check for the 'callsite' signifying a callsite location.
176  if (getToken().getSpelling() == "callsite")
177  return parseCallSiteLocation(loc);
178 
179  // If the token is 'fused', then this is a fused location.
180  if (getToken().getSpelling() == "fused")
181  return parseFusedLocation(loc);
182 
183  // Check for a 'unknown' for an unknown location.
184  if (getToken().getSpelling() == "unknown") {
185  consumeToken(Token::bare_identifier);
186  loc = UnknownLoc::get(getContext());
187  return success();
188  }
189 
190  return emitWrongTokenError("expected location instance");
191 }
@ Square
Square brackets surrounding zero or more operands.
Attributes are known-constant values of operations.
Definition: Attributes.h:25
Location objects represent source locations information in MLIR.
Definition: Location.h:31
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.
ParseResult parseLocationInstance(LocationAttr &loc)
Parse a raw location instance.
void consumeToken()
Advance the current lexer onto the next token.
Definition: Parser.h:118
MLIRContext * getContext() const
Definition: Parser.h:37
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 parseFusedLocation(LocationAttr &loc)
Parse a fused location instance.
ParseResult parseCallSiteLocation(LocationAttr &loc)
Parse a callsite location instance.
ParseResult parseNameOrFileLineColLocation(LocationAttr &loc)
Parse a name or FileLineCol location instance.
Attribute parseExtendedAttr(Type type)
Parse an extended attribute.
const Token & getToken() const
Return the current token the parser is inspecting.
Definition: Parser.h:102
bool consumeIf(Token::Kind kind)
If the current token has the specified kind, consume it and return true.
Definition: Parser.h:110
AttrTypeReplacer.
Include the generated interface declarations.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...