changeset 257:17b5e13364b7 lifetime

(none)
author maxter
date Wed, 16 Sep 2009 13:56:02 +0000
parents b1abe7f57321
children 1da8870e9a62
files build/core.txt cmake/FindD.cmake cpp/qt_core/QVariant_shell.h cpp/qt_qtd/qtd_core.cpp generator/CMakeLists.txt generator/abstractmetabuilder.cpp generator/abstractmetalang.cpp generator/abstractmetalang.h generator/cppgenerator.cpp generator/cppheadergenerator.cpp generator/cppimplgenerator.cpp generator/cppimplgenerator.h generator/dgenerator.cpp generator/dgenerator.h generator/generator.cpp generator/typesystem.h generator/typesystem_core-java.java generator/typesystem_core.xml include/qtd_core.h mini/test1/build mini/test1/main.d qt/QGlobal.d qt/d1/qt/core/QVariant.d
diffstat 23 files changed, 688 insertions(+), 359 deletions(-) [+]
line wrap: on
line diff
--- a/build/core.txt	Mon Aug 31 12:07:28 2009 +0000
+++ b/build/core.txt	Wed Sep 16 13:56:02 2009 +0000
@@ -50,6 +50,8 @@
     QUrl
     QAbstractItemModel
     QAbstractFileEngine
+    QAbstractFileEngineIterator
+    QFSFileEngine
     QFile
     QDir
     QFileInfo
--- a/cmake/FindD.cmake	Mon Aug 31 12:07:28 2009 +0000
+++ b/cmake/FindD.cmake	Wed Sep 16 13:56:02 2009 +0000
@@ -70,9 +70,9 @@
 endif(NOT ONE_BUILD_COMMAND)
 
 ## Specific flags for build configurations.
-## TODO: Add another targets.
+## TODO: Add other targets.
 set(D_RELEASE_FLAGS -O -release)
-set(D_DEBUG_FLAGS -g )
+set(D_DEBUG_FLAGS -g -debug=QtdVerbose)
 if(D_IS_LLVM)
     set(D_RELEASE_FLAGS ${D_RELEASE_FLAGS} -enable-inlining)
     set(D_DEBUG_FLAGS ${D_DEBUG_FLAGS} -d-debug)
--- a/cpp/qt_core/QVariant_shell.h	Mon Aug 31 12:07:28 2009 +0000
+++ b/cpp/qt_core/QVariant_shell.h	Wed Sep 16 13:56:02 2009 +0000
@@ -2,7 +2,7 @@
 #define QVARIANT_SHELL_H
 
 #include <QtCore/QHash>
-#include <QObjectEntity.h>
+#include <qtd_core.h>
 #include <qvariant.h>
 
 #include <QVariant>
--- a/cpp/qt_qtd/qtd_core.cpp	Mon Aug 31 12:07:28 2009 +0000
+++ b/cpp/qt_qtd/qtd_core.cpp	Wed Sep 16 13:56:02 2009 +0000
@@ -11,11 +11,16 @@
 
 #include "qtd_core.h"
 #include <iostream>
-
+#include <QCryptographicHash>
 
-extern "C" DLL_PUBLIC void* qtd_qobject(void* parent)
+extern "C" DLL_PUBLIC void* qtd_test_Object()
 {
-    return new QObject((QObject*)parent);
+    return new QCryptographicHash(QCryptographicHash::Md5);
+}
+
+extern "C" DLL_PUBLIC void qtd_test_delete_Object(void* obj)
+{
+    delete (QCryptographicHash*)obj;
 }
 
 extern "C" DLL_PUBLIC QModelIndex qtd_to_QModelIndex(QModelIndexAccessor mia)
@@ -48,10 +53,13 @@
 #ifdef CPP_SHARED
 QTD_EXPORT_VAR(qtd_toUtf8);
 QTD_EXPORT_VAR(qtd_dummy);
+QTD_EXPORT_VAR(qtd_delete_d_object);
 
-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 dummy
+    , pfunc_abstr del_d_obj) {
     QTD_EXPORT_VAR_SET(qtd_toUtf8, d_func);
     QTD_EXPORT_VAR_SET(qtd_dummy, dummy);
+    QTD_EXPORT_VAR_SET(qtd_delete_d_object, del_d_obj);
     //std::cout << "qtd_core initialized" << std::endl;
 }
 #endif
@@ -73,3 +81,31 @@
 {
     return qUnregisterResourceData(version, tree, name, data);
 }
+
+
+QtD_QObjectEntity::QtD_QObjectEntity(QObject *qObject, void *dId) : QtD_Entity(dId)
+{
+    qObject->setUserData(userDataId, this);
+}
+
+QtD_QObjectEntity::~QtD_QObjectEntity()
+{
+    if (dId)
+        destroyEntity();
+}
+
+void QtD_QObjectEntity::destroyEntity(QObject *qObject)
+{
+    Q_ASSERT(dId);
+    qtd_delete_d_object(dId);
+    if (qObject)
+    {
+        qObject->setUserData(userDataId, NULL);
+        dId = NULL;
+    }
+}
+
+QtD_QObjectEntity* QtD_QObjectEntity::getQObjectEntity(const QObject *qObject)
+{
+    return static_cast<QtD_QObjectEntity*>(qObject->userData(userDataId));
+}
--- a/generator/CMakeLists.txt	Mon Aug 31 12:07:28 2009 +0000
+++ b/generator/CMakeLists.txt	Wed Sep 16 13:56:02 2009 +0000
@@ -251,7 +251,7 @@
 	    --source-directory=${CMAKE_SOURCE_DIR}/generator 
 	    qtjambi_masterinclude.h  
 	    ${CMAKE_BINARY_DIR}/CMakeFiles/build.txt
-	COMMENT "Generating binding..."
+	COMMENT "Generating binding... ${inc_paths} ${GEN_OPT}"
 	DEPENDS ${gen_sources} ${CMAKE_BINARY_DIR}/CMakeFiles/build.txt
 )       
 add_custom_target(dgen ALL DEPENDS ${dgen_impl} COMMENT "")     
