public:
virtual ~OpAsmParser();
- //===--------------------------------------------------------------------===//
- // High level parsing methods.
- //===--------------------------------------------------------------------===//
+ /// Emit a diagnostic at the specified location and return failure.
+ virtual InFlightDiagnostic emitError(llvm::SMLoc loc,
+ const Twine &message = {}) = 0;
- // These emit an error and return failure or success.
- // This allows these to be chained together into a linear sequence of ||
- // expressions in many cases.
+ /// Return a builder which provides useful access to MLIRContext, global
+ /// objects like types and attributes.
+ virtual Builder &getBuilder() const = 0;
/// Get the location of the next token and store it into the argument. This
/// always succeeds.
return success();
}
- /// This parses... a comma!
- virtual ParseResult parseComma() = 0;
+ /// Return the location of the original name token.
+ virtual llvm::SMLoc getNameLoc() const = 0;
- /// Parses a comma if present.
- virtual ParseResult parseOptionalComma() = 0;
+ // These methods emit an error and return failure or success. This allows
+ // these to be chained together into a linear sequence of || expressions in
+ // many cases.
+
+ //===--------------------------------------------------------------------===//
+ // Token Parsing
+ //===--------------------------------------------------------------------===//
/// Parse a `:` token.
virtual ParseResult parseColon() = 0;
/// Parse a `:` token if present.
virtual ParseResult parseOptionalColon() = 0;
- /// Parse a '(' token.
- virtual ParseResult parseLParen() = 0;
-
- /// Parse a '(' token if present.
- virtual ParseResult parseOptionalLParen() = 0;
-
- /// Parse a ')' token.
- virtual ParseResult parseRParen() = 0;
+ /// Parse a `,` token.
+ virtual ParseResult parseComma() = 0;
- /// Parse a ')' token if present.
- virtual ParseResult parseOptionalRParen() = 0;
+ /// Parse a `,` token if present.
+ virtual ParseResult parseOptionalComma() = 0;
- /// Parse a '=' token.
+ /// Parse a `=` token.
virtual ParseResult parseEqual() = 0;
- /// Parse a type.
- virtual ParseResult parseType(Type &result) = 0;
-
- /// Parse a colon followed by a type.
- virtual ParseResult parseColonType(Type &result) = 0;
-
- /// Parse a type of a specific kind, e.g. a FunctionType.
- template <typename TypeType> ParseResult parseColonType(TypeType &result) {
- llvm::SMLoc loc = getCurrentLocation();
-
- // Parse any kind of type.
- Type type;
- if (parseColonType(type))
- return failure();
-
- // Check for the right kind of attribute.
- result = type.dyn_cast<TypeType>();
- if (!result)
- return emitError(loc, "invalid kind of type specified");
-
- return success();
- }
-
- /// Parse a colon followed by a type list, which must have at least one type.
- virtual ParseResult parseColonTypeList(SmallVectorImpl<Type> &result) = 0;
-
- /// Parse an optional arrow followed by a type list.
- virtual ParseResult
- parseOptionalArrowTypeList(SmallVectorImpl<Type> &result) = 0;
-
- /// Parse a keyword followed by a type.
- ParseResult parseKeywordType(const char *keyword, Type &result) {
- return failure(parseKeyword(keyword) || parseType(result));
- }
-
/// Parse a keyword.
ParseResult parseKeyword(const char *keyword, const Twine &msg = "") {
if (parseOptionalKeyword(keyword))
return success();
}
- /// If a keyword is present, then parse it.
+ /// Parse a keyword if present.
virtual ParseResult parseOptionalKeyword(const char *keyword) = 0;
- /// Add the specified type to the end of the specified type list and return
- /// success. This is a helper designed to allow parse methods to be simple
- /// and chain through || operators.
- ParseResult addTypeToList(Type type, SmallVectorImpl<Type> &result) {
- result.push_back(type);
- return success();
- }
+ /// Parse a `(` token.
+ virtual ParseResult parseLParen() = 0;
- /// Add the specified types to the end of the specified type list and return
- /// success. This is a helper designed to allow parse methods to be simple
- /// and chain through || operators.
- ParseResult addTypesToList(ArrayRef<Type> types,
- SmallVectorImpl<Type> &result) {
- result.append(types.begin(), types.end());
- return success();
- }
+ /// Parse a `(` token if present.
+ virtual ParseResult parseOptionalLParen() = 0;
+
+ /// Parse a `)` token.
+ virtual ParseResult parseRParen() = 0;
+
+ /// Parse a `)` token if present.
+ virtual ParseResult parseOptionalRParen() = 0;
+
+ //===--------------------------------------------------------------------===//
+ // Attribute Parsing
+ //===--------------------------------------------------------------------===//
/// Parse an arbitrary attribute and return it in result. This also adds the
/// attribute to the specified attribute list with the specified name.
- virtual ParseResult
- parseAttribute(Attribute &result, StringRef attrName,
- SmallVectorImpl<NamedAttribute> &attrs) = 0;
+ ParseResult parseAttribute(Attribute &result, StringRef attrName,
+ SmallVectorImpl<NamedAttribute> &attrs) {
+ return parseAttribute(result, Type(), attrName, attrs);
+ }
/// Parse an arbitrary attribute of a given type and return it in result. This
/// also adds the attribute to the specified attribute list with the specified
return success();
}
- /// If a named attribute dictionary is present, parse it into result.
+ /// Parse a named dictionary into 'result' if it is present.
virtual ParseResult
parseOptionalAttributeDict(SmallVectorImpl<NamedAttribute> &result) = 0;
+ //===--------------------------------------------------------------------===//
+ // Operand Parsing
+ //===--------------------------------------------------------------------===//
+
/// This is the representation of an operand reference.
struct OperandType {
llvm::SMLoc location; // Location of the token.
/// Parse a single operand.
virtual ParseResult parseOperand(OperandType &result) = 0;
- /// Parse a single operation successor and it's operand list.
- virtual ParseResult
- parseSuccessorAndUseList(Block *&dest,
- SmallVectorImpl<Value *> &operands) = 0;
-
/// These are the supported delimiters around operand lists, used by
/// parseOperandList.
enum class Delimiter {
delimiter);
}
+ /// Resolve an operand to an SSA value, emitting an error on failure.
+ virtual ParseResult resolveOperand(const OperandType &operand, Type type,
+ SmallVectorImpl<Value *> &result) = 0;
+
+ /// Resolve a list of operands to SSA values, emitting an error on failure, or
+ /// appending the results to the list on success. This method should be used
+ /// when all operands have the same type.
+ ParseResult resolveOperands(ArrayRef<OperandType> operands, Type type,
+ SmallVectorImpl<Value *> &result) {
+ for (auto elt : operands)
+ if (resolveOperand(elt, type, result))
+ return failure();
+ return success();
+ }
+
+ /// Resolve a list of operands and a list of operand types to SSA values,
+ /// emitting an error and returning failure, or appending the results
+ /// to the list on success.
+ ParseResult resolveOperands(ArrayRef<OperandType> operands,
+ ArrayRef<Type> types, llvm::SMLoc loc,
+ SmallVectorImpl<Value *> &result) {
+ if (operands.size() != types.size())
+ return emitError(loc)
+ << operands.size() << " operands present, but expected "
+ << types.size();
+
+ for (unsigned i = 0, e = operands.size(); i != e; ++i)
+ if (resolveOperand(operands[i], types[i], result))
+ return failure();
+ return success();
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Region Parsing
+ //===--------------------------------------------------------------------===//
+
/// Parses a region. Any parsed blocks are appended to "region" and must be
/// moved to the op regions after the op is created. The first block of the
/// region takes "arguments" of types "argTypes".
ArrayRef<OperandType> arguments,
ArrayRef<Type> argTypes) = 0;
- /// Parses an optional region.
+ /// Parses a region if present.
virtual ParseResult parseOptionalRegion(Region ®ion,
ArrayRef<OperandType> arguments,
ArrayRef<Type> argTypes) = 0;
/// checks if the values with the same name has not been defined yet.
virtual ParseResult parseRegionArgument(OperandType &argument) = 0;
- /// Parse an optional region argument.
+ /// Parse a region argument if present.
virtual ParseResult parseOptionalRegionArgument(OperandType &argument) = 0;
//===--------------------------------------------------------------------===//
- // Methods for interacting with the parser
+ // Successor Parsing
//===--------------------------------------------------------------------===//
- /// Return a builder which provides useful access to MLIRContext, global
- /// objects like types and attributes.
- virtual Builder &getBuilder() const = 0;
+ /// Parse a single operation successor and its operand list.
+ virtual ParseResult
+ parseSuccessorAndUseList(Block *&dest,
+ SmallVectorImpl<Value *> &operands) = 0;
- /// Return the location of the original name token.
- virtual llvm::SMLoc getNameLoc() const = 0;
+ //===--------------------------------------------------------------------===//
+ // Type Parsing
+ //===--------------------------------------------------------------------===//
- /// Resolve an operand to an SSA value, emitting an error on failure.
- virtual ParseResult resolveOperand(const OperandType &operand, Type type,
- SmallVectorImpl<Value *> &result) = 0;
+ /// Parse a type.
+ virtual ParseResult parseType(Type &result) = 0;
+
+ /// Parse an optional arrow followed by a type list.
+ virtual ParseResult
+ parseOptionalArrowTypeList(SmallVectorImpl<Type> &result) = 0;
+
+ /// Parse a colon followed by a type.
+ virtual ParseResult parseColonType(Type &result) = 0;
+
+ /// Parse a colon followed by a type of a specific kind, e.g. a FunctionType.
+ template <typename TypeType> ParseResult parseColonType(TypeType &result) {
+ llvm::SMLoc loc = getCurrentLocation();
+
+ // Parse any kind of type.
+ Type type;
+ if (parseColonType(type))
+ return failure();
+
+ // Check for the right kind of attribute.
+ result = type.dyn_cast<TypeType>();
+ if (!result)
+ return emitError(loc, "invalid kind of type specified");
- /// Resolve a list of operands to SSA values, emitting an error on failure, or
- /// appending the results to the list on success. This method should be used
- /// when all operands have the same type.
- virtual ParseResult resolveOperands(ArrayRef<OperandType> operands, Type type,
- SmallVectorImpl<Value *> &result) {
- for (auto elt : operands)
- if (resolveOperand(elt, type, result))
- return failure();
return success();
}
- /// Resolve a list of operands and a list of operand types to SSA values,
- /// emitting an error and returning failure, or appending the results
- /// to the list on success.
- virtual ParseResult resolveOperands(ArrayRef<OperandType> operands,
- ArrayRef<Type> types, llvm::SMLoc loc,
- SmallVectorImpl<Value *> &result) {
- if (operands.size() != types.size())
- return emitError(loc)
- << operands.size() << " operands present, but expected "
- << types.size();
+ /// Parse a colon followed by a type list, which must have at least one type.
+ virtual ParseResult parseColonTypeList(SmallVectorImpl<Type> &result) = 0;
- for (unsigned i = 0, e = operands.size(); i != e; ++i)
- if (resolveOperand(operands[i], types[i], result))
- return failure();
+ /// Parse a keyword followed by a type.
+ ParseResult parseKeywordType(const char *keyword, Type &result) {
+ return failure(parseKeyword(keyword) || parseType(result));
+ }
+
+ /// Add the specified type to the end of the specified type list and return
+ /// success. This is a helper designed to allow parse methods to be simple
+ /// and chain through || operators.
+ ParseResult addTypeToList(Type type, SmallVectorImpl<Type> &result) {
+ result.push_back(type);
return success();
}
- /// Emit a diagnostic at the specified location and return failure.
- virtual InFlightDiagnostic emitError(llvm::SMLoc loc,
- const Twine &message = {}) = 0;
+ /// Add the specified types to the end of the specified type list and return
+ /// success. This is a helper designed to allow parse methods to be simple
+ /// and chain through || operators.
+ ParseResult addTypesToList(ArrayRef<Type> types,
+ SmallVectorImpl<Type> &result) {
+ result.append(types.begin(), types.end());
+ return success();
+ }
};
} // end namespace mlir
/// Parse an operation instance.
ParseResult parseOperation();
- /// Parse a single operation successor and it's operand list.
+ /// Parse a single operation successor and its operand list.
ParseResult parseSuccessorAndUseList(Block *&dest,
SmallVectorImpl<Value *> &operands);
return success();
}
-/// Parse a single operation successor and it's operand list.
+/// Parse a single operation successor and its operand list.
///
/// successor ::= block-id branch-use-list?
/// branch-use-list ::= `(` ssa-use-list ':' type-list-no-parens `)`
CustomOpAsmParser(SMLoc nameLoc, StringRef opName, FunctionParser &parser)
: nameLoc(nameLoc), opName(opName), parser(parser) {}
+ /// Parse an instance of the operation described by 'opDefinition' into the
+ /// provided operation state.
ParseResult parseOperation(const AbstractOperation *opDefinition,
OperationState *opState) {
if (opDefinition->parseAssembly(this, opState))
}
//===--------------------------------------------------------------------===//
- // High level parsing methods.
+ // Utilities
//===--------------------------------------------------------------------===//
+ /// Return if any errors were emitted during parsing.
+ bool didEmitError() const { return emittedError; }
+
+ /// Emit a diagnostic at the specified location and return failure.
+ InFlightDiagnostic emitError(llvm::SMLoc loc, const Twine &message) override {
+ emittedError = true;
+ return parser.emitError(loc, "custom op '" + opName + "' " + message);
+ }
+
llvm::SMLoc getCurrentLocation() override {
return parser.getToken().getLoc();
}
- ParseResult parseComma() override {
- return parser.parseToken(Token::comma, "expected ','");
- }
+ Builder &getBuilder() const override { return parser.builder; }
- ParseResult parseOptionalComma() override {
- return success(parser.consumeIf(Token::comma));
- }
+ llvm::SMLoc getNameLoc() const override { return nameLoc; }
+ //===--------------------------------------------------------------------===//
+ // Token Parsing
+ //===--------------------------------------------------------------------===//
+
+ /// Parse a `:` token.
ParseResult parseColon() override {
return parser.parseToken(Token::colon, "expected ':'");
}
+ /// Parse a `:` token if present.
ParseResult parseOptionalColon() override {
return success(parser.consumeIf(Token::colon));
}
- ParseResult parseEqual() override {
- return parser.parseToken(Token::equal, "expected '='");
- }
-
- ParseResult parseType(Type &result) override {
- return failure(!(result = parser.parseType()));
- }
-
- ParseResult parseColonType(Type &result) override {
- return failure(parser.parseToken(Token::colon, "expected ':'") ||
- !(result = parser.parseType()));
- }
-
- ParseResult parseColonTypeList(SmallVectorImpl<Type> &result) override {
- if (parser.parseToken(Token::colon, "expected ':'"))
- return failure();
- return parser.parseTypeListNoParens(result);
+ /// Parse a `,` token.
+ ParseResult parseComma() override {
+ return parser.parseToken(Token::comma, "expected ','");
}
- /// Parse an arrow followed by a type list, which must have at least one type.
- ParseResult parseOptionalArrowTypeList(SmallVectorImpl<Type> &result) {
- if (!parser.consumeIf(Token::arrow))
- return success();
- return parser.parseFunctionResultTypes(result);
+ /// Parse a `,` token if present.
+ ParseResult parseOptionalComma() override {
+ return success(parser.consumeIf(Token::comma));
}
- ParseResult parseTrailingOperandList(SmallVectorImpl<OperandType> &result,
- int requiredOperandCount,
- Delimiter delimiter) override {
- if (parser.getToken().is(Token::comma)) {
- parseComma();
- return parseOperandList(result, requiredOperandCount, delimiter);
- }
- if (requiredOperandCount != -1)
- return emitError(parser.getToken().getLoc(), "expected ")
- << requiredOperandCount << " operands";
- return success();
+ /// Parse a `=` token.
+ ParseResult parseEqual() override {
+ return parser.parseToken(Token::equal, "expected '='");
}
- /// Parse an optional keyword.
+ /// Parse a keyword if present.
ParseResult parseOptionalKeyword(const char *keyword) override {
// Check that the current token is a bare identifier or keyword.
if (parser.getToken().isNot(Token::bare_identifier) &&
return failure();
}
+ /// Parse a `(` token.
+ ParseResult parseLParen() override {
+ return parser.parseToken(Token::l_paren, "expected '('");
+ }
+
+ /// Parses a '(' if present.
+ ParseResult parseOptionalLParen() override {
+ return success(parser.consumeIf(Token::l_paren));
+ }
+
+ /// Parse a `)` token.
+ ParseResult parseRParen() override {
+ return parser.parseToken(Token::r_paren, "expected ')'");
+ }
+
+ /// Parses a ')' if present.
+ ParseResult parseOptionalRParen() override {
+ return success(parser.consumeIf(Token::r_paren));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Attribute Parsing
+ //===--------------------------------------------------------------------===//
+
/// Parse an arbitrary attribute of a given type and return it in result. This
/// also adds the attribute to the specified attribute list with the specified
/// name.
return success();
}
- /// Parse an arbitrary attribute and return it in result. This also adds
- /// the attribute to the specified attribute list with the specified name.
- ParseResult parseAttribute(Attribute &result, StringRef attrName,
- SmallVectorImpl<NamedAttribute> &attrs) override {
- return parseAttribute(result, Type(), attrName, attrs);
- }
-
- /// If a named attribute list is present, parse is into result.
+ /// Parse a named dictionary into 'result' if it is present.
ParseResult
parseOptionalAttributeDict(SmallVectorImpl<NamedAttribute> &result) override {
if (parser.getToken().isNot(Token::l_brace))
return parser.parseAttributeDict(result);
}
+ //===--------------------------------------------------------------------===//
+ // Operand Parsing
+ //===--------------------------------------------------------------------===//
+
+ /// Parse a single operand.
ParseResult parseOperand(OperandType &result) override {
FunctionParser::SSAUseInfo useInfo;
if (parser.parseSSAUse(useInfo))
return success();
}
- ParseResult
- parseSuccessorAndUseList(Block *&dest,
- SmallVectorImpl<Value *> &operands) override {
- // Defer successor parsing to the function parsers.
- return parser.parseSuccessorAndUseList(dest, operands);
- }
-
- ParseResult parseLParen() override {
- return parser.parseToken(Token::l_paren, "expected '('");
- }
-
- /// Parses a '(' if present.
- ParseResult parseOptionalLParen() override {
- return success(parser.consumeIf(Token::l_paren));
- }
-
- ParseResult parseRParen() override {
- return parser.parseToken(Token::r_paren, "expected ')'");
- }
-
- /// Parses a ')' if present.
- ParseResult parseOptionalRParen() override {
- return success(parser.consumeIf(Token::r_paren));
- }
-
+ /// Parse zero or more SSA comma-separated operand references with a specified
+ /// surrounding delimiter, and an optional required operand count.
ParseResult parseOperandList(SmallVectorImpl<OperandType> &result,
int requiredOperandCount = -1,
Delimiter delimiter = Delimiter::None) override {
return success();
}
+ /// Parse zero or more trailing SSA comma-separated trailing operand
+ /// references with a specified surrounding delimiter, and an optional
+ /// required operand count. A leading comma is expected before the operands.
+ ParseResult parseTrailingOperandList(SmallVectorImpl<OperandType> &result,
+ int requiredOperandCount,
+ Delimiter delimiter) override {
+ if (parser.getToken().is(Token::comma)) {
+ parseComma();
+ return parseOperandList(result, requiredOperandCount, delimiter);
+ }
+ if (requiredOperandCount != -1)
+ return emitError(parser.getToken().getLoc(), "expected ")
+ << requiredOperandCount << " operands";
+ return success();
+ }
+
+ /// Resolve an operand to an SSA value, emitting an error on failure.
+ ParseResult resolveOperand(const OperandType &operand, Type type,
+ SmallVectorImpl<Value *> &result) override {
+ FunctionParser::SSAUseInfo operandInfo = {operand.name, operand.number,
+ operand.location};
+ if (auto *value = parser.resolveSSAUse(operandInfo, type)) {
+ result.push_back(value);
+ return success();
+ }
+ return failure();
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Region Parsing
+ //===--------------------------------------------------------------------===//
+
/// Parse a region that takes `arguments` of `argTypes` types. This
/// effectively defines the SSA values of `arguments` and assignes their type.
ParseResult parseRegion(Region ®ion, ArrayRef<OperandType> arguments,
return parser.parseRegion(region, regionArguments);
}
- /// Parses an optional region.
+ /// Parses a region if present.
ParseResult parseOptionalRegion(Region ®ion,
ArrayRef<OperandType> arguments,
ArrayRef<Type> argTypes) override {
return success();
}
- /// Parse an optional region argument.
+ /// Parse a region argument if present.
ParseResult parseOptionalRegionArgument(OperandType &argument) override {
if (parser.getToken().isNot(Token::percent_identifier))
return success();
}
//===--------------------------------------------------------------------===//
- // Methods for interacting with the parser
+ // Successor Parsing
//===--------------------------------------------------------------------===//
- Builder &getBuilder() const override { return parser.builder; }
+ /// Parse a single operation successor and its operand list.
+ ParseResult
+ parseSuccessorAndUseList(Block *&dest,
+ SmallVectorImpl<Value *> &operands) override {
+ return parser.parseSuccessorAndUseList(dest, operands);
+ }
- llvm::SMLoc getNameLoc() const override { return nameLoc; }
+ //===--------------------------------------------------------------------===//
+ // Type Parsing
+ //===--------------------------------------------------------------------===//
- ParseResult resolveOperand(const OperandType &operand, Type type,
- SmallVectorImpl<Value *> &result) override {
- FunctionParser::SSAUseInfo operandInfo = {operand.name, operand.number,
- operand.location};
- if (auto *value = parser.resolveSSAUse(operandInfo, type)) {
- result.push_back(value);
+ /// Parse a type.
+ ParseResult parseType(Type &result) override {
+ return failure(!(result = parser.parseType()));
+ }
+
+ /// Parse an optional arrow followed by a type list.
+ ParseResult parseOptionalArrowTypeList(SmallVectorImpl<Type> &result) {
+ if (!parser.consumeIf(Token::arrow))
return success();
- }
- return failure();
+ return parser.parseFunctionResultTypes(result);
}
- /// Emit a diagnostic at the specified location and return failure.
- InFlightDiagnostic emitError(llvm::SMLoc loc, const Twine &message) override {
- emittedError = true;
- return parser.emitError(loc, "custom op '" + opName + "' " + message);
+ /// Parse a colon followed by a type.
+ ParseResult parseColonType(Type &result) override {
+ return failure(parser.parseToken(Token::colon, "expected ':'") ||
+ !(result = parser.parseType()));
}
- bool didEmitError() const { return emittedError; }
+ /// Parse a colon followed by a type list, which must have at least one type.
+ ParseResult parseColonTypeList(SmallVectorImpl<Type> &result) override {
+ if (parser.parseToken(Token::colon, "expected ':'"))
+ return failure();
+ return parser.parseTypeListNoParens(result);
+ }
private:
+ /// A set of placeholder value definitions for parsed region arguments.
SmallVector<Value *, 2> parsedRegionEntryArgumentPlaceholders;
+
+ /// The source location of the operation name.
SMLoc nameLoc;
+
+ /// The name of the operation.
StringRef opName;
+
+ /// The main operation parser.
FunctionParser &parser;
+
+ /// A flag that indicates if any errors were emitted during parsing.
bool emittedError = false;
};
} // end anonymous namespace.