[Mlir-commits] [mlir] Add AsmParser::parseDecimalInteger. (PR #96255)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu Jun 20 17:08:48 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: None (quartersdg)
<details>
<summary>Changes</summary>
An attribute parser needs to parse lists of possibly negative integers separated by x in a way which is foiled by parseInteger handling hex formats and parseIntegerInDimensionList does not allow negatives.
---
Full diff: https://github.com/llvm/llvm-project/pull/96255.diff
4 Files Affected:
- (modified) mlir/include/mlir/IR/OpImplementation.h (+30-5)
- (modified) mlir/lib/AsmParser/AsmParserImpl.h (+5)
- (modified) mlir/lib/AsmParser/Parser.cpp (+46)
- (modified) mlir/lib/AsmParser/Parser.h (+3)
``````````diff
diff --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h
index fa435cb3155ed..ae412c7227f8e 100644
--- a/mlir/include/mlir/IR/OpImplementation.h
+++ b/mlir/include/mlir/IR/OpImplementation.h
@@ -714,16 +714,27 @@ class AsmParser {
return *parseResult;
}
+ /// Parse a decimal integer value from the stream.
+ template <typename IntT>
+ ParseResult parseDecimalInteger(IntT &result) {
+ auto loc = getCurrentLocation();
+ OptionalParseResult parseResult = parseOptionalDecimalInteger(result);
+ if (!parseResult.has_value())
+ return emitError(loc, "expected decimal integer value");
+ return *parseResult;
+ }
+
/// Parse an optional integer value from the stream.
virtual OptionalParseResult parseOptionalInteger(APInt &result) = 0;
+ virtual OptionalParseResult parseOptionalDecimalInteger(APInt &result) = 0;
- template <typename IntT>
- OptionalParseResult parseOptionalInteger(IntT &result) {
+ private:
+ template <typename IntT, typename ParseFn>
+ OptionalParseResult parseOptionalIntegerAndCheck(IntT &result,
+ ParseFn &&parseFn) {
auto loc = getCurrentLocation();
-
- // Parse the unsigned variant.
APInt uintResult;
- OptionalParseResult parseResult = parseOptionalInteger(uintResult);
+ OptionalParseResult parseResult = parseFn(uintResult);
if (!parseResult.has_value() || failed(*parseResult))
return parseResult;
@@ -737,6 +748,20 @@ class AsmParser {
return success();
}
+ public:
+ template <typename IntT>
+ OptionalParseResult parseOptionalInteger(IntT &result) {
+ return parseOptionalIntegerAndCheck(
+ result, [&](APInt &result) { return parseOptionalInteger(result); });
+ }
+
+ template <typename IntT>
+ OptionalParseResult parseOptionalDecimalInteger(IntT &result) {
+ return parseOptionalIntegerAndCheck(result, [&](APInt &result) {
+ return parseOptionalDecimalInteger(result);
+ });
+ }
+
/// These are the supported delimiters around operand lists and region
/// argument lists, used by parseOperandList.
enum class Delimiter {
diff --git a/mlir/lib/AsmParser/AsmParserImpl.h b/mlir/lib/AsmParser/AsmParserImpl.h
index 8f22be80865bf..b12687833e3fd 100644
--- a/mlir/lib/AsmParser/AsmParserImpl.h
+++ b/mlir/lib/AsmParser/AsmParserImpl.h
@@ -322,6 +322,11 @@ class AsmParserImpl : public BaseT {
return parser.parseOptionalInteger(result);
}
+ /// Parse an optional integer value from the stream.
+ OptionalParseResult parseOptionalDecimalInteger(APInt &result) override {
+ return parser.parseOptionalDecimalInteger(result);
+ }
+
/// Parse a list of comma-separated items with an optional delimiter. If a
/// delimiter is provided, then an empty list is allowed. If not, then at
/// least one element will be parsed.
diff --git a/mlir/lib/AsmParser/Parser.cpp b/mlir/lib/AsmParser/Parser.cpp
index 1b8b4bac1821e..48aabb0163464 100644
--- a/mlir/lib/AsmParser/Parser.cpp
+++ b/mlir/lib/AsmParser/Parser.cpp
@@ -42,6 +42,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/Sequence.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Alignment.h"
@@ -308,6 +309,51 @@ OptionalParseResult Parser::parseOptionalInteger(APInt &result) {
return success();
}
+namespace {
+bool isBinOrHexOrOctIndicator(char c) {
+ return (llvm::toLower(c) == 'x' || llvm::toLower(c) == 'b' ||
+ llvm::isDigit(c));
+}
+} // namespace
+
+/// Parse an optional integer value only in decimal format from the stream.
+OptionalParseResult Parser::parseOptionalDecimalInteger(APInt &result) {
+ Token curToken = getToken();
+ if (curToken.isNot(Token::integer, Token::minus)) {
+ return std::nullopt;
+ }
+
+ bool negative = consumeIf(Token::minus);
+ Token curTok = getToken();
+ if (parseToken(Token::integer, "expected integer value")) {
+ return failure();
+ }
+
+ StringRef spelling = curTok.getSpelling();
+ // If the integer is in bin, hex, or oct format, return only the 0 and reset
+ // the lex pointer.
+ if (spelling[0] == '0' && spelling.size() > 1 &&
+ isBinOrHexOrOctIndicator(spelling[1])) {
+ result = 0;
+ state.lex.resetPointer(spelling.data() + 1);
+ consumeToken();
+ return success();
+ }
+
+ if (spelling.getAsInteger(10, result))
+ return emitError(curTok.getLoc(), "integer value too large");
+
+ // Make sure we have a zero at the top so we return the right signedness.
+ if (result.isNegative())
+ result = result.zext(result.getBitWidth() + 1);
+
+ // Process the negative sign if present.
+ if (negative)
+ result.negate();
+
+ return success();
+}
+
/// Parse a floating point value from an integer literal token.
ParseResult Parser::parseFloatFromIntegerLiteral(
std::optional<APFloat> &result, const Token &tok, bool isNegative,
diff --git a/mlir/lib/AsmParser/Parser.h b/mlir/lib/AsmParser/Parser.h
index b959e67b8e258..4caab499e1a0e 100644
--- a/mlir/lib/AsmParser/Parser.h
+++ b/mlir/lib/AsmParser/Parser.h
@@ -144,6 +144,9 @@ class Parser {
/// Parse an optional integer value from the stream.
OptionalParseResult parseOptionalInteger(APInt &result);
+ /// Parse an optional integer value only in decimal format from the stream.
+ OptionalParseResult parseOptionalDecimalInteger(APInt &result);
+
/// Parse a floating point value from an integer literal token.
ParseResult parseFloatFromIntegerLiteral(std::optional<APFloat> &result,
const Token &tok, bool isNegative,
``````````
</details>
https://github.com/llvm/llvm-project/pull/96255
More information about the Mlir-commits
mailing list