/*
 * Copyright 2016, 2017 Tobias Grosser. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *    1. Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *
 *    2. Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY TOBIAS GROSSER ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SVEN VERDOOLAEGE OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation
 * are those of the authors and should not be interpreted as
 * representing official policies, either expressed or implied, of
 * Tobias Grosser.
 */

#include <cstdarg>
#include <cstdio>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>

#include "cpp.h"
#include "isl_config.h"

/* Print string formatted according to "fmt" to ostream "os".
 *
 * This osprintf method allows us to use printf style formatting constructs when
 * writing to an ostream.
 */
static void osprintf(ostream &os, const char *format, ...)
{
	va_list arguments;
	char *string_pointer;
	size_t size;

	va_start(arguments, format);
	size = vsnprintf(NULL, 0, format, arguments);
	string_pointer = new char[size + 1];
	va_end(arguments);
	va_start(arguments, format);
	vsnprintf(string_pointer, size + 1, format, arguments);
	va_end(arguments);
	os << string_pointer;
	delete[] string_pointer;
}

/* Convert "l" to a string.
 */
static std::string to_string(long l)
{
	std::ostringstream strm;
	strm << l;
	return strm.str();
}

/* Generate a cpp interface based on the extracted types and functions.
 *
 * Print first a set of forward declarations for all isl wrapper
 * classes, then the declarations of the classes, and at the end all
 * implementations.
 *
 * If checked C++ bindings are being generated,
 * then wrap them in a namespace to avoid conflicts
 * with the default C++ bindings (with automatic checks using exceptions).
 */
void cpp_generator::generate()
{
	ostream &os = cout;

	osprintf(os, "\n");
	osprintf(os, "namespace isl {\n\n");
	if (checked)
		osprintf(os, "namespace checked {\n\n");

	print_forward_declarations(os);
	osprintf(os, "\n");
	print_declarations(os);
	osprintf(os, "\n");
	print_implementations(os);

	if (checked)
		osprintf(os, "} // namespace checked\n");
	osprintf(os, "} // namespace isl\n");
}

/* Print forward declarations for all classes to "os".
*/
void cpp_generator::print_forward_declarations(ostream &os)
{
	map<string, isl_class>::iterator ci;

	osprintf(os, "// forward declarations\n");

	for (ci = classes.begin(); ci != classes.end(); ++ci)
		print_class_forward_decl(os, ci->second);
}

/* Print all declarations to "os".
 */
void cpp_generator::print_declarations(ostream &os)
{
	map<string, isl_class>::iterator ci;
	bool first = true;

	for (ci = classes.begin(); ci != classes.end(); ++ci) {
		if (first)
			first = false;
		else
			osprintf(os, "\n");

		print_class(os, ci->second);
	}
}

/* Print all implementations to "os".
 */
void cpp_generator::print_implementations(ostream &os)
{
	map<string, isl_class>::iterator ci;
	bool first = true;

	for (ci = classes.begin(); ci != classes.end(); ++ci) {
		if (first)
			first = false;
		else
			osprintf(os, "\n");

		print_class_impl(os, ci->second);
	}
}

/* Print declarations for class "clazz" to "os".
 */
void cpp_generator::print_class(ostream &os, const isl_class &clazz)
{
	const char *name = clazz.name.c_str();
	std::string cppstring = type2cpp(clazz);
	const char *cppname = cppstring.c_str();

	osprintf(os, "// declarations for isl::%s\n", cppname);

	print_class_factory_decl(os, clazz);
	osprintf(os, "\n");
	osprintf(os, "class %s {\n", cppname);
	print_class_factory_decl(os, clazz, "  friend ");
	osprintf(os, "\n");
	osprintf(os, "  %s *ptr = nullptr;\n", name);
	osprintf(os, "\n");
	print_private_constructors_decl(os, clazz);
	osprintf(os, "\n");
	osprintf(os, "public:\n");
	print_public_constructors_decl(os, clazz);
	print_constructors_decl(os, clazz);
	print_copy_assignment_decl(os, clazz);
	print_destructor_decl(os, clazz);
	print_ptr_decl(os, clazz);
	print_get_ctx_decl(os);
	osprintf(os, "\n");
	print_methods_decl(os, clazz);

	osprintf(os, "};\n");
}

/* Print forward declaration of class "clazz" to "os".
 */
void cpp_generator::print_class_forward_decl(ostream &os,
	const isl_class &clazz)
{
	std::string cppstring = type2cpp(clazz);
	const char *cppname = cppstring.c_str();

	osprintf(os, "class %s;\n", cppname);
}

/* Print global factory functions to "os".
 *
 * Each class has two global factory functions:
 *
 * 	set manage(__isl_take isl_set *ptr);
 * 	set manage_copy(__isl_keep isl_set *ptr);
 *
 * A user can construct isl C++ objects from a raw pointer and indicate whether
 * they intend to take the ownership of the object or not through these global
 * factory functions. This ensures isl object creation is very explicit and
 * pointers are not converted by accident. Thanks to overloading, manage() and
 * manage_copy() can be called on any isl raw pointer and the corresponding
 * object is automatically created, without the user having to choose the right
 * isl object type.
 */
void cpp_generator::print_class_factory_decl(ostream &os,
	const isl_class &clazz, const std::string &prefix)
{
	const char *name = clazz.name.c_str();
	std::string cppstring = type2cpp(clazz);
	const char *cppname = cppstring.c_str();

	os << prefix;
	osprintf(os, "inline %s manage(__isl_take %s *ptr);\n", cppname, name);
	os << prefix;
	osprintf(os, "inline %s manage_copy(__isl_keep %s *ptr);\n",
		cppname, name);
}

