3 #include <isl/options.h>
10 /* ISL_USE_EXCEPTIONS should be defined to 1 if exceptions are available.
11 * gcc and clang define __cpp_exceptions; MSVC and xlC define _CPPUNWIND.
12 * If exceptions are not available, any error condition will result
15 #ifndef ISL_USE_EXCEPTIONS
16 #if defined(__cpp_exceptions) || defined(_CPPUNWIND)
17 #define ISL_USE_EXCEPTIONS 1
19 #define ISL_USE_EXCEPTIONS 0
28 /* implicit */ ctx(isl_ctx *ctx) : ptr(ctx) {}
39 /* Macros hiding try/catch.
40 * If exceptions are not available, then no exceptions will be thrown and
41 * there is nothing to catch.
43 #if ISL_USE_EXCEPTIONS
44 #define ISL_CPP_TRY try
45 #define ISL_CPP_CATCH_ALL catch (...)
47 #define ISL_CPP_TRY if (1)
48 #define ISL_CPP_CATCH_ALL if (0)
51 #if ISL_USE_EXCEPTIONS
53 /* Class capturing isl errors.
55 * The what() return value is stored in a reference counted string
56 * to ensure that the copy constructor and the assignment operator
57 * do not throw any exceptions.
59 class exception : public std::exception {
60 std::shared_ptr<std::string> what_str;
63 inline exception(const char *what_arg, const char *msg,
64 const char *file, int line);
67 exception(const char *what_arg) {
68 what_str = std::make_shared<std::string>(what_arg);
70 static inline exception create(enum isl_error error, const char *msg,
71 const char *file, int line);
72 static inline exception create_from_last_error(ctx ctx);
73 virtual const char *what() const noexcept {
74 return what_str->c_str();
77 /* Default behavior on error conditions that occur inside isl calls
78 * performed from inside the bindings.
79 * In the case exceptions are available, isl should continue
80 * without printing a warning since the warning message
81 * will be included in the exception thrown from inside the bindings.
83 static constexpr auto on_error = ISL_ON_ERROR_CONTINUE;
84 /* Wrapper for throwing an exception on NULL input.
86 static void throw_NULL_input(const char *file, int line) {
87 throw create(isl_error_invalid, "NULL input", file, line);
89 /* Wrapper for throwing an exception corresponding to the last
92 static void throw_last_error(ctx ctx) {
93 throw create_from_last_error(ctx);
97 /* Create an exception of a type described by "what_arg", with
98 * error message "msg" in line "line" of file "file".
100 * Create a string holding the what() return value that
101 * corresponds to what isl would have printed.
102 * If no error message or no error file was set, then use "what_arg" instead.
104 exception::exception(const char *what_arg, const char *msg, const char *file,
108 what_str = std::make_shared<std::string>(what_arg);
110 what_str = std::make_shared<std::string>(std::string(file) +
111 ":" + std::to_string(line) + ": " + msg);
114 class exception_abort : public exception {
116 exception_abort(const char *msg, const char *file, int line) :
117 exception("execution aborted", msg, file, line) {}
120 class exception_alloc : public exception {
122 exception_alloc(const char *msg, const char *file, int line) :
123 exception("memory allocation failure", msg, file, line) {}
126 class exception_unknown : public exception {
128 exception_unknown(const char *msg, const char *file, int line) :
129 exception("unknown failure", msg, file, line) {}
132 class exception_internal : public exception {
134 exception_internal(const char *msg, const char *file, int line) :
135 exception("internal error", msg, file, line) {}
138 class exception_invalid : public exception {
140 exception_invalid(const char *msg, const char *file, int line) :
141 exception("invalid argument", msg, file, line) {}
144 class exception_quota : public exception {
146 exception_quota(const char *msg, const char *file, int line) :
147 exception("quota exceeded", msg, file, line) {}
150 class exception_unsupported : public exception {
152 exception_unsupported(const char *msg, const char *file, int line) :
153 exception("unsupported operation", msg, file, line) {}
156 /* Create an exception of the class that corresponds to "error", with
157 * error message "msg" in line "line" of file "file".
159 * isl_error_none is treated as an invalid error type.
161 exception exception::create(enum isl_error error, const char *msg,
162 const char *file, int line)
167 case isl_error_abort: return exception_abort(msg, file, line);
168 case isl_error_alloc: return exception_alloc(msg, file, line);
169 case isl_error_unknown: return exception_unknown(msg, file, line);
170 case isl_error_internal: return exception_internal(msg, file, line);
171 case isl_error_invalid: return exception_invalid(msg, file, line);
172 case isl_error_quota: return exception_quota(msg, file, line);
173 case isl_error_unsupported:
174 return exception_unsupported(msg, file, line);
177 throw exception_invalid("invalid error type", file, line);
180 /* Create an exception from the last error that occurred on "ctx" and
183 * If "ctx" is NULL or if it is not in an error state at the start,
184 * then an invalid argument exception is thrown.
186 exception exception::create_from_last_error(ctx ctx)
188 enum isl_error error;
189 const char *msg, *file;
192 error = isl_ctx_last_error(ctx.get());
193 msg = isl_ctx_last_error_msg(ctx.get());
194 file = isl_ctx_last_error_file(ctx.get());
195 line = isl_ctx_last_error_line(ctx.get());
196 isl_ctx_reset_error(ctx.get());
198 return create(error, msg, file, line);
208 /* Default behavior on error conditions that occur inside isl calls
209 * performed from inside the bindings.
210 * In the case exceptions are not available, isl should abort.
212 static constexpr auto on_error = ISL_ON_ERROR_ABORT;
213 /* Wrapper for throwing an exception on NULL input.
214 * In the case exceptions are not available, print an error and abort.
216 static void throw_NULL_input(const char *file, int line) {
217 fprintf(stderr, "%s:%d: NULL input\n", file, line);
220 /* Wrapper for throwing an exception corresponding to the last
222 * isl should already abort when an error condition occurs,
223 * so this function should never be called.
225 static void throw_last_error(ctx ctx) {
232 /* Helper class for setting the on_error and resetting the option
233 * to the original value when leaving the scope.
235 class options_scoped_set_on_error {
239 options_scoped_set_on_error(class ctx ctx, int on_error) {
240 this->ctx = ctx.get();
241 saved_on_error = isl_options_get_on_error(this->ctx);
242 isl_options_set_on_error(this->ctx, on_error);
244 ~options_scoped_set_on_error() {
245 isl_options_set_on_error(ctx, saved_on_error);