--- a/generator/abstractmetabuilder.cpp	Mon Aug 31 12:07:28 2009 +0000
+++ b/generator/abstractmetabuilder.cpp	Wed Sep 16 13:56:02 2009 +0000
@@ -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);
+            if (meta_function->isDestructor() && !meta_function->isFinal())                            
+                meta_class->setHasVirtualDestructor(true);            
 
             if (!meta_function->isDestructor()
                 && !meta_function->isInvalid()
@@ -1563,8 +1561,8 @@
 
     TypeInfo function_type = function_item->type();
     if (function_name.startsWith('~')) {
-        meta_function->setFunctionType(AbstractMetaFunction::DestructorFunction);
-        meta_function->setInvalid(true);
+        meta_function->setFunctionType(AbstractMetaFunction::DestructorFunction);              
+        //meta_function->setInvalid(true);
     } else if (strip_template_args(function_name) == stripped_class_name) {
         meta_function->setFunctionType(AbstractMetaFunction::ConstructorFunction);
         meta_function->setName(m_current_class->name());
--- a/generator/abstractmetalang.cpp	Mon Aug 31 12:07:28 2009 +0000
+++ b/generator/abstractmetalang.cpp	Wed Sep 16 13:56:02 2009 +0000
@@ -42,6 +42,7 @@
 #include "abstractmetalang.h"
 #include "reporthandler.h"
 #include "jumptable.h"
+#include <iostream>
 
 /*******************************************************************************
  * AbstractMetaType
@@ -1110,7 +1111,8 @@
         m_functions << function;
         qSort(m_functions.begin(), m_functions.end(), function_sorter);
     }
-
+    else
+        qFatal("blah");
 
     m_has_virtual_slots |= function->isVirtualSlot();
     m_has_virtuals |= !function->isFinal() || function->isVirtualSlot();
@@ -1160,11 +1162,12 @@
 bool AbstractMetaClass::generateShellClass() const
 {
     return m_force_shell_class ||
-        (!isFinal()
-         && (hasVirtualFunctions()
-             || hasProtectedFunctions()
-             || hasFieldAccessors()
-             || typeEntry()->isObject())); // qtd2 for being more consistent
+        m_has_virtual_destructor ||
+    (!isFinal()
+        && (hasVirtualFunctions()
+        || hasProtectedFunctions()
+        || hasFieldAccessors()
+        || typeEntry()->isObject())); // qtd2 for being more consistent
 }
 
 QPropertySpec *AbstractMetaClass::propertySpecForRead(const QString &name) const
@@ -1323,6 +1326,11 @@
     return queryFunctions(Constructors).size() != 0;
 }
 
+bool AbstractMetaClass::isPolymorphic()
+{
+    return typeEntry()->isObject() && m_has_virtual_destructor;
+}
+
 void AbstractMetaClass::addDefaultConstructor()
 {
     AbstractMetaFunction *f = new AbstractMetaFunction;
@@ -1339,7 +1347,7 @@
     f->setImplementingClass(this);
     f->setOriginalAttributes(f->attributes());
 
-    addFunction(f);
+    /*addFunction*/(f);
 }
 
 bool AbstractMetaClass::hasFunction(const AbstractMetaFunction *f) const
--- a/generator/abstractmetalang.h	Mon Aug 31 12:07:28 2009 +0000
+++ b/generator/abstractmetalang.h	Wed Sep 16 13:56:02 2009 +0000
@@ -685,6 +685,7 @@
           m_functions_fixed(false),
           m_has_public_destructor(true),
           m_force_shell_class(false),
+          m_has_virtual_destructor(false),
           m_has_hash_function(false),
           m_has_equals_operator(false),
           m_has_clone_operator(false),
@@ -755,9 +756,17 @@
 
     QString baseClassName() const { return m_base_class ? m_base_class->name() : QString(); }
 
-    AbstractMetaClass *baseClass() const { return m_base_class; }
+    AbstractMetaClass *baseClass() const { return m_base_class;}
     void setBaseClass(AbstractMetaClass *base_class) { m_base_class = base_class; }
 
+    const AbstractMetaClass *rootClass() const
+    {
+        const AbstractMetaClass *root = this;
+        while (root->baseClass())
+            root = root->baseClass();
+        return root;
+    }
+
     const AbstractMetaClass *enclosingClass() const { return m_enclosing_class; }
     void setEnclosingClass(AbstractMetaClass *cl) { m_enclosing_class = cl; }
 
@@ -775,8 +784,10 @@
     void setForceShellClass(bool on) { m_force_shell_class = on; }
     bool generateShellClass() const;
 
-    bool hasVirtualSlots() const { return m_has_virtual_slots; }
+    bool hasVirtualSlots() const { return m_has_virtual_slots; }       
     bool hasVirtualFunctions() const { return !isFinal() && m_has_virtuals; }
+    bool hasVirtualDestructor() const { return m_has_virtual_destructor; }
+    bool setHasVirtualDestructor(bool value) { m_has_virtual_destructor = value; }
     bool hasProtectedFunctions() const;
 
     QList<TypeEntry *> templateArguments() const { return m_template_args; }
@@ -843,6 +854,8 @@
 
     void setTypeAlias(bool typeAlias) { m_is_type_alias = typeAlias; }
     bool isTypeAlias() const { return m_is_type_alias; }
+    
+    bool isPolymorphic();
 
     const QStringList &depends() { return m_type_entry->depends(); }
 
@@ -857,6 +870,7 @@
     uint m_functions_fixed : 1;
     uint m_has_public_destructor : 1;
     uint m_force_shell_class : 1;
+    uint m_has_virtual_destructor : 1; 
     uint m_has_hash_function : 1;
     uint m_has_equals_operator : 1;
     uint m_has_clone_operator :1;
--- a/generator/cppgenerator.cpp	Mon Aug 31 12:07:28 2009 +0000
+++ b/generator/cppgenerator.cpp	Wed Sep 16 13:56:02 2009 +0000
@@ -230,7 +230,7 @@
     s << "(";
     const AbstractMetaClass *owner = java_function->ownerClass();
 
-    bool has_d_ptr = java_function->isConstructor() && owner && (owner->hasVirtualFunctions()/* || owner->typeEntry()->isObject()*/ );
+    bool has_d_ptr = java_function->isConstructor() && owner && owner->typeEntry()->isObject();
     const AbstractMetaArgumentList arg_list = java_function->arguments();
     if (has_d_ptr) {
         s << "void *d_ptr";
--- a/generator/cppheadergenerator.cpp	Mon Aug 31 12:07:28 2009 +0000
+++ b/generator/cppheadergenerator.cpp	Wed Sep 16 13:56:02 2009 +0000
@@ -126,7 +126,7 @@
       << "#define " << include_block << endl << endl
 //      << "#include <qtjambi_core.h>" << endl
       << "#include <QtCore/QHash>" << endl
-      << "#include <QObjectEntity.h>" << endl;
+      << "#include <qtd_core.h>" << endl;
 
     Include inc = java_class->typeEntry()->include();
     s << "#include ";
@@ -180,7 +180,7 @@
       << " : public " << java_class->qualifiedCppName();
     if (java_class->isQObject())
         s << ", public QtD_QObjectEntity";
-    else if(java_class->hasVirtualFunctions())
+    else if (java_class->hasVirtualFunctions())
         s << ", public QtD_Entity";
     s << endl  << "{" << endl;
 
@@ -207,9 +207,10 @@
         if (function->isConstructor() && !function->isPrivate())
             writeFunction(s, function);
     }
-
-    s << "    ~" << shellClassName(java_class) << "();" << endl;
-    s << endl;
+    
+    if (java_class->hasVirtualFunctions())
+        s << "    ~" << shellClassName(java_class) << "();" << endl << endl;
+    
 
     // All functions in original class that should be reimplemented in shell class
     AbstractMetaFunctionList shell_functions = java_class->functionsInShellClass();
--- a/generator/cppimplgenerator.cpp	Mon Aug 31 12:07:28 2009 +0000
+++ b/generator/cppimplgenerator.cpp	Wed Sep 16 13:56:02 2009 +0000
@@ -541,18 +541,17 @@
 #endif
 */
     if (shellInclude)
-        s << "#include \"" << java_class->name() << "_shell" << ".h\"" << endl;
+    {
+        s << "#include \"" << java_class->name() << "_shell" << ".h\"" << endl
+          << "#include <typeinfo>" << endl;
+    }
+        
 /* qtd
     if (java_class->isQObject())
         s << "#include <qtdynamicmetaobject.h>" << endl;
 */
-    if (java_class->isQObject())
-        s << "#include <QObjectEntity.h>" << endl;
-
     s << "#include <iostream>" << endl;
 
-
-
     Include inc = java_class->typeEntry()->include();
     if (!inc.name.isEmpty()) {
         s << "#include ";
@@ -589,24 +588,27 @@
     writeDefaultConstructedValues(s, java_class);
 
     if (hasCustomDestructor(java_class)) */
-    if (!java_class->isQObject())
-        writeFinalDestructor(s, java_class);
+   
+    if (java_class->hasPublicDestructor() && (!java_class->baseClass() || !java_class->hasVirtualFunctions()))
+        writeDestructor(s, java_class);
 
     if (java_class->isQObject())
         writeSignalsHandling(s, java_class);
 
     if (shellClass) {
         foreach (AbstractMetaFunction *function, java_class->functions()) {
-            if (function->isConstructor() && !function->isPrivate())
+            if (function->isConstructor())
                 writeShellConstructor(s, function);
         }
-        writeShellDestructor(s, java_class);
-
-        if (!java_class->isQObject() && java_class->hasVirtualFunctions())
-            writeQtdEntityFunction(s, java_class);
+        
+        if (java_class->typeEntry()->isObject())
+            writeShellDestructor(s, java_class);
 
         if (java_class->isQObject())
             writeQObjectFunctions(s, java_class);
+        else if (java_class->typeEntry()->isObject())
+            writeObjectFunctions(s, java_class);    
+            
 
         // Virtual overrides
         s << "// Virtual overrides" << endl;
@@ -1386,9 +1388,10 @@
             s << ", ";
     }
     s << ")";
+    
     if (cls->isQObject())
         s << "," << endl << "      QtD_QObjectEntity(this, d_ptr)";
-    else if (cls->hasVirtualFunctions())
+    else if (cls->typeEntry()->isObject() && cls->hasVirtualFunctions())
         s << "," << endl << "      QtD_Entity(d_ptr)";
 /* qtd        s << "    m_meta_object(0)," << endl;
     s << "      m_vtable(0)," << endl
@@ -1402,7 +1405,7 @@
         writeCodeInjections(s, java_function, cls, CodeSnip::Beginning, TypeSystem::ShellCode);
         writeCodeInjections(s, java_function, cls, CodeSnip::End, TypeSystem::ShellCode);
     }
-    s << "}" << endl << endl;
+    s << "}" << endl << endl;  
 }
 
 void CppImplGenerator::writeShellDestructor(QTextStream &s, const AbstractMetaClass *java_class)
@@ -1411,9 +1414,11 @@
       << shellClassName(java_class) << "()" << endl
       << "{" << endl;
     {
-        //s << "    std::cout << \"In shell destructor of " << java_class->name() << ", nativeId: \" << this << std::endl;";  
+        s << "    std::cout << \"In shell destructor of " << java_class->name() << ", nativeId: \" << this << std::endl;";
         if (java_class->isQObject())
-            s << "    destroyEntity(this);";
+            s << "    destroyEntity(this);" << endl;
+        else
+            s << "    qtd_delete_d_object(dId);" << endl;
     }
     s << "}" << endl << endl;
 }
@@ -1729,19 +1734,43 @@
     s << "}" << endl << endl;
 }
 
-void CppImplGenerator::writeQtdEntityFunction(QTextStream &s, const AbstractMetaClass *java_class)
+void CppImplGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *java_class)
 {
-    s << "extern \"C\" DLL_PUBLIC void *__" << java_class->name() << "_entity(void *q_ptr)" << endl;
+    s << "extern \"C\" DLL_PUBLIC const void* qtd_" << java_class->name() << "_staticTypeId()" << endl;
     s << "{" << endl;
     {
         Indentation indent(INDENT);
-            s << INDENT << "QtD_Entity* a = dynamic_cast<QtD_Entity*>((" << java_class->qualifiedCppName() << "*)q_ptr);" << endl
-              << INDENT << "if (a != NULL)" << endl
-              << INDENT << "    return a->dId;" << endl
-              << INDENT << "else" << endl
-              << INDENT << "    return NULL;" << endl;
+            s << INDENT << "return &typeid(" << java_class->qualifiedCppName() << ");" << endl;
     }
     s << "}" << endl << endl;
+        
+    if (java_class->hasVirtualFunctions())
+    {
+        if (!java_class->baseClass())
+        {      
+            s << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->name() << "_dId(void *q_ptr)" << endl;
+            s << "{" << endl;
+            {
+                Indentation indent(INDENT);
+                    s << INDENT << "QtD_Entity* a = dynamic_cast<QtD_Entity*>((" << java_class->qualifiedCppName() << "*)q_ptr);" << endl
+                    << INDENT << "if (a != NULL)" << endl
+                    << INDENT << "    return a->dId;" << endl
+                    << INDENT << "else" << endl
+                    << INDENT << "    return NULL;" << endl;
+            }
+            s << "}" << endl << endl;
+            
+            s << "extern \"C\" DLL_PUBLIC const void* qtd_" << java_class->name() << "_typeId(void *nativeId)" << endl;
+            s << "{" << endl;
+            {
+                Indentation indent(INDENT);
+                    s << INDENT << "return &typeid((" << java_class->qualifiedCppName() << "*)nativeId);" << endl;
+            }
+            s << "}" << endl << endl;
+        }
+        else
+            s << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->rootClass()->name() << "_dId(void *q_ptr);" << endl;            
+    }
 }
 
 void CppImplGenerator::writeVirtualFunctionOverride(QTextStream &s,
@@ -1863,9 +1892,9 @@
 */
     uint nativeArgCount = 0;
     const AbstractMetaClass *cls = java_function->ownerClass();
+          
     if (java_function->isConstructor() &&
-        ( cls->hasVirtualFunctions()
-        || cls->typeEntry()->isObject() ) )
+        cls->typeEntry()->isObject())
     {
         s << "void *d_ptr";
         nativeArgCount++;
@@ -2057,7 +2086,8 @@
         foreach (const AbstractMetaArgument *argument, arguments) {
             s << INDENT << "Q_UNUSED(" << argument->indexedName() << ")" << endl;
         }
-        s << INDENT << default_return_statement_qt(java_function->type()) << "";
+        s << INDENT << default_return_statement_qt(java_function->type()) << "";        
+        
     } else {
         writeFinalFunctionSetup(s, java_function, qt_object_name, cls);
 
@@ -2085,7 +2115,7 @@
                 if (java_class->isQObject())
                     s << "QtD_QObjectEntity::getQObjectEntity((QObject*)__this_nativeId) : false;" << endl;
                 else
-                    s << "__" << java_class->name() << "_entity(__this_nativeId) : false;" << endl;
+                    s << "qtd_" << java_class->rootClass()->name() << "_dId(__this_nativeId) : false;" << endl;
             } else {
                 option = OriginalName;
             }
@@ -2288,17 +2318,19 @@
     }
 }
 
