1/// These are automatically generated C++ bindings for isl. 2/// 3/// isl is a library for computing with integer sets and maps described by 4/// Presburger formulas. On top of this, isl provides various tools for 5/// polyhedral compilation, ranging from dependence analysis over scheduling 6/// to AST generation. 7 8#ifndef ISL_CPP 9#define ISL_CPP 10 11#include <isl/ctx.h> 12#include <isl/options.h> 13 14#include <functional> 15#include <memory> 16#include <ostream> 17#include <stdexcept> 18#include <string> 19#include <type_traits> 20 21/* ISL_USE_EXCEPTIONS should be defined to 1 if exceptions are available. 22 * gcc and clang define __cpp_exceptions; MSVC and xlC define _CPPUNWIND. 23 * Older versions of gcc (e.g., 4.9) only define __EXCEPTIONS. 24 * If exceptions are not available, any error condition will result 25 * in an abort. 26 */ 27#ifndef ISL_USE_EXCEPTIONS 28#if defined(__cpp_exceptions) || defined(_CPPUNWIND) || defined(__EXCEPTIONS) 29#define ISL_USE_EXCEPTIONS 1 30#else 31#define ISL_USE_EXCEPTIONS 0 32#endif 33#endif 34 35namespace isl { 36 37class ctx { 38 isl_ctx *ptr; 39public: 40 /* implicit */ ctx(isl_ctx *ctx) : ptr(ctx) {} 41 isl_ctx *release() { 42 auto tmp = ptr; 43 ptr = nullptr; 44 return tmp; 45 } 46 isl_ctx *get() { 47 return ptr; 48 } 49}; 50 51/* Macros hiding try/catch. 52 * If exceptions are not available, then no exceptions will be thrown and 53 * there is nothing to catch. 54 */ 55#if ISL_USE_EXCEPTIONS 56#define ISL_CPP_TRY try 57#define ISL_CPP_CATCH_ALL catch (...) 58#else 59#define ISL_CPP_TRY if (1) 60#define ISL_CPP_CATCH_ALL if (0) 61#endif 62 63#if ISL_USE_EXCEPTIONS 64 65/* Class capturing isl errors. 66 * 67 * The what() return value is stored in a reference counted string 68 * to ensure that the copy constructor and the assignment operator 69 * do not throw any exceptions. 70 */ 71class exception : public std::exception { 72 std::shared_ptr<std::string> what_str; 73 74protected: 75 inline exception(const char *what_arg, const char *msg, 76 const char *file, int line); 77public: 78 exception() {} 79 exception(const char *what_arg) { 80 what_str = std::make_shared<std::string>(what_arg); 81 } 82 static inline void throw_error(enum isl_error error, const char *msg, 83 const char *file, int line); 84 virtual const char *what() const noexcept { 85 return what_str->c_str(); 86 } 87 88 /* Default behavior on error conditions that occur inside isl calls 89 * performed from inside the bindings. 90 * In the case exceptions are available, isl should continue 91 * without printing a warning since the warning message 92 * will be included in the exception thrown from inside the bindings. 93 */ 94 static constexpr auto on_error = ISL_ON_ERROR_CONTINUE; 95 /* Wrapper for throwing an exception with the given message. 96 */ 97 static void throw_invalid(const char *msg, const char *file, int line) { 98 throw_error(isl_error_invalid, msg, file, line); 99 } 100 static inline void throw_last_error(ctx ctx); 101}; 102 103/* Create an exception of a type described by "what_arg", with 104 * error message "msg" in line "line" of file "file". 105 * 106 * Create a string holding the what() return value that 107 * corresponds to what isl would have printed. 108 * If no error message or no error file was set, then use "what_arg" instead. 109 */ 110exception::exception(const char *what_arg, const char *msg, const char *file, 111 int line) 112{ 113 if (!msg || !file) 114 what_str = std::make_shared<std::string>(what_arg); 115 else 116 what_str = std::make_shared<std::string>(std::string(file) + 117 ":" + std::to_string(line) + ": " + msg); 118} 119 120class exception_abort : public exception { 121 friend exception; 122 exception_abort(const char *msg, const char *file, int line) : 123 exception("execution aborted", msg, file, line) {} 124}; 125 126class exception_alloc : public exception { 127 friend exception; 128 exception_alloc(const char *msg, const char *file, int line) : 129 exception("memory allocation failure", msg, file, line) {} 130}; 131 132class exception_unknown : public exception { 133 friend exception; 134 exception_unknown(const char *msg, const char *file, int line) : 135 exception("unknown failure", msg, file, line) {} 136}; 137 138class exception_internal : public exception { 139 friend exception; 140 exception_internal(const char *msg, const char *file, int line) : 141 exception("internal error", msg, file, line) {} 142}; 143 144class exception_invalid : public exception { 145 friend exception; 146 exception_invalid(const char *msg, const char *file, int line) : 147 exception("invalid argument", msg, file, line) {} 148}; 149 150class exception_quota : public exception { 151 friend exception; 152 exception_quota(const char *msg, const char *file, int line) : 153 exception("quota exceeded", msg, file, line) {} 154}; 155 156class exception_unsupported : public exception { 157 friend exception; 158 exception_unsupported(const char *msg, const char *file, int line) : 159 exception("unsupported operation", msg, file, line) {} 160}; 161 162/* Throw an exception of the class that corresponds to "error", with 163 * error message "msg" in line "line" of file "file". 164 * 165 * isl_error_none is treated as an invalid error type. 166 */ 167void exception::throw_error(enum isl_error error, const char *msg, 168 const char *file, int line) 169{ 170 switch (error) { 171 case isl_error_none: 172 break; 173 case isl_error_abort: throw exception_abort(msg, file, line); 174 case isl_error_alloc: throw exception_alloc(msg, file, line); 175 case isl_error_unknown: throw exception_unknown(msg, file, line); 176 case isl_error_internal: throw exception_internal(msg, file, line); 177 case isl_error_invalid: throw exception_invalid(msg, file, line); 178 case isl_error_quota: throw exception_quota(msg, file, line); 179 case isl_error_unsupported: 180 throw exception_unsupported(msg, file, line); 181 } 182 183 throw exception_invalid("invalid error type", file, line); 184} 185 186/* Throw an exception corresponding to the last error on "ctx" and 187 * reset the error. 188 * 189 * If "ctx" is NULL or if it is not in an error state at the start, 190 * then an invalid argument exception is thrown. 191 */ 192void exception::throw_last_error(ctx ctx) 193{ 194 enum isl_error error; 195 const char *msg, *file; 196 int line; 197 198 error = isl_ctx_last_error(ctx.get()); 199 msg = isl_ctx_last_error_msg(ctx.get()); 200 file = isl_ctx_last_error_file(ctx.get()); 201 line = isl_ctx_last_error_line(ctx.get()); 202 isl_ctx_reset_error(ctx.get()); 203 204 throw_error(error, msg, file, line); 205} 206 207#else 208 209#include <stdio.h> 210#include <stdlib.h> 211 212class exception { 213public: 214 /* Default behavior on error conditions that occur inside isl calls 215 * performed from inside the bindings. 216 * In the case exceptions are not available, isl should abort. 217 */ 218 static constexpr auto on_error = ISL_ON_ERROR_ABORT; 219 /* Wrapper for throwing an exception with the given message. 220 * In the case exceptions are not available, print an error and abort. 221 */ 222 static void throw_invalid(const char *msg, const char *file, int line) { 223 fprintf(stderr, "%s:%d: %s\n", file, line, msg); 224 abort(); 225 } 226 /* Throw an exception corresponding to the last 227 * error on "ctx". 228 * isl should already abort when an error condition occurs, 229 * so this function should never be called. 230 */ 231 static void throw_last_error(ctx ctx) { 232 abort(); 233 } 234}; 235 236#endif 237 238/* Helper class for setting the on_error and resetting the option 239 * to the original value when leaving the scope. 240 */ 241class options_scoped_set_on_error { 242 isl_ctx *ctx; 243 int saved_on_error; 244public: 245 options_scoped_set_on_error(class ctx ctx, int on_error) { 246 this->ctx = ctx.get(); 247 saved_on_error = isl_options_get_on_error(this->ctx); 248 isl_options_set_on_error(this->ctx, on_error); 249 } 250 ~options_scoped_set_on_error() { 251 isl_options_set_on_error(ctx, saved_on_error); 252 } 253}; 254 255} // namespace isl 256 257