/* Print declarations of private constructors for class "clazz" to "os".
 *
 * Each class has currently one private constructor:
 *
 * 	1) Constructor from a plain isl_* C pointer
 *
 * Example:
 *
 * 	set(__isl_take isl_set *ptr);
 *
 * The raw pointer constructor is kept private. Object creation is only
 * possible through manage() or manage_copy().
 */
void cpp_generator::print_private_constructors_decl(ostream &os,
	const isl_class &clazz)
{
	const char *name = clazz.name.c_str();
	std::string cppstring = type2cpp(clazz);
	const char *cppname = cppstring.c_str();

	osprintf(os, "  inline explicit %s(__isl_take %s *ptr);\n", cppname,
		 name);
}

/* Print declarations of public constructors for class "clazz" to "os".
 *
 * Each class currently has two public constructors:
 *
 * 	1) A default constructor
 * 	2) A copy constructor
 *
 * Example:
 *
 *	set();
 *	set(const set &set);
 */
void cpp_generator::print_public_constructors_decl(ostream &os,
	const isl_class &clazz)
{
	std::string cppstring = type2cpp(clazz);
	const char *cppname = cppstring.c_str();
	osprintf(os, "  inline /* implicit */ %s();\n", cppname);

	osprintf(os, "  inline /* implicit */ %s(const %s &obj);\n",
		 cppname, cppname);
}

/* Print declarations for constructors for class "class" to "os".
 *
 * For each isl function that is marked as __isl_constructor,
 * add a corresponding C++ constructor.
 *
 * Example:
 *
 * 	inline /\* implicit *\/ union_set(basic_set bset);
 * 	inline /\* implicit *\/ union_set(set set);
 * 	inline explicit val(ctx ctx, long i);
 * 	inline explicit val(ctx ctx, const std::string &str);
 */
void cpp_generator::print_constructors_decl(ostream &os,
       const isl_class &clazz)
{
	set<FunctionDecl *>::const_iterator in;
	const set<FunctionDecl *> &constructors = clazz.constructors;

	for (in = constructors.begin(); in != constructors.end(); ++in) {
		FunctionDecl *cons = *in;
		string fullname = cons->getName();
		function_kind kind = function_kind_constructor;

		print_method_decl(os, clazz, fullname, cons, kind);
	}
}

/* Print declarations of copy assignment operator for class "clazz"
 * to "os".
 *
 * Each class has one assignment operator.
 *
 * 	isl:set &set::operator=(set obj)
 *
 */
void cpp_generator::print_copy_assignment_decl(ostream &os,
	const isl_class &clazz)
{
	std::string cppstring = type2cpp(clazz);
	const char *cppname = cppstring.c_str();

	osprintf(os, "  inline %s &operator=(%s obj);\n", cppname, cppname);
}

/* Print declaration of destructor for class "clazz" to "os".
 */
void cpp_generator::print_destructor_decl(ostream &os, const isl_class &clazz)
{
	std::string cppstring = type2cpp(clazz);
	const char *cppname = cppstring.c_str();

	osprintf(os, "  inline ~%s();\n", cppname);
}

/* Print declaration of pointer functions for class "clazz" to "os".
 *
 * To obtain a raw pointer three functions are provided:
 *
 * 	1) __isl_give isl_set *copy()
 *
 * 	  Returns a pointer to a _copy_ of the internal object
 *
 * 	2) __isl_keep isl_set *get()
 *
 * 	  Returns a pointer to the internal object
 *
 * 	3) __isl_give isl_set *release()
 *
 * 	  Returns a pointer to the internal object and resets the
 * 	  internal pointer to nullptr.
 *
 * We also provide functionality to explicitly check if a pointer is
 * currently managed by this object.
 *
 * 	4) bool is_null()
 *
 * 	  Check if the current object is a null pointer.
 *
 * The functions get() and release() model the value_ptr proposed in
 * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3339.pdf.
 * The copy() function is an extension to allow the user to explicitly
 * copy the underlying object.
 *
 * Also generate a declaration to delete copy() for r-values, for
 * r-values release() should be used to avoid unnecessary copies.
 */
void cpp_generator::print_ptr_decl(ostream &os, const isl_class &clazz)
{
	const char *name = clazz.name.c_str();

	osprintf(os, "  inline __isl_give %s *copy() const &;\n", name);
	osprintf(os, "  inline __isl_give %s *copy() && = delete;\n", name);
	osprintf(os, "  inline __isl_keep %s *get() const;\n", name);
	osprintf(os, "  inline __isl_give %s *release();\n", name);
	osprintf(os, "  inline bool is_null() const;\n");
}

/* Print the declaration of the get_ctx method.
 */
void cpp_generator::print_get_ctx_decl(ostream &os)
{
	osprintf(os, "  inline ctx get_ctx() const;\n");
}

/* Print declarations for methods in class "clazz" to "os".
 */
void cpp_generator::print_methods_decl(ostream &os, const isl_class &clazz)
{
	map<string, set<FunctionDecl *> >::const_iterator it;

	for (it = clazz.methods.begin(); it != clazz.methods.end(); ++it)
		print_method_group_decl(os, clazz, it->first, it->second);
}

/* Print declarations for methods "methods" of name "fullname" in class "clazz"
 * to "os".
 *
 * "fullname" is the name of the generated C++ method.  It commonly corresponds
 * to the isl name, with the object type prefix dropped.
 * In case of overloaded methods, the result type suffix has also been removed.
 */
void cpp_generator::print_method_group_decl(ostream &os, const isl_class &clazz,
	const string &fullname, const set<FunctionDecl *> &methods)
{
	set<FunctionDecl *>::const_iterator it;

	for (it = methods.begin(); it != methods.end(); ++it) {
		function_kind kind = get_method_kind(clazz, *it);
		print_method_decl(os, clazz, fullname, *it, kind);
	}
}

