diff --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h --- a/mlir/include/mlir/IR/OpImplementation.h +++ b/mlir/include/mlir/IR/OpImplementation.h @@ -54,6 +54,11 @@ /// provide a valid type for the attribute. virtual void printAttributeWithoutType(Attribute attr); + /// Print the given string as an identifier. The identifer will be + /// surrounded with ""s and escaped if it has any special or non-printable + /// characters in it. + virtual void printIdentifier(StringRef identifier); + /// Print the given string as a symbol reference, i.e. a form representable by /// a SymbolRefAttr. A symbol reference is represented as a string prefixed /// with '@'. The reference is surrounded with ""'s and escaped if it has any @@ -686,6 +691,17 @@ // Identifier Parsing //===--------------------------------------------------------------------===// + /// Parse and identifer and store it in a string attribute named 'attrName'. + ParseResult parseIdentifier(StringAttr &result) { + if (failed(parseOptionalIdentifier(result))) + return emitError(getCurrentLocation()) << "expected valid dentifier"; + return success(); + } + + /// Parse an optional identifier and store it in a string attribute named + /// 'attrName'. + virtual ParseResult parseOptionalIdentifier(StringAttr &result) = 0; + /// Parse an @-identifier and store it (without the '@' symbol) in a string /// attribute named 'attrName'. ParseResult parseSymbolName(StringAttr &result, StringRef attrName, diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp --- a/mlir/lib/IR/AsmPrinter.cpp +++ b/mlir/lib/IR/AsmPrinter.cpp @@ -518,6 +518,7 @@ // guaranteed to go unused. os << "%"; } + void printIdentifier(StringRef) override {} void printSymbolName(StringRef) override {} void printSuccessor(Block *) override {} void printSuccessorAndUseList(Block *, ValueRange) override {} @@ -1562,6 +1563,19 @@ }); } +static void printIdentifier(StringRef identifier, raw_ostream &os) { + // If it can be represented as a bare identifier, write it directly. + if (!identifier.empty() && isBareIdentifier(identifier)) { + os << identifier; + return; + } + + // Otherwise, output the identifier wrapped in quotes with proper escaping. + os << "\""; + printEscapedString(identifier, os); + os << '"'; +} + /// Print the given string as a symbol reference. A symbol reference is /// represented as a string prefixed with '@'. The reference is surrounded with /// ""'s and escaped if it has any special or non-printable characters in it. @@ -2114,6 +2128,11 @@ impl->printAttribute(attr, Impl::AttrTypeElision::Must); } +void AsmPrinter::printIdentifier(StringRef identifier) { + assert(impl && "expected AsmPrinter::printIdentifier to be overriden"); + ::printIdentifier(identifier, impl->getStream()); +} + void AsmPrinter::printSymbolName(StringRef symbolRef) { assert(impl && "expected AsmPrinter::printSymbolName to be overriden"); ::printSymbolReference(symbolRef, impl->getStream()); diff --git a/mlir/lib/Parser/AsmParserImpl.h b/mlir/lib/Parser/AsmParserImpl.h --- a/mlir/lib/Parser/AsmParserImpl.h +++ b/mlir/lib/Parser/AsmParserImpl.h @@ -388,6 +388,24 @@ // Identifier Parsing //===--------------------------------------------------------------------===// + /// Parse an optional identifier and store it in a string attribute named + /// 'attrName'. + ParseResult parseOptionalIdentifier(StringAttr &result) override { + StringRef keyword; + if (succeeded(parseOptionalKeyword(&keyword))) { + result = getBuilder().getStringAttr(keyword); + return success(); + } + + std::string string; + if (succeeded(parseOptionalString(&string))) { + result = getBuilder().getStringAttr(string); + return success(); + } + + return failure(); + } + /// Parse an optional @-identifier and store it (without the '@' symbol) in a /// string attribute named 'attrName'. ParseResult parseOptionalSymbolName(StringAttr &result, StringRef attrName,