NFC: Cleanup the definitions of OpAsmParser and CustomOpAsmParser by adding comments, grouping similar functionality, and adding header blocks.

PiperOrigin-RevId: 251723883
This commit is contained in:
River Riddle 2019-06-05 14:49:52 -07:00 committed by Mehdi Amini
parent 0560f153b8
commit e9d212c6aa
2 changed files with 274 additions and 215 deletions

View File

@ -142,13 +142,13 @@ class OpAsmParser {
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.
@ -158,11 +158,16 @@ public:
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;
@ -170,56 +175,15 @@ public:
/// Parse a `:` token if present.
virtual ParseResult parseOptionalColon() = 0;
/// Parse a '(' token.
virtual ParseResult parseLParen() = 0;
/// Parse a `,` token.
virtual ParseResult parseComma() = 0;
/// Parse a '(' token if present.
virtual ParseResult parseOptionalLParen() = 0;
/// Parse a `,` token if present.
virtual ParseResult parseOptionalComma() = 0;
/// Parse a ')' token.
virtual ParseResult parseRParen() = 0;
/// Parse a ')' token if present.
virtual ParseResult parseOptionalRParen() = 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))
@ -227,31 +191,31 @@ public:
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
@ -279,10 +243,14 @@ public:
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.
@ -293,11 +261,6 @@ public:
/// 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 {
@ -337,36 +300,6 @@ public:
delimiter);
}
/// 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".
virtual ParseResult parseRegion(Region &region,
ArrayRef<OperandType> arguments,
ArrayRef<Type> argTypes) = 0;
/// Parses an optional region.
virtual ParseResult parseOptionalRegion(Region &region,
ArrayRef<OperandType> arguments,
ArrayRef<Type> argTypes) = 0;
/// Parse a region argument. Region arguments define new values, so this also
/// checks if the values with the same name has not been defined yet.
virtual ParseResult parseRegionArgument(OperandType &argument) = 0;
/// Parse an optional region argument.
virtual ParseResult parseOptionalRegionArgument(OperandType &argument) = 0;
//===--------------------------------------------------------------------===//
// Methods for interacting with the parser
//===--------------------------------------------------------------------===//
/// Return a builder which provides useful access to MLIRContext, global
/// objects like types and attributes.
virtual Builder &getBuilder() const = 0;
/// Return the location of the original name token.
virtual llvm::SMLoc getNameLoc() const = 0;
/// Resolve an operand to an SSA value, emitting an error on failure.
virtual ParseResult resolveOperand(const OperandType &operand, Type type,
SmallVectorImpl<Value *> &result) = 0;
@ -374,8 +307,8 @@ public:
/// 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) {
ParseResult resolveOperands(ArrayRef<OperandType> operands, Type type,
SmallVectorImpl<Value *> &result) {
for (auto elt : operands)
if (resolveOperand(elt, type, result))
return failure();
@ -385,9 +318,9 @@ public:
/// 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) {
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 "
@ -399,9 +332,93 @@ public:
return success();
}
/// Emit a diagnostic at the specified location and return failure.
virtual InFlightDiagnostic emitError(llvm::SMLoc loc,
const Twine &message = {}) = 0;
//===--------------------------------------------------------------------===//
// 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".
virtual ParseResult parseRegion(Region &region,
ArrayRef<OperandType> arguments,
ArrayRef<Type> argTypes) = 0;
/// Parses a region if present.
virtual ParseResult parseOptionalRegion(Region &region,
ArrayRef<OperandType> arguments,
ArrayRef<Type> argTypes) = 0;
/// Parse a region argument. Region arguments define new values, so this also
/// checks if the values with the same name has not been defined yet.
virtual ParseResult parseRegionArgument(OperandType &argument) = 0;
/// Parse a region argument if present.
virtual ParseResult parseOptionalRegionArgument(OperandType &argument) = 0;
//===--------------------------------------------------------------------===//
// Successor Parsing
//===--------------------------------------------------------------------===//
/// Parse a single operation successor and its operand list.
virtual ParseResult
parseSuccessorAndUseList(Block *&dest,
SmallVectorImpl<Value *> &operands) = 0;
//===--------------------------------------------------------------------===//
// Type Parsing
//===--------------------------------------------------------------------===//
/// 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");
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 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();
}
/// 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

View File

@ -2363,7 +2363,7 @@ public:
/// 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);
@ -2815,7 +2815,7 @@ ParseResult FunctionParser::parseOperation() {
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 `)`
@ -2983,6 +2983,8 @@ public:
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))
@ -2998,69 +3000,56 @@ public:
}
//===--------------------------------------------------------------------===//
// 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));
}
/// Parse a `,` token.
ParseResult parseComma() override {
return parser.parseToken(Token::comma, "expected ','");
}
/// Parse a `,` token if present.
ParseResult parseOptionalComma() override {
return success(parser.consumeIf(Token::comma));
}
/// Parse a `=` token.
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 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);
}
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 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) &&
@ -3074,6 +3063,30 @@ public:
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.
@ -3087,14 +3100,7 @@ public:
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))
@ -3102,6 +3108,11 @@ public:
return parser.parseAttributeDict(result);
}
//===--------------------------------------------------------------------===//
// Operand Parsing
//===--------------------------------------------------------------------===//
/// Parse a single operand.
ParseResult parseOperand(OperandType &result) override {
FunctionParser::SSAUseInfo useInfo;
if (parser.parseSSAUse(useInfo))
@ -3111,31 +3122,8 @@ public:
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 {
@ -3208,6 +3196,38 @@ public:
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 &region, ArrayRef<OperandType> arguments,
@ -3234,7 +3254,7 @@ public:
return parser.parseRegion(region, regionArguments);
}
/// Parses an optional region.
/// Parses a region if present.
ParseResult parseOptionalRegion(Region &region,
ArrayRef<OperandType> arguments,
ArrayRef<Type> argTypes) override {
@ -3265,7 +3285,7 @@ public:
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();
@ -3273,37 +3293,59 @@ public:
}
//===--------------------------------------------------------------------===//
// 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.