/* Print declarations for "method" in class "clazz" to "os".
 *
 * "fullname" is the name of the generated C++ method.  It commonly corresponds
 * to the isl name, with the object type prefix dropped.
 * In case of overloaded methods, the result type suffix has also been removed.
 *
 * "kind" specifies the kind of method that should be generated.
 */
void cpp_generator::print_method_decl(ostream &os, const isl_class &clazz,
	const string &fullname, FunctionDecl *method, function_kind kind)
{
	print_method_header(os, clazz, method, fullname, true, kind);
}

/* Print implementations for class "clazz" to "os".
 */
void cpp_generator::print_class_impl(ostream &os, const isl_class &clazz)
{
	std::string cppstring = type2cpp(clazz);
	const char *cppname = cppstring.c_str();

	osprintf(os, "// implementations for isl::%s\n", cppname);

	print_class_factory_impl(os, clazz);
	osprintf(os, "\n");
	print_public_constructors_impl(os, clazz);
	osprintf(os, "\n");
	print_private_constructors_impl(os, clazz);
	osprintf(os, "\n");
	print_constructors_impl(os, clazz);
	osprintf(os, "\n");
	print_copy_assignment_impl(os, clazz);
	osprintf(os, "\n");
	print_destructor_impl(os, clazz);
	osprintf(os, "\n");
	print_ptr_impl(os, clazz);
	osprintf(os, "\n");
	print_get_ctx_impl(os, clazz);
	osprintf(os, "\n");
	print_methods_impl(os, clazz);
}

/* Print code for throwing an exception corresponding to the last error
 * that occurred on "ctx".
 * This assumes that a valid isl::ctx is available in the "ctx" variable,
 * e.g., through a prior call to print_save_ctx.
 */
static void print_throw_last_error(ostream &os)
{
	osprintf(os, "    exception::throw_last_error(ctx);\n");
}

/* Print code for throwing an exception on NULL input.
 */
static void print_throw_NULL_input(ostream &os)
{
	osprintf(os, "    exception::throw_NULL_input(__FILE__, __LINE__);\n");
}

/* Print implementation of global factory functions to "os".
 *
 * Each class has two global factory functions:
 *
 * 	set manage(__isl_take isl_set *ptr);
 * 	set manage_copy(__isl_keep isl_set *ptr);
 *
 * Unless checked C++ bindings are being generated,
 * both functions require the argument to be non-NULL.
 * An exception is thrown if anything went wrong during the copying
 * in manage_copy.
 * During the copying, isl is made not to print any error message
 * because the error message is included in the exception.
 */
void cpp_generator::print_class_factory_impl(ostream &os,
	const isl_class &clazz)
{
	const char *name = clazz.name.c_str();
	std::string cppstring = type2cpp(clazz);
	const char *cppname = cppstring.c_str();

	osprintf(os, "%s manage(__isl_take %s *ptr) {\n", cppname, name);
	if (!checked) {
		osprintf(os, "  if (!ptr)\n");
		print_throw_NULL_input(os);
	}
	osprintf(os, "  return %s(ptr);\n", cppname);
	osprintf(os, "}\n");

	osprintf(os, "%s manage_copy(__isl_keep %s *ptr) {\n", cppname,
		name);
	if (!checked) {
		osprintf(os, "  if (!ptr)\n");
		print_throw_NULL_input(os);
		osprintf(os, "  auto ctx = %s_get_ctx(ptr);\n", name);
		print_on_error_continue(os);
	}
	osprintf(os, "  ptr = %s_copy(ptr);\n", name);
	if (!checked) {
		osprintf(os, "  if (!ptr)\n");
		print_throw_last_error(os);
	}
	osprintf(os, "  return %s(ptr);\n", cppname);
	osprintf(os, "}\n");
}

/* Print implementations of private constructors for class "clazz" to "os".
 */
void cpp_generator::print_private_constructors_impl(ostream &os,
	const isl_class &clazz)
{
	const char *name = clazz.name.c_str();
	std::string cppstring = type2cpp(clazz);
	const char *cppname = cppstring.c_str();

	osprintf(os, "%s::%s(__isl_take %s *ptr)\n    : ptr(ptr) {}\n",
		 cppname, cppname, name);
}

/* Print implementations of public constructors for class "clazz" to "os".
 *
 * Throw an exception from the copy constructor if anything went wrong
 * during the copying or if the input is NULL.
 * During the copying, isl is made not to print any error message
 * because the error message is included in the exception.
 * No exceptions are thrown if checked C++ bindings
 * are being generated,
 */
void cpp_generator::print_public_constructors_impl(ostream &os,
	const isl_class &clazz)
{
	const char *name = clazz.name.c_str();
	std::string cppstring = type2cpp(clazz);
	const char *cppname = cppstring.c_str();

	osprintf(os, "%s::%s()\n    : ptr(nullptr) {}\n\n", cppname, cppname);
	osprintf(os, "%s::%s(const %s &obj)\n    : ptr(nullptr)\n",
		 cppname, cppname, cppname);
	osprintf(os, "{\n");
	if (!checked) {
		osprintf(os, "  if (!obj.ptr)\n");
		print_throw_NULL_input(os);
		osprintf(os, "  auto ctx = %s_get_ctx(obj.ptr);\n", name);
		print_on_error_continue(os);
	}
	osprintf(os, "  ptr = obj.copy();\n");
	if (!checked) {
		osprintf(os, "  if (obj.ptr && !ptr)\n");
		print_throw_last_error(os);
	}
	osprintf(os, "}\n");
}

/* Print implementations of constructors for class "clazz" to "os".
 */
void cpp_generator::print_constructors_impl(ostream &os,
       const isl_class &clazz)
{
	set<FunctionDecl *>::const_iterator in;
	const set<FunctionDecl *> constructors = clazz.constructors;

	for (in = constructors.begin(); in != constructors.end(); ++in) {
		FunctionDecl *cons = *in;
		string fullname = cons->getName();
		function_kind kind = function_kind_constructor;

		print_method_impl(os, clazz, fullname, cons, kind);
	}
}

