|
15 | 15 | //===----------------------------------------------------------------------===//
|
16 | 16 |
|
17 | 17 | #include "API/api.h"
|
| 18 | +#include "API/errors.h" |
18 | 19 | #include "Config/CLIConfig.h"
|
19 | 20 | #include "Config/EnvVarConfig.h"
|
20 | 21 |
|
21 | 22 | #include "mlir/IR/AsmState.h"
|
22 | 23 | #include "mlir/IR/BuiltinOps.h"
|
| 24 | +#include "mlir/IR/Diagnostics.h" |
23 | 25 | #include "mlir/IR/Dialect.h"
|
24 | 26 | #include "mlir/IR/MLIRContext.h"
|
25 | 27 | #include "mlir/InitAllPasses.h"
|
|
32 | 34 | #include "llvm/ADT/StringRef.h"
|
33 | 35 | #include "llvm/Support/CommandLine.h"
|
34 | 36 | #include "llvm/Support/Error.h"
|
| 37 | +#include "llvm/Support/ErrorHandling.h" |
35 | 38 | #include "llvm/Support/FileSystem.h"
|
36 | 39 | #include "llvm/Support/InitLLVM.h"
|
37 | 40 | #include "llvm/Support/SourceMgr.h"
|
@@ -474,6 +477,57 @@ static void dumpMLIR_(llvm::raw_ostream *ostream, mlir::ModuleOp moduleOp) {
|
474 | 477 | *ostream << '\n';
|
475 | 478 | }
|
476 | 479 |
|
| 480 | +/// @brief Handler for the Diagnostic Engine. |
| 481 | +/// |
| 482 | +/// Uses qssc::emitDiagnostic to forward diagnostic to the python |
| 483 | +/// diagnostic callback. |
| 484 | +/// Prints diagnostic to llvm::errs to mimic default handler. |
| 485 | +/// @param diagnostic MLIR diagnostic from the Diagnostic Engine |
| 486 | +/// @param diagnosticCb Handle to python diagnostic callback |
| 487 | +static void |
| 488 | +diagEngineHandler(Diagnostic &diagnostic, |
| 489 | + std::optional<qssc::DiagnosticCallback> diagnosticCb) { |
| 490 | + |
| 491 | + // map diagnostic severity to qssc severity |
| 492 | + auto severity = diagnostic.getSeverity(); |
| 493 | + qssc::Severity qssc_severity = qssc::Severity::Error; |
| 494 | + switch (severity) { |
| 495 | + case mlir::DiagnosticSeverity::Error: |
| 496 | + qssc_severity = qssc::Severity::Error; |
| 497 | + break; |
| 498 | + case mlir::DiagnosticSeverity::Warning: |
| 499 | + qssc_severity = qssc::Severity::Warning; |
| 500 | + break; |
| 501 | + case mlir::DiagnosticSeverity::Note: |
| 502 | + case mlir::DiagnosticSeverity::Remark: |
| 503 | + qssc_severity = qssc::Severity::Info; |
| 504 | + } |
| 505 | + // emit diagnostic cast to void to discard result as it is not needed here |
| 506 | + (void)qssc::emitDiagnostic(std::move(diagnosticCb), qssc_severity, |
| 507 | + qssc::ErrorCategory::QSSCompilationFailure, |
| 508 | + diagnostic.str()); |
| 509 | + |
| 510 | + // emit to llvm::errs as well to mimic default handler |
| 511 | + diagnostic.getLocation().print(llvm::errs()); |
| 512 | + llvm::errs() << ": "; |
| 513 | + // based on mlir's Diagnostic.cpp:getDiagKindStr which is static |
| 514 | + switch (severity) { |
| 515 | + case mlir::DiagnosticSeverity::Note: |
| 516 | + llvm::errs() << "note: "; |
| 517 | + break; |
| 518 | + case mlir::DiagnosticSeverity::Warning: |
| 519 | + llvm::errs() << "warning: "; |
| 520 | + break; |
| 521 | + case mlir::DiagnosticSeverity::Error: |
| 522 | + llvm::errs() << "error: "; |
| 523 | + break; |
| 524 | + case mlir::DiagnosticSeverity::Remark: |
| 525 | + llvm::errs() << "remark: "; |
| 526 | + } |
| 527 | + llvm::errs() << diagnostic << "\n"; |
| 528 | + return; |
| 529 | +} |
| 530 | + |
477 | 531 | static llvm::Error
|
478 | 532 | compile_(int argc, char const **argv, std::string *outputString,
|
479 | 533 | std::optional<qssc::DiagnosticCallback> diagnosticCb) {
|
@@ -560,6 +614,10 @@ compile_(int argc, char const **argv, std::string *outputString,
|
560 | 614 |
|
561 | 615 | determineOutputType();
|
562 | 616 |
|
| 617 | + context.getDiagEngine().registerHandler([&](Diagnostic &diagnostic) { |
| 618 | + diagEngineHandler(diagnostic, diagnosticCb); |
| 619 | + }); |
| 620 | + |
563 | 621 | // Set up the output.
|
564 | 622 | llvm::raw_ostream *ostream;
|
565 | 623 | llvm::Optional<llvm::raw_string_ostream> outStringStream;
|
@@ -614,7 +672,7 @@ compile_(int argc, char const **argv, std::string *outputString,
|
614 | 672 | if (auto frontendError = qssc::frontend::openqasm3::parse(
|
615 | 673 | inputSource, !directInput, emitAction == Action::DumpAST,
|
616 | 674 | emitAction == Action::DumpASTPretty, emitAction >= Action::DumpMLIR,
|
617 |
| - moduleOp, std::move(diagnosticCb))) |
| 675 | + moduleOp, diagnosticCb)) |
618 | 676 | return frontendError;
|
619 | 677 |
|
620 | 678 | if (emitAction < Action::DumpMLIR)
|
@@ -652,6 +710,10 @@ compile_(int argc, char const **argv, std::string *outputString,
|
652 | 710 | } // if input == MLIR
|
653 | 711 |
|
654 | 712 | auto errorHandler = [&](const Twine &msg) {
|
| 713 | + // format msg to python handler as a compilation failure |
| 714 | + (void)qssc::emitDiagnostic(diagnosticCb, qssc::Severity::Error, |
| 715 | + qssc::ErrorCategory::QSSCompilationFailure, |
| 716 | + msg.str()); |
655 | 717 | emitError(UnknownLoc::get(&context)) << msg;
|
656 | 718 | return failure();
|
657 | 719 | };
|
|
0 commit comments