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