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