/* Print implementation of copy assignment operator for class "clazz" to "os".
 */
void cpp_generator::print_copy_assignment_impl(ostream &os,
	const isl_class &clazz)
{
	const char *name = clazz.name.c_str();
	std::string cppstring = type2cpp(clazz);
	const char *cppname = cppstring.c_str();

	osprintf(os, "%s &%s::operator=(%s obj) {\n", cppname,
		 cppname, cppname);
	osprintf(os, "  std::swap(this->ptr, obj.ptr);\n", name);
	osprintf(os, "  return *this;\n");
	osprintf(os, "}\n");
}

/* Print implementation of destructor for class "clazz" to "os".
 */
void cpp_generator::print_destructor_impl(ostream &os,
	const isl_class &clazz)
{
	const char *name = clazz.name.c_str();
	std::string cppstring = type2cpp(clazz);
	const char *cppname = cppstring.c_str();

	osprintf(os, "%s::~%s() {\n", cppname, cppname);
	osprintf(os, "  if (ptr)\n");
	osprintf(os, "    %s_free(ptr);\n", name);
	osprintf(os, "}\n");
}

/* Print implementation of ptr() functions for class "clazz" to "os".
 */
void cpp_generator::print_ptr_impl(ostream &os, const isl_class &clazz)
{
	const char *name = clazz.name.c_str();
	std::string cppstring = type2cpp(clazz);
	const char *cppname = cppstring.c_str();

	osprintf(os, "__isl_give %s *%s::copy() const & {\n", name, cppname);
	osprintf(os, "  return %s_copy(ptr);\n", name);
	osprintf(os, "}\n\n");
	osprintf(os, "__isl_keep %s *%s::get() const {\n", name, cppname);
	osprintf(os, "  return ptr;\n");
	osprintf(os, "}\n\n");
	osprintf(os, "__isl_give %s *%s::release() {\n", name, cppname);
	osprintf(os, "  %s *tmp = ptr;\n", name);
	osprintf(os, "  ptr = nullptr;\n");
	osprintf(os, "  return tmp;\n");
	osprintf(os, "}\n\n");
	osprintf(os, "bool %s::is_null() const {\n", cppname);
	osprintf(os, "  return ptr == nullptr;\n");
	osprintf(os, "}\n");
}

/* Print the implementation of the get_ctx method.
 */
void cpp_generator::print_get_ctx_impl(ostream &os, const isl_class &clazz)
{
	const char *name = clazz.name.c_str();
	std::string cppstring = type2cpp(clazz);
	const char *cppname = cppstring.c_str();

	osprintf(os, "ctx %s::get_ctx() const {\n", cppname);
	osprintf(os, "  return ctx(%s_get_ctx(ptr));\n", name);
	osprintf(os, "}\n");
}

/* Print definitions for methods of class "clazz" to "os".
 */
void cpp_generator::print_methods_impl(ostream &os, const isl_class &clazz)
{
	map<string, set<FunctionDecl *> >::const_iterator it;
	bool first = true;

	for (it = clazz.methods.begin(); it != clazz.methods.end(); ++it) {
		if (first)
			first = false;
		else
			osprintf(os, "\n");
		print_method_group_impl(os, clazz, it->first, it->second);
	}
}

/* Print definitions for methods "methods" of name "fullname" in class "clazz"
 * to "os".
 *
 * "fullname" is the name of the generated C++ method.  It commonly corresponds
 * to the isl name, with the object type prefix dropped.
 * In case of overloaded methods, the result type suffix has also been removed.
 *
 * "kind" specifies the kind of method that should be generated.
 */
void cpp_generator::print_method_group_impl(ostream &os, const isl_class &clazz,
	const string &fullname, const set<FunctionDecl *> &methods)
{
	set<FunctionDecl *>::const_iterator it;
	bool first = true;

	for (it = methods.begin(); it != methods.end(); ++it) {
		function_kind kind;
		if (first)
			first = false;
		else
			osprintf(os, "\n");
		kind = get_method_kind(clazz, *it);
		print_method_impl(os, clazz, fullname, *it, kind);
	}
}

/* Print the use of "param" to "os".
 *
 * "load_from_this_ptr" specifies whether the parameter should be loaded from
 * the this-ptr.  In case a value is loaded from a this pointer, the original
 * value must be preserved and must consequently be copied.  Values that are
 * loaded from parameters do not need to be preserved, as such values will
 * already be copies of the actual parameters.  It is consequently possible
 * to directly take the pointer from these values, which saves
 * an unnecessary copy.
 *
 * In case the parameter is a callback function, two parameters get printed,
 * a wrapper for the callback function and a pointer to the actual
 * callback function.  The wrapper is expected to be available
 * in a previously declared variable <name>_lambda, while
 * the actual callback function is expected to be stored
 * in a structure called <name>_data.
 * The caller of this function must ensure that these variables exist.
 */
void cpp_generator::print_method_param_use(ostream &os, ParmVarDecl *param,
	bool load_from_this_ptr)
{
	string name = param->getName().str();
	const char *name_str = name.c_str();
	QualType type = param->getOriginalType();

	if (type->isIntegerType()) {
		osprintf(os, "%s", name_str);
		return;
	}

	if (is_string(type)) {
		osprintf(os, "%s.c_str()", name_str);
		return;
	}

	if (is_callback(type)) {
		osprintf(os, "%s_lambda, ", name_str);
		osprintf(os, "&%s_data", name_str);
		return;
	}

	if (!load_from_this_ptr && !is_callback(type))
		osprintf(os, "%s.", name_str);

	if (keeps(param)) {
		osprintf(os, "get()");
	} else {
		if (load_from_this_ptr)
			osprintf(os, "copy()");
		else
			osprintf(os, "release()");
	}
}

