diff generator/dgenerator.cpp @ 253:073b9153ed8a

Rev. 264 done right. Problems: - classwizard segfaults on exit due to a bug in signals/slots or runtime. - hellogl doesn't compile with dmd2 due to a bug in the compiler backend
author maxter
date Sun, 30 Aug 2009 09:59:12 +0000
parents 37eed70de029
children 17b5e13364b7 49bfc86ff583
line wrap: on
line diff
--- a/generator/dgenerator.cpp	Sat Aug 22 12:50:58 2009 +0000
+++ b/generator/dgenerator.cpp	Sun Aug 30 09:59:12 2009 +0000
@@ -317,7 +317,7 @@
     }
 */
     // Generates Java 1.5 type enums
-    s << "    public enum " << d_enum->enclosingClass()->name() << "_" << d_enum->name() << " {" << endl;
+    s << "public enum " << d_enum->enclosingClass()->name() << "_" << d_enum->name() << " {" << endl;
     const AbstractMetaEnumValueList &values = d_enum->values();
     EnumTypeEntry *entry = d_enum->typeEntry();
 
@@ -477,11 +477,11 @@
 }
 
 static QString function_call_for_ownership(TypeSystem::Ownership owner)
-{
+{  
     if (owner == TypeSystem::CppOwnership) {
-        return "__set_native_ownership(true)";
+        return "__setFlags(QtdObjectFlags.nativeOwnership, true)";
     } else /* qtd 2 if (owner == TypeSystem::TargetLangOwnership) */ {
-        return "__set_native_ownership(false)";
+        return "__setFlags(QtdObjectFlags.nativeOwnership, false)";
     }/* else if (owner == TypeSystem::DefaultOwnership) {
         return "__no_real_delete = false";
 
@@ -696,21 +696,21 @@
     s << INDENT;
     if ( (has_return_type && d_function->argumentReplaced(0).isEmpty() ) || d_function->isConstructor()) { //qtd
         if(d_function->type() && d_function->type()->isQObject()) { // qtd
-            s << "void *__qt_return_value = ";
+            s << "void *ret = ";
         } else if(return_in_arg) // qtd
             ;
         else if (d_function->isConstructor()) { // qtd
-            s << "void* __qt_return_value = ";
+            s << "void* ret = ";
         } else if (return_type && return_type->isValue() && !return_type->typeEntry()->isStructInD()) {
-            s << "void* __qt_return_value = ";
+            s << "void* ret = ";
         } else if (return_type && return_type->isVariant()) {
-            s << "void* __qt_return_value = ";
+            s << "void* ret = ";
         } else if (return_type && ( return_type->isObject() ||
                   (return_type->isNativePointer() && return_type->typeEntry()->isValue()) ||
                    return_type->typeEntry()->isInterface()) ) {
-            s << "void* __qt_return_value = ";
+            s << "void* ret = ";
         } else if (return_type && return_type->isArray()) {
-            s << return_type->arrayElementType()->name() + "* __qt_return_value = ";
+            s << return_type->arrayElementType()->name() + "* ret = ";
         } else {
             returnImmediately = true;
             s << "return ";
@@ -765,9 +765,9 @@
 
     if (!d_function->isConstructor() && !d_function->isStatic()) {
         if(dVersion == 2 && d_function->isConstant())
-            s << "(cast(" << d_function->ownerClass()->name() << ")this).nativeId";
+            s << "(cast(" << d_function->ownerClass()->name() << ")this).__nativeId";
         else
-            s << "nativeId";
+            s << "__nativeId";
     }
 
     if (d_function->isConstructor() &&
@@ -801,7 +801,7 @@
             QString arg_name = arg->argumentName();
 
             if (type->isVariant())
-                s << arg_name << " is null ? null : " << arg_name << ".nativeId";
+                s << arg_name << " is null ? null : " << arg_name << ".__nativeId";
             else if (te->designatedInterface())
                 s << arg_name << " is null ? null : " << arg_name << ".__ptr_" << te->designatedInterface()->name();
             else if (modified_type == "string" /* && type->fullName() == "char" */) {
@@ -831,9 +831,9 @@
                 } // else if (value type is abstract) then we will get a null pointer exception, which is all right
 
                 if(dVersion == 2 && type->isConstant())
-                    s << "(cast(" << type->name() << ")" << arg_name << ").nativeId";
+                    s << "(cast(" << type->name() << ")" << arg_name << ").__nativeId";
                 else
-                    s << arg_name << ".nativeId";
+                    s << arg_name << ".__nativeId";
             }
         }
     }
@@ -864,14 +864,14 @@
 /* qtd2
     if (needs_return_variable) {
         if (owner != TypeSystem::InvalidOwnership) {
-            s << INDENT << "if (__qt_return_value != null) {" << endl;
+            s << INDENT << "if (ret != null) {" << endl;
             if (return_type->isContainer())
-                writeOwnershipForContainer(s, owner, return_type, "__qt_return_value");
+                writeOwnershipForContainer(s, owner, return_type, "ret");
             else
-                s << INDENT << "    __qt_return_value." << function_call_for_ownership(owner) << ";" << endl;
+                s << INDENT << "    ret." << function_call_for_ownership(owner) << ";" << endl;
             s << INDENT << "}" << endl;
         }
-        s << INDENT << "return __qt_return_value;" << endl;
+        s << INDENT << "return ret;" << endl;
     }
 */
     if (d_function->isConstructor()) {
@@ -893,29 +893,31 @@
         }
 
         if ( ( has_return_type && d_function->argumentReplaced(0).isEmpty() )) // qtd
