changeset 354:18bd68f586c6

removed superfluous destructors
author Max Samukha <maxter@spambox.com>
date Mon, 24 May 2010 23:43:30 +0300
parents 0a671b1382d7
children 08c1ca7975ab
files Makefile cpp/qt_qtd/qtd_core.cpp d2/qt/QGlobal.d d2/qtd/QtdObject.d generator/abstractmetabuilder.cpp generator/abstractmetalang.cpp generator/abstractmetalang.h generator/cppgenerator.h generator/cppimplgenerator.cpp generator/dgenerator.cpp generator/typesystem_core.xml include/QObjectEntity.h include/qtd_core.h
diffstat 13 files changed, 109 insertions(+), 334 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Fri May 21 14:16:02 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,233 +0,0 @@
-## TODO: CPP_SHARED is very experemental on posix.
-## TODO: "make clean" don`t work as expected.
-## TODO: add target "install"
-## TODO: delete 'lib' prefix from output library name under windows.
-
-## Read variable from shell.
-export QTDIR
-export QTDIR_INC
-export QTDIR_LIB
-## End. Read variable from shell.
-
-## Try identify system.
-ifeq ($(strip $(shell uname)),Linux)
-	SYSTEM=posix
-else
-	ifeq ($(strip $(shell uname)),Darwin)
-		SYSTEM=posix
-	else
-		SYSTEM=windows
-	endif
-endif
-## End, Try identify system.
-
-## Load system specify settings.
-include build/$(SYSTEM).makefile
-
-## Main settings.
-## D compiler.
-ifndef $(DC)
-DC = dmd
-endif
-## C++ compiler.
-ifndef $(CC)
-CC = g++
-endif
-## Archiver.
-ifndef $(AR)
-AR = ar
-endif
-## Set default target.
-ifndef $(BUILD_TYPE)
-BUILD_TYPE = release
-endif
-
-## Tmp path.
-ifndef $(TMP_PATH)
-TMP_PATH_ = tmp
-TMP_PATH = $(TMP_PATH_)$(SL)$(BUILD_TYPE)
-endif
-## Output path.
-ifndef $(OUTPUT_PATH)
-OUTPUT_PATH = lib
-endif
-## Prefix for lib name.
-ifndef $(NAME_PREFIX)
-NAME_PREFIX = qtd
-endif
-
-ifndef $(PACKAGES)
-PACKAGES = core gui
-endif
-
-ifeq ($(DMD_WIN), false)
-LIB_PREFIX = lib
-endif
-
-CC_INCLUDE += include $(QTDIR_INC) $(QTDIR_INC)$(SL)Qt $(QTDIR_INC)$(SL)QtCore $(QTDIR_INC)$(SL)QtGui $(QTDIR_INC)$(SL)QtOpenGL $(QTDIR_INC)$(SL)QtSvg
-D_INCLUDE +=
-CC_LFLAGS += -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-s -mthreads
-CC_CFLAGS +=
-D_CFLAGS +=
-CC_LIB_PATH += $(QTDIR_LIB) $(TMP_PATH)
-D_LIB_PATH += $(TMP_PATH)
-
-## D target
-ifndef D_TARGET
-D_TARGET = d1-tango
-endif
-
-ifeq ($(D_TARGET), d1-tango)
-D_VERSION = 1
-else
-D_VERSION = 2
-endif
-D_CFLAGS += -Iqt/d$(D_VERSION)
-
-#End. Main settings.
-
-## Flags for debug version.
-ifeq ($(BUILD_TYPE), debug)
-CC_CFLAGS += -O0
-D_CFLAGS += -debug -g -gc
-LIB_POSTFIX = d
-else ifeq ($(BUILD_TYPE), release)
-## End. Flags for debug version.
-## Flags for release version
-CC_CFLAGS += -O
-D_CFLAGS += -O -release -inline
-endif
-## End. Flags for release version.
-
-## Load classes list.
-## param 1 - package name.
-define MODULE_template
-    include build/$(1).makefile
-    qt_$(1)_lib_name = $$(qt_$(1)_name)$(QT_LIB_POSTFIX)
-    $(1)_cpp_files += $$($(1)_classes:%=cpp/qt_$(1)/%_shell.cpp)
-    $(1)_cpp_obj_files = $$($(1)_cpp_files:cpp/%.cpp=$(TMP_PATH)/%.o)
-    $(1)_d_files += $$($(1)_classes:%=qt/$(1)/%.d)
-endef
-$(foreach package,$(PACKAGES),$(eval $(call MODULE_template,$(package))))
-## End. Load classes list
-
-## DMD compile template bug fix
-ifeq ($(DC), dmd)
-NOT_SEPARATE_D_OBJ = true
-endif
-
-ifeq ($(SYSTEM), windows)
-	ifeq ($(DC), dmd)
-		DMD_WIN = true
-	endif
-endif
-
-ifeq ($(DMD_WIN), true)
-	CPP_SHARED = true
-	LIB_EXT = lib
-else
-	LIB_EXT = a
-endif
-
-## CPP_SHARED options.
-ifeq ($(CPP_SHARED), true)
-CC_CFLAGS += -DCPP_SHARED
-GEN_OPT   += --cpp_shared
-D_CFLAGS += -version=cpp_shared
-endif
-## End. CPP_SHARED options.
-
-all: dgen build
-
-windows:
-	$(MAKE) SYSTEM=windows
-
-posix:
-	$(MAKE) SYSTEM=posix
-
-release: all
-
-debug:
-	$(MAKE) BUILD_TYPE=debug
-
-build: mkdir $(PACKAGES)
-
-## DGenerator
-make_gen:
-	cd generator && qmake && $(MAKE)
-
-dgen:  make_gen
-	cd generator && $(GEN) $(GEN_OPT) --d-target=$(D_TARGET) --output-directory=../ qtjambi_masterinclude.h build_gui.txt
-## DGenerator ## end
-
-mkdir:
-	@$(MKDIR) $(TMP_PATH_)
-	@$(MKDIR) $(TMP_PATH)
-	@$(MKDIR) $(TMP_PATH)$(SL)qt_qtd
-	@$(MKDIR) $(TMP_PATH)$(SL)qtd
-	@$(MKDIR) $(OUTPUT_PATH)
-
-## Build cpp files.
-$(TMP_PATH)/%.o: cpp/%.cpp
-	$(CC) $(CC_CFLAGS) $(CC_INCLUDE:%=-I%) -c $(@:$(TMP_PATH)/%.o=cpp/%.cpp) -o$@
-
-## Build d files.
-$(TMP_PATH)/%_d.o: qt/%.d
-	$(DC) $(D_CFLAGS) -c $(@:$(TMP_PATH)/%_d.o=qt/%.d) -of$@
-
-## Build package.
-## param 1 - package name.
-define BUILD_template
-    ## mkdir
-    mkdir_$(1):
-	    @$(MKDIR) $(TMP_PATH)$(SL)qt_$(1)
-	    @$(MKDIR) $(TMP_PATH)$(SL)$(1)
-    ## End. mkdir
-    ## Build d part.
-    ifeq ($(NOT_SEPARATE_D_OBJ), true)
-    ## DMD compile template bug fix
-    $(1)_D_RULE =$(TMP_PATH)/$(1)_dobj.$(D_OBJ_EXT)
-    $$($(1)_D_RULE):
-	    $(DC) $(D_CFLAGS) $(D_INCLUDE) -c $$($(1)_d_files) -of$$($(1)_D_RULE)
-    else
-    $(1)_D_RULE = $$($(1)_d_files:qt/%.d=$(TMP_PATH)/%_d.o)
-    endif
-    ## End. Build d part.
-    ## Build cpp part.
-    ifeq ($(CPP_SHARED), true)
-    ifeq ($(SYSTEM), windows)
-    $(1)_CPP_DYN_LIB = $(OUTPUT_PATH)$(SL)$(LIB_PREFIX)$(NAME_PREFIX)$(1)$(LIB_POSTFIX).$(DYN_LIB_EXT)
-    $$($(1)_CPP_DYN_LIB): $$($(1)_cpp_obj_files)
-	    $(CC) $(CC_LFLAGS) -shared $$($(1)_cpp_obj_files) -o $$($(1)_CPP_DYN_LIB) $(CC_LIB_PATH:%=-L%) -l$(qt_$(1)_lib_name) $$($(1)_link_cpp:%=-l%) -Wl,--out-implib,$(TMP_PATH)\$(LIB_PREFIX)$(NAME_PREFIX)$(1)_cpp.a
-    $(1)_CPP_RULE = $(TMP_PATH)\cpp_$(1).$(LIB_EXT)
-    $$($(1)_CPP_RULE): $$($(1)_CPP_DYN_LIB)
-	    $(IMPLIB) $$($(1)_CPP_RULE) $$($(1)_CPP_DYN_LIB)
-    else ## CPP_SHARED != true
-    $(1)_CPP_RULE = $(OUTPUT_PATH)$(SL)$(LIB_PREFIX)$(NAME_PREFIX)$(1)$(LIB_POSTFIX).$(DYN_LIB_EXT)
-    $$($(1)_CPP_RULE): $$($(1)_cpp_obj_files)
-	    $(CC) $(CC_LFLAGS) $(QTDIR_LIB)/$(LIB_PREFIX)$(qt_$(1)_name).$(DYN_LIB_EXT) $$($(1)_link_cpp:%=-l%) $$($(1)_cpp_obj_files) -o $$($(1)_CPP_RULE)
-    endif ## CPP_SHARED
-    DELETE_FILES += $$($(1)_CPP_DYN_LIB) $$($(1)_cpp_obj_files) $(TMP_PATH)\$(LIB_PREFIX)$(NAME_PREFIX)$(1)_cpp.a
-    else
-    $(1)_CPP_RULE = $$($(1)_cpp_obj_files)
-    endif
-    ## End. Build cpp part.
-
-    DELETE_FILES += $$($(1)_D_RULE) $$($(1)_CPP_RULE) $(OUTPUT_PATH)/$(LIB_PREFIX)$$(qt_$(1)_name)D.$(LIB_EXT)
-    ## Implib link.
-    $(1)_LIB = $(OUTPUT_PATH)$(SL)$(LIB_PREFIX)$(NAME_PREFIX)$(1)$(LIB_POSTFIX).$(LIB_EXT)
-    ifeq ($(DMD_WIN), true)
-    $$($(1)_LIB): $$($(1)_D_RULE) $$($(1)_CPP_RULE)
-	    $(DC) $$($(1)_D_RULE) $$($(1)_CPP_RULE) $(D_LIB_PATH:%=-L-L%) $$($(1)_link_d:%=-L-l%) -lib -of$$($(1)_LIB)
-    else
-    $$($(1)_LIB): $$($(1)_D_RULE) $$($(1)_CPP_RULE)
-	    $(AR) rcs $$($(1)_LIB) $$($(1)_D_RULE) $$($(1)_CPP_RULE)
-    endif
-    # End. Implib link.
-    $(1): mkdir_$(1) $$($(1)_LIB)
-endef
-$(foreach package,$(PACKAGES),$(eval $(call BUILD_template,$(package))))
-## End. Build package.
-
-clean:
-	@$(RM) $(DELETE_FILES)
--- a/cpp/qt_qtd/qtd_core.cpp	Fri May 21 14:16:02 2010 +0300
+++ b/cpp/qt_qtd/qtd_core.cpp	Mon May 24 23:43:30 2010 +0300
@@ -12,12 +12,6 @@
 #include "qtd_core.h"
 #include <iostream>
 