-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
-          << INDENT << "{" << endl;
-        {
-            s << INDENT << "delete (" << shellClassName(cls) << " *)ptr;" << endl;
-        }
-
-        s << INDENT << "}" << endl << endl;
+void CppImplGenerator::writeDestructor(QTextStream &s, const AbstractMetaClass *cls)
+{    
+    if (!cls->hasConstructors())
+        return;
+
+    s << INDENT << "extern \"C\" DLL_PUBLIC void qtd_" << cls->name() << "_destructor(void *ptr)" << endl
+        << INDENT << "{" << endl;
+    {
+        QString className = cls->hasVirtualFunctions() ? cls->typeEntry()->name() : shellClassName(cls);
+        s << INDENT << "delete (" << className << " *)ptr;" << endl;
     }
+
+    s << INDENT << "}" << endl << endl;
 }
 
 void CppImplGenerator::writeFinalConstructor(QTextStream &s,
@@ -3051,7 +3083,7 @@
 //            return_type = fixCppTypeName(java_type->typeEntry()->qualifiedCppName());
         }
 /*        if( (java_type->isValue() && !java_type->typeEntry()->isStructInD())
-            || java_type->isObject() )
+//             || java_type->isObject() )
             s << INDENT << return_type << " *" << java_name << " = (" << return_type << "*) ";
         else*/
             s << INDENT << return_type << " " << java_name << " = (" << return_type << ") ";
@@ -3510,7 +3542,7 @@
 
     int written_arguments = 0;
     const AbstractMetaClass *cls = java_function->ownerClass();
-    if (java_function->isConstructor() && cls->hasVirtualFunctions()) {
+    if (java_function->isConstructor() && cls->typeEntry()->isObject()) {
         s << "d_ptr";
         written_arguments++;
     }
--- a/generator/cppimplgenerator.h	Mon Aug 31 12:07:28 2009 +0000
+++ b/generator/cppimplgenerator.h	Wed Sep 16 13:56:02 2009 +0000
@@ -105,11 +105,12 @@
                                     const AbstractMetaFunction *java_function,
                                     const AbstractMetaClass *java_class,
                                     Option options = NoOption);
-    void writeFinalDestructor(QTextStream &s, const AbstractMetaClass *cls);
+    void writeDestructor(QTextStream &s, const AbstractMetaClass *cls);
     void writeFinalConstructor(QTextStream &s,
                                const AbstractMetaFunction *java_function,
                                const QString &qt_object_name,
                                const QString &java_object_name);
+    void writeObjectFunctions(QTextStream &s, const AbstractMetaClass *java_class);
     void writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *java_class);
     void writeFunctionCall(QTextStream &s,
                            const QString &variable_name,
--- a/generator/dgenerator.cpp	Mon Aug 31 12:07:28 2009 +0000
+++ b/generator/dgenerator.cpp	Wed Sep 16 13:56:02 2009 +0000
@@ -61,7 +61,7 @@
       m_docs_enabled(false),
       m_native_jump_table(false),
       m_recursive(0),
-      m_isRecursive(false)
+      m_isRecursive(false)      
 {
     excludedTypes << "long long" << "bool" << "int" << "QString" << "char" << "WId"
                   << "unsigned char" << "uint" << "double" << "short" << "float"
@@ -479,9 +479,9 @@
 static QString function_call_for_ownership(TypeSystem::Ownership owner)
 {  
     if (owner == TypeSystem::CppOwnership) {
-        return "__setFlags(QtdObjectFlags.nativeOwnership, true)";
+        return "__nativeOwnership = true";
     } else /* qtd 2 if (owner == TypeSystem::TargetLangOwnership) */ {
-        return "__setFlags(QtdObjectFlags.nativeOwnership, false)";
+        return "__nativeOwnership = false";
     }/* else if (owner == TypeSystem::DefaultOwnership) {
         return "__no_real_delete = false";
 
@@ -639,6 +639,7 @@
         }
     }
 
+    /*
     QList<ReferenceCount> referenceCounts;
     for (int i=0; i<arguments.size() + 1; ++i) {
         referenceCounts = d_function->referenceCounts(d_function->implementingClass(),
@@ -649,6 +650,8 @@
     }
 
     referenceCounts = d_function->referenceCounts(d_function->implementingClass(), 0);
+    */
+    
     AbstractMetaType *return_type = d_function->type();
     QString new_return_type = QString(d_function->typeReplaced(0)).replace('$', '.');
     bool has_return_type = new_return_type != "void"
@@ -880,7 +883,7 @@
             s << INDENT << "this." << function_call_for_ownership(owner) << ";" << endl;
     }
 
-    // return value marschalling
+    // return value marshalling
     if(return_type) {
         if (!returnImmediately && !d_function->storeResult()) {
             s << INDENT;
@@ -892,37 +895,36 @@
             s << " __d_return_value = ";
         }
 
-        if ( ( has_return_type && d_function->argumentReplaced(0).isEmpty() )) // qtd
-        {
-            if(return_type->isQObject())
-                s << return_type->name() << ".__getObject(ret);" << endl;
-        }
-
-        if (return_type->isValue() && !return_type->typeEntry()->isStructInD())
+        if(return_type->isQObject())
+            s << return_type->name() << ".__wrap(ret);" << endl;
+        
+
+        if (return_type->isValue() && !return_type->typeEntry()->isStructInD()
+            || return_type->isNativePointer() && return_type->typeEntry()->isValue()
+            || return_type->name() == "QVariant")
             s << "new " << return_type->name() << "(ret);" << endl;
-
-        if (return_type->isVariant())
-            s << "new QVariant(ret);" << endl;
-
-        if (return_type->isNativePointer() && return_type->typeEntry()->isValue())
-            s << "new " << return_type->name() << "(ret, QtdObjectFlags.nativeOwnership);" << endl;
-
+        
         if (return_type->isObject()) {
             if(d_function->storeResult())
-                s << INDENT << QString("__m_%1.__nativeId = ret;").arg(d_function->name()) << endl
-                  << INDENT << QString("return __m_%1;").arg(d_function->name()) << endl;
+            {
+                QString fieldName = QString("__m_%1;").arg(d_function->name());
+                s << INDENT << "if (!" << fieldName << " || " << fieldName << ".__nativeId != ret) {" << endl
+                  << INDENT << "    " << fieldName << " = " << return_type->name() << ".__wrap(ret);" << endl
+                  << INDENT << "return " << fieldName << ";" << endl;
+            }
             else
-                s << "qtd_" << return_type->name() << "_from_ptr(ret);" << endl;
-            s << endl;
+                s << return_type->name() << ".__wrap(ret);" << endl;
         }
 
         if (return_type->isArray()) {
             s << "ret[0 .. " << return_type->arrayElementCount() << "];" << endl;
         }
 
+        /*
         foreach (ReferenceCount referenceCount, referenceCounts) {
             writeReferenceCount(s, referenceCount, "__d_return_value");
         }
+        */
 
         if (!returnImmediately && !d_function->storeResult())
             s << INDENT << "return __d_return_value;" << endl;
@@ -1682,26 +1684,19 @@
     if (!d_class->hasConstructors())
         return;
 
-    bool isTheQObject = d_class->name() == "QObject";
-    if (isTheQObject || !d_class->isQObject())
-    {
-        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 << "}" << endl << endl;
-    }
+    s << "    override void __deleteNative() {" << endl
+        << "        qtd_" << d_class->name() << "_destructor(__nativeId);" << endl          
+        << "    }" << endl;
 }
 
-void DGenerator::writeFlagsSetter(QTextStream &s, const AbstractMetaClass *d_class)
+void DGenerator::writeOwnershipSetter(QTextStream &s, const AbstractMetaClass *d_class)
 {
     if (d_class->isInterface() || d_class->isNamespace())
-        s << INDENT << "void __setFlags(QtdObjectFlags flags, bool val);";
-    else // COMPILER BUG:
-        s << INDENT << "void __setFlags(QtdObjectFlags flags, bool val) { super.__setFlags(flags, val); }";
+        s << INDENT << "void __nativeOwnership(bool value);";
+    else if (d_class->typeEntry()->isObject())
+    {// COMPILER BUG:
+        s << INDENT << "void __nativeOwnership(bool value) { super.__nativeOwnership = value; }";
+    }
 }
 
 void DGenerator::writeSignalHandlers(QTextStream &s, const AbstractMetaClass *d_class)
@@ -1763,7 +1758,7 @@
                     if(ctype->isAbstract())
                         type_name = type_name + "_ConcreteWrapper";
                     s << INDENT << "scope " << arg_name << " = new " << type_name
-                                << "(cast(void*)(" << arg_ptr << "), QtdObjectFlags.nativeOwnership);" << endl;
+                                << "(cast(void*)(" << arg_ptr << "), QtdObjectFlags.skipNativeDelete);" << endl;
                 }
                 s << endl;
             }
@@ -1785,7 +1780,7 @@
 
 void DGenerator::write(QTextStream &s, const AbstractMetaClass *d_class)
 {
-    ReportHandler::debugSparse("Generating class: " + d_class->fullName());
+    ReportHandler::debugSparse("Generating class: " + d_class->fullName());    
 
     bool fakeClass = d_class->attributes() & AbstractMetaAttributes::Fake;
 
@@ -1795,7 +1790,7 @@
     auxFile.isDone = true;
     auxFile.stream << "module " << auxModName << ";" << endl << endl;
 
-    bool staticInit = d_class->isQObject() || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface());
+    bool staticInit = (d_class->typeEntry()->isObject() && d_class->hasVirtualFunctions()) || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface());
     if (staticInit)
     {
         auxFile.isDone = false;
@@ -1901,17 +1896,17 @@
     if (!m_isRecursive) {
         s << "public import qt.QGlobal;" << endl
           << "public import qt.core.Qt;" << endl
-          << "private import qt.QtdObject;" << endl
+          << "public 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
-              << "public import qt.core.QMetaObject;" << endl
-              << "public import qt.qtd.Traits;" << endl;
-
+            s << "public import qt.Signal;" << endl;
             if (d_class->name() != "QObject")
                 s << "public import qt.core.QObject;" << endl;
         }
+        
+        if (d_class->typeEntry()->isObject() && d_class->hasVirtualFunctions())
+            s << "public import qt.core.QMetaObject;" << endl;
 
         // qtd2 hack!
         if (d_class->name() == "QCoreApplication")
@@ -2003,12 +1998,15 @@
     }
 
     if (!d_class->isNamespace() && !d_class->isInterface()) {
-        if (!d_class->baseClassName().isEmpty()) {
-            s << " : " << d_class->baseClass()->name();
-        } else {
-            QString sc = type->defaultSuperclass();
-            if ((sc != d_class->name()) && !sc.isEmpty())
-                s << " : " << sc;
+        s << " : ";
+        if (d_class->baseClass()) {            
+            s << d_class->baseClass()->name();
+        } else {            
+            if (d_class->typeEntry()->isValue())
+                s << "QtdObjectBase";
+            else if (d_class->typeEntry()->isObject())
+                s << "QtdObject";
+                
         }
     }/* qtd else if (d_class->isInterface()) {
         s << " extends QtJambiInterface";
@@ -2194,7 +2192,6 @@
     if(d_class->isInterface())
         s << endl << INDENT << "public void* __ptr_" << d_class->name() << "();" << endl << endl;
 
-
     s << "// Field accessors" << endl;
     // Field accessors
     AbstractMetaFieldList fields = d_class->fields();
@@ -2203,38 +2200,20 @@
             writeFieldAccessors(s, field);
     }
 
-/* qtd
-
-    // the static fromNativePointer function...
-    if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) {
-        s << endl
-          << INDENT << "public static native " << d_class->name() << " fromNativePointer("
-          << "QNativePointer nativePointer);" << endl;
-    }
-
-    if (d_class->isQObject()) {
-        s << endl;
-        if (TypeDatabase::instance()->includeEclipseWarnings())
-            s << INDENT << "@SuppressWarnings(\"unused\")" << endl;
-
-        s << INDENT << "private static native long originalMetaObject();" << endl;
+    if (d_class->typeEntry()->isObject() && d_class->hasVirtualFunctions())
+    {
+        if (d_class->isQObject())
+            writeQObjectFunctions(s, d_class);
+        else
+            writeObjectFunctions(s, d_class);
+    
+        s << "    static QtdObjectBase __createWrapper(void* nativeId, QtdObjectFlags flags) {" << endl
+          << "        return new(flags) " << d_class->name() << "(nativeId, flags);" << endl
+          << "    }" << endl << endl;
     }
-
-    // The __qt_signalInitialization() function
-    if (signal_funcs.size() > 0) {
-        s << endl
-          << INDENT << "@Override" << endl
-          << INDENT << "@QtBlockedSlot protected boolean __qt_signalInitialization(String name) {" << endl
-          << INDENT << "    return (__qt_signalInitialization(nativeId(), name)" << endl
-          << INDENT << "            || super.__qt_signalInitialization(name));" << endl
-          << INDENT << "}" << endl
-          << endl
-          << INDENT << "@QtBlockedSlot" << endl
-          << INDENT << "private native boolean __qt_signalInitialization(long ptr, String name);" << endl;
-    }
-*/
-    if (d_class->isQObject())
-        writeQObjectFunctions(s, d_class);
+    
+    if (d_class->hasPublicDestructor() && (!d_class->baseClass() || !d_class->hasVirtualFunctions()))
+        writeDestructor(s, d_class);
 
     // Add dummy constructor for use when constructing subclasses
     if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) {
@@ -2244,20 +2223,19 @@
 
 
         Indentation indent(INDENT);
-
-        s << "(void* native_id, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl
-          << INDENT << "super(native_id, flags);" << endl;
-
+        
+       
+        QString flags = d_class->hasVirtualFunctions() && d_class->typeEntry()->isObject() ? "QtdObjectFlags.hasDId" : "QtdObjectFlags.none";
+        s << "(void* nativeId, QtdObjectFlags flags = " << flags << ") {" << endl
+        << INDENT << "super(nativeId, flags);" << endl;
+        
         if (d_class->name() == "QObject")
         {
-            // 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;
+            s << INDENT << "if (!(__flags & QtdObjectFlags.hasDId))" << endl
+            << INDENT << "    __createEntity;" << endl;
         }
-
+        
+        
         /*
         if (cpp_shared) {
             if (d_class->generateShellClass() && !d_class->isInterface())
@@ -2266,6 +2244,7 @@
         }
         */
 
+        
         // customized store-result instances
         d_funcs = d_class->functionsInTargetLang();
         for (int i=0; i<d_funcs.size(); ++i) {
@@ -2285,10 +2264,7 @@
                 if(ctype->isAbstract())
                     type_name = type_name + "_ConcreteWrapper";
 
-                s << INDENT << "    __m_" << d_function->name() << " = new "
-                        << type_name << "(cast(void*)null);" << endl;
-                if (d_function->type()->isQObject())
-                    s << INDENT << "    __m_" << d_function->name() << ".__setFlags(QtdObjectFlags.nativeOwnership, true);" << endl;
+                s << INDENT << "    __m_" << d_function->name() << ";" << endl;                
             }
         }
 
@@ -2340,9 +2316,7 @@
                 s << INDENT << "private void* __m_ptr_" << iface->name() << ";" << endl
                   << INDENT << "public void* __ptr_" << iface->name() << "() { return __m_ptr_" << iface->name() << "; }" << endl << endl;
             }
-        }
-
-        writeDestructor(s, d_class);
+        }       
     }
 
 /* qtd
@@ -2371,7 +2345,7 @@
 
 /* qtd    writeJavaLangObjectOverrideFunctions(s, d_class);
 */
-    writeFlagsSetter(s, d_class);
+    writeOwnershipSetter(s, d_class);
     s << "// Injected code in class" << endl;
     writeExtraFunctions(s, d_class);
 // qtd2    writeToStringFunction(s, d_class);
@@ -2411,9 +2385,8 @@
         s << INDENT << "public class " << d_class->name() << "_ConcreteWrapper : " << d_class->name() << " {" << endl;
 
         {
-            Indentation indent(INDENT);
-            QString hasShellFlag = d_class->generateShellClass() ? " | QtdObjectFlags.hasShell" : "";
-            s << INDENT << "public this(void* native_id, QtdObjectFlags flags = QtdObjectFlags.nativeOwnership) {" << endl
+            Indentation indent(INDENT);            
+            s << INDENT << "public this(void* native_id, QtdObjectFlags flags) {" << endl
               << INDENT << "    super(native_id, flags);" << endl << endl;
             
             /******************!!!DUPLICATE!!!*********************/
@@ -2432,9 +2405,7 @@
                     if(ctype->isAbstract())
                         type_name = type_name + "_ConcreteWrapper";
                     s << INDENT << "    __m_" << d_function->name() << " = new "
-                            << type_name << "(cast(void*)null);" << endl;
-                    if (d_function->type()->isQObject())
-                        s << INDENT << "    __m_" << d_function->name() << ".__setFlags(QtdObjectFlags.nativeOwnership, true);" << endl;
+                            << type_name << "(cast(void*)null);" << endl;                    
                 }
             }
 
@@ -2489,18 +2460,22 @@
         s  << INDENT << "}" << endl << endl;
     }
 
-    if (d_class->generateShellClass()) { // qtd2
-        if (d_class->hasVirtualFunctions()
-            && (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->typeEntry()->isObject() && d_class->hasVirtualFunctions())
+    {
+        if (!d_class->typeEntry()->isQObject())
+        {
+            s << "extern(C) void* qtd_" << d_class->name() << "_dId(void *q_ptr);" << endl << endl;
+            s << "extern(C) void* qtd_" << d_class->name() << "_typeId(void* nativeId);" << endl;
+        }
+        
+        s << "extern(C) void* qtd_" << d_class->name() << "_staticTypeId();" << endl;
     }
 
-
 //    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 << endl;
+//        writeConversionFunction(s, d_class);
+
+    if (d_class->hasConstructors())
+        s << "extern(C) void qtd_" << d_class->name() << "_destructor(void *ptr);" << endl << endl;
 
     // qtd
     s << endl << "// C wrappers" << endl;
@@ -2525,7 +2500,7 @@
                 writePrivateNativeFunction(s, d_function);
             }
         }
-    }
+   }
 
 
     foreach (const AbstractMetaField *field, fields) {
@@ -2558,7 +2533,7 @@
 
         s << "extern(C) void static_init_" << d_class->name() << "() {" << endl;
 
-        if (d_class->isQObject()) {
+        if (d_class->typeEntry()->isObject() && d_class->hasVirtualFunctions()) {
             s << INDENT << "if (!" << d_class->name() << "._staticMetaObject) " << endl
             << INDENT << "    " << d_class->name() << ".createStaticMetaObject;" << endl << endl;
         }
@@ -2620,6 +2595,7 @@
     }
 }
 
+/*
 void DGenerator::writeConversionFunction(QTextStream &s, const AbstractMetaClass *d_class)
 {
     const ComplexTypeEntry *ctype = d_class->typeEntry();
@@ -2640,20 +2616,74 @@
     // 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
+        s << INDENT << "void* d_obj = qtd_" << ctype->targetLangName() << "_dId(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 << "    auto return_value = new " << type_name << "(ret, QtdObjectFlags.skipNativeDelete);" << endl
           << INDENT << "    return return_value;" << endl
           << INDENT << "}" << endl;
     } else {
-        s << INDENT << "auto return_value = new " << type_name << "(ret, QtdObjectFlags.nativeOwnership);" << endl
+        s << INDENT << "auto return_value = new " << type_name << "(ret, QtdObjectFlags.skipNativeDelete);" << endl
           << INDENT << "return return_value;" << endl;
     }
     s << "}" << endl << endl;
 }
+*/
+
+// Polymorphic non-QObject
+void DGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class)
+{   
+    QString rootClassName = d_class->rootClass()->name();
+    QString concreteArg;
+    if (d_class->isAbstract())
+        concreteArg += ", " + d_class->name() + "_ConcreteWrapper";      
+
+  s << "    private static QtdMetaObject _staticMetaObject;" << endl
+    //<< "    private static QtdMetaObject[void*] _nativeToTargetMap;" << endl
+    
+    << "    protected static void createStaticMetaObject() {" << endl
+    << "        assert(!_staticMetaObject);" << endl
+    << "        QtdMetaObject base;" << endl;
+
+    if (d_class->baseClass())
+    {
+        QString baseName = d_class->baseClassName();
+        s << "        if (!" << baseName << "._staticMetaObject)" << endl
+        << "            " << baseName << ".createStaticMetaObject;" << endl
+        << "        base = " << baseName << "._staticMetaObject;" << endl;
+    }
+    
+    s << "        _staticMetaObject = new QtdMetaObject(qtd_" << d_class->name() << "_staticTypeId, base);"   << endl
+    << "        _staticMetaObject.construct!(" << d_class->name() << concreteArg << ");" << endl
+    << "    }" << endl << endl
+
+    << "    QtdMetaObject metaObject() {" << endl
+    << "        return _staticMetaObject;" << endl
+    << "    }" << endl << endl
+    
+    << "    static QtdMetaObject staticMetaObject() {" << endl
+    << "        return _staticMetaObject;" << endl
+    << "    }" << endl << endl
+
+    << "    static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.skipNativeDelete) {" << endl
+    << "        auto obj = cast("  << d_class->name() << ") qtd_" << rootClassName << "_dId(nativeId);" << endl
+    << "        if (!obj)" << endl
+    << "            obj = static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId,"
+                        "qtd_" << rootClassName << "_typeId(nativeId), flags));" << endl
+    << "        return obj;" << endl                   
+    << "    }" << endl << endl;
+    /*
+    << "    overrive protected void __addMapping() {" << endl
+    << "        _nativeToTargetMap[__nativeId] = this;" << endl
+    << "    }" << endl << endl
+    
+    << "    override protected void __removeMapping() {" << endl
+    << "        _nativeToTargetMap.remove(__nativeId);" << endl
+    << "    }" << endl << endl
+    */  
+}
 
 void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class)
 {
@@ -2686,12 +2716,12 @@
     << "        return _staticMetaObject;" << endl
     << "    }" << endl << endl
 
-    << "    static " << d_class->name() << " __getObject(void* nativeId) {" << endl
-    << "        return static_cast!(" << d_class->name() << ")(_staticMetaObject.getObject(nativeId));" << endl
+    << "    static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl
+    << "        return static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId, flags));" << endl
     << "    }" << endl << endl
 
-    << "    static void __createEntity(void* nativeId, void* dId) {" << endl
-    << "        return qtd_" << d_class->name() << "_createEntity(nativeId, dId);" << endl
+    << "    void __createEntity() {" << endl
+    << "        return qtd_" << d_class->name() << "_createEntity(__nativeId, cast(void*)this);" << endl
     << "    }" << endl << endl;
 }
 
@@ -2701,23 +2731,62 @@
 
 }
 */
-void DGenerator::marshallFromCppToD(QTextStream &s, const ComplexTypeEntry* ctype)
+
+// Returns the name of the resulting variable
+QString DGenerator::marshalToD(QTextStream &s, QString argName, const TypeEntry* type, MarshalFlags flags)
 {
-    if(ctype->isQObject()) {
-        QString type_name = ctype->name();
-        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() << "(ret);" << endl;
-    } else if (ctype->isVariant()) {
-        s << INDENT << "return new QVariant(ret);" << endl;
+    if (type->isBasicValue())
+        return argName;
+         
+    QString qtdObjFlags = "QtdObjectFlags.none";    
+    const ObjectTypeEntry *ctype = 0;
+    bool stackObject = false;   
+    
+    if (type->isObject())
+        ctype = static_cast<const ObjectTypeEntry *>(ctype);
+    
+    if (type->isValue())
+        flags |= MarshalScope;  
+    
+    if (flags & MarshalScope)
+    {
+        if (type->isObject() && type->hasVirtualDestructor())
+        {
+            qtdObjectFlags += " | QtdObjectFlags.stackAllocated";
+            bool stackObject = true;
+        }
+        else
+            s << INDENT << "scope ";
+        
+        qtdObjectFlags += "| QtdObjectFlags.skipNativeDelete";
+    }
+    else
+        s << INDENT << "auto ";
+    
+    s << resultName << " = ";        
+    
+            
+    if (ctype->isObject() && type->hasVirtualDestructor()) {        
+        exp = type->name() + ".__wrap(ret);" + endl;
+    }
+    else if (type->isValue())
+    {
+        if (type->actualIndirections() == 0)
+            s << "new " << type->name() << "(" << argName << ");" << endl;
+        else if (type->actualIndirections() == 1)
+            s << "new "         
+    }
+            
+    
     } else if (ctype->name() == "QModelIndex" || ctype->isStructInD()) {
         s << INDENT << "return ret;" << endl;
-    } else if (ctype->isObject()) {
-        QString type_name = ctype->name();
-        s << "return qtd_" << type_name << "_from_ptr(ret);" << endl;
     }
+    
+    if (stackObject)
+    {
+        s << ""
+    }
+    
 }
 
 void DGenerator::writeNativeField(QTextStream &s, const AbstractMetaField *field)
@@ -2850,29 +2919,57 @@
                 else if (type->typeEntry()->isValue() && type->isNativePointer() && type->typeEntry()->name() == "QString") {
                     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 << ", QtdObjectFlags.nativeOwnership);";
+                }
                 else if (type->typeEntry()->isStructInD())
                     continue;
-                else if (!type->hasNativeId() && !(type->typeEntry()->isValue() && type->isNativePointer()))
+                else if ((type->typeEntry()->isValue() && type->isNativePointer())
+                    || type->isValue() || type->isVariant()){
+                    s << INDENT << "scope " << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ");" << endl;
+                
+                    (*logstream) << type->name() << ", " << argument->argumentIndex() + 1 << ", "
+                            << implementor->name() << "::" <<  d_function->name();
+                
+                    if (type->typeEntry()->isValue())                    
+                        (*logstream) << ", type entry value";
+                    
+                    if (type->typeEntry()->isValue())                    
+                        (*logstream) << ", value";
+                    
+                    if (type->isNativePointer())                    
+                        (*logstream) << ", native pointer";
+                    
+                    const ComplexTypeEntry* ctype = dynamic_cast<const ComplexTypeEntry*>(type->typeEntry());
+                    if (ctype && ctype->hasVirtualFunctions())                    
+                        (*logstream) << ", polymorphic";
+                    
+                    (*logstream) << endl;
+                }                
+                else if (!type->hasNativeId())
                     continue;
-                else if(type->isObject()
-                    || (type->typeEntry()->isValue() && type->isNativePointer())
-                    || type->isValue() || type->isVariant()) {
-                    QString type_name = type->typeEntry()->name();
-                    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 << ", QtdObjectFlags.nativeOwnership);";
+                else if (type->isObject() || type->isQObject())
+                {
+                    if (!type->isQObject())
+                    {
+                        (*logstream) << type->name() << ", " << argument->argumentIndex() + 1 << ", "
+                            << implementor->name() << "::" <<  d_function->name();
+                    
+                        (*logstream) << ", object";
+                            
+                        const ComplexTypeEntry* ctype = dynamic_cast<const ComplexTypeEntry*>(type->typeEntry());
+                        if (ctype && ctype->hasVirtualFunctions())                    
+                            (*logstream) << ", polymorphic";
+                        
+                        (*logstream) << endl;
+                    }
+                
+                    if (((ComplexTypeEntry*)type->typeEntry())->hasVirtualFunctions() || !d_function->resetObjectAfterUse(argument->argumentIndex() + 1))
+                        s << INDENT << "auto " << arg_name << "_d_ref = " << type->typeEntry()->name() << ".__wrap(" << arg_name << ");";
+                    else
+                        s << INDENT << "scope " << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags.skipNativeDelete);";
                 }
-                else if (type->isQObject()) {
-                    QString type_name = type->name();
-                    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 << ", QtdObjectFlags.nativeOwnership);" << endl;
-                }
+                else
+                    qFatal(qPrintable(type->typeEntry()->name()));
+                
                 s << endl;
             }
     }
@@ -2973,15 +3070,18 @@
 
 void DGenerator::generate()
 {
+    log = new QFile("arglog.txt");
+    log->open(QFile::ReadWrite);
+    logstream = new QTextStream(log);
     // qtd
     // code for including classses in 1 module for avoiding circular imports
     foreach (AbstractMetaClass *cls, m_classes) {
-        const ComplexTypeEntry *ctype = cls->typeEntry();
-
-        if (!cls->isInterface() && cls->isAbstract()) {
-            ComplexTypeEntry *ctype_m = (ComplexTypeEntry *)ctype;
-            ctype_m->setAbstract(true);
-        }
+        ComplexTypeEntry *ctype = const_cast<ComplexTypeEntry *>(cls->typeEntry());
+
+        if (!cls->isInterface() && cls->isAbstract())            
+            ctype->setAbstract(true);
+                
+        ctype->setHasVirtualFunctions(cls->hasVirtualFunctions());
 
         foreach(QString child, ctype->includedClasses) {
             ComplexTypeEntry *ctype_child = TypeDatabase::instance()->findComplexType(child);
@@ -2990,20 +3090,6 @@
 
         foreach (AbstractMetaFunction *function, cls->functions())
             function->checkStoreResult();
-/* we don't need this anymore
-        // generate QObject conversion functions only those that are required
-        AbstractMetaFunctionList d_funcs = cls->functionsInTargetLang();
-        for (int i=0; i<d_funcs.size(); ++i) {
-            AbstractMetaType *f_type = d_funcs.at(i)->type();
-            if (!f_type)
-                continue;
-            if (f_type->isQObject() || f_type->isObject()) {
-                const ComplexTypeEntry* cte = static_cast<const ComplexTypeEntry *>(f_type->typeEntry());
-                AbstractMetaClass* d_class = ClassFromEntry::get(cte);
-                if (d_class)
-                    d_class->needsConversionFunc = true;
-            }
-        }*/
     }
 
     Generator::generate();
@@ -3079,6 +3165,9 @@
         }
         file.close();
     }
+    
+    delete logstream;
+    delete log;
 }
 
 void DGenerator::writeFunctionAttributes(QTextStream &s, const AbstractMetaFunction *d_function,
--- a/generator/dgenerator.h	Mon Aug 31 12:07:28 2009 +0000
+++ b/generator/dgenerator.h	Wed Sep 16 13:56:02 2009 +0000
@@ -45,6 +45,7 @@
 #include "generator.h"
 #include "metajava.h"
 #include "cppimplgenerator.h"
+#include "fileout.h"
 
 #include <QTextStream>
 
@@ -137,7 +138,13 @@
 
     void writeShellVirtualFunction(QTextStream &s, const AbstractMetaFunction *function,
                                           const AbstractMetaClass *implementor, int id);
-    void marshallFromCppToD(QTextStream &s, const ComplexTypeEntry* ctype);
+                                          
+    enum MarshalFlags
+    {        
+        MarhsalScope    = 0x1
+    }
+    
+    void marshalToD(QTextStream &s, const ComplexTypeEntry* ctype);
 
 private:
     QString subDirectoryForPackage(const QString &package) const { return QString(package).replace(".", "/"); }
@@ -151,11 +158,12 @@
     const TypeEntry* fixedTypeEntry(const TypeEntry *type);
 
     void writeDestructor(QTextStream &s, const AbstractMetaClass *d_class);
-    void writeFlagsSetter(QTextStream &s, const AbstractMetaClass *d_class);
+    void writeOwnershipSetter(QTextStream &s, const AbstractMetaClass *d_class);
     void writeSignalHandlers(QTextStream &s, const AbstractMetaClass *d_class);
     void writeEnumAlias(QTextStream &s, const AbstractMetaEnum *d_enum);
     void writeSignalSignatures(QTextStream &s, const AbstractMetaClass *d_class, AbstractMetaFunctionList signal_funcs);
     void writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class);
+    void writeObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class);
     void writeConversionFunction(QTextStream &s, const AbstractMetaClass *d_class);
 
 //    void writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class);
