Skip to content

Commit 7804189

Browse files
authored
Improve Error Reporting (#162)
Adds additional support for error reporting: * connects qssc:emitDiagnostic to mlir diagnostic engine and pass manager error handler * adds CMAKE support for adding additional python files from the target directory at build time.
1 parent 482d377 commit 7804189

File tree

2 files changed

+94
-1
lines changed

2 files changed

+94
-1
lines changed

lib/API/api.cpp

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
//===----------------------------------------------------------------------===//
1616

1717
#include "API/api.h"
18+
#include "API/errors.h"
1819
#include "Config/CLIConfig.h"
1920
#include "Config/EnvVarConfig.h"
2021

2122
#include "mlir/IR/AsmState.h"
2223
#include "mlir/IR/BuiltinOps.h"
24+
#include "mlir/IR/Diagnostics.h"
2325
#include "mlir/IR/Dialect.h"
2426
#include "mlir/IR/MLIRContext.h"
2527
#include "mlir/InitAllPasses.h"
@@ -32,6 +34,7 @@
3234
#include "llvm/ADT/StringRef.h"
3335
#include "llvm/Support/CommandLine.h"
3436
#include "llvm/Support/Error.h"
37+
#include "llvm/Support/ErrorHandling.h"
3538
#include "llvm/Support/FileSystem.h"
3639
#include "llvm/Support/InitLLVM.h"
3740
#include "llvm/Support/SourceMgr.h"
@@ -474,6 +477,57 @@ static void dumpMLIR_(llvm::raw_ostream *ostream, mlir::ModuleOp moduleOp) {
474477
*ostream << '\n';
475478
}
476479

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+
477531
static llvm::Error
478532
compile_(int argc, char const **argv, std::string *outputString,
479533
std::optional<qssc::DiagnosticCallback> diagnosticCb) {
@@ -560,6 +614,10 @@ compile_(int argc, char const **argv, std::string *outputString,
560614

561615
determineOutputType();
562616

617+
context.getDiagEngine().registerHandler([&](Diagnostic &diagnostic) {
618+
diagEngineHandler(diagnostic, diagnosticCb);
619+
});
620+
563621
// Set up the output.
564622
llvm::raw_ostream *ostream;
565623
llvm::Optional<llvm::raw_string_ostream> outStringStream;
@@ -614,7 +672,7 @@ compile_(int argc, char const **argv, std::string *outputString,
614672
if (auto frontendError = qssc::frontend::openqasm3::parse(
615673
inputSource, !directInput, emitAction == Action::DumpAST,
616674
emitAction == Action::DumpASTPretty, emitAction >= Action::DumpMLIR,
617-
moduleOp, std::move(diagnosticCb)))
675+
moduleOp, diagnosticCb))
618676
return frontendError;
619677

620678
if (emitAction < Action::DumpMLIR)
@@ -652,6 +710,10 @@ compile_(int argc, char const **argv, std::string *outputString,
652710
} // if input == MLIR
653711

654712
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());
655717
emitError(UnknownLoc::get(&context)) << msg;
656718
return failure();
657719
};

python_lib/CMakeLists.txt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,27 @@ macro(python_pkg_add_file file lib)
2525
LIST(APPEND ${lib} ${dest_file})
2626
endmacro()
2727

28+
29+
macro(python_pkg_add_target_file file lib)
30+
set(src_file ${file})
31+
get_filename_component(barename ${file} NAME)
32+
set(dest_file ${CMAKE_CURRENT_BINARY_DIR}/qss_compiler/${barename})
33+
add_custom_command(OUTPUT ${dest_file}
34+
COMMAND ${CMAKE_COMMAND} -E copy
35+
${src_file}
36+
${dest_file}
37+
DEPENDS ${src_file}
38+
)
39+
LIST(APPEND ${lib} ${dest_file})
40+
endmacro()
41+
42+
43+
macro(python_pkg_add_target_files)
44+
foreach(file ${ARGN})
45+
python_pkg_add_target_file(${file} PY_LIB_FILES)
46+
endforeach()
47+
endmacro()
48+
2849
# collect python package files from this directory
2950
# into a variable PY_LIB_FILES
3051
macro(python_pkg_add_files)
@@ -44,6 +65,16 @@ python_pkg_add_files(
4465
setup.py
4566
)
4667

68+
foreach(dir ${QSSC_TARGET_PYTHON_DIRS})
69+
message(STATUS "Adding Python target directory: ${dir}")
70+
file(GLOB_RECURSE
71+
dir_files
72+
"${dir}/*py"
73+
)
74+
python_pkg_add_target_files("${dir_files}")
75+
unset(dir_files)
76+
endforeach()
77+
4778
configure_file(pyproject.toml.in ${CMAKE_CURRENT_BINARY_DIR}/pyproject.toml)
4879

4980
add_subdirectory(qss_compiler)

0 commit comments

Comments
 (0)