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 
mlirDiagnosticPrint(MlirDiagnostic diagnostic,MlirStringCallback callback,void * userData)18 void mlirDiagnosticPrint(MlirDiagnostic diagnostic, MlirStringCallback callback,
19                          void *userData) {
20   detail::CallbackOstream stream(callback, userData);
21   unwrap(diagnostic).print(stream);
22 }
23 
mlirDiagnosticGetLocation(MlirDiagnostic diagnostic)24 MlirLocation mlirDiagnosticGetLocation(MlirDiagnostic diagnostic) {
25   return wrap(unwrap(diagnostic).getLocation());
26 }
27 
mlirDiagnosticGetSeverity(MlirDiagnostic diagnostic)28 MlirDiagnosticSeverity mlirDiagnosticGetSeverity(MlirDiagnostic diagnostic) {
29   switch (unwrap(diagnostic).getSeverity()) {
30   case mlir::DiagnosticSeverity::Error:
31     return MlirDiagnosticError;
32   case mlir::DiagnosticSeverity::Warning:
33     return MlirDiagnosticWarning;
34   case mlir::DiagnosticSeverity::Note:
35     return MlirDiagnosticNote;
36   case mlir::DiagnosticSeverity::Remark:
37     return MlirDiagnosticRemark;
38   }
39   llvm_unreachable("unhandled diagnostic severity");
40 }
41 
42 // Notes are stored in a vector, so note iterator range is a pair of
43 // random access iterators, for which it is cheap to compute the size.
mlirDiagnosticGetNumNotes(MlirDiagnostic diagnostic)44 intptr_t mlirDiagnosticGetNumNotes(MlirDiagnostic diagnostic) {
45   return static_cast<intptr_t>(llvm::size(unwrap(diagnostic).getNotes()));
46 }
47 
48 // Notes are stored in a vector, so the iterator is a random access iterator,
49 // cheap to advance multiple steps at a time.
mlirDiagnosticGetNote(MlirDiagnostic diagnostic,intptr_t pos)50 MlirDiagnostic mlirDiagnosticGetNote(MlirDiagnostic diagnostic, intptr_t pos) {
51   return wrap(*std::next(unwrap(diagnostic).getNotes().begin(), pos));
52 }
53 
deleteUserDataNoop(void * userData)54 static void deleteUserDataNoop(void *userData) {}
55 
mlirContextAttachDiagnosticHandler(MlirContext context,MlirDiagnosticHandler handler,void * userData,void (* deleteUserData)(void *))56 MlirDiagnosticHandlerID mlirContextAttachDiagnosticHandler(
57     MlirContext context, MlirDiagnosticHandler handler, void *userData,
58     void (*deleteUserData)(void *)) {
59   assert(handler && "unexpected null diagnostic handler");
60   if (deleteUserData == NULL)
61     deleteUserData = deleteUserDataNoop;
62   std::shared_ptr<void> sharedUserData(userData, deleteUserData);
63   DiagnosticEngine::HandlerID id =
64       unwrap(context)->getDiagEngine().registerHandler(
65           [handler, sharedUserData](Diagnostic &diagnostic) {
66             return unwrap(handler(wrap(diagnostic), sharedUserData.get()));
67           });
68   return static_cast<MlirDiagnosticHandlerID>(id);
69 }
70 
mlirContextDetachDiagnosticHandler(MlirContext context,MlirDiagnosticHandlerID id)71 void mlirContextDetachDiagnosticHandler(MlirContext context,
72                                         MlirDiagnosticHandlerID id) {
73   unwrap(context)->getDiagEngine().eraseHandler(
74       static_cast<DiagnosticEngine::HandlerID>(id));
75 }
76 
mlirEmitError(MlirLocation location,const char * message)77 void mlirEmitError(MlirLocation location, const char *message) {
78   emitError(unwrap(location)) << message;
79 }
80