From: Sven Verdoolaege Date: Thu, 22 Nov 2012 12:29:31 +0000 (+0100) Subject: AST printing callbacks: pass isl_ast_print_options X-Git-Tag: isl-0.11~60 X-Git-Url: https://repo.or.cz/w/isl.git/commitdiff_plain/dc4255aed9aa1b0adc656216612031c68d9f1214 AST printing callbacks: pass isl_ast_print_options The callback may want to pass control back to isl_ast_node_*_print, for which it needs an isl_ast_print_options object. Since the caller of the callback already has a reference to such an object, we might as well pass it along to the callback. Since the callback may want to modifiy the isl_ast_print_options object, we turn it into a properly reference counted isl object. Signed-off-by: Sven Verdoolaege --- diff --git a/doc/user.pod b/doc/user.pod index bf2bdde2..abf40311 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -5541,15 +5541,15 @@ More advanced printing can be performed using the following functions. __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_ast_print_options *options); __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_ast_print_options *options); __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_ast_print_options *options); While printing an C in C, C may print out an AST that makes use of macros such @@ -5571,6 +5571,9 @@ This object can be created using the following functions. #include __isl_give isl_ast_print_options * isl_ast_print_options_alloc(isl_ctx *ctx); + __isl_give isl_ast_print_options * + isl_ast_print_options_copy( + __isl_keep isl_ast_print_options *options); void *isl_ast_print_options_free( __isl_take isl_ast_print_options *options); @@ -5579,6 +5582,7 @@ This object can be created using the following functions. __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); __isl_give isl_ast_print_options * @@ -5586,6 +5590,7 @@ This object can be created using the following functions. __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); diff --git a/include/isl/ast.h b/include/isl/ast.h index 7ff8d0fe..76fe4502 100644 --- a/include/isl/ast.h +++ b/include/isl/ast.h @@ -141,16 +141,22 @@ __isl_give isl_printer *isl_printer_print_ast_node(__isl_take isl_printer *p, void isl_ast_node_dump(__isl_keep isl_ast_node *node); __isl_give isl_ast_print_options *isl_ast_print_options_alloc(isl_ctx *ctx); +__isl_give isl_ast_print_options *isl_ast_print_options_copy( + __isl_keep isl_ast_print_options *options); void *isl_ast_print_options_free(__isl_take isl_ast_print_options *options); +isl_ctx *isl_ast_print_options_get_ctx( + __isl_keep isl_ast_print_options *options); __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); __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); @@ -162,13 +168,13 @@ __isl_give isl_printer *isl_ast_node_print_macros( __isl_keep isl_ast_node *node, __isl_take isl_printer *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_ast_print_options *options); __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_ast_print_options *options); __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_ast_print_options *options); #if defined(__cplusplus) } diff --git a/isl_ast.c b/isl_ast.c index 92244710..85a568cf 100644 --- a/isl_ast.c +++ b/isl_ast.c @@ -11,13 +11,81 @@ #include +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; } @@ -30,9 +98,11 @@ void *isl_ast_print_options_free(__isl_take isl_ast_print_options *options) __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; @@ -49,9 +119,11 @@ __isl_give isl_ast_print_options *isl_ast_print_options_set_print_user( __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; @@ -1274,7 +1346,8 @@ static __isl_give isl_printer *print_body_c(__isl_take isl_printer *p, 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; } @@ -1393,8 +1466,9 @@ static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *p, switch (node->type) { case isl_ast_node_for: if (options->print_for) - return options->print_for(p, node, - options->print_for_user); + 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); break; case isl_ast_node_if: @@ -1417,8 +1491,9 @@ static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *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, ";"); @@ -1433,15 +1508,18 @@ static __isl_give isl_printer *print_ast_node_c(__isl_take isl_printer *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); + isl_ast_print_options_free(options); + return p; error: + isl_ast_print_options_free(options); isl_printer_free(p); return NULL; } @@ -1449,15 +1527,18 @@ error: /* 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; } @@ -1465,12 +1546,15 @@ error: /* 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); + isl_ast_print_options_free(options); + return p; error: + isl_ast_print_options_free(options); isl_printer_free(p); return NULL; } @@ -1494,7 +1578,6 @@ __isl_give isl_printer *isl_printer_print_ast_node(__isl_take isl_printer *p, 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, diff --git a/isl_ast_private.h b/isl_ast_private.h index 8aef29a8..ed2217c2 100644 --- a/isl_ast_private.h +++ b/isl_ast_private.h @@ -95,10 +95,15 @@ __isl_give isl_ast_node *isl_ast_node_if_set_then( __isl_take isl_ast_node *node, __isl_take isl_ast_node *child); struct isl_ast_print_options { + int ref; + isl_ctx *ctx; + __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 *print_for_user; __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 *print_user_user; };