/* Print code that checks that all isl object arguments to "method" are valid
 * (not NULL) and throws an exception if they are not.
 * "kind" specifies the kind of method that is being generated.
 *
 * If checked bindings are being generated,
 * then no such check is performed.
 */
void cpp_generator::print_argument_validity_check(ostream &os,
	FunctionDecl *method, function_kind kind)
{
	int n;
	bool first = true;

	if (checked)
		return;

	n = method->getNumParams();
	for (int i = 0; i < n; ++i) {
		bool is_this;
		ParmVarDecl *param = method->getParamDecl(i);
		string name = param->getName().str();
		const char *name_str = name.c_str();
		QualType type = param->getOriginalType();

		is_this = i == 0 && kind == function_kind_member_method;
		if (!is_this && (is_isl_ctx(type) || !is_isl_type(type)))
			continue;

		if (first)
			osprintf(os, "  if (");
		else
			osprintf(os, " || ");

		if (is_this)
			osprintf(os, "!ptr");
		else
			osprintf(os, "%s.is_null()", name_str);

		first = false;
	}
	if (first)
		return;
	osprintf(os, ")\n");
	print_throw_NULL_input(os);
}

/* Print code for saving a copy of the isl::ctx available at the start
 * of the method "method" in a "ctx" variable, for use in exception handling.
 * "kind" specifies what kind of method "method" is.
 *
 * If checked bindings are being generated,
 * then the "ctx" variable is not needed.
 * If "method" is a member function, then obtain the isl_ctx from
 * the "this" object.
 * If the first argument of the method is an isl::ctx, then use that one,
 * assuming it is not already called "ctx".
 * Otherwise, save a copy of the isl::ctx associated to the first argument
 * of isl object type.
 */
void cpp_generator::print_save_ctx(ostream &os, FunctionDecl *method,
	function_kind kind)
{
	int n;
	ParmVarDecl *param = method->getParamDecl(0);
	QualType type = param->getOriginalType();

	if (checked)
		return;
	if (kind == function_kind_member_method) {
		osprintf(os, "  auto ctx = get_ctx();\n");
		return;
	}
	if (is_isl_ctx(type)) {
		const char *name;

		name = param->getName().str().c_str();
		if (strcmp(name, "ctx") != 0)
			osprintf(os, "  auto ctx = %s;\n", name);
		return;
	}
	n = method->getNumParams();
	for (int i = 0; i < n; ++i) {
		ParmVarDecl *param = method->getParamDecl(i);
		QualType type = param->getOriginalType();

		if (!is_isl_type(type))
			continue;
		osprintf(os, "  auto ctx = %s.get_ctx();\n",
			param->getName().str().c_str());
		return;
	}
}

/* Print code to make isl not print an error message when an error occurs
 * within the current scope (if exceptions are available),
 * since the error message will be included in the exception.
 * If exceptions are not available, then exception::on_error
 * is set to ISL_ON_ERROR_ABORT and isl is therefore made to abort instead.
 *
 * If checked bindings are being generated,
 * then leave it to the user to decide what isl should do on error.
 * Otherwise, assume that a valid isl::ctx is available in the "ctx" variable,
 * e.g., through a prior call to print_save_ctx.
 */
void cpp_generator::print_on_error_continue(ostream &os)
{
	if (checked)
		return;
	osprintf(os, "  options_scoped_set_on_error saved_on_error(ctx, "
		     "exception::on_error);\n");
}

/* Print code that checks whether the execution of the core of "method"
 * was successful.
 *
 * If checked bindings are being generated,
 * then no checks are performed.
 *
 * Otherwise, first check if any of the callbacks failed with
 * an exception.  If so, the "eptr" in the corresponding data structure
 * contains the exception that was caught and that needs to be rethrown.
 * Then check if the function call failed in any other way and throw
 * the appropriate exception.
 * In particular, if the return type is isl_stat or isl_bool,
 * then a negative value indicates a failure.  If the return type
 * is an isl type, then a NULL value indicates a failure.
 * Assume print_save_ctx has made sure that a valid isl::ctx
 * is available in the "ctx" variable.
 */
void cpp_generator::print_exceptional_execution_check(ostream &os,
	FunctionDecl *method)
{
	int n;
	bool check_null, check_neg;
	QualType return_type = method->getReturnType();

	if (checked)
		return;

	n = method->getNumParams();
	for (int i = 0; i < n; ++i) {
		ParmVarDecl *param = method->getParamDecl(i);
		const char *name;

		if (!is_callback(param->getOriginalType()))
			continue;
		name = param->getName().str().c_str();
		osprintf(os, "  if (%s_data.eptr)\n", name);
		osprintf(os, "    std::rethrow_exception(%s_data.eptr);\n",
			name);
	}

	check_neg = is_isl_stat(return_type) || is_isl_bool(return_type);
	check_null = is_isl_type(return_type);
	if (!check_null && !check_neg)
		return;

	if (check_neg)
		osprintf(os, "  if (res < 0)\n");
	else
		osprintf(os, "  if (!res)\n");
	print_throw_last_error(os);
}