-
-extern "C" DLL_PUBLIC void* qtd_qobject(void* parent)
-{
-    return new QObject((QObject*)parent);
-}
-
 extern "C" DLL_PUBLIC QModelIndex qtd_to_QModelIndex(QModelIndexAccessor mia)
 {
     return * (QModelIndex *) (&mia) ;
@@ -45,14 +39,14 @@
     return qSharedBuild();
 }
 
+//TODO: this has to be replaced with something that makes some sense
 #ifdef CPP_SHARED
 QTD_EXPORT_VAR(qtd_toUtf8);
-QTD_EXPORT_VAR(qtd_dummy);
+QTD_EXPORT_VAR(qtd_QtdObject_delete);
 
-extern "C" DLL_PUBLIC void qtd_core_initCallBacks(pfunc_abstr d_func, pfunc_abstr dummy) {
+extern "C" DLL_PUBLIC void qtd_core_initCallBacks(pfunc_abstr d_func, pfunc_abstr del_d_qobj) {
     QTD_EXPORT_VAR_SET(qtd_toUtf8, d_func);
-    QTD_EXPORT_VAR_SET(qtd_dummy, dummy);
-    //std::cout << "qtd_core initialized" << std::endl;
+    QTD_EXPORT_VAR_SET(qtd_QtdObject_delete, del_d_qobj);
 }
 #endif
 
--- a/d2/qt/QGlobal.d	Fri May 21 14:16:02 2010 +0300
+++ b/d2/qt/QGlobal.d	Mon May 24 23:43:30 2010 +0300
@@ -40,21 +40,14 @@
 mixin QT_BEGIN_HEADER;
 mixin QT_BEGIN_NAMESPACE;
 
-//TODO: this sucks
-extern(C) void qtd_dummy() {}
-// Defined in QObject.d
-extern(C) void qtd_delete_d_qobject(void* dPtr);
+// Defined in qtd.QtdObject
+extern(C) void qtd_QtdObject_delete(void* dPtr);
 
 version(cpp_shared)
 {
-    extern (C) void qtd_core_initCallBacks(void* toUtf8, void* dummy);
+    extern (C) void qtd_core_initCallBacks(void* toUtf8, void* del_d_obj);
     static this() {
-        qtd_core_initCallBacks(&qtd_toUtf8, &qtd_dummy);
-    }
-
-    extern (C) void qtd_QObjectEntity_initCallBacks(void* del_d_obj);
-    static this() {
-        qtd_QObjectEntity_initCallBacks(&qtd_delete_d_qobject);
+        qtd_core_initCallBacks(&qtd_toUtf8, &qtd_QtdObject_delete);
     }
 }
 
--- a/d2/qtd/QtdObject.d	Fri May 21 14:16:02 2010 +0300
+++ b/d2/qtd/QtdObject.d	Mon May 24 23:43:30 2010 +0300
@@ -60,3 +60,15 @@
         }
     }
 }