@@ -178,6 +186,8 @@
     QList<const AbstractMetaFunction *> m_nativepointer_functions;
     QList<const AbstractMetaFunction *> m_resettable_object_functions;
     QList<const AbstractMetaFunction *> m_reference_count_candidate_functions;
+    QFile *log;
+    QTextStream *logstream;
 };
 
 class ClassFromEntry : Generator
--- a/generator/generator.cpp	Mon Aug 31 12:07:28 2009 +0000
+++ b/generator/generator.cpp	Wed Sep 16 13:56:02 2009 +0000
@@ -61,6 +61,24 @@
                                .arg(metaObject()->className()));
         return;
     }
+    
+    {
+        FileOut fileOut("temp.txt");
+        foreach (AbstractMetaClass *cls, m_classes) {
+           
+               fileOut.stream << cls->name();
+               if (cls->typeEntry()->isValue())
+                   fileOut.stream << ", value";
+               if (cls->isQObject())
+                   fileOut.stream << ", QObject";
+               else if (cls->typeEntry()->isObject())
+                   fileOut.stream << ", object";                                  
+               if (cls->hasVirtualFunctions())
+                   fileOut.stream << ", polymorphic";              
+               fileOut.stream << endl;
+           
+        }
+    }
 
 
     foreach (AbstractMetaClass *cls, m_classes) {
--- a/generator/typesystem.h	Mon Aug 31 12:07:28 2009 +0000
+++ b/generator/typesystem.h	Wed Sep 16 13:56:02 2009 +0000
@@ -884,6 +884,9 @@
     bool isAbstract() const { return m_isAbstract; }
     void setAbstract(bool isAbstract) { m_isAbstract = isAbstract; }
 
+    bool hasVirtualFunctions() const { return m_hasVirtualFunctions; }
+    void setHasVirtualFunctions(bool value) { m_hasVirtualFunctions = value; }
+
     void setDepends(const QStringList &depends) {m_depends = depends; }
     const QStringList &depends() {return m_depends; }
 
@@ -916,6 +919,7 @@
     // qtd
     bool m_isStructInD;
     bool m_isAbstract;
+    bool m_hasVirtualFunctions;
     QStringList m_depends;
 };
 
--- a/generator/typesystem_core-java.java	Mon Aug 31 12:07:28 2009 +0000
+++ b/generator/typesystem_core-java.java	Wed Sep 16 13:56:02 2009 +0000
@@ -72,14 +72,7 @@
         }
     }
     */
-    
-    private
-    {
-        static QObject __root;
-        QObject __next;
-        QObject __prev;
-    }
-    
+       
     override void onSignalHandlerCreated(ref SignalHandler sh)
     {
         sh.signalEvent = &onSignalEvent;
@@ -88,16 +81,16 @@
     private void onSignalEvent(int signalId, SignalEventId event)
     {
         stringz signature;
-        signalSignature(signalId, signature);        
+        signalSignature(signalId, signature);
         if (signature)
         {
             switch (event)
             {
                 case SignalEventId.firstSlotConnected:
-                    qtd_connect(__nativeId, signature, signalId, cast(bool)(__flags_ & QtdObjectFlags.dynamicEntity));
+                    qtd_connect(__nativeId, signature, signalId, cast(bool)(__flags & QtdObjectFlags.hasDId));
                     break;
                 case SignalEventId.lastSlotDisconnected:
-                    qtd_disconnect(__nativeId, signature, signalId, cast(bool)(__flags_ & QtdObjectFlags.dynamicEntity));
+                    qtd_disconnect(__nativeId, signature, signalId, cast(bool)(__flags & QtdObjectFlags.hasDId));
                     break;
                 default:
                     assert (false);
@@ -105,17 +98,6 @@
         }
     }
     
-    ~this()
-    {
-        if (__prev)
-            __prev.__next = __next;
-        else
-            __root = __next;
-        
-        if (__next)      
-            __next.__prev = __prev;        
-    }
-    
     /**
     */
     T findChild(T : QObject = QObject)(string name = null)
@@ -153,7 +135,7 @@
         
         find(children);
         return result;
-    }
+    }  
 }// class
 
 abstract class QAbstractItemModel___ extends QAbstractItemModel {
--- a/generator/typesystem_core.xml	Mon Aug 31 12:07:28 2009 +0000
+++ b/generator/typesystem_core.xml	Wed Sep 16 13:56:02 2009 +0000
@@ -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);
@@ -2394,20 +2379,20 @@
     return (void*)((QObject*)nativeId)->metaObject();
 }
 
-extern "C" DLL_PUBLIC void qtd_connect(void* nativeId, char* signal, int id, bool dynamicEntity)
-{   
+extern "C" DLL_PUBLIC void qtd_connect(void* nativeId, char* signal, int id, bool hasDId)
+{
     QObject *sender = (QObject*)nativeId;
-    QObject *receiver = dynamicEntity ? dynamic_cast&lt;QObject*&gt;(QtD_QObjectEntity::getQObjectEntity(sender)) : sender;
+    QObject *receiver = hasDId ?  sender : dynamic_cast&lt;QObject*&gt;(QtD_QObjectEntity::getQObjectEntity(sender));
     const QMetaObject *mo = sender->metaObject();
     int nativeSigId = mo-&gt;indexOfSignal(signal);
     QMetaObject::connect(sender, nativeSigId, receiver, receiver-&gt;metaObject()-&gt;methodCount() + id);
 }
 
-extern "C" DLL_PUBLIC void qtd_disconnect(void* nativeId, char* signal, int id, bool dynamicEntity)
+extern "C" DLL_PUBLIC void qtd_disconnect(void* nativeId, char* signal, int id, bool hasDId)
 {
     QObject *sender = (QObject*)nativeId;
-    QObject *receiver = dynamicEntity ? dynamic_cast&lt;QObject*&gt;(QtD_QObjectEntity::getQObjectEntity(sender)) : sender;
-    const QMetaObject *mo = sender->metaObject();    
+    QObject *receiver = hasDId ? sender : dynamic_cast&lt;QObject*&gt;(QtD_QObjectEntity::getQObjectEntity(sender));
+    const QMetaObject *mo = sender->metaObject();
     int nativeSigId = mo-&gt;indexOfSignal(signal);
     QMetaObject::disconnect(sender, nativeSigId, receiver, receiver-&gt;metaObject()-&gt;methodCount() + id);
 }
@@ -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;
-	}
-}
+extern(C) void qtd_connect(void *nativeId, cstringz signal, int id, bool hasDId);
+extern(C) void qtd_disconnect(void *nativeId, cstringz signal, int id, bool hasDId);
+
 	</inject-code>
 
     <modify-function signature="childEvent(QChildEvent*)">
@@ -2589,8 +2562,8 @@
     <modify-function signature="setUserIniPath(const QString&amp;)" remove="all"/> <!--### Obsolete in 4.3-->
   </object-type>
 
-  <object-type name="QEvent" polymorphic-base="yes" polymorphic-id-expression="%1-&gt;type() == QEvent::None"/>
-  <object-type name="QChildEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::ChildAdded || %1-&gt;type() == QEvent::ChildPolished || %1-&gt;type() == QEvent::ChildRemoved">
+  <object-type name="QEvent"/>
+  <object-type name="QChildEvent">
     <modify-field name="c" read="false" write="false"/>
   </object-type>
   <object-type name="QTimerEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::Timer"/>
--- a/include/qtd_core.h	Mon Aug 31 12:07:28 2009 +0000
+++ b/include/qtd_core.h	Wed Sep 16 13:56:02 2009 +0000
@@ -13,6 +13,7 @@
 #define QTD_CORE_H
 
 #include <QAbstractItemModel>
+#include <QObject>
 
 #if defined WIN32
   #define DLL_PUBLIC __declspec(dllexport)
@@ -34,6 +35,10 @@
     extern "C" TYPE NAME ARGS;
 #endif
 
+
+//TODO: user data ID must be registered with QObject::registerUserData;
+#define userDataId 0
+
 struct QModelIndexAccessor {
 	int row;
 	int col;
@@ -46,14 +51,6 @@
     void* ptr;
 };
 
-enum QtdObjectFlags
-{
-    qNone,
-    qNativeOwnership            = 0x01,
-    qDOwnership                 = 0x02
-    //gcManaged                 = 0x04
-};
-
 class QtD_Entity
 {
 public:
@@ -64,6 +61,15 @@
     }
 };
 
+class QtD_QObjectEntity : public QtD_Entity, public QObjectUserData
+{
+public:
+    QtD_QObjectEntity(QObject *qObject, void *dId);
+    virtual ~QtD_QObjectEntity();
+    void destroyEntity(QObject *qObject = NULL);
+    static QtD_QObjectEntity* getQObjectEntity(const QObject *qObject);
+};
+
 #define Array DArray
 
 #ifdef CPP_SHARED
@@ -72,10 +78,12 @@
 
 QTD_EXPORT(void, qtd_toUtf8, (const unsigned short* arr, uint size, void* str))
 QTD_EXPORT(void, qtd_dummy, ())