/* Print definition for "method" in class "clazz" to "os".
 *
 * "fullname" is the name of the generated C++ method.  It commonly corresponds
 * to the isl name, with the object type prefix dropped.
 * In case of overloaded methods, the result type suffix has also been removed.
 *
 * "kind" specifies the kind of method that should be generated.
 *
 * This method distinguishes three kinds of methods: member methods, static
 * methods, and constructors.
 *
 * Member methods call "method" by passing to the underlying isl function the
 * isl object belonging to "this" as first argument and the remaining arguments
 * as subsequent arguments. The result of the isl function is returned as a new
 * object if the underlying isl function returns an isl_* ptr, as a bool
 * if the isl function returns an isl_bool, as void if the isl functions
 * returns an isl_stat,
 * as std::string if the isl function returns 'const char *', and as
 * unmodified return value otherwise.
 * If checked C++ bindings are being generated,
 * then an isl_bool return type is transformed into a boolean and
 * an isl_stat into a stat since no exceptions can be generated
 * on negative results from the isl function.
 *
 * Static methods call "method" by passing all arguments to the underlying isl
 * function, as no this-pointer is available. The result is a newly managed
 * isl C++ object.
 *
 * Constructors create a new object from a given set of input parameters. They
 * do not return a value, but instead update the pointer stored inside the
 * newly created object.
 *
 * If the method has a callback argument, we reduce the number of parameters
 * that are exposed by one to hide the user pointer from the interface. On
 * the C++ side no user pointer is needed, as arguments can be forwarded
 * as part of the std::function argument which specifies the callback function.
 *
 * Unless checked C++ bindings are being generated,
 * the inputs of the method are first checked for being valid isl objects and
 * a copy of the associated isl::ctx is saved (if needed).
 * If any failure occurs, either during the check for the inputs or
 * during the isl function call, an exception is thrown.
 * During the function call, isl is made not to print any error message
 * because the error message is included in the exception.
 */
void cpp_generator::print_method_impl(ostream &os, const isl_class &clazz,
	const string &fullname, FunctionDecl *method, function_kind kind)
{
	string methodname = method->getName();
	int num_params = method->getNumParams();
	QualType return_type = method->getReturnType();
	string rettype_str = type2cpp(return_type);
	bool has_callback = false;

	print_method_header(os, clazz, method, fullname, false, kind);
	osprintf(os, "{\n");
	print_argument_validity_check(os, method, kind);
	print_save_ctx(os, method, kind);
	print_on_error_continue(os);

	for (int i = 0; i < num_params; ++i) {
		ParmVarDecl *param = method->getParamDecl(i);
		if (is_callback(param->getType())) {
			has_callback = true;
			num_params -= 1;
			print_callback_local(os, param);
		}
	}

	osprintf(os, "  auto res = %s(", methodname.c_str());

	for (int i = 0; i < num_params; ++i) {
		ParmVarDecl *param = method->getParamDecl(i);
		bool load_from_this_ptr = false;

		if (i == 0 && kind == function_kind_member_method)
			load_from_this_ptr = true;

		print_method_param_use(os, param, load_from_this_ptr);

		if (i != num_params - 1)
			osprintf(os, ", ");
	}
	osprintf(os, ");\n");

	print_exceptional_execution_check(os, method);
	if (kind == function_kind_constructor) {
		osprintf(os, "  ptr = res;\n");
	} else if (is_isl_type(return_type) ||
		    (checked &&
		     (is_isl_bool(return_type) || is_isl_stat(return_type)))) {
		osprintf(os, "  return manage(res);\n");
	} else if (has_callback) {
		osprintf(os, "  return %s(res);\n", rettype_str.c_str());
	} else if (is_string(return_type)) {
		osprintf(os, "  std::string tmp(res);\n");
		if (gives(method))
			osprintf(os, "  free(res);\n");
		osprintf(os, "  return tmp;\n");
	} else {
		osprintf(os, "  return res;\n");
	}

	osprintf(os, "}\n");
}

/* Print the header for "method" in class "clazz" to "os".
 *
 * Print the header of a declaration if "is_declaration" is set, otherwise print
 * the header of a method definition.
 *
 * "fullname" is the name of the generated C++ method.  It commonly corresponds
 * to the isl name, with the object type prefix dropped.
 * In case of overloaded methods, the result type suffix has also been removed.
 *
 * "kind" specifies the kind of method that should be generated.
 *
 * This function prints headers for member methods, static methods, and
 * constructors, either for their declaration or definition.
 *
 * Member functions are declared as "const", as they do not change the current
 * object, but instead create a new object. They always retrieve the first
 * parameter of the original isl function from the this-pointer of the object,
 * such that only starting at the second parameter the parameters of the
 * original function become part of the method's interface.
 *
 * A function
 *
 * 	__isl_give isl_set *isl_set_intersect(__isl_take isl_set *s1,
 * 		__isl_take isl_set *s2);
 *
 * is translated into:
 *
 * 	inline set intersect(set set2) const;
 *
 * For static functions and constructors all parameters of the original isl
 * function are exposed.
 *
 * Parameters that are defined as __isl_keep or are of type string, are passed
 * as const reference, which allows the compiler to optimize the parameter
 * transfer.
 *
 * Constructors are marked as explicit using the C++ keyword 'explicit' or as
 * implicit using a comment in place of the explicit keyword. By annotating
 * implicit constructors with a comment, users of the interface are made
 * aware of the potential danger that implicit construction is possible
 * for these constructors, whereas without a comment not every user would
 * know that implicit construction is allowed in absence of an explicit keyword.
 */
