Add negative parsing tests using mlir-opt.
Add parsing tests with errors. Follows direct path of splitting file into test groups (using a marker) and parsing each section individually. The expected errors are checked using FileCheck and parser error does not result in terminating parsing the rest of the file if check-parser-error.
This is an interim approach until refactoring lexer/parser.
PiperOrigin-RevId: 201867941
diff --git a/tools/mlir-opt/mlir-opt.cpp b/tools/mlir-opt/mlir-opt.cpp
index a75ba76..75ed4f5 100644
--- a/tools/mlir-opt/mlir-opt.cpp
+++ b/tools/mlir-opt/mlir-opt.cpp
@@ -39,6 +39,9 @@
outputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"),
cl::init("-"));
+static cl::opt<bool>
+checkParserErrors("check-parser-errors", cl::desc("Check for parser errors"),
+ cl::init(false));
/// Open the specified output file and return it, exiting if there is any I/O or
/// other errors.
@@ -54,11 +57,43 @@
return result;
}
+/// Parses the memory buffer and, if successfully parsed, prints the parsed
+/// output. Returns whether parsing succeeded.
+bool parseAndPrintMemoryBuffer(std::unique_ptr<MemoryBuffer> buffer) {
+ // Tell sourceMgr about this buffer, which is what the parser will pick up.
+ SourceMgr sourceMgr;
+ sourceMgr.AddNewSourceBuffer(std::move(buffer), SMLoc());
+
+ // Parse the input file and emit any errors.
+ MLIRContext context;
+ std::unique_ptr<Module> module(parseSourceFile(sourceMgr, &context));
+ if (!module) return false;
+
+ // Print the output.
+ auto output = getOutputStream();
+ module->print(output->os());
+ output->keep();
+
+ // Success.
+ return true;
+}
+
+/// Split the memory buffer into multiple buffers using the marker -----.
+bool splitMemoryBufferForErrorChecking(std::unique_ptr<MemoryBuffer> buffer) {
+ const char marker[] = "-----";
+ SmallVector<StringRef, 2> sourceBuffers;
+ buffer->getBuffer().split(sourceBuffers, marker);
+ for (auto& subbuffer : sourceBuffers)
+ parseAndPrintMemoryBuffer(MemoryBuffer::getMemBufferCopy(subbuffer));
+
+ // Ignore errors returned by parseAndPrintMemoryBuffer when checking parse
+ // errors reported.
+ return true;
+}
+
int main(int argc, char **argv) {
InitLLVM x(argc, argv);
- MLIRContext context;
-
cl::ParseCommandLineOptions(argc, argv, "MLIR modular optimizer driver\n");
// Set up the input file.
@@ -69,19 +104,7 @@
return 1;
}
- // Tell sourceMgr about this buffer, which is what the parser will pick up.
- SourceMgr sourceMgr;
- sourceMgr.AddNewSourceBuffer(std::move(*fileOrErr), SMLoc());
-
- // Parse the input file and emit any errors.
- std::unique_ptr<Module> module(parseSourceFile(sourceMgr, &context));
- if (!module) return 1;
-
- // Print the output.
- auto output = getOutputStream();
- module->print(output->os());
- output->keep();
-
- // Success.
- return 0;
+ if (checkParserErrors)
+ return !splitMemoryBufferForErrorChecking(std::move(*fileOrErr));
+ return !parseAndPrintMemoryBuffer(std::move(*fileOrErr));
}