summaryrefslogtreecommitdiff
path: root/polly/lib/External/isl/interface/cpp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'polly/lib/External/isl/interface/cpp.cc')
-rw-r--r--polly/lib/External/isl/interface/cpp.cc170
1 files changed, 140 insertions, 30 deletions
diff --git a/polly/lib/External/isl/interface/cpp.cc b/polly/lib/External/isl/interface/cpp.cc
index 23e2281de1b9..d5c08ebf25f0 100644
--- a/polly/lib/External/isl/interface/cpp.cc
+++ b/polly/lib/External/isl/interface/cpp.cc
@@ -649,11 +649,11 @@ void cpp_generator::class_printer::print_method_header(
else
os << cppstring;
- method.print_cpp_arg_list(os, [&] (int i) {
+ method.print_cpp_arg_list(os, [&] (int i, int arg) {
std::string name = method.fd->getParamDecl(i)->getName().str();
ParmVarDecl *param = method.get_param(i);
QualType type = param->getOriginalType();
- string cpptype = type_printer.param(i, type);
+ string cpptype = type_printer.param(arg, type);
if (!method.param_needs_copy(i))
os << "const " << cpptype << " &" << name;
@@ -928,6 +928,24 @@ bool cpp_generator::is_implicit_conversion(const Method &cons)
return false;
}
+/* Construct a list combiner for printing a list.
+ */
+Method::list_combiner Method::print_combiner(std::ostream &os)
+{
+ return {
+ [&] () { os << "("; },
+ [&] () { os << ", "; },
+ [&] () { os << ")"; }
+ };
+}
+
+/* Construct a list combiner for simply iterating over a list.
+ */
+Method::list_combiner Method::empty_combiner()
+{
+ return { [&] () { }, [&] () { }, [&] () { } };
+}
+
/* Get kind of "method" in "clazz".
*
* Given the declaration of a static or member method, returns its kind.
@@ -942,20 +960,20 @@ static Method::Kind get_kind(const isl_class &clazz, FunctionDecl *method)
return Method::Kind::member_method;
}
-/* Return the callback argument of "fd", if there is any.
- * Return NULL otherwise.
+/* Return the callback arguments of "fd".
*/
-static ParmVarDecl *find_callback_arg(FunctionDecl *fd)
+static std::vector<ParmVarDecl *> find_callback_args(FunctionDecl *fd)
{
+ std::vector<ParmVarDecl *> callbacks;
int num_params = fd->getNumParams();
for (int i = 0; i < num_params; ++i) {
ParmVarDecl *param = fd->getParamDecl(i);
if (generator::is_callback(param->getType()))
- return param;
+ callbacks.emplace_back(param);
}
- return NULL;
+ return callbacks;
}
/* Construct a C++ method object from the class to which is belongs,
@@ -968,7 +986,7 @@ Method::Method(const isl_class &clazz, FunctionDecl *fd,
const std::string &name) :
clazz(clazz), fd(fd), name(rename_method(name)),
kind(get_kind(clazz, fd)),
- callback(find_callback_arg(fd))
+ callbacks(find_callback_args(fd))
{
}
@@ -985,19 +1003,13 @@ Method::Method(const isl_class &clazz, FunctionDecl *fd) :
/* Return the number of parameters of the corresponding C function.
*
- * 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.
- *
- * The user pointer is also removed from the number of parameters
- * of the C function because the pair of callback and user pointer
- * is considered as a single argument that is printed as a whole
- * by Method::print_param_use.
+ * This number includes any possible user pointers that follow callback
+ * arguments. These are skipped by Method::print_fd_arg_list
+ * during the actual argument printing.
*/
int Method::c_num_params() const
{
- return fd->getNumParams() - (callback != NULL);
+ return fd->getNumParams();
}
/* Return the number of parameters of the method
@@ -1011,30 +1023,128 @@ int Method::num_params() const
return c_num_params();
}
-/* Print the arguments from "start" (inclusive) to "end" (exclusive)
- * as arguments to a method of C function call, using "print_arg"
- * to print each individual argument.
+/* Call "on_arg_skip_next" on the arguments from "start" (inclusive)
+ * to "end" (exclusive), calling the methods of "combiner"
+ * before, between and after the arguments.
+ * If "on_arg_skip_next" returns true then the next argument is skipped.
*/
-void Method::print_arg_list(std::ostream &os, int start, int end,
- const std::function<void(int i)> &print_arg)
+void Method::on_arg_list(int start, int end,
+ const Method::list_combiner &combiner,
+ const std::function<bool(int i)> &on_arg_skip_next)
{
- os << "(";
+ combiner.before();
for (int i = start; i < end; ++i) {
if (i != start)
- os << ", ";
- print_arg(i);
+ combiner.between();
+ if (on_arg_skip_next(i))
+ ++i;
}
- os << ")";
+ combiner.after();
+}
+
+/* Print the arguments from "start" (inclusive) to "end" (exclusive)
+ * as arguments to a method of C function call, using "print_arg_skip_next"
+ * to print each individual argument. If this callback return true
+ * then the next argument is skipped.
+ */
+void Method::print_arg_list(std::ostream &os, int start, int end,
+ const std::function<bool(int i)> &print_arg_skip_next)
+{
+ on_arg_list(start, end, print_combiner(os), [&] (int i) {
+ return print_arg_skip_next(i);
+ });
+}
+
+/* Call "on_arg" on the arguments from "start" (inclusive) to "end" (exclusive),
+ * calling the methods of "combiner" before, between and after the arguments.
+ * The first argument to "on_arg" is the position of the argument
+ * in this->fd.
+ * The second argument is the (first) position in the list of arguments
+ * with all callback arguments spliced in.
+ *
+ * Call on_arg_list to do the actual iteration over the arguments, skipping
+ * the user argument that comes after every callback argument.
+ * 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.
+ * The user pointer is also removed from the number of parameters
+ * of the C function because the pair of callback and user pointer
+ * is considered as a single argument that is printed as a whole
+ * by Method::print_param_use.
+ *
+ * In case of a callback argument, the second argument to "print_arg"
+ * is also adjusted to account for the spliced-in arguments of the callback.
+ * The return value takes the place of the callback itself,
+ * while the arguments (excluding the final user pointer)
+ * take the following positions.
+ */
+void Method::on_fd_arg_list(int start, int end,
+ const Method::list_combiner &combiner,
+ const std::function<void(int i, int arg)> &on_arg) const
+{
+ int arg = start;
+
+ on_arg_list(start, end, combiner, [this, &on_arg, &arg] (int i) {
+ auto type = fd->getParamDecl(i)->getType();
+
+ on_arg(i, arg++);
+ if (!generator::is_callback(type))
+ return false;
+ arg += generator::prototype_n_args(type) - 1;
+ return true;
+ });
+}
+
+/* Print the arguments from "start" (inclusive) to "end" (exclusive)
+ * as arguments to a method of C function call, using "print_arg"
+ * to print each individual argument.
+ * The first argument to this callback is the position of the argument
+ * in this->fd.
+ * The second argument is the (first) position in the list of arguments
+ * with all callback arguments spliced in.
+ */
+void Method::print_fd_arg_list(std::ostream &os, int start, int end,
+ const std::function<void(int i, int arg)> &print_arg) const
+{
+ on_fd_arg_list(start, end, print_combiner(os), print_arg);
+}
+
+/* Call "on_arg" on the arguments to the method call,
+ * calling the methods of "combiner" before, between and after the arguments.
+ * The first argument to "on_arg" is the position of the argument
+ * in this->fd.
+ * The second argument is the (first) position in the list of arguments
+ * with all callback arguments spliced in.
+ */
+void Method::on_cpp_arg_list(const Method::list_combiner &combiner,
+ const std::function<void(int i, int arg)> &on_arg) const
+{
+ int first_param = kind == member_method ? 1 : 0;
+ on_fd_arg_list(first_param, num_params(), combiner, on_arg);
+}
+
+/* Call "on_arg" on the arguments to the method call.
+ * The first argument to "on_arg" is the position of the argument
+ * in this->fd.
+ * The second argument is the (first) position in the list of arguments
+ * with all callback arguments spliced in.
+ */
+void Method::on_cpp_arg_list(
+ const std::function<void(int i, int arg)> &on_arg) const
+{
+ on_cpp_arg_list(empty_combiner(), on_arg);
}
/* Print the arguments to the method call, using "print_arg"
* to print each individual argument.
+ * The first argument to this callback is the position of the argument
+ * in this->fd.
+ * The second argument is the (first) position in the list of arguments
+ * with all callback arguments spliced in.
*/
void Method::print_cpp_arg_list(std::ostream &os,
- const std::function<void(int i)> &print_arg) const
+ const std::function<void(int i, int arg)> &print_arg) const
{
- int first_param = kind == member_method ? 1 : 0;
- print_arg_list(os, first_param, num_params(), print_arg);
+ on_cpp_arg_list(print_combiner(os), print_arg);
}
/* Should the parameter at position "pos" be a copy (rather than