From f4f57da3f20b0a47381d34e7f5d663c012926ff4 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 10 Sep 2012 14:23:40 +0200 Subject: [PATCH] add isl_id_set_free_user Allow the user to specify a callback to be called on the user pointer when the last reference to the isl_id disappears. This is convenient for attaching dynamically allocated data structures to isl_ids, especially in annotations to AST nodes. Signed-off-by: Sven Verdoolaege --- doc/user.pod | 5 +++++ include/isl/id.h | 3 +++ isl_id.c | 18 +++++++++++++++++- isl_id_private.h | 7 +++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/doc/user.pod b/doc/user.pod index c9c0b39..737f6de 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -598,6 +598,9 @@ using the following functions. #include __isl_give isl_id *isl_id_alloc(isl_ctx *ctx, __isl_keep const char *name, void *user); + __isl_give isl_id *isl_id_set_free_user( + __isl_take isl_id *id, + __isl_give void (*free_user)(void *user)); __isl_give isl_id *isl_id_copy(isl_id *id); void *isl_id_free(__isl_take isl_id *id); @@ -608,6 +611,8 @@ using the following functions. __isl_give isl_printer *isl_printer_print_id( __isl_take isl_printer *p, __isl_keep isl_id *id); +The callback set by C is called on the user +pointer when the last reference to the C is freed. Note that C returns a pointer to some internal data structure, so the result can only be used while the corresponding C is alive. diff --git a/include/isl/id.h b/include/isl/id.h index 86232f7..d237b23 100644 --- a/include/isl/id.h +++ b/include/isl/id.h @@ -21,6 +21,9 @@ void *isl_id_free(__isl_take isl_id *id); void *isl_id_get_user(__isl_keep isl_id *id); __isl_keep const char *isl_id_get_name(__isl_keep isl_id *id); +__isl_give isl_id *isl_id_set_free_user(__isl_take isl_id *id, + __isl_give void (*free_user)(void *user)); + __isl_give isl_printer *isl_printer_print_id(__isl_take isl_printer *p, __isl_keep isl_id *id); void isl_id_dump(__isl_keep isl_id *id); diff --git a/isl_id.c b/isl_id.c index fd3f68d..26f19c6 100644 --- a/isl_id.c +++ b/isl_id.c @@ -44,7 +44,7 @@ static __isl_give isl_id *id_alloc(isl_ctx *ctx, const char *name, void *user) if (name && !copy) return NULL; - id = isl_alloc_type(ctx, struct isl_id); + id = isl_calloc_type(ctx, struct isl_id); if (!id) goto error; @@ -135,6 +135,19 @@ uint32_t isl_hash_id(uint32_t hash, __isl_keep isl_id *id) return hash; } +/* Replace the free_user callback by "free_user". + */ +__isl_give isl_id *isl_id_set_free_user(__isl_take isl_id *id, + __isl_give void (*free_user)(void *user)) +{ + if (!id) + return NULL; + + id->free_user = free_user; + + return id; +} + /* If the id has a negative refcount, then it is a static isl_id * and should not be freed. */ @@ -159,6 +172,9 @@ void *isl_id_free(__isl_take isl_id *id) else isl_hash_table_remove(id->ctx, &id->ctx->id_table, entry); + if (id->free_user) + id->free_user(id->user); + free((char *)id->name); isl_ctx_deref(id->ctx); free(id); diff --git a/isl_id_private.h b/isl_id_private.h index c89773e..c583b31 100644 --- a/isl_id_private.h +++ b/isl_id_private.h @@ -12,6 +12,11 @@ #include +/* Represent a name and/or user pointer. + * + * If "free_user" is set, then it will be called on "user" when + * the last instance of the isl_id is freed. + */ struct isl_id { int ref; isl_ctx *ctx; @@ -19,6 +24,8 @@ struct isl_id { const char *name; void *user; uint32_t hash; + + __isl_give void (*free_user)(void *user); }; uint32_t isl_hash_id(uint32_t hash, __isl_keep isl_id *id); -- 2.7.4