diff --git a/mlir/lib/Parser/Token.h b/mlir/lib/Parser/Token.h --- a/mlir/lib/Parser/Token.h +++ b/mlir/lib/Parser/Token.h @@ -19,8 +19,8 @@ class Token { public: enum Kind { -#define TOK_MARKER(NAME) NAME, -#define TOK_IDENTIFIER(NAME) NAME, +#define TOK_MARKER(NAME, DESCRIPTION) NAME, +#define TOK_IDENTIFIER(NAME, DESCRIPTION) NAME, #define TOK_LITERAL(NAME) NAME, #define TOK_PUNCTUATION(NAME, SPELLING) NAME, #define TOK_KEYWORD(SPELLING) kw_##SPELLING, @@ -105,6 +105,9 @@ /// literal tokens since they have no fixed spelling. static StringRef getTokenSpelling(Kind kind); + /// Return a human readable description of a token kind. + static StringRef getTokenDescription(Kind kind); + private: /// Discriminator that indicates the sort of token this is. Kind kind; diff --git a/mlir/lib/Parser/Token.cpp b/mlir/lib/Parser/Token.cpp --- a/mlir/lib/Parser/Token.cpp +++ b/mlir/lib/Parser/Token.cpp @@ -164,6 +164,28 @@ } } +/// Return a human readable description of a token kind. +StringRef Token::getTokenDescription(Kind kind) { + switch (kind) { +#define TOK_MARKER(NAME, DESCRIPTION) \ + case NAME: \ + return DESCRIPTION; +#define TOK_IDENTIFIER(NAME, DESCRIPTION) \ + case NAME: \ + return DESCRIPTION; +#define TOK_LITERAL(NAME) \ + case NAME: \ + return #NAME; +#define TOK_PUNCTUATION(NAME, SPELLING) \ + case NAME: \ + return "'" SPELLING "'"; +#define TOK_KEYWORD(SPELLING) \ + case kw_##SPELLING: \ + return "keyword '" #SPELLING "'"; +#include "TokenKinds.def" + } +} + /// Return true if this is one of the keyword token kinds (e.g. kw_if). bool Token::isKeyword() const { switch (kind) { diff --git a/mlir/lib/Parser/TokenKinds.def b/mlir/lib/Parser/TokenKinds.def --- a/mlir/lib/Parser/TokenKinds.def +++ b/mlir/lib/Parser/TokenKinds.def @@ -18,10 +18,10 @@ #endif #ifndef TOK_MARKER -#define TOK_MARKER(X) +#define TOK_MARKER(X, DESCRIPTION) #endif #ifndef TOK_IDENTIFIER -#define TOK_IDENTIFIER(NAME) +#define TOK_IDENTIFIER(NAME, DESCRIPTION) #endif #ifndef TOK_LITERAL #define TOK_LITERAL(NAME) @@ -34,16 +34,16 @@ #endif // Markers -TOK_MARKER(eof) -TOK_MARKER(error) +TOK_MARKER(eof, "end of file") +TOK_MARKER(error, "error") // Identifiers. -TOK_IDENTIFIER(bare_identifier) // foo -TOK_IDENTIFIER(at_identifier) // @foo -TOK_IDENTIFIER(hash_identifier) // #foo -TOK_IDENTIFIER(percent_identifier) // %foo -TOK_IDENTIFIER(caret_identifier) // ^foo -TOK_IDENTIFIER(exclamation_identifier) // !foo +TOK_IDENTIFIER(bare_identifier, "bare-id") // foo +TOK_IDENTIFIER(at_identifier, "symbol-ref-id") // @foo +TOK_IDENTIFIER(hash_identifier, "attribute-id") // #foo +TOK_IDENTIFIER(percent_identifier, "value-id") // %foo +TOK_IDENTIFIER(caret_identifier, "caret-id") // ^foo +TOK_IDENTIFIER(exclamation_identifier, "type-id") // !foo // Literals TOK_LITERAL(floatliteral) // 2.0 diff --git a/mlir/lib/Parser/TypeParser.cpp b/mlir/lib/Parser/TypeParser.cpp --- a/mlir/lib/Parser/TypeParser.cpp +++ b/mlir/lib/Parser/TypeParser.cpp @@ -311,7 +311,9 @@ Type Parser::parseNonFunctionType() { switch (getToken().getKind()) { default: - return (emitError("expected non-function type"), nullptr); + emitError("expected non-function type, but found " + + Token::getTokenDescription(getToken().getKind())); + return nullptr; case Token::kw_memref: return parseMemRefType(); case Token::kw_tensor: diff --git a/mlir/test/IR/invalid-func-op.mlir b/mlir/test/IR/invalid-func-op.mlir --- a/mlir/test/IR/invalid-func-op.mlir +++ b/mlir/test/IR/invalid-func-op.mlir @@ -52,7 +52,7 @@ // ----- -// expected-error@+1 {{expected non-function type}} +// expected-error@+1 {{expected non-function type, but found bare-id}} func @f() -> (foo // ----- diff --git a/mlir/test/IR/invalid-locations.mlir b/mlir/test/IR/invalid-locations.mlir --- a/mlir/test/IR/invalid-locations.mlir +++ b/mlir/test/IR/invalid-locations.mlir @@ -81,7 +81,7 @@ func @location_fused_missing_metadata() { ^bb: - // expected-error@+1 {{expected non-function type}} + // expected-error@+1 {{expected non-function type, but found ')'}} return loc(fused<) // expected-error {{expected valid attribute metadata}} } diff --git a/mlir/test/IR/invalid-ops.mlir b/mlir/test/IR/invalid-ops.mlir --- a/mlir/test/IR/invalid-ops.mlir +++ b/mlir/test/IR/invalid-ops.mlir @@ -202,7 +202,7 @@ // Comparisons must have the "predicate" attribute. func @func_with_ops(i32, i32) { ^bb0(%a : i32, %b : i32): - %r = cmpi %a, %b : i32 // expected-error {{expected non-function type}} + %r = cmpi %a, %b : i32 // expected-error {{expected non-function type, but found value-id}} } // ----- diff --git a/mlir/test/IR/invalid.mlir b/mlir/test/IR/invalid.mlir --- a/mlir/test/IR/invalid.mlir +++ b/mlir/test/IR/invalid.mlir @@ -3,12 +3,12 @@ // Check different error cases. // ----- -func @illegaltype(i) // expected-error {{expected non-function type}} +func @illegaltype(i) // expected-error {{expected non-function type, but found bare-id}} // ----- func @illegaltype() { - %0 = constant dense<0> : : vector<4 x f32> // expected-error {{expected non-function type}} + %0 = constant dense<0> : : vector<4 x f32> // expected-error {{expected non-function type, but found '<'}} } // ----- @@ -239,7 +239,7 @@ // ----- func @nonconstant_step(%1 : i32) { - affine.for %2 = 1 to 5 step %1 { // expected-error {{expected non-function type}} + affine.for %2 = 1 to 5 step %1 { // expected-error {{expected non-function type, but found value-id}} // ----- @@ -332,7 +332,7 @@ // ----- -func @malformed_type(%a : intt) { // expected-error {{expected non-function type}} +func @malformed_type(%a : intt) { // expected-error {{expected non-function type, but found bare-id}} } // ----- @@ -402,7 +402,7 @@ ^bb0: %c = "foo"() : () -> i1 %a = "foo"() : () -> i32 - cond_br %c, ^bb0(%a, %a : i32, ^bb0) // expected-error {{expected non-function type}} + cond_br %c, ^bb0(%a, %a : i32, ^bb0) // expected-error {{expected non-function type, but found caret-id}} } // ----- @@ -497,7 +497,7 @@ // ----- -// expected-error@+1 {{expected non-function type}} +// expected-error@+1 {{expected non-function type, but found '...'}} func @func_variadic(...) // ----- @@ -555,7 +555,7 @@ // ----- func @max_in_upper_bound(%N : index) { - affine.for %i = 1 to max affine_map<(i)->(N, 100)> { //expected-error {{expected non-function type}} + affine.for %i = 1 to max affine_map<(i)->(N, 100)> { // expected-error {{expected non-function type, but found keyword 'max'}} } return } @@ -820,7 +820,7 @@ // ----- -!missing_type_alias = type // expected-error@+2 {{expected non-function type}} +!missing_type_alias = type // expected-error@+2 {{expected non-function type, but found end of file}} // ----- @@ -896,27 +896,27 @@ // ----- -// expected-error @+1 {{expected non-function type}} +// expected-error @+1 {{expected non-function type, but found '-'}} func @negative_in_vector_size() -> vector<1x-1xi32> // ----- -// expected-error @+1 {{expected non-function type}} +// expected-error @+1 {{expected non-function type, but found '-'}} func @negative_memref_size() -> memref<-1xi32> // ----- -// expected-error @+1 {{expected non-function type}} +// expected-error @+1 {{expected non-function type, but found '-'}} func @negative_in_memref_size() -> memref<1x-1xi32> // ----- -// expected-error @+1 {{expected non-function type}} +// expected-error @+1 {{expected non-function type, but found '-'}} func @negative_tensor_size() -> tensor<-1xi32> // ----- -// expected-error @+1 {{expected non-function type}} +// expected-error @+1 {{expected non-function type, but found '-'}} func @negative_in_tensor_size() -> tensor<1x-1xi32> // -----