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
This commit is contained in:
Jacques Pienaar
2018-06-24 09:10:36 -07:00
committed by jpienaar
parent 81f5332e45
commit a5fb2f47e1
2 changed files with 63 additions and 17 deletions

View File

@@ -0,0 +1,23 @@
; TODO(andydavis) Resolve relative path issue w.r.t invoking mlir-opt in RUN
; statements (perhaps through using lit config substitutions).
;
; RUN: %S/../../mlir-opt %s -o - -check-parser-errors 2>&1 | FileCheck %s
; Check different error cases.
; TODO(jpienaar): This is checking the errors by simplify verifying the output.
; -----
; CHECK: expected type
; CHECK-NEXT: illegaltype
extfunc @illegaltype(i42)
; -----
; CHECK: expected type
; CHECK-NEXT: nestedtensor
extfunc @nestedtensor(tensor<tensor<i8>>) -> ()
; -----
; CHECK: expected '{' in CFG function
cfgfunc @foo()
cfgfunc @bar()
; -----
; CHECK: expected a function identifier like
; CHECK-NEXT: missingsigil
extfunc missingsigil() -> (i1, int, f32)

View File

@@ -39,6 +39,9 @@ static cl::opt<std::string>
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 @@ static std::unique_ptr<ToolOutputFile> getOutputStream() {
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 @@ int main(int argc, char **argv) {
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));
}