diff options
author | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2022-06-08 18:33:59 +0200 |
---|---|---|
committer | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2022-06-08 18:33:59 +0200 |
commit | a41d6e28461bad90fdb78756344daa7c7d9db1dd (patch) | |
tree | 67ae38a3f3b7ee2a8cb5b8c321bc2eb25601339a /tools | |
parent | 6dc1ce0d7cae09f3ea84f4a7b44f5ff440803765 (diff) | |
download | glibmm-a41d6e28461bad90fdb78756344daa7c7d9db1dd.tar.gz |
gmmproc: Improved handling of final types
Some GObject-derived classes shall not be derived from.
* glib/glibmm/class.cc:
* glib/glibmm/interface.cc: Don't derive or add interfaces to a class
if G_TYPE_IS_FINAL(gtype) is true.
* tools/m4/class_shared.m4: Fix gtype_ when _DO_NOT_DERIVE_GTYPE is used.
Add _ABI_AS_WITH_DERIVED_GTYPE, making it possible to
add _DO_NOT_DERIVE_GTYPE without breaking ABI.
Diffstat (limited to 'tools')
-rw-r--r-- | tools/m4/class_shared.m4 | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/tools/m4/class_shared.m4 b/tools/m4/class_shared.m4 index 587a1f2f..1dab09d0 100644 --- a/tools/m4/class_shared.m4 +++ b/tools/m4/class_shared.m4 @@ -1,5 +1,5 @@ -dnl $Id$ - +dnl If you change this file, check if there is a copy of it +dnl at gtkmm/tools/m4/ that you shall also change. dnl This is just a hint to generate_wrap_init.pl. dnl It does not generate any code in the actual .h and .cc file. @@ -57,7 +57,7 @@ ifelse(`$2',,,` _POP() ') -dnl GVolumeMonitor can be broken/impeded by defining a sub-type. +dnl Use if the C base type is declared G_DECLARE_FINAL_TYPE. define(`_DO_NOT_DERIVE_GTYPE',`dnl _PUSH() dnl Define this macro to be tested for later. @@ -65,7 +65,14 @@ define(`__BOOL_DO_NOT_DERIVE_GTYPE__',`$1') _POP() ') -dnl GVolumeMonitor can be broken/impeded by defining a sub-type. +dnl If you add _DO_NOT_DERIVE_GTYPE to an existing class, and ABI must not be broken. +define(`_ABI_AS_WITH_DERIVED_GTYPE',`dnl +_PUSH() +dnl Define this macro to be tested for later. +define(`__BOOL_ABI_AS_WITH_DERIVED_GTYPE__',`$1') +_POP() +') + define(`_DYNAMIC_GTYPE_REGISTRATION',`dnl _PUSH() dnl Define this macro to be tested for later. @@ -108,8 +115,13 @@ public: using CppObjectType = __CPPNAME__; using BaseObjectType = __REAL_CNAME__; ifdef(`__BOOL_DO_NOT_DERIVE_GTYPE__',`dnl +ifdef(`__BOOL_ABI_AS_WITH_DERIVED_GTYPE__',`dnl + using BaseClassType = __REAL_CNAME__`'Class; using CppClassParent = __CPPPARENT__`'_Class; + using BaseClassParent = __REAL_CPARENT__`'Class; ',`dnl + using CppClassParent = __CPPPARENT__`'_Class; +')',`dnl using BaseClassType = __REAL_CNAME__`'Class; using CppClassParent = __CPPPARENT__`'_Class; using BaseClassParent = __REAL_CPARENT__`'Class; @@ -125,7 +137,10 @@ ifdef(`__BOOL_DYNAMIC_GTYPE_REGISTRATION__',` ',`') ifdef(`__BOOL_DO_NOT_DERIVE_GTYPE__',`dnl +ifdef(`__BOOL_ABI_AS_WITH_DERIVED_GTYPE__',`dnl + static void class_init_function(void* g_class, void* class_data); ',`dnl +')',`dnl static void class_init_function(void* g_class, void* class_data); ')dnl @@ -153,9 +168,16 @@ const Glib::Class& __CPPNAME__`'_Class::init() if(!gtype_) // create the GType if necessary { ifdef(`__BOOL_DO_NOT_DERIVE_GTYPE__',`dnl - // Do not derive a GType, or use a derived klass: - gtype_ = CppClassParent::CppObjectType::get_type(); +ifdef(`__BOOL_ABI_AS_WITH_DERIVED_GTYPE__',`dnl + // Glib::Class has to know the class init function to clone custom types. + class_init_func_ = &__CPPNAME__`'_Class::class_init_function; + + // Do not derive a GType, or use a derived class: + gtype_ = _LOWER(__CCAST__)_get_type(); ',`dnl + // Do not derive a GType, or use a derived class: + gtype_ = _LOWER(__CCAST__)_get_type(); +')',`dnl not __BOOL_DO_NOT_DERIVE_GTYPE__ // Glib::Class has to know the class init function to clone custom types. class_init_func_ = &__CPPNAME__`'_Class::class_init_function; @@ -180,9 +202,16 @@ const Glib::Class& __CPPNAME__`'_Class::init(GTypeModule* module) if(!gtype_) // create the GType if necessary { ifdef(`__BOOL_DO_NOT_DERIVE_GTYPE__',`dnl - // Do not derive a GType, or use a derived klass: - gtype_ = CppClassParent::CppObjectType::get_type(); +ifdef(`__BOOL_ABI_AS_WITH_DERIVED_GTYPE__',`dnl + // Glib::Class has to know the class init function to clone custom types. + class_init_func_ = &__CPPNAME__`'_Class::class_init_function; + + // Do not derive a GType, or use a derived class: + gtype_ = _LOWER(__CCAST__)_get_type(); ',`dnl + // Do not derive a GType, or use a derived class: + gtype_ = _LOWER(__CCAST__)_get_type(); +')',`dnl // Glib::Class has to know the class init function to clone custom types. class_init_func_ = &__CPPNAME__`'_Class::class_init_function; @@ -202,7 +231,19 @@ _IMPORT(SECTION_CC_IMPLEMENTS_INTERFACES) ',`') ifdef(`__BOOL_DO_NOT_DERIVE_GTYPE__',`dnl +ifdef(`__BOOL_ABI_AS_WITH_DERIVED_GTYPE__',`dnl + +void __CPPNAME__`'_Class::class_init_function(void* g_class, void* class_data) +{ + const auto klass = static_cast<BaseClassType*>(g_class); + CppClassParent::class_init_function(klass, class_data); + +_IMPORT(SECTION_PCC_CLASS_INIT_VFUNCS) + +_IMPORT(SECTION_PCC_CLASS_INIT_DEFAULT_SIGNAL_HANDLERS) +} ',`dnl +')',`dnl not __BOOL_DO_NOT_DERIVE_GTYPE__ void __CPPNAME__`'_Class::class_init_function(void* g_class, void* class_data) { |