diff --git a/dtool/pptempl/Template.unix.pp b/dtool/pptempl/Template.unix.pp index b3cd31d4b5..e092720fac 100644 --- a/dtool/pptempl/Template.unix.pp +++ b/dtool/pptempl/Template.unix.pp @@ -179,6 +179,23 @@ cleanall : clean rm -f $[DEPENDENCY_CACHE_FILENAME] #endif +clean-igate : +#forscopes metalib_target lib_target ss_lib_target + #define igatedb $[get_igatedb] + #define igateoutput $[get_igateoutput] + #define igatemscan $[components $[get_igatedb:%=$[RELDIR]/$[so_dir]/%],$[active_component_libs]] + #define igatemout $[if $[igatemscan],lib$[TARGET]_module.cxx] + #if $[igatedb] + rm -f $[so_dir]/$[igatedb] + #endif + #if $[igateoutput] + rm -f $[so_dir]/$[igateoutput] $[igateoutput:%.cxx=$[so_dir]/%.o] + #endif + #if $[igatemout] + rm -f $[so_dir]/$[igatemout] $[igatemout:%.cxx=$[so_dir]/%.o] + #endif +#end metalib_target lib_target ss_lib_target + // Now, 'install' and 'uninstall'. These simply copy files into the // install directory (or remove them). The 'install' rule also makes // the directories if necessary. @@ -189,6 +206,9 @@ cleanall : clean $[INSTALL_DATA:%=$[install_data_dir]/%] \ $[INSTALL_CONFIG:%=$[install_config_dir]/%] +#define installed_igate_files \ + $[get_igatedb(metalib_target lib_target ss_lib_target):%=$[install_igatedb_dir]/%] + #define install_targets \ $[sort \ $[if $[install_lib],$[install_lib_dir]] \ @@ -204,11 +224,18 @@ cleanall : clean $[installed_files] install : all $[install_targets] +install-igate : $[sort $[installed_igate_files]] + uninstall : $[TARGET(metalib_target lib_target ss_lib_target static_lib_target):%=uninstall-lib%] $[TARGET(bin_target):%=uninstall-%] #if $[installed_files] rm -f $[sort $[installed_files]] #endif +uninstall-igate : +#if $[installed_igate_files] + rm -f $[sort $[installed_igate_files]] +#endif + // We need a rule for each directory we might need to make. This // loops through the full set of directories and creates a rule to @@ -737,12 +764,15 @@ $[DEPENDENCY_CACHE_FILENAME] : $[dep_sources] all : $[subdirs] test : $[subdirs:%=test-%] clean : $[subdirs:%=clean-%] +clean-igate : $[subdirs:%=clean-igate-%] cleanall : $[subdirs:%=cleanall-%] install : $[if $[CONFIG_HEADER],$[install_headers_dir] $[install_headers_dir]/$[CONFIG_HEADER]] $[subdirs:%=install-%] +install-igate : $[subdirs:%=install-igate-%] uninstall : $[subdirs:%=uninstall-%] #if $[CONFIG_HEADER] rm -f $[install_headers_dir]/$[CONFIG_HEADER] #endif +uninstall-igate : $[subdirs:%=uninstall-igate-%] // Somehow, something in the cttools confuses some shells, so that // when we are attached, 'cd foo' doesn't work, but 'cd ./foo' does. @@ -765,6 +795,11 @@ clean-$[dirname] : cd ./$[PATH]; $(MAKE) clean #end dirname +#formap dirname subdirs +clean-igate-$[dirname] : + cd ./$[PATH]; $(MAKE) clean-igate +#end dirname + #formap dirname subdirs cleanall-$[dirname] : $[patsubst %,cleanall-%,$[dirnames $[if $[build_directory],$[DIRNAME]],$[DEPEND_DIRS]]] cd ./$[PATH]; $(MAKE) cleanall @@ -775,11 +810,21 @@ install-$[dirname] : $[patsubst %,install-%,$[dirnames $[if $[build_directory],$ cd ./$[PATH]; $(MAKE) install #end dirname +#formap dirname subdirs +install-igate-$[dirname] : + cd ./$[PATH]; $(MAKE) install-igate +#end dirname + #formap dirname subdirs uninstall-$[dirname] : cd ./$[PATH]; $(MAKE) uninstall #end dirname +#formap dirname subdirs +uninstall-igate-$[dirname] : + cd ./$[PATH]; $(MAKE) uninstall-igate +#end dirname + #if $[ne $[CONFIG_HEADER],] $[install_headers_dir] : @test -d $[install_headers_dir] || echo mkdir -p $[install_headers_dir] diff --git a/dtool/src/interrogate/interrogate.cxx b/dtool/src/interrogate/interrogate.cxx index ddb4c4788f..842ac6761e 100644 --- a/dtool/src/interrogate/interrogate.cxx +++ b/dtool/src/interrogate/interrogate.cxx @@ -36,6 +36,7 @@ bool build_python_wrappers = false; bool save_unique_names = false; bool no_database = false; bool generate_spam = false; +bool left_inheritance_requires_upcast = false; CPPVisibility min_vis = V_published; string library_name; string module_name; diff --git a/dtool/src/interrogate/interrogate.h b/dtool/src/interrogate/interrogate.h index 494cbdcb00..2034bf2d45 100644 --- a/dtool/src/interrogate/interrogate.h +++ b/dtool/src/interrogate/interrogate.h @@ -30,6 +30,7 @@ extern bool build_python_wrappers; extern bool save_unique_names; extern bool no_database; extern bool generate_spam; +extern bool left_inheritance_requires_upcast; extern CPPVisibility min_vis; extern string library_name; extern string module_name; diff --git a/dtool/src/interrogate/interrogateBuilder.cxx b/dtool/src/interrogate/interrogateBuilder.cxx index 4221aa881d..8406f8028e 100644 --- a/dtool/src/interrogate/interrogateBuilder.cxx +++ b/dtool/src/interrogate/interrogateBuilder.cxx @@ -2003,21 +2003,6 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype, itype._flags |= InterrogateType::F_global; CPPScope *scope = cpptype->_scope; - - // Record the derivation of this class. Do we need to synthesize - // upcast/downcast functions? - bool generate_casts = false; - if (cpptype->_derivation.size() > 1) { - // If we have multiple inheritance, we need explicit cast operators. - generate_casts = true; - } - if (cpptype->_derivation.size() == 1) { - // If we have single inheritance, but it's a virtual inheritance, - // we also need explicit cast operators. - if (cpptype->_derivation.front()._is_virtual) { - generate_casts = true; - } - } CPPStructType::Derivation::const_iterator bi; for (bi = cpptype->_derivation.begin(); @@ -2033,12 +2018,32 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype, d._base = base_index; d._upcast = 0; d._downcast = 0; + + // Do we need to synthesize upcast and downcast functions? + bool generate_casts = false; + if (base._is_virtual) { + // We do in the presence of virtual inheritance. + generate_casts = true; + + } else if (bi != cpptype->_derivation.begin()) { + // Or if we're not talking about the leftmost fork of multiple + // inheritance. + generate_casts = true; + + } else if (cpptype->_derivation.size() != 1 && + left_inheritance_requires_upcast) { + // Or even if we are the leftmost fork of multiple + // inheritance, if the flag is set indicating that this + // requires a pointer change. (For most compilers, this does + // not require a pointer change.) + generate_casts = true; + } if (generate_casts) { d._upcast = get_cast_function(base_type, cpptype, "upcast"); d._flags |= InterrogateType::DF_upcast; - if ((*bi)._is_virtual) { + if (base._is_virtual) { // If this is a virtual inheritance, we can't write a // downcast. d._flags |= InterrogateType::DF_downcast_impossible;