diff generator/dgenerator.cpp @ 130:7ae9bc9d6935

reference counting for return values. applied to QMenu
author eldar
date Sun, 07 Jun 2009 11:42:29 +0000
parents e416c5215366
children 4d1c5d1d1bbf
line wrap: on
line diff
--- a/generator/dgenerator.cpp	Fri Jun 05 15:48:27 2009 +0000
+++ b/generator/dgenerator.cpp	Sun Jun 07 11:42:29 2009 +0000
@@ -675,12 +675,16 @@
             s << INDENT << this->translateType(d_function->type(), d_function->ownerClass(), NoOption) << " res;" << endl;
     }
 
-    //returning string or a struct
+    // returning string or a struct
     bool return_in_arg = return_type && (return_type->isTargetLangString() ||
                                          return_type->name() == "QModelIndex" ||
                                          return_type->isContainer() ||
                                          return_type->typeEntry()->isStructInD());
 
+    // bool flag showing if we return value immediately, without any conversions
+    // which is commpon for primitive types, initially set up to return_in_arg, because in that case
+    // we don't need type conversions
+    bool returnImmediately = return_in_arg;
 
     s << INDENT;
     if ( (has_return_type && d_function->argumentReplaced(0).isEmpty() ) || d_function->isConstructor()) { //qtd
@@ -701,6 +705,7 @@
         } else if (return_type && return_type->isArray()) {
             s << return_type->arrayElementType()->name() + "* __qt_return_value = ";
         } else {
+            returnImmediately = true;
             s << "return ";
         }
 
@@ -840,41 +845,8 @@
 // qtd2    if (return_type && (/* qtdreturn_type->isTargetLangEnum() ||*/ return_type->isTargetLangFlags()))
 //        s << ")";
 
-    foreach (ReferenceCount referenceCount, referenceCounts) {
-        writeReferenceCount(s, referenceCount, "__qt_return_value");
-    }
-
     s << ";" << endl;
 
-    // return value marschalling
-    if(return_type) {
-        if ( ( has_return_type && d_function->argumentReplaced(0).isEmpty() )) // qtd
-            if(return_type->isQObject())
-                s << INDENT << "return qtd_" << return_type->name() << "_from_ptr(__qt_return_value);" << endl;
-
-        if (return_type->isValue() && !return_type->typeEntry()->isStructInD())
-            s << INDENT << "return new " << return_type->name() << "(__qt_return_value, false);" << endl;
-
-        if (return_type->isVariant())
-            s << INDENT << "return new QVariant(__qt_return_value, false);" << endl;
-
-        if (return_type->isNativePointer() && return_type->typeEntry()->isValue())
-            s << INDENT << "return new " << return_type->name() << "(__qt_return_value, true);" << endl;
-
-        if (return_type->isObject()) {
-            if(d_function->storeResult())
-                s << INDENT << QString("__m_%1.nativeId = __qt_return_value;").arg(d_function->name()) << endl
-                        << INDENT << QString("return __m_%1;").arg(d_function->name()) << endl;
-            else
-                s << INDENT << "return qtd_" << return_type->name() << "_from_ptr(__qt_return_value);" << endl;
-            s << endl;
-        }
-
-        if (return_type->isArray()) {
-            s << INDENT << "return __qt_return_value[0 .. " << return_type->arrayElementCount() << "];" << endl;
-        }
-    }
-    writeInjectedCode(s, d_function, CodeSnip::End);
 /* qtd2
     if (needs_return_variable) {
         if (owner != TypeSystem::InvalidOwnership) {
@@ -894,6 +866,53 @@
             s << INDENT << "this." << function_call_for_ownership(owner) << ";" << endl;
     }
 
+    // return value marschalling
+    if(return_type) {
+        if (!returnImmediately && !d_function->storeResult()) {
+            s << INDENT;
+            QString modified_type = d_function->typeReplaced(0);
+            if (modified_type.isEmpty())
+                s << translateType(d_function->type(), d_function->implementingClass());
+            else
+                s << modified_type.replace('$', '.');
+            s << " __d_return_value = ";
+        }
+
+        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;
+
+        if (return_type->isValue() && !return_type->typeEntry()->isStructInD())
+            s << "new " << return_type->name() << "(__qt_return_value, false);" << endl;
+
+        if (return_type->isVariant())
+            s << "new QVariant(__qt_return_value, false);" << endl;
+
+        if (return_type->isNativePointer() && return_type->typeEntry()->isValue())
+            s << "new " << return_type->name() << "(__qt_return_value, true);" << endl;
+
+        if (return_type->isObject()) {
+            if(d_function->storeResult())
+                s << INDENT << QString("__m_%1.nativeId = __qt_return_value;").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 << endl;
+        }
+
+        if (return_type->isArray()) {
+            s << "__qt_return_value[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;
+    }
+    writeInjectedCode(s, d_function, CodeSnip::End);
+
     if(return_in_arg) // qtd
         s << INDENT << "return res;" << endl;
 }