+
+extern(C) void qtd_QtdObject_delete(void* dId)
+{
+    auto obj = cast(QtdObject)dId;
+
+    if (!(obj.__flags & QtdObjectFlags.dOwnership))
+    {
+        // Avoid deleting native object twice
+        obj.__setFlags(QtdObjectFlags.nativeOwnership, true);
+        delete obj;
+    }
+}
--- a/generator/abstractmetabuilder.cpp	Fri May 21 14:16:02 2010 +0300
+++ b/generator/abstractmetabuilder.cpp	Mon May 24 23:43:30 2010 +0300
@@ -1310,10 +1310,8 @@
                 meta_class->setHasNonPrivateConstructor(true);
             }
 
-            // Classes with virtual destructors should always have a shell class
-            // (since we aren't registering the destructors, we need this extra check)
             if (meta_function->isDestructor() && !meta_function->isFinal())
-                meta_class->setForceShellClass(true);
+                meta_class->setHasVirtualDestructor(true);
 
             if (!meta_function->isDestructor()
                 && !meta_function->isInvalid()
--- a/generator/abstractmetalang.cpp	Fri May 21 14:16:02 2010 +0300
+++ b/generator/abstractmetalang.cpp	Mon May 24 23:43:30 2010 +0300
@@ -1172,7 +1172,7 @@
 {
     return m_force_shell_class ||
         (!isFinal()
-         && (hasVirtualFunctions()
+         && (isPolymorphic()
              || hasProtectedFunctions()
              || hasFieldAccessors()
              || typeEntry()->isObject())); // qtd2 for being more consistent
@@ -1773,7 +1773,10 @@
                         }
 
                         // Set the class which first declares this function, afawk
-                        f->setDeclaringClass(sf->declaringClass());
+                        if (!f->isFinal() && sf->isFinal())
+                            f->setDeclaringClass(f->ownerClass());
+                        else
+                            f->setDeclaringClass(sf->declaringClass());
 
                         if (sf->isFinalInTargetLang() && !sf->isPrivate() && !f->isPrivate() && !sf->isStatic() && !f->isStatic()) {
                             // Shadowed funcion, need to make base class
--- a/generator/abstractmetalang.h	Fri May 21 14:16:02 2010 +0300
+++ b/generator/abstractmetalang.h	Mon May 24 23:43:30 2010 +0300
@@ -689,6 +689,7 @@
           m_has_hash_function(false),
           m_has_equals_operator(false),
           m_has_clone_operator(false),
+          m_has_virtual_destructor(false),
           m_is_type_alias(false),
           m_enclosing_class(0),
           m_base_class(0),
@@ -781,6 +782,51 @@
     bool hasVirtualFunctions() const { return !isFinal() && m_has_virtuals; }
     bool hasProtectedFunctions() const;
 
+    // returns true if this class or its base classes have a
+    // virtual destructor
+    bool hasVirtualDestructor() const { return m_has_virtual_destructor
+        || m_base_class && m_base_class->hasVirtualDestructor(); }
+
+    const AbstractMetaClass* destructorBase() const
+    {
+        const AbstractMetaClass* ret = this;
+        for (const AbstractMetaClass* base = this->m_base_class; base; base = base->m_base_class) {
+            if (base->m_has_virtual_destructor)
+                ret = base;
+        }
+        return ret;
+    }
+
+    bool isDestructorBase() const
+    {
+        return this == destructorBase();
+    }
+
+    const AbstractMetaClass* polymorphicBase() const
+    {
+        const AbstractMetaClass *ret = 0;
+
+        for (const AbstractMetaClass *base = this; base; base = base->baseClass()) {
+            if (base->m_has_virtuals || base->m_has_virtual_destructor)
+                ret = base;
+        }
+
+        return ret;
+    }
+
+
+
+    bool isPolymorphic() const
+    {
+        for (const AbstractMetaClass *base = this; base; base = base->baseClass()) {
+            if (base->m_has_virtuals || base->m_has_virtual_destructor)
+                return true;
+        }
+        return false;
+    }
+
+    bool setHasVirtualDestructor(bool value) { m_has_virtual_destructor = value; }
+
     QList<TypeEntry *> templateArguments() const { return m_template_args; }
     void setTemplateArguments(const QList<TypeEntry *> &args) { m_template_args = args; }
 
@@ -864,7 +910,8 @@
     uint m_has_equals_operator : 1;
     uint m_has_clone_operator :1;
     uint m_is_type_alias : 1;
-    uint m_reserved : 19;
+    uint m_has_virtual_destructor : 1;
+    uint m_reserved : 18;
 
     const AbstractMetaClass *m_enclosing_class;
     AbstractMetaClass *m_base_class;
--- a/generator/cppgenerator.h	Fri May 21 14:16:02 2010 +0300
+++ b/generator/cppgenerator.h	Mon May 24 23:43:30 2010 +0300
@@ -82,10 +82,11 @@
             && !(java_class->attributes() & AbstractMetaAttributes::Fake);
     }
 
-    static QString shellClassName(const AbstractMetaClass *java_class) {
-        return java_class->generateShellClass()
-               ? java_class->name() + "_QtDShell"
-               : java_class->qualifiedCppName();
+    static QString shellClassName(const AbstractMetaClass *java_class, bool fullName = true) {
+        if (java_class->generateShellClass())
+            return java_class->name() + "_QtDShell";
+        else
+            return fullName ? java_class->qualifiedCppName() : java_class->typeEntry()->name();
     }
 
  protected:
--- a/generator/cppimplgenerator.cpp	Fri May 21 14:16:02 2010 +0300
+++ b/generator/cppimplgenerator.cpp	Mon May 24 23:43:30 2010 +0300
@@ -587,8 +587,8 @@
     writeDefaultConstructedValues(s, java_class);
 
     if (hasCustomDestructor(java_class)) */
-    if (!java_class->isQObject())
-        writeFinalDestructor(s, java_class);
+
+    writeFinalDestructor(s, java_class);
 
     if (java_class->isQObject()) {
         writeQObjectEntity(s, java_class);
@@ -1500,14 +1500,14 @@
 
 void CppImplGenerator::writeShellDestructor(QTextStream &s, const AbstractMetaClass *java_class)
 {
-    s << shellClassName(java_class) << "::~"
-      << shellClassName(java_class) << "()" << endl
-      << "{" << endl;
-    {
-        //s << "    std::cout << \"In shell destructor of " << java_class->name() << ", nativeId: \" << this << std::endl;";  
-        if (java_class->isQObject())
-            s << "    destroyEntity(this);";
-    }
+    QString className = shellClassName(java_class);
+    s << className << "::~" << className << "() {" << endl;
+
+    if (java_class->isQObject())
+        s << "    destroyEntity(this);";
+    //else if (java_class->isPolymorphic())
+    //    s << "    qtd_QtdObject_delete(dId);" << endl;
+
     s << "}" << endl << endl;
 }
 
@@ -2385,15 +2385,15 @@
 
 void CppImplGenerator::writeFinalDestructor(QTextStream &s, const AbstractMetaClass *cls)
 {
-    if (cls->hasConstructors()) {
-        s << INDENT << "extern \"C\" DLL_PUBLIC void qtd_" << cls->name() << "_destructor(void *ptr)" << endl
+    if (cls->hasConstructors() && cls->isDestructorBase()) {
+        s << INDENT << "extern \"C\" DLL_PUBLIC void qtd_" << cls->name() << "_delete(void* nativeId)" << endl
           << INDENT << "{" << endl
-          << INDENT << "    delete (" << shellClassName(cls) << " *)ptr;" << endl
+          << INDENT << "    delete (" << shellClassName(cls) << "*)nativeId;" << endl
           << INDENT << "}" << endl << endl;
 
-        s << INDENT << "extern \"C\" DLL_PUBLIC void qtd_" << cls->name() << "_call_destructor(" << shellClassName(cls) << " *ptr)" << endl
+        s << INDENT << "extern \"C\" DLL_PUBLIC void qtd_" << cls->name() << "_destroy(void* nativeId)" << endl
           << INDENT << "{" << endl
-          << INDENT << "    call_destructor(ptr);" << endl
+          << INDENT << "    call_destructor((" << shellClassName(cls) << "*)nativeId);" << endl
           << INDENT << "}" << endl << endl;
     }
 }
--- a/generator/dgenerator.cpp	Fri May 21 14:16:02 2010 +0300
+++ b/generator/dgenerator.cpp	Mon May 24 23:43:30 2010 +0300
@@ -1702,30 +1702,20 @@
     if (!d_class->hasConstructors())
         return;
 
-    bool isTheQObject = d_class->name() == "QObject";
-    if (isTheQObject || !d_class->isQObject())
+    if (d_class->isDestructorBase())
     {
         s << INDENT << "protected override void __deleteNative() {" << endl;
         {
-            if (isTheQObject)
-                s << INDENT << "qtd_delete_qobject(__nativeId);" << endl;
-            else if (!d_class->isQObject())
-                s << INDENT << "qtd_" << d_class->name() << "_destructor(__nativeId);" << endl;
+            s << INDENT << "qtd_" << d_class->name() << "_delete(__nativeId);" << endl;
         }
         s << INDENT << "}" << endl << endl;
-    }
-
-    if (d_class->typeEntry()->isValue())
-    {
-        s << INDENT << "public static void __deleteNativeObject(void* ptr) {" << endl
-          << INDENT << "    qtd_" << d_class->name() << "_destructor(ptr);" << endl
+
+        s << INDENT << "static void __deleteNativeObject(void* ptr) {" << endl
+          << INDENT << "    qtd_" << d_class->name() << "_delete(ptr);" << endl
           << INDENT << "}" << endl << endl;
-    }
-
-    if (d_class->typeEntry()->isValue())
-    {
-        s << INDENT << "public static void __callNativeDestructor(void* ptr) {" << endl
-          << INDENT << "    qtd_" << d_class->name() << "_call_destructor(ptr);" << endl
+
+        s << INDENT << "static void __callNativeDestructor(void* nativeId) {" << endl
+          << INDENT << "    qtd_" << d_class->name() << "_destroy(nativeId);" << endl
           << INDENT << "}" << endl << endl;
     }
 }
@@ -2482,9 +2472,9 @@
 //    if (d_class->needsConversionFunc)
         writeConversionFunction(s, d_class);
 
-    if (d_class->hasConstructors() && !d_class->isQObject())
-        s << "extern (C) void qtd_" << d_class->name() << "_destructor(void *ptr);" << endl
-          << "extern (C) void qtd_" << d_class->name() << "_call_destructor(void *ptr);" << endl << endl;
+    if (d_class->hasConstructors() && d_class->isDestructorBase())
+        s << "extern (C) void qtd_" << d_class->name() << "_delete(void *ptr);" << endl
+          << "extern (C) void qtd_" << d_class->name() << "_destroy(void *ptr);" << endl << endl;
 
     // qtd
 
--- a/generator/typesystem_core.xml	Fri May 21 14:16:02 2010 +0300
+++ b/generator/typesystem_core.xml	Mon May 24 23:43:30 2010 +0300
@@ -2363,27 +2363,12 @@
   <object-type name="QObject">
 	<inject-code class="native">
 
-#ifdef CPP_SHARED
-QTD_EXPORT_VAR(qtd_delete_d_qobject);
-
-extern "C" DLL_PUBLIC void qtd_QObjectEntity_initCallBacks(pfunc_abstr del_d_qobj)
-{
-	QTD_EXPORT_VAR_SET(qtd_delete_d_qobject, del_d_qobj);
-}
-#endif
-
-
 extern "C" DLL_PUBLIC void* qtd_get_d_qobject(void *nativeId)
 {
     QtD_QObjectEntity *entity = QtD_QObjectEntity::getQObjectEntity((QObject*)nativeId);
     return entity ? entity-&gt;dId : NULL;
 }
 
-extern "C" DLL_PUBLIC void qtd_delete_qobject(void *nativeId)
-{    
-    delete (QObject*)nativeId;    
-}
-
 extern "C" DLL_PUBLIC void qtd_create_qobject_entity(void* nativeId, void *dId)
 {
 	new QtD_QObjectEntity((QObject*)nativeId, dId);
@@ -2416,23 +2401,11 @@
 
 	<inject-code class="java-free">
 extern(C) void* qtd_get_d_qobject(void* nativeId);
-extern(C) void qtd_delete_qobject(void* nativeId);
 extern(C) void* qtd_create_qobject_entity(void* nativeId, void* dId);
 extern(C) void* qtd_QObject_metaObject(void* nativeId);
 extern(C) void qtd_connect(void *nativeId, cstringz signal, int id, bool dynamicEntity);
 extern(C) void qtd_disconnect(void *nativeId, cstringz signal, int id, bool dynamicEntity);
 
-extern(C) void qtd_delete_d_qobject(void* dId)
-{
-    auto obj = cast(QObject)dId;
-	
-	if (!(obj.__flags &amp; QtdObjectFlags.dOwnership))
-	{
-		// Avoid deleting native object twice
-		obj.__setFlags(QtdObjectFlags.nativeOwnership, true);
-		delete obj;
-	}
-}
 	</inject-code>
 
     <modify-function signature="childEvent(QChildEvent*)">
--- a/include/QObjectEntity.h	Fri May 21 14:16:02 2010 +0300
+++ b/include/QObjectEntity.h	Mon May 24 23:43:30 2010 +0300
@@ -7,10 +7,6 @@
 
 QTD_EXPORT(void, qtd_delete_d_qobject, (void* dPtr))
 
-#ifdef CPP_SHARED
-#define qtd_delete_d_qobject qtd_get_qtd_delete_d_qobject()
-#endif
-
 //TODO: user data ID must be registered with QObject::registerUserData;
 #define userDataId 0
 
@@ -32,7 +28,7 @@
     inline void destroyEntity(QObject *qObject = NULL)
     {
         Q_ASSERT(dId);
-        qtd_delete_d_qobject(dId);
+        qtd_QtdObject_delete(dId);
         if (qObject)
         {
             qObject->setUserData(userDataId, NULL);
--- a/include/qtd_core.h	Fri May 21 14:16:02 2010 +0300
+++ b/include/qtd_core.h	Mon May 24 23:43:30 2010 +0300
@@ -71,11 +71,11 @@
 #endif
 
 QTD_EXPORT(void, qtd_toUtf8, (const unsigned short* arr, uint size, void* str))
-QTD_EXPORT(void, qtd_dummy, ())
+QTD_EXPORT(void, qtd_QtdObject_delete, (void* dId))
 
 #ifdef CPP_SHARED
 #define qtd_toUtf8 qtd_get_qtd_toUtf8()
-#define qtd_dummy qtd_get_qtd_dummy()
+#define qtd_QtdObject_delete qtd_get_qtd_QtdObject_delete()
 #endif
 
 extern "C" QModelIndex qtd_to_QModelIndex(QModelIndexAccessor mia);
@@ -90,4 +90,5 @@
 {
     a->~T();
 }
+
 #endif // QTD_CORE_H