+        {
             if(return_type->isQObject())
-                s << "qtd_" << return_type->name() << "_from_ptr(__qt_return_value);" << endl;
+                s << return_type->name() << ".__getObject(ret);" << endl;
+        }
 
         if (return_type->isValue() && !return_type->typeEntry()->isStructInD())
-            s << "new " << return_type->name() << "(__qt_return_value, false);" << endl;
+            s << "new " << return_type->name() << "(ret);" << endl;
 
         if (return_type->isVariant())
-            s << "new QVariant(__qt_return_value, false);" << endl;
+            s << "new QVariant(ret);" << endl;
 
         if (return_type->isNativePointer() && return_type->typeEntry()->isValue())
-            s << "new " << return_type->name() << "(__qt_return_value, true);" << endl;
+            s << "new " << return_type->name() << "(ret, QtdObjectFlags.nativeOwnership);" << endl;
 
         if (return_type->isObject()) {
             if(d_function->storeResult())
-                s << INDENT << QString("__m_%1.nativeId = __qt_return_value;").arg(d_function->name()) << endl
+                s << INDENT << QString("__m_%1.__nativeId = ret;").arg(d_function->name()) << endl
                   << INDENT << QString("return __m_%1;").arg(d_function->name()) << endl;
             else
-                s << "qtd_" << return_type->name() << "_from_ptr(__qt_return_value);" << endl;
+                s << "qtd_" << return_type->name() << "_from_ptr(ret);" << endl;
             s << endl;
         }
 
         if (return_type->isArray()) {
-            s << "__qt_return_value[0 .. " << return_type->arrayElementCount() << "];" << endl;
+            s << "ret[0 .. " << return_type->arrayElementCount() << "];" << endl;
         }
 
         foreach (ReferenceCount referenceCount, referenceCounts) {
@@ -1680,60 +1682,32 @@
     if (!d_class->hasConstructors())
         return;
 
-    s << endl;
-    if (d_class->baseClassName().isEmpty()) {
-        s << INDENT << "~this() { " << endl;
+    bool isTheQObject = d_class->name() == "QObject";
+    if (isTheQObject || !d_class->isQObject())
+    {
+        s << INDENT << "protected override void __deleteNative() {" << endl;
         {
-            Indentation indent(INDENT);
-
-/*
-            if(d_class->name() == "QObject")
-                s << INDENT << "if(!__gc_managed)" << endl
-                        << INDENT << "    remove(__gc_ref_list, this);" << endl
-                        << INDENT << "if(!__no_real_delete && __gc_managed) {" << endl
-                        << INDENT << "    __qobject_is_deleting = true;" << endl
-                        << INDENT << "    scope(exit) __qobject_is_deleting = false;" << endl
-                        << INDENT << "    __free_native_resources();" << endl
-                        << INDENT << "}" << endl;
-*/
-            if(d_class->name() == "QObject")
-                s << INDENT << "if(!__no_real_delete) {" << endl
-                  << INDENT << "    __qobject_is_deleting = true;" << endl
-                  << INDENT << "    scope(exit) __qobject_is_deleting = false;" << endl
-                  << INDENT << "    __free_native_resources();" << endl
-                  << INDENT << "}" << endl;
-            else
-                s << INDENT << "if(!__no_real_delete)" << endl
-                  << INDENT << "    __free_native_resources();" << 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 << "}" << endl << endl;
     }
-
-    s << INDENT << "protected void __free_native_resources() {" << endl;
-    {
-        Indentation indent(INDENT);
-        s << INDENT << "qtd_" << d_class->name() << "_destructor(nativeId());" << endl;
-    }
-    s << INDENT << "}" << endl << endl;
 }
 
-void DGenerator::writeOwnershipMethods(QTextStream &s, const AbstractMetaClass *d_class)
+void DGenerator::writeFlagsSetter(QTextStream &s, const AbstractMetaClass *d_class)
 {
-    s << INDENT << "void __set_native_ownership(bool ownership_)";
     if (d_class->isInterface() || d_class->isNamespace())
-        s << ";";
-    else {
-        s << " {" << endl
-          << INDENT << "    __no_real_delete = ownership_;" << endl
-          << INDENT << "}" << endl << endl;
-    }
+        s << INDENT << "void __setFlags(QtdObjectFlags flags, bool val);";
+    else // COMPILER BUG:
+        s << INDENT << "void __setFlags(QtdObjectFlags flags, bool val) { super.__setFlags(flags, val); }";
 }
 
 void DGenerator::writeSignalHandlers(QTextStream &s, const AbstractMetaClass *d_class)
 {
     AbstractMetaFunctionList signal_funcs = signalFunctions(d_class);
 
-    //TODO: linkage trivia should be abstracted away
     QString attr;
 
     s << "// signal handlers" << endl;
@@ -1789,8 +1763,7 @@
                     if(ctype->isAbstract())
                         type_name = type_name + "_ConcreteWrapper";
                     s << INDENT << "scope " << arg_name << " = new " << type_name
-                                << "(cast(void*)(" << arg_ptr << "), true);" << endl
-                                << INDENT << arg_name << ".__no_real_delete = true;";
+                                << "(cast(void*)(" << arg_ptr << "), QtdObjectFlags.nativeOwnership);" << endl;
                 }
                 s << endl;
             }
@@ -1816,6 +1789,20 @@
 
     bool fakeClass = d_class->attributes() & AbstractMetaAttributes::Fake;
 
+
+    QString auxModName = d_class->package() + "." + d_class->name() + "_aux";
+    FileOut auxFile(outputDirectory() + "/" + subDirectoryForClass(d_class) + "/" + d_class->name() + "_aux.d");
+    auxFile.isDone = true;
+    auxFile.stream << "module " << auxModName << ";" << endl << endl;
+
+    bool staticInit = d_class->isQObject() || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface());
+    if (staticInit)
+    {
+        auxFile.isDone = false;
+        auxFile.stream << "extern(C) void static_init_" << d_class->name() << "();" << endl;
+        auxFile.stream << "static this() { static_init_" << d_class->name() << "; }" << endl << endl;
+    }
+
     if (m_docs_enabled) {
         m_doc_parser = new DocParser(m_doc_directory + "/" + d_class->name().toLower() + ".jdoc");
     }