void cpp_generator::print_method_header(ostream &os, const isl_class &clazz,
	FunctionDecl *method, const string &fullname, bool is_declaration,
	function_kind kind)
{
	string cname = fullname.substr(clazz.name.length() + 1);
	string rettype_str = type2cpp(method->getReturnType());
	string classname = type2cpp(clazz);
	int num_params = method->getNumParams();
	int first_param = 0;

	cname = rename_method(cname);
	if (kind == function_kind_member_method)
		first_param = 1;

	if (is_declaration) {
		osprintf(os, "  ");

		if (kind == function_kind_static_method)
			osprintf(os, "static ");

		osprintf(os, "inline ");

		if (kind == function_kind_constructor) {
			if (is_implicit_conversion(clazz, method))
				osprintf(os, "/* implicit */ ");
			else
				osprintf(os, "explicit ");
		}
	}

	if (kind != function_kind_constructor)
		osprintf(os, "%s ", rettype_str.c_str());

	if (!is_declaration)
		osprintf(os, "%s::", classname.c_str());

	if (kind != function_kind_constructor)
		osprintf(os, "%s", cname.c_str());
	else
		osprintf(os, "%s", classname.c_str());

	osprintf(os, "(");

	for (int i = first_param; i < num_params; ++i) {
		ParmVarDecl *param = method->getParamDecl(i);
		QualType type = param->getOriginalType();
		string cpptype = type2cpp(type);

		if (is_callback(type))
			num_params--;

		if (keeps(param) || is_string(type) || is_callback(type))
			osprintf(os, "const %s &%s", cpptype.c_str(),
				 param->getName().str().c_str());
		else
			osprintf(os, "%s %s", cpptype.c_str(),
				 param->getName().str().c_str());

		if (i != num_params - 1)
			osprintf(os, ", ");
	}

	osprintf(os, ")");

	if (kind == function_kind_member_method)
		osprintf(os, " const");

	if (is_declaration)
		osprintf(os, ";");
	osprintf(os, "\n");
}

/* Generate the list of argument types for a callback function of
 * type "type".  If "cpp" is set, then generate the C++ type list, otherwise
 * the C type list.
 *
 * For a callback of type
 *
 *      isl_stat (*)(__isl_take isl_map *map, void *user)
 *
 * the following C++ argument list is generated:
 *
 *      map
 */
string cpp_generator::generate_callback_args(QualType type, bool cpp)
{
	std::string type_str;
	const FunctionProtoType *callback;
	int num_params;

	callback = type->getPointeeType()->getAs<FunctionProtoType>();
	num_params = callback->getNumArgs();
	if (cpp)
		num_params--;

	for (long i = 0; i < num_params; i++) {
		QualType type = callback->getArgType(i);

		if (cpp)
			type_str += type2cpp(type);
		else
			type_str += type.getAsString();

		if (!cpp)
			type_str += "arg_" + ::to_string(i);

		if (i != num_params - 1)
			type_str += ", ";
	}

	return type_str;
}

/* Generate the full cpp type of a callback function of type "type".
 *
 * For a callback of type
 *
 *      isl_stat (*)(__isl_take isl_map *map, void *user)
 *
 * the following type is generated:
 *
 *      std::function<stat(map)>
 */
string cpp_generator::generate_callback_type(QualType type)
{
	std::string type_str;
	const FunctionProtoType *callback = type->getPointeeType()->getAs<FunctionProtoType>();
	QualType return_type = callback->getReturnType();
	string rettype_str = type2cpp(return_type);

	type_str = "std::function<";
	type_str += rettype_str;
	type_str += "(";
	type_str += generate_callback_args(type, true);
	type_str += ")>";

	return type_str;
}

/* Print the call to the C++ callback function "call", wrapped
 * for use inside the lambda function that is used as the C callback function,
 * in the case where checked C++ bindings are being generated.
 *
 * In particular, print
 *
 *        stat ret = @call@;
 *        return ret.release();
 */
void cpp_generator::print_wrapped_call_checked(ostream &os,
	const string &call)
{
	osprintf(os, "    stat ret = %s;\n", call.c_str());
	osprintf(os, "    return ret.release();\n");
}

/* Print the call to the C++ callback function "call", wrapped
 * for use inside the lambda function that is used as the C callback function.
 *
 * In particular, print
 *
 *        ISL_CPP_TRY {
 *          @call@;
 *          return isl_stat_ok;
 *        } ISL_CPP_CATCH_ALL {
 *          data->eptr = std::current_exception();
 *          return isl_stat_error;
 *        }
 *
 * where ISL_CPP_TRY is defined to "try" and ISL_CPP_CATCH_ALL to "catch (...)"
 * (if exceptions are available).
 *
 * If checked C++ bindings are being generated, then
 * the call is wrapped differently.
 */
void cpp_generator::print_wrapped_call(ostream &os, const string &call)
{
	if (checked)
		return print_wrapped_call_checked(os, call);

	osprintf(os, "    ISL_CPP_TRY {\n");
	osprintf(os, "      %s;\n", call.c_str());
	osprintf(os, "      return isl_stat_ok;\n");
	osprintf(os, "    } ISL_CPP_CATCH_ALL {\n"
		     "      data->eptr = std::current_exception();\n");
	osprintf(os, "      return isl_stat_error;\n");
	osprintf(os, "    }\n");
}

/* Print the local variables that are needed for a callback argument,
 * in particular, print a lambda function that wraps the callback and
 * a pointer to the actual C++ callback function.
 *
 * For a callback of the form
 *
 *      isl_stat (*fn)(__isl_take isl_map *map, void *user)
 *
 * the following lambda function is generated:
 *
 *      auto fn_lambda = [](isl_map *arg_0, void *arg_1) -> isl_stat {
 *        auto *data = static_cast<struct fn_data *>(arg_1);
 *        try {
 *          stat ret = (*data->func)(manage(arg_0));
 *          return isl_stat_ok;
 *        } catch (...) {
 *          data->eptr = std::current_exception();
 *          return isl_stat_error;
 *        }
 *      };
 *
 * The pointer to the std::function C++ callback function is stored in
 * a fn_data data structure for passing to the C callback function,
 * along with an std::exception_ptr that is used to store any
 * exceptions thrown in the C++ callback.
 *
 *      struct fn_data {
 *        const std::function<stat(map)> *func;
 *        std::exception_ptr eptr;
 *      } fn_data = { &fn };
 *
 * This std::function object represents the actual user
 * callback function together with the locally captured state at the caller.
 *
 * The lambda function is expected to be used as a C callback function
 * where the lambda itself is provided as the function pointer and
 * where the user void pointer is a pointer to fn_data.
 * The std::function object is extracted from the pointer to fn_data
 * inside the lambda function.
 *
 * The std::exception_ptr object is not added to fn_data
 * if checked C++ bindings are being generated.
 * The body of the generated lambda function then is as follows:
 *
 *        stat ret = (*data->func)(manage(arg_0));
 *        return isl_stat(ret);
 */
