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