@@ -1897,14 +1884,31 @@
         }
     }
 
+    // Enums aliases outside of the class - hack
+    if (!d_class->enums().isEmpty()) {
+        auxFile.isDone = false;
+        foreach (AbstractMetaEnum *d_enum, d_class->enums())
+            writeEnum(auxFile.stream, d_enum);
+    }
+
+    // Auxiliary file contents should have been written at this point
+    if (!auxFile.isDone)
+    {
+        s << "public import " << auxModName << ";" << endl;
+        auxFile.done();
+    }
+
     if (!m_isRecursive) {
         s << "public import qt.QGlobal;" << endl
           << "public import qt.core.Qt;" << endl
-          << "private import qt.QtDObject;" << endl
+          << "private import qt.QtdObject;" << endl
           << "private import qt.core.QString;" << endl
           << "private import qt.qtd.Array;" << endl;
         if (d_class->isQObject()) {
-            s << "public import qt.Signal;" << endl;
+            s << "public import qt.Signal;" << endl
+              << "public import qt.core.QMetaObject;" << endl
+              << "public import qt.qtd.Traits;" << endl;
+
             if (d_class->name() != "QObject")
                 s << "public import qt.core.QObject;" << endl;
         }
@@ -1924,9 +1928,6 @@
         if(d_class->isQObject())
             s << "private import " << d_class->package() << ".ArrayOps2;" << endl;
 
-        if (!d_class->enums().isEmpty())
-            s << "public import " << d_class->package() << "." << d_class->name() << "_enum;" << endl << endl;
-
         s << "// automatic imports-------------" << endl;
         writeRequiredImports(s, d_class);
         s << endl;
@@ -1935,35 +1936,23 @@
             s << "import std.stdio;" << endl
               << "import std.string;" << endl
               << "import std.utf;" << endl
-              << "import core.memory;";
+              << "import core.memory;" << endl;
         }
         else
         {
             s << "import tango.io.Stdout;" << endl
               << "import tango.stdc.stringz;" << endl
               << "import tango.text.convert.Utf;" << endl
-              << "import tango.core.Memory;";
+              << "import tango.core.Memory;" << endl;
         }
-        s << endl << endl << endl;
+
+        s << endl << endl;
     }
 
     if (m_doc_parser) {
         s << m_doc_parser->documentation(d_class) << endl << endl;
     }
 
-    // Enums aliases outside of the class - hack
-    if (!d_class->enums().isEmpty()) {
-        QString fileName = QString("%1_enum.d").arg(d_class->name());
-        FileOut fileOut(outputDirectory() + "/" + subDirectoryForClass(d_class) + "/" + fileName);
-
-        fileOut.stream << "module " << d_class->package() << "." << d_class->name() << "_enum;" << endl << endl;
-        foreach (AbstractMetaEnum *d_enum, d_class->enums())
-            writeEnum(fileOut.stream, d_enum);
-    }
-
-
-    s << endl;
-
 /* qtd    s << "@QtJambiGeneratedClass" << endl;
 
     if ((d_class->typeEntry()->typeFlags() & ComplexTypeEntry::Deprecated) != 0) {
@@ -2156,21 +2145,14 @@
     foreach (AbstractMetaEnum *d_enum, d_class->enums())
         writeEnumAlias(s, d_enum);
 
-    if (!d_class->enums().isEmpty() && !d_class->functions().isEmpty())
-        s << endl;
-
-    // Signals
-    AbstractMetaFunctionList signal_funcs;
-
-    signal_funcs = signalFunctions(d_class);
-    if (signal_funcs.size())
+    // Signals    
+    if (d_class->isQObject())
     {
-        writeSignalConnectors(s, d_class, signal_funcs);
+        AbstractMetaFunctionList signal_funcs = signalFunctions(d_class, false);
+        writeSignalSignatures(s, d_class, signal_funcs);
+   
         foreach (AbstractMetaFunction *signal, signal_funcs)
-        {
-            if (d_class == signal->implementingClass())
-                writeSignal(s, signal);
-        }
+            writeSignal(s, signal);
     }
 
     // Class has subclasses but also only private constructors
@@ -2251,37 +2233,39 @@
           << INDENT << "private native boolean __qt_signalInitialization(long ptr, String name);" << endl;
     }
 */
