1 //===- Diagnostics.cpp - C Interface for MLIR Diagnostics -----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "mlir-c/Diagnostics.h"
10 #include "mlir/CAPI/Diagnostics.h"
11 #include "mlir/CAPI/IR.h"
12 #include "mlir/CAPI/Support.h"
13 #include "mlir/CAPI/Utils.h"
14 #include "mlir/IR/Diagnostics.h"
15 
16 using namespace mlir;
17 
18 void mlirDiagnosticPrint(MlirDiagnostic diagnostic, MlirStringCallback callback,
19                          void *userData) {
20   detail::CallbackOstream stream(callback, userData);
21   unwrap(diagnostic).print(stream);
22   stream.flush();
23 }
24 
25 MlirLocation mlirDiagnosticGetLocation(MlirDiagnostic diagnostic) {
26   return wrap(unwrap(diagnostic).getLocation());
27 }
28 
29 MlirDiagnosticSeverity mlirDiagnosticGetSeverity(MlirDiagnostic diagnostic) {
30   switch (unwrap(diagnostic).getSeverity()) {
31   case mlir::DiagnosticSeverity::Error:
32     return MlirDiagnosticError;
33   case mlir::DiagnosticSeverity::Warning:
34     return MlirDiagnosticWarning;
35   case mlir::DiagnosticSeverity::Note:
36     return MlirDiagnosticNote;
37   case mlir::DiagnosticSeverity::Remark:
38     return MlirDiagnosticRemark;
39   }
40   llvm_unreachable("unhandled diagnostic severity");
41 }
42 
43 // Notes are stored in a vector, so note iterator range is a pair of
44 // random access iterators, for which it is cheap to compute the size.
45 intptr_t mlirDiagnosticGetNumNotes(MlirDiagnostic diagnostic) {
46   return static_cast<intptr_t>(llvm::size(unwrap(diagnostic).getNotes()));
47 }
48 
49 // Notes are stored in a vector, so the iterator is a random access iterator,
50 // cheap to advance multiple steps at a time.
51 MlirDiagnostic mlirDiagnosticGetNote(MlirDiagnostic diagnostic, intptr_t pos) {
52   return wrap(*std::next(unwrap(diagnostic).getNotes().begin(), pos));
53 }
54 
55 MlirDiagnosticHandlerID
56 mlirContextAttachDiagnosticHandler(MlirContext context,
57                                    MlirDiagnosticHandler handler) {
58   assert(handler && "unexpected null diagnostic handler");
59   DiagnosticEngine::HandlerID id =
60       unwrap(context)->getDiagEngine().registerHandler(
61           [handler](Diagnostic &diagnostic) {
62             return unwrap(handler(wrap(diagnostic)));
63           });
64   return static_cast<MlirDiagnosticHandlerID>(id);
65 }
66 
67 void mlirContextDetachDiagnosticHandler(MlirContext context,
68                                         MlirDiagnosticHandlerID id) {
69   unwrap(context)->getDiagEngine().eraseHandler(
70       static_cast<DiagnosticEngine::HandlerID>(id));
71 }
72 
73 void mlirEmitError(MlirLocation location, const char *message) {
74   emitError(unwrap(location)) << message;
75 }
76