void cpp_generator::print_callback_local(ostream &os, ParmVarDecl *param)
{
	string pname;
	QualType ptype;
	string call, c_args, cpp_args, rettype, last_idx;
	const FunctionProtoType *callback;
	int num_params;

	pname = param->getName().str();
	ptype = param->getType();

	c_args = generate_callback_args(ptype, false);
	cpp_args = generate_callback_type(ptype);

	callback = ptype->getPointeeType()->getAs<FunctionProtoType>();
	rettype = callback->getReturnType().getAsString();
	num_params = callback->getNumArgs();

	last_idx = ::to_string(num_params - 1);

	call = "(*data->func)(";
	for (long i = 0; i < num_params - 1; i++) {
		call += "manage(arg_" + ::to_string(i) + ")";
		if (i != num_params - 2)
			call += ", ";
	}
	call += ")";

	osprintf(os, "  struct %s_data {\n", pname.c_str());
	osprintf(os, "    const %s *func;\n", cpp_args.c_str());
	if (!checked)
		osprintf(os, "    std::exception_ptr eptr;\n");
	osprintf(os, "  } %s_data = { &%s };\n", pname.c_str(), pname.c_str());
	osprintf(os, "  auto %s_lambda = [](%s) -> %s {\n",
		 pname.c_str(), c_args.c_str(), rettype.c_str());
	osprintf(os,
		 "    auto *data = static_cast<struct %s_data *>(arg_%s);\n",
		 pname.c_str(), last_idx.c_str());
	print_wrapped_call(os, call);
	osprintf(os, "  };\n");
}

/* An array listing functions that must be renamed and the function name they
 * should be renamed to. We currently rename functions in case their name would
 * match a reserved C++ keyword, which is not allowed in C++.
 */
static const char *rename_map[][2] = {
	{ "union", "unite" },
};

/* Rename method "name" in case the method name in the C++ bindings should not
 * match the name in the C bindings. We do this for example to avoid
 * C++ keywords.
 */
std::string cpp_generator::rename_method(std::string name)
{
	for (size_t i = 0; i < sizeof(rename_map) / sizeof(rename_map[0]); i++)
		if (name.compare(rename_map[i][0]) == 0)
			return rename_map[i][1];

	return name;
}

/* Translate isl class "clazz" to its corresponding C++ type.
 */
string cpp_generator::type2cpp(const isl_class &clazz)
{
	return type2cpp(clazz.name);
}

/* Translate type string "type_str" to its C++ name counterpart.
*/
string cpp_generator::type2cpp(string type_str)
{
	return type_str.substr(4);
}

/* Translate QualType "type" to its C++ name counterpart.
 *
 * An isl_bool return type is translated into "bool",
 * while an isl_stat is translated into "void".
 * The exceptional cases are handled through exceptions.
 * If checked C++ bindings are being generated, then
 * C++ counterparts of isl_bool and isl_stat need to be used instead.
 */
string cpp_generator::type2cpp(QualType type)
{
	if (is_isl_type(type))
		return type2cpp(type->getPointeeType().getAsString());

	if (is_isl_bool(type))
		return checked ? "boolean" : "bool";

	if (is_isl_stat(type))
		return checked ? "stat" : "void";

	if (type->isIntegerType())
		return type.getAsString();

	if (is_string(type))
		return "std::string";

	if (is_callback(type))
		return generate_callback_type(type);

	die("Cannot convert type to C++ type");
}

/* Check if "subclass_type" is a subclass of "class_type".
 */
bool cpp_generator::is_subclass(QualType subclass_type,
	const isl_class &class_type)
{
	std::string type_str = subclass_type->getPointeeType().getAsString();
	std::vector<std::string> superclasses;
	std::vector<const isl_class *> parents;
	std::vector<std::string>::iterator ci;

	superclasses = generator::find_superclasses(classes[type_str].type);

	for (ci = superclasses.begin(); ci < superclasses.end(); ci++)
		parents.push_back(&classes[*ci]);

	while (!parents.empty()) {
		const isl_class *candidate = parents.back();

		parents.pop_back();

		if (&class_type == candidate)
			return true;

		superclasses = generator::find_superclasses(candidate->type);

		for (ci = superclasses.begin(); ci < superclasses.end(); ci++)
			parents.push_back(&classes[*ci]);
	}

	return false;
}

/* Check if "cons" is an implicit conversion constructor of class "clazz".
 *
 * An implicit conversion constructor is generated in case "cons" has a single
 * parameter, where the parameter type is a subclass of the class that is
 * currently being generated.
 */
bool cpp_generator::is_implicit_conversion(const isl_class &clazz,
	FunctionDecl *cons)
{
	ParmVarDecl *param = cons->getParamDecl(0);
	QualType type = param->getOriginalType();

	int num_params = cons->getNumParams();
	if (num_params != 1)
		return false;

	if (is_isl_type(type) && !is_isl_ctx(type) && is_subclass(type, clazz))
		return true;

	return false;
}

/* Get kind of "method" in "clazz".
 *
 * Given the declaration of a static or member method, returns its kind.
 */
cpp_generator::function_kind cpp_generator::get_method_kind(
	const isl_class &clazz, FunctionDecl *method)
{
	if (is_static(clazz, method))
		return function_kind_static_method;
	else
		return function_kind_member_method;
}
