44#include "isl_config.h"
51static void osprintf(ostream &os,
const char *format, va_list arguments)
57 va_copy(copy, arguments);
58 size = vsnprintf(NULL, 0, format, copy);
59 string_pointer =
new char[
size + 1];
61 vsnprintf(string_pointer,
size + 1, format, arguments);
63 delete[] string_pointer;
71static void osprintf(ostream &os,
const char *format, ...)
75 va_start(arguments, format);
86static void osprintf(ostream &os,
int indent,
const char *format, ...)
91 va_start(arguments, format);
100 std::ostringstream strm;
135 osprintf(os,
"namespace isl {\n\n");
137 osprintf(os,
"namespace checked {\n\n");
146 osprintf(os,
"} // namespace checked\n");
147 osprintf(os,
"} // namespace isl\n");
156 osprintf(os,
"// forward declarations\n");
209 const char *supername;
211 if (!
clazz.is_type_subclass())
215 supername = super.c_str();
218 generator.isl_bool2cpp().c_str(), supername);
219 osprintf(
os,
" friend %s %s::as<%s>() const;\n",
220 cppname, supername, cppname);
221 osprintf(
os,
" static const auto type = %s;\n",
222 clazz.subclass_name.c_str());
241 const char *
name = clazz.
name.c_str();
242 const char *cppname = printer.
cppstring.c_str();
244 osprintf(os,
"// declarations for isl::%s\n", cppname);
274 std::string cppstring =
type2cpp(clazz);
275 const char *cppname = cppstring.c_str();
277 osprintf(os,
"class %s;\n", cppname);
300 const std::string &prefix)
305 if (
clazz.is_type_subclass())
309 osprintf(
os,
"inline %s manage(__isl_take %s *ptr);\n", cppname,
name);
311 osprintf(
os,
"inline %s manage_copy(__isl_keep %s *ptr);\n",
333 osprintf(
os,
" inline explicit %s(__isl_take %s *ptr);\n", cppname,
352 osprintf(
os,
" inline /* implicit */ %s();\n", cppname);
354 osprintf(
os,
" inline /* implicit */ %s(const %s &obj);\n",
401 osprintf(
os,
" inline %s &operator=(%s obj);\n", cppname, cppname);
412 if (
clazz.is_type_subclass())
456 if (
clazz.is_type_subclass())
460 osprintf(
os,
" inline __isl_give %s *copy() && = delete;\n",
name);
463 osprintf(
os,
" inline bool is_null() const;\n");
481 "template <typename T,\n");
483 " typename = typename std::enable_if<std::is_same<\n");
485 " const decltype(%s(NULL)),\n",
486 super.
fn_type->getNameAsString().c_str());
488 " const T>::value>::type>\n");
508 osprintf(
os,
" inline %s isa_type(T subtype) const;\n",
511 osprintf(
os,
" template <class T> inline %s isa() const;\n",
513 osprintf(
os,
" template <class T> inline T as() const;\n");
520 std::string ns =
generator.isl_namespace();
522 osprintf(
os,
" inline %sctx ctx() const;\n", ns.c_str());
546 FunctionDecl *method)
550 const FunctionProtoType *callback;
554 ptype = param->getType();
557 rettype = callback->getReturnType().getAsString();
560 c_args =
generator.generate_callback_args(ptype,
false);
566 rettype.c_str(), classname.c_str(),
575 FunctionDecl *method)
583 cpptype =
generator.param2cpp(param->getOriginalType());
585 osprintf(
os,
"void %sset_%s_data(const %s &%s)",
587 param->getName().str().c_str());
601 FunctionDecl *method)
604 ParmVarDecl *param =
generator.persistent_callback_arg(method);
609 osprintf(
os,
" std::shared_ptr<%s_data> %s_data;\n",
631 if (!
clazz.has_persistent_callbacks())
635 osprintf(
os,
" inline %s ©_callbacks(const %s &obj);\n",
637 for (
const auto &callback :
clazz.persistent_callbacks)
641 for (
const auto &callback :
clazz.persistent_callbacks)
650 string base =
clazz.base_method_name(fd);
660 const char *cppname = printer.
cppstring.c_str();
662 osprintf(os,
"// implementations for isl::%s", cppname);
677 osprintf(os,
" exception::throw_last_error(saved_ctx);\n");
686 "exception::throw_invalid(\"%s\", __FILE__, __LINE__);\n", msg);
703 const char *msg,
const char *checked_code)
707 "isl_die(ctx().get(), isl_error_invalid, "
708 "\"%s\", %s);\n", msg, checked_code);
730 if (!
clazz.fn_to_str)
734 osprintf(
os,
"inline std::ostream &operator<<(std::ostream &os, ");
742 osprintf(
os,
" os.setstate(std::ios_base::badbit);\n");
818 if (
clazz.is_type_subclass())
827 osprintf(
os,
"%s manage_copy(__isl_keep %s *ptr) {\n", cppname,
845 bool subclass =
clazz.is_type_subclass();
848 osprintf(
os,
"%s::%s(__isl_take %s *ptr)\n", cppname, cppname,
name);
877 bool subclass =
clazz.is_type_subclass();
884 osprintf(
os,
" : %s() {}\n\n", super.c_str());
887 osprintf(
os,
"%s::%s(const %s &obj)\n", cppname, cppname, cppname);
896 if (
clazz.has_persistent_callbacks())
926 string methodname = method.
fd->getName().str();
936 for (
const auto &callback : method.
callbacks)
939 osprintf(
os,
" auto res = %s", methodname.c_str());
968 std::string
name = dst->getName().str();
969 QualType
type = dst->getOriginalType();
975 os << cpptype <<
"(" <<
name <<
")";
977 os << cpptype <<
"(ctx(), " <<
name <<
")";
1000 die(
"Automatic conversion currently only supported "
1001 "for object methods");
1010 ParmVarDecl *param = method.
fd->getParamDecl(i);
1044 os <<
" std::any *p = new std::any(any);\n";
1045 os <<
" auto res = isl_id_alloc(ctx.get(), str.c_str(), p);\n";
1046 os <<
" res = isl_id_set_free_user(res, &ctx::free_user);\n";
1047 os <<
" if (!res) {\n";
1048 os <<
" delete p;\n";
1052 os <<
" ptr = res;\n";
1072 auto fail = [&] (
const char *msg) {
1074 os <<
" return std::nullopt;\n";
1076 generator.print_invalid(
os, 4, msg,
"return T()");
1082 os <<
" std::any *p = (std::any *) isl_id_get_user(ptr);\n";
1084 fail(
"no user pointer");
1085 os <<
" if (isl_id_get_free_user(ptr) != &ctx::free_user)\n";
1086 fail(
"user pointer not attached by C++ interface");
1087 os <<
" T *res = std::any_cast<T>(p);\n";
1088 os <<
" if (!res)\n";
1089 fail(
"user pointer not of given type");
1090 os <<
" return *res;\n";
1102 const char *cppname =
cppstring.c_str();
1105 osprintf(
os,
"%s &%s::operator=(%s obj) {\n", cppname,
1108 if (
clazz.has_persistent_callbacks())
1121 const char *cppname =
cppstring.c_str();
1123 if (
clazz.is_type_subclass())
1127 osprintf(
os,
"%s::~%s() {\n", cppname, cppname);
1138 const isl_class &clazz, FunctionDecl *fd)
1143 print_invalid(os, 4,
"cannot release object with persistent callbacks",
1158 const char *cppname =
cppstring.c_str();
1162 if (
clazz.is_type_subclass())
1166 osprintf(
os,
"__isl_give %s *%s::copy() const & {\n",
name, cppname);
1169 osprintf(
os,
"__isl_keep %s *%s::get() const {\n",
name, cppname);
1173 for (in = callbacks.begin(); in != callbacks.end(); ++in)
1179 osprintf(
os,
"bool %s::is_null() const {\n", cppname);
1201 const char *cppname =
cppstring.c_str();
1207 osprintf(
os,
"template <typename T, typename>\n");
1208 osprintf(
os,
"%s %s::isa_type(T subtype) const\n",
1209 generator.isl_bool2cpp().c_str(), cppname);
1216 osprintf(
os,
" return %s(get()) == subtype;\n",
1217 clazz.fn_type->getNameAsString().c_str());
1222 generator.isl_bool2cpp().c_str(), cppname);
1224 osprintf(
os,
" return isa_type<decltype(T::type)>(T::type);\n");
1234 generator.print_invalid(
os, 4,
"not an object of the requested subtype",
1245 const char *cppname =
cppstring.c_str();
1246 std::string ns =
generator.isl_namespace();
1249 osprintf(
os,
"%sctx %s::ctx() const {\n", ns.c_str(), cppname);
1250 osprintf(
os,
" return %sctx(%s_get_ctx(ptr));\n", ns.c_str(),
name);
1267 const char *cppname =
cppstring.c_str();
1270 if (!
clazz.has_persistent_callbacks())
1274 osprintf(
os,
"%s &%s::copy_callbacks(const %s &obj)\n",
1275 cppname, classname.c_str(), cppname);
1277 for (
const auto &callback :
clazz.persistent_callbacks) {
1286 for (
const auto &callback :
clazz.persistent_callbacks)
1299 string get_name =
clazz.base_method_name(fd);
1301 int num_params = fd->getNumParams();
1307 for (
int i = 1; i < num_params; ++i) {
1308 ParmVarDecl *param = fd->getParamDecl(i);
1312 osprintf(
os,
"%s", param->getName().str().c_str());
1334 for (
int i = 0; i <
n; ++i) {
1336 ParmVarDecl *param = method.
fd->getParamDecl(i);
1337 string name = param->getName().str();
1338 const char *name_str =
name.c_str();
1339 QualType
type = param->getOriginalType();
1367 os <<
" auto saved_ctx = " << ctx <<
";\n";
1385 ParmVarDecl *param = method.
fd->getParamDecl(0);
1386 QualType
type = param->getOriginalType();
1395 for (
int i = 0; i <
n; ++i) {
1396 ParmVarDecl *param = method.
fd->getParamDecl(i);
1397 QualType
type = param->getOriginalType();
1422 osprintf(
os,
" options_scoped_set_on_error saved_on_error(saved_ctx, "
1423 "exception::on_error);\n");
1444 osprintf(os,
" if (%s_data && %s_data->eptr) {\n",
1446 osprintf(os,
" std::exception_ptr eptr = %s_data->eptr;\n",
1448 osprintf(os,
" %s_data->eptr = nullptr;\n",
1450 osprintf(os,
" std::rethrow_exception(eptr);\n");
1475 bool check_null, check_neg;
1476 QualType return_type = method.
fd->getReturnType();
1483 for (
const auto &callback : method.
callbacks) {
1486 name = callback->getName().str();
1488 osprintf(
os,
" std::rethrow_exception(%s_data.eptr);\n",
1494 if (!check_null && !check_neg)
1517 return std::unique_ptr<cpp_type_printer>(printer);
1541 string fullname = method.
fd->getName().str();
1553 pname = param->getName().str();
1558 osprintf(
os,
" %s_data = std::make_shared<struct %s_data>();\n",
1562 osprintf(
os,
" ptr = %s(ptr, &%s, %s_data.get());\n",
1598 QualType return_type = method.
fd->getReturnType();
1599 string rettype_str =
generator.get_return_type(method);
1606 clazz.has_persistent_callbacks())
1609 osprintf(
os,
".as<%s>()", rettype_str.c_str());
1677 osprintf(
os, indent,
"auto ret = %s;\n", call.c_str());
1678 osprintf(
os, indent,
"return ret.release();\n");
1720 const string &call, QualType rtype)
1727 osprintf(
os, indent,
" %s;\n", call.c_str());
1729 osprintf(
os, indent,
" auto ret = %s;\n", call.c_str());
1731 osprintf(
os, indent,
" return isl_stat_ok;\n");
1734 " return ret ? isl_bool_true : isl_bool_false;\n");
1736 osprintf(
os, indent,
" return ret.release();\n");
1737 osprintf(
os, indent,
"} ISL_CPP_CATCH_ALL {\n");
1738 osprintf(
os, indent,
" data->eptr = std::current_exception();\n");
1740 osprintf(
os, indent,
" return isl_stat_error;\n");
1742 osprintf(
os, indent,
" return isl_bool_error;\n");
1772 const string &prefix)
1776 cpp_args =
generator.generate_callback_type(param->getType());
1778 osprintf(
os,
" struct %s_data {\n", prefix.c_str());
1779 osprintf(
os,
" %s func;\n", cpp_args.c_str());
1802 return methods.size() > 1;
1813 os <<
" inline explicit ";
1816 os <<
"id(" <<
generator.isl_namespace() <<
"ctx ctx, "
1817 <<
"const std::string &str, const std::any &any)";
1831 os << indent <<
"template <class T>\n";
1832 os << indent << (optional ?
"std::optional<T> " :
"T ");
1835 os << (optional ?
"try_" :
"");
1836 os <<
"user() const";
1847 os <<
"#if __cplusplus >= 201703L\n";
1877 if (
clazz.name ==
"isl_id")
1928 ParmVarDecl *param,
const string &prefix)
1930 QualType ptype, rtype;
1931 string call, last_idx;
1932 const FunctionProtoType *callback;
1935 ptype = param->getType();
1938 rtype = callback->getReturnType();
1939 num_params = callback->getNumArgs();
1943 call =
"(data->func)(";
1944 for (
long i = 0; i < num_params - 1; i++) {
1945 if (!
generator.callback_takes_argument(param, i))
1946 call +=
"manage_copy";
1950 if (i != num_params - 2)
1956 "auto *data = static_cast<struct %s_data *>(arg_%s);\n",
1957 prefix.c_str(), last_idx.c_str());
2014 QualType ptype, rtype;
2015 string c_args, cpp_args, rettype;
2016 const FunctionProtoType *callback;
2018 pname = param->getName().str();
2019 ptype = param->getType();
2021 c_args =
generator.generate_callback_args(ptype,
false);
2024 rtype = callback->getReturnType();
2025 rettype = rtype.getAsString();
2028 osprintf(
os,
" %s_data = { %s };\n", pname.c_str(), pname.c_str());
2029 osprintf(
os,
" auto %s_lambda = [](%s) -> %s {\n",
2030 pname.c_str(), c_args.c_str(), rettype.c_str());
2068 return "class size";
2077 return "isl::checked::";
cpp_generator(SourceManager &SM, set< RecordDecl * > &exported_types, set< FunctionDecl * > exported_functions, set< FunctionDecl * > functions)
static string type2cpp(const isl_class &clazz)
static bool is_isl_type(QualType type)
static ParmVarDecl * persistent_callback_arg(FunctionDecl *fd)
static bool gives(Decl *decl)
static bool is_isl_ctx(QualType type)
static bool is_mutator(const isl_class &clazz, FunctionDecl *fd)
static bool is_string(QualType type)
static bool is_isl_neg_error(QualType type)
static bool is_isl_bool(QualType type)
static bool is_isl_stat(QualType type)
map< string, isl_class > classes
static const FunctionProtoType * extract_prototype(QualType type)
void print_class_forward_decl(ostream &os, const isl_class &clazz)
void print_check_no_persistent_callback(ostream &os, const isl_class &clazz, FunctionDecl *fd)
void print_invalid(ostream &os, int indent, const char *msg, const char *checked_code)
void print_class_impl(ostream &os, const isl_class &clazz)
void print_class(ostream &os, const isl_class &clazz)
void print_declarations(ostream &os)
string generate_callback_args(QualType type, bool cpp)
string param2cpp(QualType type)
string generate_callback_type(QualType type)
void print_implementations(ostream &os)
std::unique_ptr< cpp_type_printer > type_printer()
plain_cpp_generator(SourceManager &SM, set< RecordDecl * > &exported_types, set< FunctionDecl * > exported_functions, set< FunctionDecl * > functions, bool checked=false)
std::string get_return_type(const Method &method)
void print_forward_declarations(ostream &os)
std::set< FunctionDecl *, function_name_less > function_set
isl_stat isl_stat(* fn)(__isl_take ISL_KEY *key, __isl_take ISL_VAL *val, void *user)
static void print_throw_last_error(ostream &os)
static void print_persistent_callback_exceptional_execution_check(ostream &os, const Method &method)
static void on_cplusplus17(ostream &os, const std::function< void(void)> &fn)
static void osprintf(ostream &os, const char *format, va_list arguments)
static string add_space_to_return_type(const string &type)
static void print_throw_NULL_input(ostream &os)
static void print_throw_invalid(ostream &os, int indent, const char *msg)
static std::string to_string(long l)
void print_call(std::ostream &os, const std::string &ns) const
virtual clang::ParmVarDecl * get_param(int pos) const override
void print_fd_arg_list(std::ostream &os, int start, int end, const std::function< void(int i, int arg)> &print_arg) const
virtual int num_params() const
virtual void print_param_use(ostream &os, int pos) const
bool is_subclass_mutator() const
const std::vector< ParmVarDecl * > callbacks
void print_cpp_arg_list(std::ostream &os, const std::function< void(int i, int arg)> &print_arg) const
virtual std::string isl_stat() const override
virtual std::string isl_bool() const override
virtual std::string isl_namespace() const override
virtual std::string isl_size() const override
void print_constructors()
void print_set_enums(FunctionDecl *fd)
const std::string cppstring
void print_method_header(const Method &method, const cpp_type_printer &type_printer)
bool is_type_subclass() const
string persistent_callback_name(FunctionDecl *fd) const
set< FunctionDecl * > persistent_callbacks
virtual void print_id_constructor_user() override
virtual void print_downcast() override
virtual void print_persistent_callbacks() override
virtual void print_id_user(bool optional) override
virtual void print_method_separator() override
void print_persistent_callback_data(FunctionDecl *method)
virtual void print_method(const Method &method) override
virtual void print_get_method(FunctionDecl *fd) override
virtual void print_ptr() override
virtual void print_copy_assignment() override
void print_subclass_type()
virtual void print_ctx() override
void print_isa_type_template(int indent, const isl_class &super)
virtual void print_destructor() override
virtual void print_public_constructors() override
void print_class_factory(const std::string &prefix=std::string())
void print_protected_constructors()
void print_check_ptr(const char *ptr)
void print_save_ctx(const std::string &ctx)
void print_set_persistent_callback(const Method &method)
virtual void print_persistent_callbacks() override
virtual void print_copy_assignment() override
virtual void print_ctx() override
virtual void print_destructor() override
void print_wrapped_call(int indent, const std::string &call, QualType rtype)
void print_on_error_continue()
virtual void print_id_constructor_user() override
void print_protected_constructors()
void print_arg_conversion(ParmVarDecl *dst, ParmVarDecl *src)
void print_callback_local(ParmVarDecl *param)
void print_argument_validity_check(const Method &method)
virtual void print_method_separator() override
virtual void print_public_constructors() override
void print_method_return(const Method &method)
void print_class_factory()
virtual void print_id_user(bool optional) override
void print_check_ptr_start(const char *ptr)
void print_wrapped_call_checked(int indent, const std::string &call)
virtual void print_method(const Method &method) override
void print_check_ptr_end(const char *ptr)
void print_exceptional_execution_check(const Method &method)
virtual void print_downcast() override
virtual void print_ptr() override
void print_callback_body(int indent, ParmVarDecl *param, const string &name)
void print_stream_insertion()
virtual void print_get_method(FunctionDecl *fd) override
virtual void print_ptr()=0
virtual void print_id_user(bool optional)=0
virtual void print_downcast()=0
virtual void print_persistent_callbacks()=0
void print_persistent_callback_setter_prototype(FunctionDecl *method)
virtual void print_public_constructors()=0
void print_id_constructor_user_header()
virtual void print_copy_assignment()=0
virtual void print_destructor()=0
virtual void print_method_separator()=0
void print_persistent_callback_prototype(FunctionDecl *method)
void print_callback_data_decl(ParmVarDecl *param, const string &name)
virtual void print_id_constructor_user()=0
virtual void print_ctx()=0
void print_full_method_header(const Method &method)
plain_cpp_generator & generator
virtual bool want_descendent_overloads(const function_set &methods) override
void print_public_methods()
void print_id_user_header(bool optional)
const std::string callback_name(const Method &method)