diff --git a/doc/user.pod b/doc/user.pod index 1bb0da48..1bf6fa67 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -896,6 +896,8 @@ 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_from_name(isl_ctx *ctx, + __isl_keep const char *name); __isl_give isl_id *isl_id_set_free_user( __isl_take isl_id *id, void (*free_user)(void *user)); @@ -903,6 +905,7 @@ using the following functions. __isl_null isl_id *isl_id_free(__isl_take isl_id *id); void *isl_id_get_user(__isl_keep isl_id *id); + isl_bool isl_id_has_name(__isl_keep isl_id *id); __isl_keep const char *isl_id_get_name(__isl_keep isl_id *id); __isl_give isl_printer *isl_printer_print_id( diff --git a/include/isl/id.h b/include/isl/id.h index c025d513..8314a8c9 100644 --- a/include/isl/id.h +++ b/include/isl/id.h @@ -10,7 +10,7 @@ extern "C" { #endif -struct isl_id; +struct __isl_export isl_id; typedef struct isl_id isl_id; ISL_DECLARE_LIST(id) @@ -20,11 +20,17 @@ uint32_t isl_id_get_hash(__isl_keep isl_id *id); __isl_give isl_id *isl_id_alloc(isl_ctx *ctx, __isl_keep const char *name, void *user); +__isl_constructor +__isl_give isl_id *isl_id_from_name(isl_ctx *ctx, + __isl_keep const char *name); __isl_give isl_id *isl_id_copy(isl_id *id); __isl_null isl_id *isl_id_free(__isl_take isl_id *id); void *isl_id_get_user(__isl_keep isl_id *id); +__isl_export __isl_keep const char *isl_id_get_name(__isl_keep isl_id *id); +__isl_export +isl_bool isl_id_has_name(__isl_keep isl_id *id); __isl_give isl_id *isl_id_set_free_user(__isl_take isl_id *id, void (*free_user)(void *user)); diff --git a/interface/isl_test_cpp.cpp b/interface/isl_test_cpp.cpp index a6b1e631..942cb41f 100644 --- a/interface/isl_test_cpp.cpp +++ b/interface/isl_test_cpp.cpp @@ -314,6 +314,48 @@ void test_foreach(isl::ctx ctx) assert(ret2 == isl::stat::error); } +/* Test that identifiers are constructed correctly and their uniqueness + * property holds for both C and C++ interfaces. + * + * Verify that two identifiers with the same name and same user pointer are + * pointer-equal independently of how they were allocated. Check that + * identifier with an empty name is not equal to an identifier with a NULL + * name. + */ +void test_id(isl::ctx ctx) +{ + isl::id id1(ctx, "whatever"); + isl::id id2(ctx, "whatever"); + isl_id *id3 = isl_id_alloc(ctx.get(), "whatever", NULL); + int dummy; + isl_id *id4 = isl_id_alloc(ctx.get(), "whatever", &dummy); + + assert(id1.get() == id2.get()); + assert(id1.get() == id3); + assert(id2.get() == id3); + assert(id3 != id4); + assert(id1.get() != id4); + + isl::id id5 = isl::manage(id3); + isl::id id6 = isl::manage(id4); + assert(id5.get() == id1.get()); + + assert(id1.has_name()); + assert(id5.has_name()); + assert(id6.has_name()); + assert("whatever" == id1.get_name()); + assert("whatever" == id5.get_name()); + assert("whatever" == id6.get_name()); + + isl_id *nameless = isl_id_alloc(ctx.get(), NULL, &dummy); + isl::id id7 = isl::manage(nameless); + assert(!id7.has_name()); + + isl::id id8(ctx, ""); + assert(id8.has_name()); + assert(id8.get() != id7.get()); +} + /* Test the isl C++ interface * * This includes: @@ -322,6 +364,7 @@ void test_foreach(isl::ctx ctx) * - Different parameter types * - Different return types * - Foreach functions + * - Identifier allocation and equality */ int main() { @@ -332,6 +375,7 @@ int main() test_parameters(ctx); test_return(ctx); test_foreach(ctx); + test_id(ctx); isl_ctx_free(ctx); } diff --git a/isl_id.c b/isl_id.c index d5c7c711..4652384c 100644 --- a/isl_id.c +++ b/isl_id.c @@ -42,6 +42,14 @@ const char *isl_id_get_name(__isl_keep isl_id *id) return id ? id->name : NULL; } +isl_bool isl_id_has_name(__isl_keep isl_id *id) +{ + if (!id) + return isl_bool_error; + + return id->name ? isl_bool_true : isl_bool_false; +} + static __isl_give isl_id *id_alloc(isl_ctx *ctx, const char *name, void *user) { const char *copy = name ? strdup(name) : NULL; @@ -122,6 +130,16 @@ __isl_give isl_id *isl_id_alloc(isl_ctx *ctx, const char *name, void *user) return entry->data; } +/* Construct an isl_id with a given "name" and a NULL user field. + */ +__isl_give isl_id *isl_id_from_name(isl_ctx *ctx, const char *name) +{ + if (!name) + return NULL; + + return isl_id_alloc(ctx, name, NULL); +} + /* If the id has a negative refcount, then it is a static isl_id * which should not be changed. */