+    if (d_class->isQObject())
+        writeQObjectFunctions(s, d_class);
+
     // Add dummy constructor for use when constructing subclasses
     if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) {
         s << endl
           << INDENT << "public "
           << "this";
 
-        if(d_class->name() == "QObject")
+
+        Indentation indent(INDENT);
+
+        s << "(void* native_id, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl
+          << INDENT << "super(native_id, flags);" << endl;
+
+        if (d_class->name() == "QObject")
         {
-            {
-                Indentation indent(INDENT);
-                s << "(void* native_id, bool gc_managed) {" << endl
-/*                  << INDENT << "if(!gc_managed)" << endl
-                  << INDENT << "    __gc_ref_list ~= this;" << endl
-                  << INDENT << "__gc_managed = gc_managed;" << endl */
-                  << INDENT << "super(native_id);" << endl;
-            }
+            // To prevent GC from collecting the object, add it to the statically rooted linked list
+            s << INDENT << "    __next = __root;" << endl
+            << INDENT << "    __root = this;" << endl
+            << INDENT << "    if (__next) {" << endl
+            << INDENT << "        __next.__prev = this;" << endl
+            << INDENT << "    }" << endl << endl;
         }
-        else {
-            Indentation indent(INDENT);
-            if(d_class->isQObject())
-                s << "(void* native_id, bool gc_managed) {" << endl
-                  << INDENT << "super(native_id, gc_managed);" << endl;
-            else
-                s << "(void* native_id, bool no_real_delete = false) {" << endl
-                  << INDENT << "super(native_id, no_real_delete);" << endl;
-        }
+
+        /*
         if (cpp_shared) {
             if (d_class->generateShellClass() && !d_class->isInterface())
-                s << INDENT << "if (!init_flag_" << d_class->name() << ")" << endl
+                s << INDENT << "if (!static_inited)" << endl
                   << INDENT << "    static_init_" << d_class->name() << "();" << endl << endl;
         }
+        */
+
         // customized store-result instances
         d_funcs = d_class->functionsInTargetLang();
         for (int i=0; i<d_funcs.size(); ++i) {
@@ -2304,7 +2288,7 @@
                 s << INDENT << "    __m_" << d_function->name() << " = new "
                         << type_name << "(cast(void*)null);" << endl;
                 if (d_function->type()->isQObject())
-                    s << INDENT << "    __m_" << d_function->name() << ".__no_real_delete = true;" << endl;
+                    s << INDENT << "    __m_" << d_function->name() << ".__setFlags(QtdObjectFlags.nativeOwnership, true);" << endl;
             }
         }
 
@@ -2316,14 +2300,14 @@
                 AbstractMetaClass *iface = interfaces.at(i);
 
                 s << INDENT << "    __m_ptr_" << iface->name() << " = qtd_" << d_class->name() << "_cast_to_" << iface->qualifiedCppName()
-                  << "(nativeId);" << endl;
+                  << "(__nativeId);" << endl;
             }
         }
 
 
         s << INDENT << "}" << endl << endl;
 
-/******************!!!DUBLICATE OF ABOVE!!!*********************/
+/******************!!!DUPLICATE OF ABOVE!!!*********************/
         for (int i=0; i<d_funcs.size(); ++i) {
             AbstractMetaFunction *d_function = d_funcs.at(i);
             uint included_attributes = 0;
@@ -2387,7 +2371,7 @@
 
 /* qtd    writeJavaLangObjectOverrideFunctions(s, d_class);
 */
-    writeOwnershipMethods(s, d_class);
+    writeFlagsSetter(s, d_class);
     s << "// Injected code in class" << endl;
     writeExtraFunctions(s, d_class);
 // qtd2    writeToStringFunction(s, d_class);
@@ -2428,13 +2412,11 @@
 
         {
             Indentation indent(INDENT);
-            s << INDENT << "public this(void* native_id, bool no_real_delete = true) {" << endl
-              << INDENT << "    super(native_id, no_real_delete);" << endl;
-
-
-
-
-            /******************!!!DUBLICATE!!!*********************/
+            QString hasShellFlag = d_class->generateShellClass() ? " | QtdObjectFlags.hasShell" : "";
+            s << INDENT << "public this(void* native_id, QtdObjectFlags flags = QtdObjectFlags.nativeOwnership) {" << endl
+              << INDENT << "    super(native_id, flags);" << endl << endl;
+            
+            /******************!!!DUPLICATE!!!*********************/
             d_funcs = d_class->functionsInTargetLang();
             for (int i=0; i<d_funcs.size(); ++i) {
                 AbstractMetaFunction *d_function = d_funcs.at(i);
@@ -2452,7 +2434,7 @@
                     s << INDENT << "    __m_" << d_function->name() << " = new "
                             << type_name << "(cast(void*)null);" << endl;
                     if (d_function->type()->isQObject())
-                        s << INDENT << "    __m_" << d_function->name() << ".__no_real_delete = true;" << endl;
+                        s << INDENT << "    __m_" << d_function->name() << ".__setFlags(QtdObjectFlags.nativeOwnership, true);" << endl;
                 }
             }
 
@@ -2509,18 +2491,15 @@
 
     if (d_class->generateShellClass()) { // qtd2
         if (d_class->hasVirtualFunctions()
-            && (d_class->typeEntry()->isObject() || d_class->typeEntry()->isQObject()) )
+            && (d_class->typeEntry()->isObject() && !d_class->typeEntry()->isQObject()) )
         s << endl << "extern (C) void *__" << d_class->name() << "_entity(void *q_ptr);" << endl << endl;
     }
 
