From: Stephen Neuendorffer Date: Sun, 5 Apr 2020 05:54:35 +0000 (-0700) Subject: [MLIR] Add note for file-line numbers in tablegen errors for assembly formats X-Git-Tag: llvmorg-12-init~9739 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=19fec004e23adbc43b839ddf1be8bc2e22e58aca;p=platform%2Fupstream%2Fllvm.git [MLIR] Add note for file-line numbers in tablegen errors for assembly formats Error messages for the custom assembly format are difficult to understand because there are no line numbers. This happens because the assembly format is parsed as a standalone line, separate from it's parent file, with no useful location information. Fixing this properly probably requires quite a bit of invasive plumbing through the SourceMgr, similar to how included files are handled This proposal is a less invasive short term solution. When generating an error message we generate an additional note which at least properly describes the operation definition the error occured in, if not the actual line number of the assemblyFormat definition. A typical message is like: error: type of operand #0, named 'operand', is not buildable and a buildable type cannot be inferred $operand type($result) attr-dict ^ /src/llvm-project/mlir/test/mlir-tblgen/op-format-spec.td:296:1: note: in custom assembly format for this operation def ZCoverageInvalidC : TestFormat_Op<"variable_invalid_c", [{ ^ note: suggest adding a type constraint to the operation or adding a 'type($operand)' directive to the custom assembly format $operand type($result) attr-dict ^ Differential Revision: https://reviews.llvm.org/D77488 --- diff --git a/mlir/test/mlir-tblgen/op-format-spec.td b/mlir/test/mlir-tblgen/op-format-spec.td index 1e7a974..482175b 100644 --- a/mlir/test/mlir-tblgen/op-format-spec.td +++ b/mlir/test/mlir-tblgen/op-format-spec.td @@ -19,7 +19,7 @@ class TestFormat_Op traits = []> //===----------------------------------------------------------------------===// // attr-dict -// CHECK: error: 'attr-dict' directive not found in custom assembly format +// CHECK: error: 'attr-dict' directive not found def DirectiveAttrDictInvalidA : TestFormat_Op<"attrdict_invalid_a", [{ }]>; // CHECK: error: 'attr-dict' directive has already been seen @@ -300,7 +300,7 @@ def VariableInvalidK : TestFormat_Op<"variable_invalid_k", [{ def ZCoverageInvalidA : TestFormat_Op<"variable_invalid_a", [{ attr-dict }]>, Arguments<(ins AnyMemRef:$operand)>, Results<(outs AnyMemRef:$result)>; -// CHECK: error: operand #0, named 'operand', not found in custom assembly format +// CHECK: error: operand #0, named 'operand', not found // CHECK: note: suggest adding a '$operand' directive to the custom assembly format def ZCoverageInvalidB : TestFormat_Op<"variable_invalid_b", [{ type($result) attr-dict @@ -320,7 +320,7 @@ def ZCoverageInvalidD : TestFormat_Op<"variable_invalid_d", [{ def ZCoverageInvalidE : TestFormat_Op<"variable_invalid_e", [{ attr-dict }]>, Results<(outs Variadic:$result)>; -// CHECK: error: successor #0, named 'successor', not found in custom assembly format +// CHECK: error: successor #0, named 'successor', not found // CHECK: note: suggest adding a '$successor' directive to the custom assembly format def ZCoverageInvalidF : TestFormat_Op<"variable_invalid_f", [{ attr-dict diff --git a/mlir/tools/mlir-tblgen/OpFormatGen.cpp b/mlir/tools/mlir-tblgen/OpFormatGen.cpp index e4b6694..4cd9dfb 100644 --- a/mlir/tools/mlir-tblgen/OpFormatGen.cpp +++ b/mlir/tools/mlir-tblgen/OpFormatGen.cpp @@ -1055,7 +1055,7 @@ private: /// This class implements a simple lexer for operation assembly format strings. class FormatLexer { public: - FormatLexer(llvm::SourceMgr &mgr); + FormatLexer(llvm::SourceMgr &mgr, Operator &op); /// Lex the next token and return it. Token lexToken(); @@ -1080,23 +1080,29 @@ private: Token lexVariable(const char *tokStart); llvm::SourceMgr &srcMgr; + Operator &op; StringRef curBuffer; const char *curPtr; }; } // end anonymous namespace -FormatLexer::FormatLexer(llvm::SourceMgr &mgr) : srcMgr(mgr) { +FormatLexer::FormatLexer(llvm::SourceMgr &mgr, Operator &op) + : srcMgr(mgr), op(op) { curBuffer = srcMgr.getMemoryBuffer(mgr.getMainFileID())->getBuffer(); curPtr = curBuffer.begin(); } Token FormatLexer::emitError(llvm::SMLoc loc, const Twine &msg) { srcMgr.PrintMessage(loc, llvm::SourceMgr::DK_Error, msg); + llvm::SrcMgr.PrintMessage(op.getLoc()[0], llvm::SourceMgr::DK_Note, + "in custom assembly format for this operation"); return formToken(Token::error, loc.getPointer()); } Token FormatLexer::emitErrorAndNote(llvm::SMLoc loc, const Twine &msg, const Twine ¬e) { srcMgr.PrintMessage(loc, llvm::SourceMgr::DK_Error, msg); + llvm::SrcMgr.PrintMessage(op.getLoc()[0], llvm::SourceMgr::DK_Note, + "in custom assembly format for this operation"); srcMgr.PrintMessage(loc, llvm::SourceMgr::DK_Note, note); return formToken(Token::error, loc.getPointer()); } @@ -1233,7 +1239,7 @@ namespace { class FormatParser { public: FormatParser(llvm::SourceMgr &mgr, OperationFormat &format, Operator &op) - : lexer(mgr), curToken(lexer.lexToken()), fmt(format), op(op), + : lexer(mgr, op), curToken(lexer.lexToken()), fmt(format), op(op), seenOperandTypes(op.getNumOperands()), seenResultTypes(op.getNumResults()) {} @@ -1481,8 +1487,7 @@ LogicalResult FormatParser::verifyOperands( if (!hasAllOperands && !seenOperands.count(&operand)) { return emitErrorAndNote(loc, "operand #" + Twine(i) + ", named '" + - operand.name + - "', not found in custom assembly format", + operand.name + "', not found", "suggest adding a '$" + operand.name + "' directive to the custom assembly format"); } @@ -1572,8 +1577,7 @@ LogicalResult FormatParser::verifySuccessors(llvm::SMLoc loc) { if (!seenSuccessors.count(&successor)) { return emitErrorAndNote(loc, "successor #" + Twine(i) + ", named '" + - successor.name + - "', not found in custom assembly format", + successor.name + "', not found", "suggest adding a '$" + successor.name + "' directive to the custom assembly format"); }