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