-    if (d_class->isQObject())
-        writeQObjectFunctions(s, d_class);
-
 
 //    if (d_class->needsConversionFunc)
         writeConversionFunction(s, d_class);
 
-    if (d_class->hasConstructors())
+    if (d_class->hasConstructors() && !d_class->isQObject())
         s << "extern (C) void qtd_" << d_class->name() << "_destructor(void *ptr);" << endl << endl;
 
     // qtd
@@ -2564,22 +2543,29 @@
             writeShellVirtualFunction(s, function, d_class, pos);
     }
 
-    //init callbacks from dll to D side
-    if (cpp_shared) {
-        bool shellClass = d_class->generateShellClass();
-        if (shellClass && !d_class->isInterface()) {
-            QString initArgs = "void* virtuals";
+    // write static constructor
+    if (staticInit) {
+        QString initArgs;
+        if (cpp_shared)
+        {
+            initArgs = "void* virtuals";
             if (d_class->isQObject())
-                initArgs += ", void* signals, void* qobj_del";
+                initArgs += ", void* signals";
 
             s << "private extern (C) void qtd_" << d_class->name()
-              << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl
-              << "private bool init_flag_" << d_class->name() << " = false;" << endl
-              << "void static_init_" << d_class->name() << "() {" << endl
-              << INDENT << "init_flag_" << d_class->name() << " = true;" << endl << endl
-
-              // virtual functions
-              << INDENT << "void*[" << virtualFunctions.size() << "] virt_arr;" << endl;
+            << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl;
+        }
+
+        s << "extern(C) void static_init_" << d_class->name() << "() {" << endl;
+
+        if (d_class->isQObject()) {
+            s << INDENT << "if (!" << d_class->name() << "._staticMetaObject) " << endl
+            << INDENT << "    " << d_class->name() << ".createStaticMetaObject;" << endl << endl;
+        }
+
+        if (cpp_shared) {
+             // virtual functions
+            s << INDENT << "void*[" << virtualFunctions.size() << "] virt_arr;" << endl;
             for (int pos = 0; pos<virtualFunctions.size(); ++pos) {
                 const AbstractMetaFunction *function = virtualFunctions.at(pos);
                 if (!notWrappedYet(function)) // qtd2
@@ -2590,8 +2576,9 @@
             else
                 initArgs = "virt_arr.ptr";
 
-            // signals
             if (d_class->isQObject()) {
+
+                // signals
                 AbstractMetaFunctionList signal_funcs = signalFunctions(d_class);
                 s << endl << INDENT << "void*[" << signal_funcs.size() << "] sign_arr;" << endl;
                 for(int i = 0; i < signal_funcs.size(); i++) {
@@ -2602,16 +2589,12 @@
                     initArgs += ", null";
                 else
                     initArgs += ", sign_arr.ptr";
-
-                // QObject_delete
-                s << endl << INDENT << "void *qobj_del;" << endl
-                  << INDENT << "qobj_del = &qtd_D_" << d_class->name() << "_delete;" << endl;
-                initArgs += ", qobj_del";
             }
 
-            s << INDENT << "qtd_" << d_class->name() << QString("_initCallBacks(%1);").arg(initArgs) << endl
-              << "}" << endl << endl;
+            s << INDENT << "qtd_" << d_class->name() << QString("_initCallBacks(%1);").arg(initArgs) << endl;
         }
+
+        s << "}" << endl << endl;
     }
 
     writeSignalHandlers(s, d_class);
@@ -2628,71 +2611,88 @@
         write(s, cls);
         m_isRecursive = false;
     }
+
+
+    if (d_class->isQObject())
+    {
+      s << "private extern(C) void* qtd_" << d_class->name() << "_staticMetaObject();" << endl << endl
+        << "private extern(C) void qtd_" << d_class->name() << "_createEntity(void* nativeId, void* dId);" <<  endl << endl;
+    }
 }
 
 void DGenerator::writeConversionFunction(QTextStream &s, const AbstractMetaClass *d_class)
 {
     const ComplexTypeEntry *ctype = d_class->typeEntry();
-    if(!ctype->isQObject() && !ctype->isObject())
+    if(ctype->isQObject() || !ctype->isObject())
         return;
     QString class_name = ctype->name();
     QString return_type_name = class_name;
     if(ctype->designatedInterface())
         return_type_name = ctype->designatedInterface()->name();
-    s << return_type_name << " qtd_" << class_name << "_from_ptr(void* __qt_return_value) {" << endl;
-
-    if(ctype->isQObject()) {
-        QString type_name = class_name;
-        if(ctype->isAbstract())
-            type_name = type_name + "_ConcreteWrapper";
-
-        s << INDENT << "if (__qt_return_value is null)" << endl
-          << INDENT << "    return null;" << endl
-          << INDENT << "void* d_obj = qtd_" << class_name << "_d_pointer(__qt_return_value);" << endl
-          << INDENT << "if (d_obj is null) {" << endl
-          << INDENT << "    auto new_obj = new " << type_name << "(__qt_return_value, false);" << endl
-          << INDENT << "    qtd_" << class_name << "_create_link(new_obj.nativeId, cast(void*) new_obj);" << endl
-          << INDENT << "    new_obj.__no_real_delete = true;" << endl
-          << INDENT << "    return new_obj;" << endl
-          << INDENT << "} else" << endl
-          << INDENT << "    return cast(" << class_name << ") d_obj;" << endl;
-    } else if (ctype->isObject()) {
-        QString type_name = class_name;
-        if(ctype->isAbstract())
-            type_name = ctype->targetLangName() + "_ConcreteWrapper";
-
-        // if class has virtual functions then it has classname_entity function so
-        // we can look for D Object pointer. otherwise create new wrapper
-        if (d_class->hasVirtualFunctions()) {
-            s << INDENT << "void* d_obj = __" << ctype->targetLangName() << "_entity(__qt_return_value);" << endl
-              << INDENT << "if (d_obj !is null) {" << endl
-              << INDENT << "    auto d_obj_ref = cast (Object) d_obj;" << endl
-              << INDENT << "    return cast(" << return_type_name << ") d_obj_ref;" << endl
-              << INDENT << "} else {" << endl
-              << INDENT << "    auto return_value = new " << type_name << "(__qt_return_value, true);" << endl
-              << INDENT << "    return_value.__no_real_delete = true;" << endl
-              << INDENT << "    return return_value;" << endl
-              << INDENT << "}" << endl;
-        } else {
-            s << INDENT << "auto return_value = new " << type_name << "(__qt_return_value, true);" << endl
-              << INDENT << "return_value.__no_real_delete = true;" << endl
-              << INDENT << "return return_value;" << endl;
-        }
+
+    s << return_type_name << " qtd_" << class_name << "_from_ptr(void* ret) {" << endl;
+
+
+    QString type_name = class_name;
+    if(ctype->isAbstract())
+        type_name = ctype->targetLangName() + "_ConcreteWrapper";
+
+    // if class has virtual functions then it has classname_entity function so
+    // we can look for D Object pointer. otherwise create new wrapper
+    if (d_class->hasVirtualFunctions()) {
+        s << INDENT << "void* d_obj = __" << ctype->targetLangName() << "_entity(ret);" << endl
+          << INDENT << "if (d_obj !is null) {" << endl
+          << INDENT << "    auto d_obj_ref = cast (Object) d_obj;" << endl
+          << INDENT << "    return cast(" << return_type_name << ") d_obj_ref;" << endl
+          << INDENT << "} else {" << endl
+          << INDENT << "    auto return_value = new " << type_name << "(ret, QtdObjectFlags.nativeOwnership);" << endl
+          << INDENT << "    return return_value;" << endl
+          << INDENT << "}" << endl;
+    } else {
+        s << INDENT << "auto return_value = new " << type_name << "(ret, QtdObjectFlags.nativeOwnership);" << endl
+          << INDENT << "return return_value;" << endl;
     }
     s << "}" << endl << endl;
 }
 
-
 void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class)
 {
-    s << "extern(C) void* qtd_" << d_class->name() << "_d_pointer(void *obj);" << endl
-      << "extern(C) void qtd_" << d_class->name() << "_create_link(void *obj, void* d_obj);" << endl << endl;
-    s << "private extern (C) void qtd_D_" << d_class->name() << "_delete(void *d_ptr) {" << endl
-      << "    auto d_ref = cast(QObject) d_ptr;" << endl
-      << "    d_ref.__no_real_delete = true;" << endl
-      << "    if(!d_ref.__qobject_is_deleting)"
-      << "        delete d_ref;" << endl
-      << "}" << endl << endl;
+    QString concreteArg;
+    if (d_class->isAbstract())
+        concreteArg += ", " + d_class->name() + "_ConcreteWrapper";
+
+  s << "    private static QMetaObject _staticMetaObject;" << endl
+    << "    protected static void createStaticMetaObject() {" << endl
+    << "        assert(!_staticMetaObject);" << endl
+    << "        QMetaObject base;" << endl;
+
+    if (d_class->name() != "QObject")
+    {
+        QString baseName = d_class->baseClassName();
+      s << "        if (!" << baseName << "._staticMetaObject)" << endl
+        << "            " << baseName << ".createStaticMetaObject;" << endl
+        << "        base = " << baseName << "._staticMetaObject;" << endl;
+    }
+
+  s << "        _staticMetaObject = new QMetaObject(qtd_" << d_class->name() << "_staticMetaObject, base);"   << endl
+    << "        _staticMetaObject.construct!(" << d_class->name() << concreteArg << ");" << endl
+    << "    }" << endl << endl
+
+    << "    QMetaObject metaObject() {" << endl
+    << "        return _staticMetaObject;" << endl
+    << "    }" << endl << endl
+
+    << "    static QMetaObject staticMetaObject() {" << endl
+    << "        return _staticMetaObject;" << endl
+    << "    }" << endl << endl
+
+    << "    static " << d_class->name() << " __getObject(void* nativeId) {" << endl
+    << "        return static_cast!(" << d_class->name() << ")(_staticMetaObject.getObject(nativeId));" << endl
+    << "    }" << endl << endl
+
+    << "    static void __createEntity(void* nativeId, void* dId) {" << endl
+    << "        return qtd_" << d_class->name() << "_createEntity(nativeId, dId);" << endl
+    << "    }" << endl << endl;
 }
 
 /*
@@ -2705,16 +2705,18 @@
 {
     if(ctype->isQObject()) {
         QString type_name = ctype->name();
-        s << "return qtd_" << type_name << "_from_ptr(__qt_return_value);" << endl;
+        if (ctype->isAbstract())
+            type_name += "_ConcreteWrapper";
+        s << "return " << type_name << ".__getObject(ret);" << endl;
     } else if (ctype->isValue() && !ctype->isStructInD()) {
-        s << INDENT << "return new " << ctype->name() << "(__qt_return_value, false);" << endl;
+        s << INDENT << "return new " << ctype->name() << "(ret);" << endl;
     } else if (ctype->isVariant()) {
-        s << INDENT << "return new QVariant(__qt_return_value, false);" << endl;
+        s << INDENT << "return new QVariant(ret);" << endl;
     } else if (ctype->name() == "QModelIndex" || ctype->isStructInD()) {
-        s << INDENT << "return __qt_return_value;" << endl;
+        s << INDENT << "return ret;" << endl;
     } else if (ctype->isObject()) {
         QString type_name = ctype->name();
-        s << "return qtd_" << type_name << "_from_ptr(__qt_return_value);" << endl;
+        s << "return qtd_" << type_name << "_from_ptr(ret);" << endl;
     }
 }
 
@@ -2755,41 +2757,36 @@
     }
 }
 
-void DGenerator::writeSignalConnectors(QTextStream &s, const AbstractMetaClass *d_class, AbstractMetaFunctionList signal_funcs)
+void DGenerator::writeSignalSignatures(QTextStream &s, const AbstractMetaClass *d_class, AbstractMetaFunctionList signal_funcs)
 {
-    s << INDENT << "private static SlotConnector[" << signal_funcs.size() << "] __slotConnectors;" << endl;
-    s << INDENT << "private static SlotConnector[" << signal_funcs.size() << "] __slotDisconnectors;" << endl << endl;
-
-    s << INDENT << "protected void onSignalHandlerCreated(ref SignalHandler sh) {" << endl;
+    s << INDENT << "private const string[" << signal_funcs.size() << "] __signalSignatures = [";
     {
         Indentation indent(INDENT);
-        s << INDENT << "sh.firstSlotConnected = &onFirstSlot;" << endl;
-        s << INDENT << "sh.lastSlotDisconnected = &onLastSlot;" << endl << endl;
-
-        for(int i = 0; i < signal_funcs.size(); i++) {
-            AbstractMetaFunction *signal = signal_funcs.at(i);
-            QString sigExternName = signalExternName(d_class, signal);
-            s << INDENT << "__slotConnectors[" << i << "] = &" << sigExternName << "_connect;" << endl;
-            s << INDENT << "__slotDisconnectors[" << i << "] = &" << sigExternName << "_disconnect;" << endl;
+        for (int i = 0; i < signal_funcs.size(); ++i)
+        {            
+            if (i)
+                s << ", ";                
+            s << endl << INDENT << "    \"" << signal_funcs.at(i)->minimalSignature() << "\"";
         }
     }
-    s << INDENT << "}" << endl << endl;
-
-    s << INDENT << "private final void onFirstSlot(int signalId) {" << endl;
+    s << INDENT << "];" << endl << endl;
+
+    s << INDENT << "int signalSignature(int signalId, ref stringz signature) {" << endl;
     {
         Indentation indent(INDENT);
-        s << INDENT << "if (signalId < __slotConnectors.length) {" << endl;
-        s << INDENT << "    __slotConnectors[signalId](nativeId);" << endl;
-        s << INDENT << "}" << endl;
-    }
-    s << INDENT << "}" << endl;
-
-    s << INDENT << "private final void onLastSlot(int signalId) {" << endl;
-    {
-        Indentation indent(INDENT);
-        s << INDENT << "if (signalId < __slotDisconnectors.length) {" << endl;
-        s << INDENT << "    __slotDisconnectors[signalId](nativeId);" << endl;
-        s << INDENT << "}" << endl;
+        
+        if (d_class->name() != "QObject")
+        {
+            s << INDENT << "signalId = super.signalSignature(signalId, signature);" << endl
+              << INDENT << "if (signature)" << endl
+              << INDENT << "    return signalId;" << endl;            
+        }
+        
+        s << INDENT << "if (signalId < __signalSignatures.length)" << endl
+          << INDENT << "    signature = __signalSignatures[signalId].ptr;" << endl
+          << INDENT << "else" << endl
+          << INDENT << "    signalId -= __signalSignatures.length;" << endl
+          << INDENT << "return signalId;" << endl;
     }
     s << INDENT << "}" << endl;
 }
@@ -2854,7 +2851,7 @@
                     s << INDENT << "auto " << arg_name << "_d_qstr = QString(" << arg_name << ", true);" << endl
                       << INDENT << "string " << arg_name << "_d_ref = " << arg_name << "_d_qstr.toNativeString();";
                 } else if(type->isVariant())
-                    s << INDENT << "scope " << arg_name << "_d_ref = new QVariant(" << arg_name << ", true);";
+                    s << INDENT << "scope " << arg_name << "_d_ref = new QVariant(" << arg_name << ", QtdObjectFlags.nativeOwnership);";
                 else if (type->typeEntry()->isStructInD())
                     continue;
                 else if (!type->hasNativeId() && !(type->typeEntry()->isValue() && type->isNativePointer()))
@@ -2866,7 +2863,7 @@
                     const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(type->typeEntry());
                     if(ctype->isAbstract())
                         type_name = type_name + "_ConcreteWrapper";
-                    s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name << ", true);";
+                    s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name << ", QtdObjectFlags.nativeOwnership);";
                 }
                 else if (type->isQObject()) {
                     QString type_name = type->name();
@@ -2874,13 +2871,7 @@
                     if(ctype->isAbstract())
                         type_name = type_name + "_ConcreteWrapper";
 
-                    s << INDENT << "scope " << arg_name << "_so = new StackObject!(" << type_name << ");" << endl
-                      << INDENT << "auto " << arg_name << "_d_ref = " << arg_name << "_so(" << arg_name <<", true);" << endl
-                      << INDENT << arg_name << "_d_ref.__no_real_delete = true;";
-/*
-                    s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name <<", true);" << endl
-                      << INDENT << arg_name << "_d_ref.__no_real_delete = true;";
-*/
+                    s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name << ", QtdObjectFlags.nativeOwnership);" << endl;
                 }
                 s << endl;
             }
