Error message out of mlir::InFlightDiagnostic

Hi:
I am bit confused on how to capture (to say, std::string) the error message that comes out of a failed mlir::ParseSourceString(sourceStr, &context).

Suppose my sourceStr has an error: integer constant out of range. I can see it dumped to screen when calling parseSourceString from my code :

mlir::OwningModuleRef module { parseSourceString(source, &context)}

However, when I try to capture that message through module->emitError() which returns an InFlightDiagnostic I run into problems and get quite confused. I have tried to read the documentation Diagnostic Infrastructure - MLIR and see existing codes, but it is not clear whats the right way to do it. Documentation says I must register a DiagnosticEngine but then it also says it is not the preferred way as operation have emit utility method (e.g. emitError). Some help on this will be useful. I tried registering DiagnosticEngine but that approach is not so straightforward to me either.
Thanks a lot

Hi,

How do you want to capture it? An example of how to define/use a scoped diagnostic handler is here - basically it registers a handler which captures errors emitted and creates a Status from (which is common error reporting interface there and useful for reporting error outside lifetime of context). The comment about not using diagnostic engine is about using the emit method mentioned there to emit errors rather than using the emit method on the ops and the like. Basically the more precise location one can use the better the reporting could be and using the emit methods to report helps in that regard.

Hi:

I want to be able to do something like this:

mlir::OwningModuleRef module { parseSourceString(source, &context)};
if (!module) {
  std::cout << "Parse string failed with error: " << module->emitError().message() << std::endl;
}

module->emitError() isn’t used to retrieve an error, but to emit a new one. It is used like this:

module->emitError() << "can't parse the module";

If you want to capture the diagnostics issues while calling parseSourceString you need to install a handler on the MLIRContext first. I don’t know if we have an example in-tree, we should likely add this if it isn’t there yet.

Thanks Mehdi. Now i understand the purpose of emitError. I was able to register handler and get the str I wanted. Suggestion on possible improvement much appreciated.

std::string error_msg;
mlir::DiagnosticEngine& engine = context.getDiagEngine();

mlir::DiagnosticEngine::HandlerID id = engine.registerHandler( 
      [&](mlir::Diagnostic &diag) -> mlir::LogicalResult {
            bool should_propagate_diagnostic = true;
           if (diag.getSeverity() == mlir::DiagnosticSeverity::Error) {
             msg += diag.str();
             should_propagate_diagnostic = false;
            }
            return mlir::failure(should_propagate_diagnostic);
  });

    mlir::OwningModuleRef module {
                   mlir::parseSourceString(sourceStr, &context)};
   if (!module) {
       throw .... 
1 Like

Yes that is similar to what is done in StatusScopedDiagnosticHandler above except we use llvm::raw_string_ostream to concat and just remember to deregister before you throw.

OK . Thank you