From c07dd416cffc9e57fc282b2bf89375bdb2df9c95 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 9 Feb 2021 10:45:00 +0000 Subject: [PATCH] gtype: Add a "final" flag We want to have the ability to mark types that should not be derivable even if they are in a deeply derivable type hierarchy; in other words, leaf nodes in the types tree. --- gobject/gtype.c | 9 ++++++++- gobject/gtype.h | 19 +++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/gobject/gtype.c b/gobject/gtype.c index 2cdbe7ce4..422e1cae4 100644 --- a/gobject/gtype.c +++ b/gobject/gtype.c @@ -143,7 +143,7 @@ G_TYPE_FLAG_INSTANTIATABLE | \ G_TYPE_FLAG_DERIVABLE | \ G_TYPE_FLAG_DEEP_DERIVABLE) -#define TYPE_FLAG_MASK (G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT) +#define TYPE_FLAG_MASK (G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT | G_TYPE_FLAG_FINAL) #define SIZEOF_FUNDAMENTAL_INFO ((gssize) MAX (MAX (sizeof (GTypeFundamentalInfo), \ sizeof (gpointer)), \ sizeof (glong))) @@ -804,6 +804,13 @@ check_derivation_I (GType parent_type, NODE_NAME (pnode)); return FALSE; } + if ((G_TYPE_FLAG_FINAL & GPOINTER_TO_UINT (type_get_qdata_L (pnode, static_quark_type_flags))) == G_TYPE_FLAG_FINAL) + { + g_warning ("cannot derive '%s' from final parent type '%s'", + type_name, + NODE_NAME (pnode)); + return FALSE; + } return TRUE; } diff --git a/gobject/gtype.h b/gobject/gtype.h index f38b4cf4c..9dfd85ac9 100644 --- a/gobject/gtype.h +++ b/gobject/gtype.h @@ -370,6 +370,18 @@ G_BEGIN_DECLS * Returns: %TRUE on success */ #define G_TYPE_HAS_VALUE_TABLE(type) (g_type_value_table_peek (type) != NULL) +/** + * G_TYPE_IS_FINAL: + * @type: a #GType value + * + * Checks if @type is a final type. A final type cannot be derived any + * further. + * + * Returns: %TRUE on success + * + * Since: 2.70 + */ +#define G_TYPE_IS_FINAL(type) (g_type_test_flags ((type), G_TYPE_FLAG_FINAL)) GLIB_AVAILABLE_MACRO_IN_2_70 /* Typedefs @@ -1002,13 +1014,16 @@ typedef enum /*< skip >*/ * @G_TYPE_FLAG_VALUE_ABSTRACT: Indicates an abstract value type, i.e. a type * that introduces a value table, but can't be used for * g_value_init() + * @G_TYPE_FLAG_FINAL: Indicates a final type. A final type is a non-derivable + * leaf node in a deep derivable type hierarchy tree. Since: 2.70 * * Bit masks used to check or determine characteristics of a type. */ typedef enum /*< skip >*/ { - G_TYPE_FLAG_ABSTRACT = (1 << 4), - G_TYPE_FLAG_VALUE_ABSTRACT = (1 << 5) + G_TYPE_FLAG_ABSTRACT = (1 << 4), + G_TYPE_FLAG_VALUE_ABSTRACT = (1 << 5), + G_TYPE_FLAG_FINAL GLIB_AVAILABLE_ENUMERATOR_IN_2_70 = (1 << 6) } GTypeFlags; /** * GTypeInfo: