comparison generator/dgenerator.cpp @ 81:1750a803af74

return values as pointers
author eldar
date Sun, 24 May 2009 15:45:33 +0000
parents d5a6b6269f44
children 64b874c86f9b
comparison
equal deleted inserted replaced
80:85c59c4e5f19 81:1750a803af74
124 if (context != 0 && d_type != 0 && context->typeEntry()->isGenericClass() && d_type->originalTemplateType() != 0) 124 if (context != 0 && d_type != 0 && context->typeEntry()->isGenericClass() && d_type->originalTemplateType() != 0)
125 d_type = d_type->originalTemplateType(); 125 d_type = d_type->originalTemplateType();
126 126
127 if (!d_type) { 127 if (!d_type) {
128 s = "void"; 128 s = "void";
129 } else if (d_type->typeEntry()->qualifiedCppName() == "QChar") 129 } else if (d_type->typeEntry()->qualifiedCppName() == "QChar") {
130 s = "wchar" + QString(d_type->actualIndirections(), '*'); 130 s = "wchar" + QString(d_type->actualIndirections(), '*');
131 else if (d_type->typeEntry() && d_type->typeEntry()->qualifiedCppName() == "QString") { 131 } else if (d_type->typeEntry() && d_type->typeEntry()->qualifiedCppName() == "QString") {
132 s = "string"; 132 s = "string";
133 } else if (d_type->isArray()) { 133 } else if (d_type->isArray()) {
134 s = translateType(d_type->arrayElementType(), context) + "[]"; 134 s = translateType(d_type->arrayElementType(), context) + "[]";
135 } else if (d_type->isEnum() /* qtd2 || d_type->isFlags() */) { 135 } else if (d_type->isEnum() /* qtd2 || d_type->isFlags() */) {
136 if (( d_type->isEnum() && ((EnumTypeEntry *)d_type->typeEntry())->forceInteger() ) 136 if (( d_type->isEnum() && ((EnumTypeEntry *)d_type->typeEntry())->forceInteger() )
666 if (return_type->isTargetLangString()) 666 if (return_type->isTargetLangString())
667 s << INDENT << "string res;" << endl; 667 s << INDENT << "string res;" << endl;
668 668
669 if(return_type->name() == "QModelIndex") 669 if(return_type->name() == "QModelIndex")
670 s << INDENT << "QModelIndex res;" << endl; 670 s << INDENT << "QModelIndex res;" << endl;
671 else if (return_type->typeEntry()->isStructInD())
672 s << INDENT << return_type->name() << " res;" << endl;
671 673
672 if(return_type->isContainer()) 674 if(return_type->isContainer())
673 s << INDENT << this->translateType(d_function->type(), d_function->ownerClass(), NoOption) << " res;" << endl; 675 s << INDENT << this->translateType(d_function->type(), d_function->ownerClass(), NoOption) << " res;" << endl;
674 } 676 }
677
678 //returning string or a struct
679 bool return_in_arg = return_type && (return_type->isTargetLangString() ||
680 return_type->name() == "QModelIndex" ||
681 return_type->isContainer() ||
682 return_type->typeEntry()->isStructInD());
683
675 684
676 s << INDENT; 685 s << INDENT;
677 if ( (has_return_type && d_function->argumentReplaced(0).isEmpty() ) || d_function->isConstructor()) { //qtd 686 if ( (has_return_type && d_function->argumentReplaced(0).isEmpty() ) || d_function->isConstructor()) { //qtd
678 if(d_function->type() && d_function->type()->isQObject()) { // qtd 687 if(d_function->type() && d_function->type()->isQObject()) { // qtd
679 s << "void *__qt_return_value = "; 688 s << "void *__qt_return_value = ";
680 } else if(d_function->type() && (d_function->type()->isTargetLangString() || 689 } else if(return_in_arg) // qtd
681 d_function->type()->name() == "QModelIndex" ||
682 d_function->type()->isContainer())) // qtd
683 ; 690 ;
684 /* qtd2 not sure else if (needs_return_variable) { 691 else if (d_function->isConstructor()) { // qtd
685 if (new_return_type.isEmpty())
686 s << translateType(return_type, d_function->implementingClass());
687 else
688 s << new_return_type;
689
690 s << " __qt_return_value = ";
691 }*/ else if (d_function->isConstructor()) { // qtd
692 s << "void* __qt_return_value = "; 692 s << "void* __qt_return_value = ";
693 } else if (return_type && return_type->isValue() && !return_type->typeEntry()->isStructInD()) { 693 } else if (return_type && return_type->isValue() && !return_type->typeEntry()->isStructInD()) {
694 s << "void* __qt_return_value = "; 694 s << "void* __qt_return_value = ";
695 } else if (return_type && return_type->isVariant()) { 695 } else if (return_type && return_type->isVariant()) {
696 s << "void* __qt_return_value = "; 696 s << "void* __qt_return_value = ";
697 } else if (return_type && ( return_type->isObject() || 697 } else if (return_type && ( return_type->isObject() ||
698 (return_type->isNativePointer() && return_type->typeEntry()->isValue()) || 698 (return_type->isNativePointer() && return_type->typeEntry()->isValue()) ||
760 s << "cast(void*) this"; 760 s << "cast(void*) this";
761 if (arguments.count() > 0) 761 if (arguments.count() > 0)
762 s << ", "; 762 s << ", ";
763 } 763 }
764 764
765 //returning string or a struct
766 bool return_in_arg = d_function->type() && (d_function->type()->isTargetLangString() ||
767 d_function->type()->name() == "QModelIndex" ||
768 d_function->type()->isContainer());
769 if(return_in_arg) { // qtd 765 if(return_in_arg) { // qtd
770 if (!d_function->isStatic() && !d_function->isConstructor()) // qtd 766 if (!d_function->isStatic() && !d_function->isConstructor()) // qtd
771 s << ", "; 767 s << ", ";
772 s << "&res"; 768 s << "&res";
773 } 769 }
792 s << arg_name << " is null ? null : " << arg_name << ".nativeId"; 788 s << arg_name << " is null ? null : " << arg_name << ".nativeId";
793 else if (te->designatedInterface()) 789 else if (te->designatedInterface())
794 s << arg_name << " is null ? null : " << arg_name << ".__ptr_" << te->designatedInterface()->name(); 790 s << arg_name << " is null ? null : " << arg_name << ".__ptr_" << te->designatedInterface()->name();
795 else if (modified_type == "string" /* && type->fullName() == "char" */) { 791 else if (modified_type == "string" /* && type->fullName() == "char" */) {
796 s << "toStringz(" << arg_name << ")"; 792 s << "toStringz(" << arg_name << ")";
797 } else if (type->isArray()) 793 } else if (type->isArray()) {
798 s << arg_name << ".ptr"; 794 s << arg_name << ".ptr";
799 else if(type->isContainer()) { 795 } else if(type->isContainer()) {
800 const ContainerTypeEntry *cte = 796 const ContainerTypeEntry *cte =
801 static_cast<const ContainerTypeEntry *>(te); 797 static_cast<const ContainerTypeEntry *>(te);
802 if(isLinearContainer(cte)) 798 if(isLinearContainer(cte))
803 s << QString("%1.ptr, %1.length").arg(arg_name); 799 s << QString("%1.ptr, %1.length").arg(arg_name);
804 } else if (type->typeEntry()->qualifiedCppName() == "QChar") 800 } else if (type->typeEntry()->qualifiedCppName() == "QChar") {
805 s << arg_name; 801 s << arg_name;
806 else if (type->isTargetLangString() || (te && te->qualifiedCppName() == "QString")) 802 } else if (type->isTargetLangString() || (te && te->qualifiedCppName() == "QString")) {
807 s << arg_name; 803 s << arg_name;
808 else if (type->isTargetLangEnum() || type->isTargetLangFlags()) { 804 } else if (type->isTargetLangEnum() || type->isTargetLangFlags()) {
809 s << arg_name; 805 s << arg_name;
810 // qtd s << arg->argumentName() << ".value()"; 806 // qtd s << arg->argumentName() << ".value()";
811 } else if (!type->hasNativeId() && !(te->isValue() && type->isNativePointer())) { // qtd2 hack for QStyleOption not being a nativeId based for some reason 807 } else if (!type->hasNativeId() && !(te->isValue() && type->isNativePointer())) { // qtd2 hack for QStyleOption not being a nativeId based for some reason
812 s << arg_name; 808 s << arg_name;
813 } else if (te->isStructInD()) { 809 } else if (te->isStructInD()) {
851 s << ";" << endl; 847 s << ";" << endl;
852 848
853 // return value marschalling 849 // return value marschalling
854 if(return_type) { 850 if(return_type) {
855 if ( ( has_return_type && d_function->argumentReplaced(0).isEmpty() )/* || d_function->isConstructor()*/) // qtd 851 if ( ( has_return_type && d_function->argumentReplaced(0).isEmpty() )/* || d_function->isConstructor()*/) // qtd
856 if(d_function->type()->isQObject()) { 852 if(return_type->isQObject()) {
857 853
858 QString type_name = d_function->type()->name(); 854 QString type_name = return_type->name();
859 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(d_function->type()->typeEntry()); 855 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(d_function->type()->typeEntry());
860 if(ctype->isAbstract()) 856 if(ctype->isAbstract())
861 type_name = type_name + "_ConcreteWrapper"; 857 type_name = type_name + "_ConcreteWrapper";
862 858
863 s << INDENT << "if (__qt_return_value is null)" << endl 859 s << INDENT << "if (__qt_return_value is null)" << endl
866 << INDENT << "if (d_obj is null) {" << endl 862 << INDENT << "if (d_obj is null) {" << endl
867 << INDENT << " auto new_obj = new " << type_name << "(__qt_return_value, true);" << endl 863 << INDENT << " auto new_obj = new " << type_name << "(__qt_return_value, true);" << endl
868 << INDENT << " new_obj.__no_real_delete = true;" << endl 864 << INDENT << " new_obj.__no_real_delete = true;" << endl
869 << INDENT << " return new_obj;" << endl 865 << INDENT << " return new_obj;" << endl
870 << INDENT << "} else" << endl 866 << INDENT << "} else" << endl
871 << INDENT << " return cast(" << d_function->type()->name() << ") d_obj;" << endl; 867 << INDENT << " return cast(" << return_type->name() << ") d_obj;" << endl;
872 } 868 }
873 869
874 870
875 if (return_type->isValue() && !return_type->typeEntry()->isStructInD()) 871 if (return_type->isValue() && !return_type->typeEntry()->isStructInD())
876 s << INDENT << "return new " << d_function->type()->name() << "(__qt_return_value, false);" << endl; 872 s << INDENT << "return new " << return_type->name() << "(__qt_return_value, false);" << endl;
877 873
878 if (return_type->isVariant()) 874 if (return_type->isVariant())
879 s << INDENT << "return new QVariant(__qt_return_value, false);" << endl; 875 s << INDENT << "return new QVariant(__qt_return_value, false);" << endl;
880 876
881 if (return_type->isNativePointer() && return_type->typeEntry()->isValue()) 877 if (return_type->isNativePointer() && return_type->typeEntry()->isValue())
885 if(d_function->storeResult()) 881 if(d_function->storeResult())
886 s << INDENT << QString("__m_%1.nativeId = __qt_return_value;").arg(d_function->name()) << endl 882 s << INDENT << QString("__m_%1.nativeId = __qt_return_value;").arg(d_function->name()) << endl
887 << INDENT << QString("return __m_%1;").arg(d_function->name()) << endl; 883 << INDENT << QString("return __m_%1;").arg(d_function->name()) << endl;
888 else { 884 else {
889 QString type_name = return_type->name(); 885 QString type_name = return_type->name();
890 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(d_function->type()->typeEntry()); 886 const ComplexTypeEntry *ctype = static_cast<const ComplexTypeEntry *>(return_type->typeEntry());
891 if(ctype->isAbstract()) 887 if(ctype->isAbstract())
892 type_name = type_name + "_ConcreteWrapper"; 888 type_name = type_name + "_ConcreteWrapper";
893 889
894 QString return_type_name = d_function->type()->name(); 890 QString return_type_name = return_type->name();
895 if(return_type->typeEntry()->designatedInterface()) 891 if(return_type->typeEntry()->designatedInterface())
896 return_type_name = d_function->type()->typeEntry()->designatedInterface()->name(); 892 return_type_name = return_type->typeEntry()->designatedInterface()->name();
897 893
898 AbstractMetaClass *classForTypeEntry = NULL; 894 AbstractMetaClass *classForTypeEntry = NULL;
899 // search in AbstractMetaClass list for return type 895 // search in AbstractMetaClass list for return type
900 // find a better way to perform TypeEntry -> AbstractMetaClass lookup, maybe create hash before generation 896 // find a better way to perform TypeEntry -> AbstractMetaClass lookup, maybe create hash before generation
901 // qtd2 897 // qtd2
902 /*foreach (AbstractMetaClass *cls, m_classes) { 898 /*foreach (AbstractMetaClass *cls, m_classes) {
903 if ( cls->name() == d_function->type()->name() ) 899 if ( cls->name() == d_function->type()->name() )
904 classForTypeEntry = cls; 900 classForTypeEntry = cls;
905 }*/ 901 }*/
906 902
907 classForTypeEntry = ClassFromEntry::get(d_function->type()->typeEntry()); 903 classForTypeEntry = ClassFromEntry::get(return_type->typeEntry());
908 904
909 // if class has virtual functions then it has classname_entity function so 905 // if class has virtual functions then it has classname_entity function so
910 // we can look for D Object pointer. otherwise create new wrapper 906 // we can look for D Object pointer. otherwise create new wrapper
911 if (classForTypeEntry != NULL && classForTypeEntry->hasVirtualFunctions()) { 907 if (classForTypeEntry != NULL && classForTypeEntry->hasVirtualFunctions()) {
912 s << INDENT << "void* d_obj = __" << return_type->name() << "_entity(__qt_return_value);" << endl 908 s << INDENT << "void* d_obj = __" << d_function->type()->name() << "_entity(__qt_return_value);" << endl
913 << INDENT << "if (d_obj !is null) {" << endl 909 << INDENT << "if (d_obj !is null) {" << endl
914 << INDENT << " auto d_obj_ref = cast (Object) d_obj;" << endl 910 << INDENT << " auto d_obj_ref = cast (Object) d_obj;" << endl
915 << INDENT << " return cast(" << return_type_name << ") d_obj_ref;" << endl 911 << INDENT << " return cast(" << return_type_name << ") d_obj_ref;" << endl
916 << INDENT << "} else {" << endl 912 << INDENT << "} else {" << endl
917 << INDENT << " auto return_value = new " << type_name << "(__qt_return_value, true);" << endl 913 << INDENT << " auto return_value = new " << type_name << "(__qt_return_value, true);" << endl
924 << INDENT << "return return_value;" << endl; 920 << INDENT << "return return_value;" << endl;
925 } 921 }
926 } 922 }
927 s << endl; 923 s << endl;
928 } 924 }
929
930 if (return_type->isArray()) { 925 if (return_type->isArray()) {
931 s << INDENT << "return __qt_return_value[0 .. " << return_type->arrayElementCount() << "];" << endl; 926 s << INDENT << "return __qt_return_value[0 .. " << return_type->arrayElementCount() << "];" << endl;
932 } 927 }
933 } 928 }
934 writeInjectedCode(s, d_function, CodeSnip::End); 929 writeInjectedCode(s, d_function, CodeSnip::End);
1908 1903
1909 if (!m_isRecursive) { 1904 if (!m_isRecursive) {
1910 s << "public import qt.QGlobal;" << endl 1905 s << "public import qt.QGlobal;" << endl
1911 << "public import qt.core.Qt;" << endl 1906 << "public import qt.core.Qt;" << endl
1912 << "private import qt.QtDObject;" << endl 1907 << "private import qt.QtDObject;" << endl
1913 << "private import qt.qtd.Array;" << endl 1908 << "private import qt.core.QString;" << endl
1914 << "private import qt.core.QString;" << endl; 1909 << "private import qt.qtd.Array;" << endl;
1915 if (d_class->isQObject()) { 1910 if (d_class->isQObject()) {
1916 s << "public import qt.Signal;" << endl; 1911 s << "public import qt.Signal;" << endl;
1917 if (d_class->name() != "QObject") 1912 if (d_class->name() != "QObject")
1918 s << "public import qt.core.QObject;" << endl; 1913 s << "public import qt.core.QObject;" << endl;
1919 } 1914 }
2391 writeCloneFunction(s, d_class); 2386 writeCloneFunction(s, d_class);
2392 } 2387 }
2393 */ 2388 */
2394 s << "}" << endl; 2389 s << "}" << endl;
2395 2390
2396 /* ---------------- injected free code ----------------*/ 2391 /* ---------------- injected free code ----------------*/
2397 const ComplexTypeEntry *class_type = d_class->typeEntry(); 2392 const ComplexTypeEntry *class_type = d_class->typeEntry();
2398 Q_ASSERT(class_type); 2393 Q_ASSERT(class_type);
2399 2394
2400 CodeSnipList code_snips = class_type->codeSnips(); 2395 CodeSnipList code_snips = class_type->codeSnips();
2401 foreach (const CodeSnip &snip, code_snips) { 2396 foreach (const CodeSnip &snip, code_snips) {
2402 if (!d_class->isInterface() && snip.language == TypeSystem::TargetLangFreeCode) { 2397 if (!d_class->isInterface() && snip.language == TypeSystem::TargetLangFreeCode) {
2403 s << endl; 2398 s << endl;
2404 snip.formattedCode(s, INDENT); 2399 snip.formattedCode(s, INDENT);
2405 } 2400 }
2406 } 2401 }
2407 /* --------------------------------------------------- */ 2402 /* --------------------------------------------------- */
2408 2403
2409 interfaces = d_class->interfaces(); 2404 interfaces = d_class->interfaces();
2410 if (!interfaces.isEmpty()) { 2405 if (!interfaces.isEmpty()) {
2411 for (int i=0; i<interfaces.size(); ++i) { 2406 for (int i=0; i<interfaces.size(); ++i) {
2412 AbstractMetaClass *iface = interfaces.at(i); 2407 AbstractMetaClass *iface = interfaces.at(i);
2870 f_type_name = f_type->typeEntry()->designatedInterface()->name(); 2865 f_type_name = f_type->typeEntry()->designatedInterface()->name();
2871 s << f_type_name << " ret_value = "; 2866 s << f_type_name << " ret_value = ";
2872 } 2867 }
2873 else if (f_type && f_type->isTargetLangString()) 2868 else if (f_type && f_type->isTargetLangString())
2874 s << "string _d_str = "; 2869 s << "string _d_str = ";
2875 else if (f_type && f_type->name() == "QModelIndex") 2870 else if (f_type && (f_type->name() == "QModelIndex" || f_type->typeEntry()->isStructInD()))
2876 s << "*__d_return_value = "; 2871 s << "*__d_return_value = ";
2877 else 2872 else
2878 s << "auto return_value = "; 2873 s << "auto return_value = ";
2879 } 2874 }
2880 s << "d_object." << d_function->name() << "("; 2875 s << "d_object." << d_function->name() << "(";
2937 << INDENT << "ret_str_size = _d_str.length;" << endl; 2932 << INDENT << "ret_str_size = _d_str.length;" << endl;
2938 else if (f_type->isContainer()) 2933 else if (f_type->isContainer())
2939 s << INDENT << "*__d_arr_ptr = return_value.ptr;" << endl 2934 s << INDENT << "*__d_arr_ptr = return_value.ptr;" << endl
2940 << INDENT << "*__d_arr_size = return_value.length;" << endl; 2935 << INDENT << "*__d_arr_size = return_value.length;" << endl;
2941 // << INDENT << "addReference(return_value.ptr);" << endl; 2936 // << INDENT << "addReference(return_value.ptr);" << endl;
2942 else if (f_type->name() == "QModelIndex") 2937 else if (f_type->name() == "QModelIndex" || f_type->typeEntry()->isStructInD())
2943 ; 2938 ;
2944 else 2939 else
2945 s << INDENT << "return return_value;" << endl; 2940 s << INDENT << "return return_value;" << endl;
2946 } else 2941 } else
2947 s << INDENT << "return return_value;" << endl; 2942 s << INDENT << "return return_value;" << endl;