#include <isl_list_templ.c>
+isl_ctx *isl_ast_print_options_get_ctx(
+ __isl_keep isl_ast_print_options *options)
+{
+ return options ? options->ctx : NULL;
+}
+
__isl_give isl_ast_print_options *isl_ast_print_options_alloc(isl_ctx *ctx)
{
- return isl_calloc_type(ctx, isl_ast_print_options);
+ isl_ast_print_options *options;
+
+ options = isl_calloc_type(ctx, isl_ast_print_options);
+ if (!options)
+ return NULL;
+
+ options->ctx = ctx;
+ isl_ctx_ref(ctx);
+ options->ref = 1;
+
+ return options;
+}
+
+__isl_give isl_ast_print_options *isl_ast_print_options_dup(
+ __isl_keep isl_ast_print_options *options)
+{
+ isl_ctx *ctx;
+ isl_ast_print_options *dup;
+
+ if (!options)
+ return NULL;
+
+ ctx = isl_ast_print_options_get_ctx(options);
+ dup = isl_ast_print_options_alloc(ctx);
+ if (!dup)
+ return NULL;
+
+ dup->print_for = options->print_for;
+ dup->print_for_user = options->print_for_user;
+ dup->print_user = options->print_user;
+ dup->print_user_user = options->print_user_user;
+
+ return dup;
+}
+
+__isl_give isl_ast_print_options *isl_ast_print_options_cow(
+ __isl_take isl_ast_print_options *options)
+{
+ if (!options)
+ return NULL;
+
+ if (options->ref == 1)
+ return options;
+ options->ref--;
+ return isl_ast_print_options_dup(options);
+}
+
+__isl_give isl_ast_print_options *isl_ast_print_options_copy(
+ __isl_keep isl_ast_print_options *options)
+{
+ if (!options)
+ return NULL;
+
+ options->ref++;
+ return options;
}
void *isl_ast_print_options_free(__isl_take isl_ast_print_options *options)
{
+ if (!options)
+ return NULL;
+
+ if (--options->ref > 0)
+ return NULL;
+
+ isl_ctx_deref(options->ctx);
+
free(options);
return NULL;
}
__isl_give isl_ast_print_options *isl_ast_print_options_set_print_user(
__isl_take isl_ast_print_options *options,
__isl_give isl_printer *(*print_user)(__isl_take isl_printer *p,
+ __isl_take isl_ast_print_options *options,
__isl_keep isl_ast_node *node, void *user),
void *user)
{
+ options = isl_ast_print_options_cow(options);
if (!options)
return NULL;
__isl_give isl_ast_print_options *isl_ast_print_options_set_print_for(
__isl_take isl_ast_print_options *options,
__isl_give isl_printer *(*print_for)(__isl_take isl_printer *p,
+ __isl_take isl_ast_print_options *options,
__isl_keep isl_ast_node *node, void *user),
void *user)
{
+ options = isl_ast_print_options_cow(options);
if (!options)
return NULL;
static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
__isl_keep isl_ast_node *node,
- __isl_keep isl_ast_print_options *options, int in_block);
+ __isl_keep isl_ast_print_options *options, int in_block, int in_list);
static __isl_give isl_printer *print_if_c(__isl_take isl_printer *p,
__isl_keep isl_ast_node *node,
__isl_keep isl_ast_print_options *options, int new_line);
if (!else_node && !need_block(node)) {
p = isl_printer_end_line(p);
p = isl_printer_indent(p, 2);
- p = isl_ast_node_print(node, p, options);
+ p = isl_ast_node_print(node, p,
+ isl_ast_print_options_copy(options));
p = isl_printer_indent(p, -2);
return p;
}
p = isl_printer_print_str(p, " {");
p = isl_printer_end_line(p);
p = isl_printer_indent(p, 2);
- p = print_ast_node_c(p, node, options, 1);
+ p = print_ast_node_c(p, node, options, 1, 0);
p = isl_printer_indent(p, -2);
p = isl_printer_start_line(p);
p = isl_printer_print_str(p, "}");
return p;
}
+/* Print the start of a compound statement.
+ */
+static __isl_give isl_printer *start_block(__isl_take isl_printer *p)
+{
+ p = isl_printer_start_line(p);
+ p = isl_printer_print_str(p, "{");
+ p = isl_printer_end_line(p);
+ p = isl_printer_indent(p, 2);
+
+ return p;
+}
+
+/* Print the end of a compound statement.
+ */
+static __isl_give isl_printer *end_block(__isl_take isl_printer *p)
+{
+ p = isl_printer_indent(p, -2);
+ p = isl_printer_start_line(p);
+ p = isl_printer_print_str(p, "}");
+ p = isl_printer_end_line(p);
+
+ return p;
+}
+
/* Print the for node "node".
*
* If the for node is degenerate, it is printed as
* body
*
* "in_block" is set if we are currently inside a block.
- * We simply pass it along to print_ast_node_c in case of a degenerate
- * for loop.
+ * "in_list" is set if the current node is not alone in the block.
+ * If we are not in a block or if the current not is not alone in the block
+ * then we print a block around a degenerate for loop such that the variable
+ * declaration will not conflict with any potential other declaration
+ * of the same variable.
*/
static __isl_give isl_printer *print_for_c(__isl_take isl_printer *p,
__isl_keep isl_ast_node *node,
- __isl_keep isl_ast_print_options *options, int in_block)
+ __isl_keep isl_ast_print_options *options, int in_block, int in_list)
{
isl_id *id;
const char *name;
id = isl_ast_expr_get_id(node->u.f.iterator);
name = isl_id_get_name(id);
isl_id_free(id);
+ if (!in_block || in_list)
+ p = start_block(p);
p = isl_printer_start_line(p);
p = isl_printer_print_str(p, type);
p = isl_printer_print_str(p, " ");
p = isl_printer_print_ast_expr(p, node->u.f.init);
p = isl_printer_print_str(p, ";");
p = isl_printer_end_line(p);
- p = print_ast_node_c(p, node->u.f.body, options, in_block);
+ p = print_ast_node_c(p, node->u.f.body, options, 1, 0);
+ if (!in_block || in_list)
+ p = end_block(p);
}
return p;
* If so, we do not print a block around the children of a block node.
* We do this to avoid an extra block around the body of a degenerate
* for node.
+ *
+ * "in_list" is set if the current node is not alone in the block.
*/
static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p,
__isl_keep isl_ast_node *node,
- __isl_keep isl_ast_print_options *options, int in_block)
+ __isl_keep isl_ast_print_options *options, int in_block, int in_list)
{
switch (node->type) {
case isl_ast_node_for:
if (options->print_for)
- return options->print_for(p, node,
- options->print_for_user);
- p = print_for_c(p, node, options, in_block);
+ return options->print_for(p,
+ isl_ast_print_options_copy(options),
+ node, options->print_for_user);
+ p = print_for_c(p, node, options, in_block, in_list);
break;
case isl_ast_node_if:
p = print_if_c(p, node, options, 1);
break;
case isl_ast_node_block:
- if (!in_block) {
- p = isl_printer_start_line(p);
- p = isl_printer_print_str(p, "{");
- p = isl_printer_end_line(p);
- p = isl_printer_indent(p, 2);
- }
+ if (!in_block)
+ p = start_block(p);
p = isl_ast_node_list_print(node->u.b.children, p, options);
- if (!in_block) {
- p = isl_printer_indent(p, -2);
- p = isl_printer_start_line(p);
- p = isl_printer_print_str(p, "}");
- p = isl_printer_end_line(p);
- }
+ if (!in_block)
+ p = end_block(p);
break;
case isl_ast_node_user:
if (options->print_user)
- return options->print_user(p, node,
- options->print_user_user);
+ return options->print_user(p,
+ isl_ast_print_options_copy(options),
+ node, options->print_user_user);
p = isl_printer_start_line(p);
p = isl_printer_print_ast_expr(p, node->u.e.expr);
p = isl_printer_print_str(p, ";");
/* Print the for node "node" to "p".
*/
__isl_give isl_printer *isl_ast_node_for_print(__isl_keep isl_ast_node *node,
- __isl_take isl_printer *p, __isl_keep isl_ast_print_options *options)
+ __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
{
if (!node || !options)
goto error;
if (node->type != isl_ast_node_for)
isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
"not a for node", goto error);
- return print_for_c(p, node, options, 0);
+ p = print_for_c(p, node, options, 0, 0);
+ isl_ast_print_options_free(options);
+ return p;
error:
+ isl_ast_print_options_free(options);
isl_printer_free(p);
return NULL;
}
/* Print the if node "node" to "p".
*/
__isl_give isl_printer *isl_ast_node_if_print(__isl_keep isl_ast_node *node,
- __isl_take isl_printer *p, __isl_keep isl_ast_print_options *options)
+ __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
{
if (!node || !options)
goto error;
if (node->type != isl_ast_node_if)
isl_die(isl_ast_node_get_ctx(node), isl_error_invalid,
"not an if node", goto error);
- return print_if_c(p, node, options, 1);
+ p = print_if_c(p, node, options, 1);
+ isl_ast_print_options_free(options);
+ return p;
error:
+ isl_ast_print_options_free(options);
isl_printer_free(p);
return NULL;
}
/* Print "node" to "p".
*/
__isl_give isl_printer *isl_ast_node_print(__isl_keep isl_ast_node *node,
- __isl_take isl_printer *p, __isl_keep isl_ast_print_options *options)
+ __isl_take isl_printer *p, __isl_take isl_ast_print_options *options)
{
if (!options || !node)
goto error;
- return print_ast_node_c(p, node, options, 0);
+ p = print_ast_node_c(p, node, options, 0, 0);
+ isl_ast_print_options_free(options);
+ return p;
error:
+ isl_ast_print_options_free(options);
isl_printer_free(p);
return NULL;
}
case ISL_FORMAT_C:
options = isl_ast_print_options_alloc(isl_printer_get_ctx(p));
p = isl_ast_node_print(node, p, options);
- isl_ast_print_options_free(options);
break;
default:
isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
return isl_printer_free(p);
for (i = 0; i < list->n; ++i)
- p = print_ast_node_c(p, list->p[i], options, 1);
+ p = print_ast_node_c(p, list->p[i], options, 1, 1);
return p;
}