3 #include <isl/options.h>
11 /* ISL_USE_EXCEPTIONS should be defined to 1 if exceptions are available.
12 * gcc and clang define __cpp_exceptions; MSVC and xlC define _CPPUNWIND.
13 * Older versions of gcc (e.g., 4.9) only define __EXCEPTIONS.
14 * If exceptions are not available, any error condition will result
17 #ifndef ISL_USE_EXCEPTIONS
18 #if defined(__cpp_exceptions) || defined(_CPPUNWIND) || defined(__EXCEPTIONS)
19 #define ISL_USE_EXCEPTIONS 1
21 #define ISL_USE_EXCEPTIONS 0
30 /* implicit */ ctx(isl_ctx *ctx) : ptr(ctx) {}
41 /* Macros hiding try/catch.
42 * If exceptions are not available, then no exceptions will be thrown and
43 * there is nothing to catch.
45 #if ISL_USE_EXCEPTIONS
46 #define ISL_CPP_TRY try
47 #define ISL_CPP_CATCH_ALL catch (...)
49 #define ISL_CPP_TRY if (1)
50 #define ISL_CPP_CATCH_ALL if (0)
53 #if ISL_USE_EXCEPTIONS
55 /* Class capturing isl errors.
57 * The what() return value is stored in a reference counted string
58 * to ensure that the copy constructor and the assignment operator
59 * do not throw any exceptions.
61 class exception : public std::exception {
62 std::shared_ptr<std::string> what_str;
65 inline exception(const char *what_arg, const char *msg,
66 const char *file, int line);
69 exception(const char *what_arg) {
70 what_str = std::make_shared<std::string>(what_arg);
72 static inline void throw_error(enum isl_error error, const char *msg,
73 const char *file, int line);
74 virtual const char *what() const noexcept {
75 return what_str->c_str();
78 /* Default behavior on error conditions that occur inside isl calls
79 * performed from inside the bindings.
80 * In the case exceptions are available, isl should continue
81 * without printing a warning since the warning message
82 * will be included in the exception thrown from inside the bindings.
84 static constexpr auto on_error = ISL_ON_ERROR_CONTINUE;
85 /* Wrapper for throwing an exception on NULL input.
87 static void throw_NULL_input(const char *file, int line) {
88 throw_error(isl_error_invalid, "NULL input", file, line);
90 static inline void throw_last_error(ctx ctx);
93 /* Create an exception of a type described by "what_arg", with
94 * error message "msg" in line "line" of file "file".
96 * Create a string holding the what() return value that
97 * corresponds to what isl would have printed.
98 * If no error message or no error file was set, then use "what_arg" instead.
100 exception::exception(const char *what_arg, const char *msg, const char *file,
104 what_str = std::make_shared<std::string>(what_arg);
106 what_str = std::make_shared<std::string>(std::string(file) +
107 ":" + std::to_string(line) + ": " + msg);
110 class exception_abort : public exception {
112 exception_abort(const char *msg, const char *file, int line) :
113 exception("execution aborted", msg, file, line) {}
116 class exception_alloc : public exception {
118 exception_alloc(const char *msg, const char *file, int line) :
119 exception("memory allocation failure", msg, file, line) {}
122 class exception_unknown : public exception {
124 exception_unknown(const char *msg, const char *file, int line) :
125 exception("unknown failure", msg, file, line) {}
128 class exception_internal : public exception {
130 exception_internal(const char *msg, const char *file, int line) :
131 exception("internal error", msg, file, line) {}
134 class exception_invalid : public exception {
136 exception_invalid(const char *msg, const char *file, int line) :
137 exception("invalid argument", msg, file, line) {}
140 class exception_quota : public exception {
142 exception_quota(const char *msg, const char *file, int line) :
143 exception("quota exceeded", msg, file, line) {}
146 class exception_unsupported : public exception {
148 exception_unsupported(const char *msg, const char *file, int line) :
149 exception("unsupported operation", msg, file, line) {}
152 /* Throw an exception of the class that corresponds to "error", with
153 * error message "msg" in line "line" of file "file".
155 * isl_error_none is treated as an invalid error type.
157 void exception::throw_error(enum isl_error error, const char *msg,
158 const char *file, int line)
163 case isl_error_abort: throw exception_abort(msg, file, line);
164 case isl_error_alloc: throw exception_alloc(msg, file, line);
165 case isl_error_unknown: throw exception_unknown(msg, file, line);
166 case isl_error_internal: throw exception_internal(msg, file, line);
167 case isl_error_invalid: throw exception_invalid(msg, file, line);
168 case isl_error_quota: throw exception_quota(msg, file, line);
169 case isl_error_unsupported:
170 throw exception_unsupported(msg, file, line);
173 throw exception_invalid("invalid error type", file, line);
176 /* Throw an exception corresponding to the last error on "ctx" and
179 * If "ctx" is NULL or if it is not in an error state at the start,
180 * then an invalid argument exception is thrown.
182 void exception::throw_last_error(ctx ctx)
184 enum isl_error error;
185 const char *msg, *file;
188 error = isl_ctx_last_error(ctx.get());
189 msg = isl_ctx_last_error_msg(ctx.get());
190 file = isl_ctx_last_error_file(ctx.get());
191 line = isl_ctx_last_error_line(ctx.get());
192 isl_ctx_reset_error(ctx.get());
194 throw_error(error, msg, file, line);
204 /* Default behavior on error conditions that occur inside isl calls
205 * performed from inside the bindings.
206 * In the case exceptions are not available, isl should abort.
208 static constexpr auto on_error = ISL_ON_ERROR_ABORT;
209 /* Wrapper for throwing an exception on NULL input.
210 * In the case exceptions are not available, print an error and abort.
212 static void throw_NULL_input(const char *file, int line) {
213 fprintf(stderr, "%s:%d: NULL input\n", file, line);
216 /* Throw an exception corresponding to the last
218 * isl should already abort when an error condition occurs,
219 * so this function should never be called.
221 static void throw_last_error(ctx ctx) {
228 /* Helper class for setting the on_error and resetting the option
229 * to the original value when leaving the scope.
231 class options_scoped_set_on_error {
235 options_scoped_set_on_error(class ctx ctx, int on_error) {
236 this->ctx = ctx.get();
237 saved_on_error = isl_options_get_on_error(this->ctx);
238 isl_options_set_on_error(this->ctx, on_error);
240 ~options_scoped_set_on_error() {
241 isl_options_set_on_error(ctx, saved_on_error);