diff --git a/flang/test/Fir/fir-types.fir b/flang/test/Fir/fir-types.fir --- a/flang/test/Fir/fir-types.fir +++ b/flang/test/Fir/fir-types.fir @@ -25,12 +25,14 @@ // CHECK-LABEL: func private @dvd4() -> !fir.type // CHECK-LABEL: func private @dvd5() -> !fir.type // CHECK-LABEL: func private @dvd6() -> !fir.type>}> +// CHECK-LABEL: func private @dvd7() -> !fir.type func private @dvd1() -> !fir.type func private @dvd2() -> !fir.type func private @dvd3() -> !fir.type func private @dvd4() -> !fir.type func private @dvd5() -> !fir.type func private @dvd6() -> !fir.type>}> +func private @dvd7() -> !fir.type // FIR array types // CHECK-LABEL: func private @arr1() -> !fir.array<10xf32> diff --git a/mlir/lib/Dialect/Quant/IR/TypeParser.cpp b/mlir/lib/Dialect/Quant/IR/TypeParser.cpp --- a/mlir/lib/Dialect/Quant/IR/TypeParser.cpp +++ b/mlir/lib/Dialect/Quant/IR/TypeParser.cpp @@ -29,15 +29,16 @@ // Parse storage type (alpha_ident, integer_literal). StringRef identifier; unsigned storageTypeWidth = 0; - if (failed(parser.parseOptionalKeyword(&identifier))) { - // If we didn't parse a keyword, this must be a signed type. - if (parser.parseType(type)) + OptionalParseResult result = parser.parseOptionalType(type); + if (result.hasValue()) { + if (!succeeded(*result)) { + parser.parseType(type); return nullptr; - isSigned = true; + } + isSigned = !type.isUnsigned(); storageTypeWidth = type.getWidth(); - + } else if (succeeded(parser.parseKeyword(&identifier))) { // Otherwise, this must be an unsigned integer (`u` integer-literal). - } else { if (!identifier.consume_front("u")) { parser.emitError(typeLoc, "illegal storage type prefix"); return nullptr; @@ -48,6 +49,8 @@ } isSigned = false; type = parser.getBuilder().getIntegerType(storageTypeWidth); + } else { + return nullptr; } if (storageTypeWidth == 0 || diff --git a/mlir/lib/Parser/DialectSymbolParser.cpp b/mlir/lib/Parser/DialectSymbolParser.cpp --- a/mlir/lib/Parser/DialectSymbolParser.cpp +++ b/mlir/lib/Parser/DialectSymbolParser.cpp @@ -250,7 +250,7 @@ /// Returns true if the current token corresponds to a keyword. bool isCurrentTokenAKeyword() const { - return parser.getToken().is(Token::bare_identifier) || + return parser.getToken().isAny(Token::bare_identifier, Token::inttype) || parser.getToken().isKeyword(); } diff --git a/mlir/test/mlir-tblgen/types.mlir b/mlir/test/mlir-tblgen/types.mlir --- a/mlir/test/mlir-tblgen/types.mlir +++ b/mlir/test/mlir-tblgen/types.mlir @@ -504,3 +504,27 @@ "test.indexElementsAttr"() {attr = dense<[1, 2]>:tensor<2xi32>} : () -> () return } + +// ----- + +// CHECK-LABEL: @struct_success +func @struct_success() { + "test.simple_struct"() : () -> (!test.struct<{a, i32}, {b, f64}>) + return +} + +// ----- + +// CHECK-LABEL: @struct_with_field_names_like_types +func @struct_with_field_names_like_types() { + "test.struct_with_field_names_like_types"() : () -> (!test.struct<{i32, i32}, {f64, f64}>) + return +} + +// ----- + +func @struct_bad_keywords() { + // expected-error@+1 {{expected valid keyword}} + "test.struct_bad_keywords"() : () -> (!test.struct<{42, i32}>) + return +}