@@ -2959,7 +2950,7 @@
         if(f_type) {
             if(f_type->isObject() || f_type->isQObject() || f_type->isVariant() ||
                (f_type->isValue() && !f_type->typeEntry()->isStructInD())) {
-                QString native_id = "nativeId";
+                QString native_id = "__nativeId";
                 if (f_type->typeEntry()->designatedInterface())
                     native_id =  "__ptr_" + f_type->typeEntry()->designatedInterface()->name();
                 s << INDENT << "return ret_value is null? null : ret_value." << native_id << ";" << endl;
@@ -3255,34 +3246,7 @@
             }
         }
 
-        if(d_function->implementingClass()->isQObject())
-        {
-            bool hasParentArg = false;
-            AbstractMetaArgumentList arguments = d_function->arguments();
-            int arg_index = 0;
-            for (int i=0; i<arguments.count(); ++i) {
-                const AbstractMetaArgument *arg = arguments.at(i);
-                if (arg->argumentName().contains("parent", Qt::CaseInsensitive)) {
-                    arg_index = i;
-                    hasParentArg = true;
-                }
-            }
-
-            const AbstractMetaArgument *arg = arguments.at(arg_index);
-//            QString ctor_call = d_function->implementingClass()->name() == "QObject"? "this" : "super";
-            QString ctor_call = "this";
-            if (hasParentArg) {
-                s << INDENT << "bool gc_managed = " << arg->argumentName() << " is null ? true : false;" << endl
-                  << INDENT << ctor_call << "(__qt_return_value, gc_managed);" << endl;
-            } else {
-                s << INDENT << ctor_call << "(__qt_return_value, true);" << endl;
-            }
-
-            // creating a link object associated with the current QObject for signal handling and metadata
-            s << INDENT << "qtd_" << d_function->ownerClass()->name() << "_create_link(this.nativeId, cast(void*) this);" << endl;
-        }
-        else
-            s << INDENT << "this(__qt_return_value);" << endl;
+        s << INDENT << "this(ret);" << endl;
     }
     s << INDENT << "}" << endl << endl;
 
@@ -3353,7 +3317,7 @@
             s << endl
               << "    @Override" << endl
               << "    public String toString() {" << endl
-              << "        if (nativeId() == 0)" << endl
+              << "        if (__nativeId == 0)" << endl
               << "            throw new QNoNativeResourcesException(\"Function call on incomplete object of type: \" +getClass().getName());" << endl
               << "        return __qt_toString(nativeId());" << endl
               << "    }" << endl