+QTD_EXPORT(void, qtd_delete_d_object, (void* dPtr))
 
 #ifdef CPP_SHARED
 #define qtd_toUtf8 qtd_get_qtd_toUtf8()
 #define qtd_dummy qtd_get_qtd_dummy()
+#define qtd_delete_d_object qtd_get_qtd_delete_d_object()
 #endif
 
 extern "C" QModelIndex qtd_to_QModelIndex(QModelIndexAccessor mia);
--- a/mini/test1/build	Mon Aug 31 12:07:28 2009 +0000
+++ b/mini/test1/build	Wed Sep 16 13:56:02 2009 +0000
@@ -1,3 +1,3 @@
 #! /bin/bash
 
-dmd main.d -L-L../../lib -L-lqtdcore -I../../ -I../../qt/d2 -L-lQtCore
\ No newline at end of file
+dmd main.d -gc -debug -debug=QtdVerbose -L-L../../output/build/lib -L-lqtdcore -I../../output/build -I../../ -I../../qt/d1 -L-lQtCore -L-lQtGui
\ No newline at end of file
--- a/mini/test1/main.d	Mon Aug 31 12:07:28 2009 +0000
+++ b/mini/test1/main.d	Wed Sep 16 13:56:02 2009 +0000
@@ -1,30 +1,125 @@
+module main;
+
+/+
+import qt.gui.QApplication;
 import qt.core.QCoreApplication;
+import qt.gui.QDialogButtonBox;
++/
+import tango.io.Stdout;
 
-version(Tango) {} else { import std.stdio; }
+extern(C) void* qtd_test_Object();
+extern(C) void qtd_test_delete_Object(void* obj);
+
+import qt.core.QObject;
+import qt.core.QCryptographicHash;
+import qt.core.QFSFileEngine;
+import qt.QtdObject;
+
 
-int main(string[] args)
+void main()
+{
+    //auto nativeId = qtd_test_Object();    
+    scope obj = new QCryptographicHash(QCryptographicHash_Algorithm.Md5);
+    obj.__nativeOwnership = true;
+    qtd_test_delete_Object(obj.__nativeId);
+    //Stdout(obj).newline;
+}
+
+/+
+void main(char[][] args)
 {
-    auto app = new QCoreApplication(args);
+    /+
+    scope app = new QCoreApplication(args);
+    app.aboutToQuit.connect(&quit);
+    Stdout(app.children[0]).newline;
+    +/
+    
+    /+    
+    scope parent = new QObject;
+    qtd_qobject(parent.__nativeId);
+    Stdout(parent.children[0]).newline;
+    +/
+    
+    
+    
     
-    auto parent = new QObject();
-    parent.setObjectName("papa");
-    auto child1 = new QObject(parent);
-    child1.setObjectName("child1");
-    auto child2 = new QObject(parent);
-    child2.setObjectName("child2");
-    auto child3 = new QObject(parent);
-    child3.setObjectName("child3");
-    
-    auto cd = parent.children;
+    //return app.exec();
+}
+
+void quit()
+{
+    Stdout("Quitting").newline;
+}
++/
+
+/+
+import tango.io.Stdout;
+
+import qt.gui.QMainWindow;
+
+public class TestWindow : QMainWindow
+{
+    public this()
+    {       
+        //Stdout(qVersion).newline;
+        
+        //Stdout(this.children.length).newline;
+        auto box = new QDialogButtonBox(this);
+        auto closeButton = box.addButton(QDialogButtonBox.Close);
+        closeButton.clicked.connect(&onCloseClick);
+    }
     
-    writeln(app.arguments);
-    foreach(child; cd)
-        writeln(child.objectName);
-    
-    app.setLibraryPaths(["freakin", "bloody", "awesome!"]);
+    void onCloseClick()
+    {
+        Stdout("Close clicked").newline;
+    }
+}
+
+void main(char[][] args)
+{
+    scope app = new QApplication(args);
+    scope mainWin = new TestWindow;
+    mainWin.show();
+    return app.exec();
+}
++/
+
+/+
 
-    writeln(app.libraryPaths);
+import qt.gui.QListWidget;
+import qt.gui.QApplication;
+import qt.gui.QMainWindow;
+import tango.io.Stdout;
+void main( char[][] args )
+{
     
-    return 5;
-//    return app.exec();
+    Stdout(qVersion).newline;
+        static void itemChanged( QListWidgetItem cur, QListWidgetItem prev )
+        {
+            if(prev )
+                {
+                    Stdout("Here prev", prev, prev.__nativeId).newline;
+                        prev.text; // This causes the SIGSEGV
+                    Stdout("There prev").newline;
+                }
+                
+                if( cur )
+                {
+                    Stdout("Here", cur, cur.__nativeId).newline;
+                        cur.text; // This causes the SIGSEGV
+                    Stdout("There").newline;
+                }
+        }
+        scope app = new QApplication(args);
+        scope mainWin = new QMainWindow;
+        scope lw = new QListWidget( mainWin );
+        scope lwi = new QListWidgetItem("text", lw);
+        lwi.text;
+        Stdout("Here 0 ", lwi.__nativeId).newline;
+        
+        lw.currentItemChanged.connect( &itemChanged );
+        mainWin.show;
+        return app.exec;
 }
+
++/
\ No newline at end of file
--- a/qt/QGlobal.d	Mon Aug 31 12:07:28 2009 +0000
+++ b/qt/QGlobal.d	Wed Sep 16 13:56:02 2009 +0000
@@ -3,9 +3,17 @@
 public import qt.qtd.Str;
 public import qt.QDefines;
 
-version (Tango)
+version (D_Version2)
+{
+    import std.stdio;
+    package import std.c.stdlib,
+                   core.memory;
+}
+else
 {
     import tango.io.Stdout;
+    import tango.core.Thread;
+    
     void writeln(string s)
     {
         Stdout(s).newline;
@@ -13,11 +21,67 @@
     package import tango.stdc.stdlib,
                    tango.core.Memory;
 }
+
+private enum : size_t { stackSize = 1024 * 1024 }
+
+final class StackAlloc
+{
+    alias typeof(this) This;
+    private void* _data;
+    
+    private static size_t align16(size_t size)
+    {
+        return size + 16 - (size - size & ~15);        
+    }
+    
+    this(size_t size)
+    {
+        _data = (new void[size]).ptr;
+    }
+        
+    void* alloc(size_t size)
+    {
+        void* res = _data;
+        _data += align16(size);
+        return res;            
+    }
+    
+    void free(size_t size)
+    {
+        _data -= align16(size);
+    }
+}
+ 
+version (D_Version2)
+{
+    void StackAlloc __stackAlloc()
+    {
+        static StackAlloc instance; // thread-local instance
+        // COMPILER BUG: No thread-local static constructors, Using lazy construction
+        if (!instance)
+            instance = new This(stackSize);
+        return instance;
+    }
+}
 else
 {
-    import std.stdio;
-    package import std.c.stdlib,
-                   core.memory;
+    private static ThreadLocal!(StackAlloc) stackAllocInst;
+    
+    static this()
+    {
+        stackAllocInst = new ThreadLocal!(StackAlloc);
+    }
+    
+    static StackAlloc __stackAlloc()
+    {            
+        auto res = stackAllocInst.val;
+        if (!res)
+        {
+            res = new This(stackSize);
+            stackAllocInst.val = res;
+        }
+        return res;
+    }
 }
 
 T static_cast(T, U)(U obj)
@@ -40,21 +104,15 @@
 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 QtdObject.d
+extern(C) void qtd_delete_d_object(void* dPtr);
 
 version(cpp_shared)
 {
-    extern (C) void qtd_core_initCallBacks(void* toUtf8, void* dummy);
+    extern (C) void qtd_core_initCallBacks(void* toUtf8, void* dummy, 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_dummy, &qtd_delete_d_object);
     }
 }
 
@@ -225,7 +283,7 @@
 //class QString;
 //char[] qPrintable(QString string) { string.toLocal8Bit().constData(); }
 //TODO(katrina) These should probably actually call into the c++ functions
-void qDebug( char[] str ) /* print debug message */
+void qDebug(string str) /* print debug message */
 { writeln(str); }
 
 extern (C) void Qt_qWarning( char * );
--- a/qt/d1/qt/core/QVariant.d	Mon Aug 31 12:07:28 2009 +0000
+++ b/qt/d1/qt/core/QVariant.d	Wed Sep 16 13:56:02 2009 +0000
@@ -33,7 +33,7 @@
 }
 
 
-public class QVariant : QtdObject
+public class QVariant : QtdObjectBase
 {
     enum Type {
         Invalid = 0,
@@ -481,7 +481,7 @@
 
     public final QVariant operator_assign(QVariant other) {
         void* __qt_return_value = qtd_QVariant_operator_assign_QVariant(__nativeId, other is null ? null : other.__nativeId);
-        return new QVariant(__qt_return_value, QtdObjectFlags.nativeOwnership);
+        return new QVariant(__qt_return_value, QtdObjectFlags.skipNativeDelete);
     }
 
     private final bool operator_equal(QVariant v) {