comparison generator/dgenerator.cpp @ 357:9784459f0750

An attempt (failed due to optlink) to improve locality of declarations exported from QtD executables Q_CLASSINFO implementation Now Qtd can be built on Windows
author Max Samukha <maxter@spambox.com>
date Wed, 02 Jun 2010 19:38:05 +0300
parents 08c1ca7975ab
children a3f5c10414f3
comparison
equal deleted inserted replaced
356:12cec2d14e1c 357:9784459f0750
2546 if (staticInit) { 2546 if (staticInit) {
2547 QString initArgs; 2547 QString initArgs;
2548 if (cpp_shared && d_class->generateShellClass()) 2548 if (cpp_shared && d_class->generateShellClass())
2549 { 2549 {
2550 initArgs = "void* virtuals"; 2550 initArgs = "void* virtuals";
2551 if (d_class->isQObject()) 2551 if (d_class->name() == "QObject")
2552 initArgs += ", void* signals"; 2552 initArgs += ", void* signals";
2553 2553
2554 s << "private extern (C) void qtd_" << d_class->name() 2554 s << "private extern (C) void qtd_" << d_class->name()
2555 << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl; 2555 << QString("_initCallBacks(%1);").arg(initArgs) << endl << endl;
2556 } 2556 }
2557 2557
2558 s << "extern(C) void static_init_" << d_class->name() << "() {" << endl; 2558 s << "extern(C) void static_init_" << d_class->name() << "() {" << endl;
2559 2559
2560 if (d_class->typeEntry()->isValue()) 2560 if (d_class->typeEntry()->isValue())
2564 // ensure meta-object is created at static construction 2564 // ensure meta-object is created at static construction
2565 s << INDENT << d_class->name() << ".staticMetaObject();" << endl; 2565 s << INDENT << d_class->name() << ".staticMetaObject();" << endl;
2566 } 2566 }
2567 2567
2568 if (cpp_shared && d_class->generateShellClass()) { 2568 if (cpp_shared && d_class->generateShellClass()) {
2569 // virtual functions 2569
2570 AbstractMetaFunction::Options opts(AbstractMetaFunction::DeclaringClass | AbstractMetaFunction::NoExternNamespace);
2571
2572 // virtual functions
2570 s << INDENT << "void*[" << virtualFunctions.size() << "] virt_arr;" << endl; 2573 s << INDENT << "void*[" << virtualFunctions.size() << "] virt_arr;" << endl;
2571 for (int pos = 0; pos<virtualFunctions.size(); ++pos) { 2574 for (int pos = 0; pos<virtualFunctions.size(); ++pos) {
2572 const AbstractMetaFunction *function = virtualFunctions.at(pos); 2575 const AbstractMetaFunction *function = virtualFunctions.at(pos);
2573 if (!notWrappedYet(function) && d_class == function->declaringClass()) // qtd2 2576 if (!notWrappedYet(function) && d_class == function->declaringClass()) {
2574 s << INDENT << "virt_arr[" << pos << "] = &" << function->marshalledName(false) << "_dispatch;" <<endl; 2577 QString mName = function->marshalledName(opts);
2575 } 2578 s << INDENT << "virt_arr[" << pos << "] = &qtd_export_" << mName << "_dispatch;" <<endl;
2579 }
2580 }
2581
2576 if (virtualFunctions.size() == 0) 2582 if (virtualFunctions.size() == 0)
2577 initArgs = "null"; 2583 initArgs = "null";
2578 else 2584 else
2579 initArgs = "virt_arr.ptr"; 2585 initArgs = "virt_arr.ptr";
2580 2586
2581 if (d_class->name() == "QObject") { 2587 if (d_class->name() == "QObject") {
2582 // qt_metacall, metaObject 2588 // qt_metacall, metaObject
2583 s << endl << INDENT << "void*[2] sign_arr;" << endl; 2589 s << endl << INDENT << "void*[2] sign_arr;" << endl;
2584 s << INDENT << "sign_arr[0] = &qtd_QObject_qt_metacall_dispatch;" << endl; 2590 s << INDENT << "sign_arr[0] = &qtd_export_QObject_qt_metacall_dispatch;" << endl;
2585 s << INDENT << "sign_arr[1] = &qtd_QObject_metaObject_dispatch;" << endl; 2591 s << INDENT << "sign_arr[1] = &qtd_export_QObject_metaObject_dispatch;" << endl;
2586 initArgs += ", sign_arr.ptr"; 2592 initArgs += ", sign_arr.ptr";
2587 } 2593 }
2588 2594
2589 s << INDENT << "qtd_" << d_class->name() << QString("_initCallBacks(%1);").arg(initArgs) << endl; 2595 s << INDENT << "qtd_" << d_class->name() << QString("_initCallBacks(%1);").arg(initArgs) << endl;
2590 } 2596 }
2678 s << "}" << endl << endl; 2684 s << "}" << endl << endl;
2679 } 2685 }
2680 2686
2681 void DGenerator::writeQObjectFreeFunctions(QTextStream &s, const AbstractMetaClass *d_class) 2687 void DGenerator::writeQObjectFreeFunctions(QTextStream &s, const AbstractMetaClass *d_class)
2682 { 2688 {
2683 s << "private extern(C) QMetaObjectNative* qtd_" << d_class->name() << "_staticMetaObject();" << endl << endl 2689 s << "extern(C) QMetaObjectNative* qtd_" << d_class->name() << "_staticMetaObject();" << endl << endl
2684 << "private extern(C) void qtd_" << d_class->name() << "_createEntity(void* nativeId, void* dId);" << endl << endl; 2690 << "extern(C) void qtd_" << d_class->name() << "_createEntity(void* nativeId, void* dId);" << endl << endl
2685 2691 << "extern(C) int qtd_" << d_class->name() << "_qt_metacall(void *nativeId, QMetaObject.Call _c, int _id, void **_a);" << endl;
2686 if (!d_class->isFinal()) 2692
2687 s << "private extern(C) int qtd_" << d_class->name() << "_qt_metacall(void* __this_nativeId, QMetaObject.Call _c, int _id, void **_a);" 2693 QString prefix = cpp_shared ? "qtd_export_" : "qtd_";
2688 << "private extern(C) int qtd_" << d_class->name() << "_qt_metacall_dispatch(void *d_entity, QMetaObject.Call _c, int _id, void **_a) {" 2694
2689 << " auto d_object = cast(" << d_class->name() << ") d_entity;" 2695 if (d_class->name() == "QObject") {
2690 << " return d_object.qt_metacall(_c, _id, _a);" 2696 s << "extern(C) int " << prefix << "QObject_qt_metacall_dispatch(void *d_entity, QMetaObject.Call _c, int _id, void **_a) {" << endl
2691 << "}" << endl << endl 2697 << " auto d_object = cast(QObject) d_entity;" << endl
2692 2698 << " return d_object.qt_metacall(_c, _id, _a);" << endl
2693 << "private extern(C) void* qtd_" << d_class->name() << "_metaObject_dispatch(void *d_entity) {" 2699 << "};" << endl << endl;
2694 << " auto d_object = cast(" << d_class->name() << ") d_entity;" 2700
2695 << " return d_object.metaObject().nativeId();" 2701 s << "extern(C) void* " << prefix << "QObject_metaObject_dispatch(void *d_entity) {" << endl
2696 << "}" << endl << endl; 2702 << " auto d_object = cast(QObject) d_entity;" << endl
2697 } 2703 << " return d_object.metaObject().nativeId();" << endl
2704 << "};" << endl << endl;
2705 }
2706 }
2698 2707
2699 void writeMetaMethodSignatures(QTextStream &s, const QString &var_name, AbstractMetaFunctionList meta_funcs) 2708 void writeMetaMethodSignatures(QTextStream &s, const QString &var_name, AbstractMetaFunctionList meta_funcs)
2700 { 2709 {
2701 s << INDENT << "private static const string[] " << var_name << " = ["; 2710 s << INDENT << "private static const string[] " << var_name << " = [";
2702 { 2711 {
2724 s << INDENT << "];" << endl << endl; 2733 s << INDENT << "];" << endl << endl;
2725 } 2734 }
2726 2735
2727 void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class) 2736 void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class)
2728 { 2737 {
2729 AbstractMetaFunctionList d_funcs_gen = generatedClassFunctions(d_class); 2738 AbstractMetaFunctionList d_funcs_gen = generatedClassFunctions(d_class);
2730 AbstractMetaFunctionList slot_funcs; 2739 AbstractMetaFunctionList slot_funcs;
2731 for (int i=0; i<d_funcs_gen.size(); ++i) { 2740 for (int i=0; i<d_funcs_gen.size(); ++i) {
2732 AbstractMetaFunction *function = d_funcs_gen.at(i); 2741 AbstractMetaFunction *function = d_funcs_gen.at(i);
2733 if(function->isSlot()) 2742 if(function->isSlot())
2734 slot_funcs += function; 2743 slot_funcs += function;
2735 } 2744 }
2736 writeMetaMethodSignatures(s, "__slotSignatures", slot_funcs); 2745 writeMetaMethodSignatures(s, "__slotSignatures", slot_funcs);
2737 2746
2738 if (d_class->isAbstract()) 2747 if (d_class->isAbstract())
2739 s << "alias " << d_class->name() << "_ConcreteWrapper ConcreteType;" << endl; 2748 s << "alias " << d_class->name() << "_ConcreteWrapper ConcreteType;" << endl;
2740 2749
2741 if (!d_class->isFinal()) 2750 if (!d_class->isFinal()) {
2742 s << " int qt_metacall(QMetaObject.Call _c, int _id, void **_a) {" << endl 2751 s << " int qt_metacall(QMetaObject.Call _c, int _id, void **_a) {" << endl
2743 << " return qtd_" << d_class->name() << "_qt_metacall(__nativeId, _c, _id, _a);" << endl 2752 << " return qtd_" << d_class->name() << "_qt_metacall(__nativeId, _c, _id, _a);" << endl
2744 << " }" << endl << endl; 2753 << " }" << endl << endl;
2745 2754 }
2746 s << " private static __gshared QMetaObject _staticMetaObject;" << endl 2755
2747 << " protected static void setStaticMetaObject(QMetaObject m) {" << endl 2756 s << " private static __gshared QMetaObject _staticMetaObject;" << endl
2748 << " _staticMetaObject = m;" << endl 2757 << " protected static void setStaticMetaObject(QMetaObject m) {" << endl
2749 << " }" << endl << endl 2758 << " _staticMetaObject = m;" << endl
2750 2759 << " }" << endl << endl
2751 << " @property QMetaObject metaObject() {" << endl 2760
2752 << " return _staticMetaObject;" << endl 2761 << " @property QMetaObject metaObject() {" << endl
2753 << " }" << endl << endl 2762 << " return _staticMetaObject;" << endl
2754 2763 << " }" << endl << endl
2755 << " @property static QMetaObject staticMetaObject() {" << endl 2764
2756 << " if (!_staticMetaObject)" << endl 2765 << " @property static QMetaObject staticMetaObject() {" << endl
2757 << " QMetaObject.create!(typeof(this))(qtd_" << d_class->name() << "_staticMetaObject());" << endl 2766 << " if (!_staticMetaObject)" << endl
2758 << " return _staticMetaObject;" << endl 2767 << " QMetaObject.create!(typeof(this))(qtd_" << d_class->name() << "_staticMetaObject());" << endl
2759 << " }" << endl << endl 2768 << " return _staticMetaObject;" << endl
2760 2769 << " }" << endl << endl
2761 << " static " << d_class->name() << " __getObject(void* nativeId) {" << endl 2770
2762 << " return static_cast!(" << d_class->name() << ")(_staticMetaObject.getObject(nativeId));" << endl 2771 << " static " << d_class->name() << " __getObject(void* nativeId) {" << endl
2763 << " }" << endl << endl 2772 << " return static_cast!(" << d_class->name() << ")(_staticMetaObject.getObject(nativeId));" << endl
2764 2773 << " }" << endl << endl
2765 << " /* internal */ static void __createEntity(void* nativeId, void* dId) {" << endl 2774
2766 << " return qtd_" << d_class->name() << "_createEntity(nativeId, dId);" << endl 2775 << " /* internal */ static void __createEntity(void* nativeId, void* dId) {" << endl
2767 << " }" << endl << endl 2776 << " return qtd_" << d_class->name() << "_createEntity(nativeId, dId);" << endl
2768 2777 << " }" << endl << endl
2769 << " /* internal */ static void _populateMetaInfo() {" << endl 2778
2770 << " int index;" << endl << endl; 2779 << " /* internal */ static void _populateMetaInfo() {" << endl
2771 2780 << " int index;" << endl << endl;
2772 AbstractMetaFunctionList signal_funcs = signalFunctions(d_class, false); 2781
2773 2782 AbstractMetaFunctionList signal_funcs = signalFunctions(d_class, false);
2774 int staticId = 0; 2783
2775 for (int i = 0; i < signal_funcs.size(); ++i) 2784 int staticId = 0;
2776 { 2785 for (int i = 0; i < signal_funcs.size(); ++i)
2786 {
2777 int j = 0; 2787 int j = 0;
2778 bool hasDefault = false; 2788 bool hasDefault = false;
2779 do // need this to look for default arguments and generate extra signatures 2789 do // need this to look for default arguments and generate extra signatures
2780 { 2790 {
2781 AbstractMetaFunction *fn = signal_funcs.at(i); 2791 AbstractMetaFunction *fn = signal_funcs.at(i);
2782 s << " index = _staticMetaObject.indexOfMethod_Cpp(__signalSignatures[" << staticId << "]);" << endl 2792 s << " index = _staticMetaObject.indexOfMethod_Cpp(__signalSignatures[" << staticId << "]);" << endl
2783 << " _staticMetaObject.addMethod(new QMetaSignal(signature!("; 2793 << " _staticMetaObject.addMethod(new QMetaSignal(signature!(";
2784 writeMetaMethodArguments(s, fn, j); 2794 writeMetaMethodArguments(s, fn, j);
2785 s << ")(\"" << fn->name() << "\"), index));" << endl << endl; 2795 s << ")(\"" << fn->name() << "\"), index));" << endl << endl;
2786 AbstractMetaArgumentList args = fn->arguments(); 2796 AbstractMetaArgumentList args = fn->arguments();
2787 if(args.size() && j<args.size()) 2797 if(args.size() && j<args.size())
2788 hasDefault = !args.at(args.size() - 1 - j)->defaultValueExpression().isEmpty(); 2798 hasDefault = !args.at(args.size() - 1 - j)->defaultValueExpression().isEmpty();
2789 else 2799 else
2790 hasDefault = false; 2800 hasDefault = false;
2791 j++; 2801 j++;
2792 staticId++; 2802 staticId++;
2793 } while (hasDefault); 2803 } while (hasDefault);
2794 } 2804 }
2795 2805
2796 staticId = 0; 2806 staticId = 0;
2797 for (int i = 0; i < slot_funcs.size(); ++i) 2807 for (int i = 0; i < slot_funcs.size(); ++i)
2798 { 2808 {
2799 int j = 0; 2809 int j = 0;
2800 bool hasDefault = false; 2810 bool hasDefault = false;
2801 do // need this to look for default arguments and generate extra signatures 2811 do // need this to look for default arguments and generate extra signatures
2802 { 2812 {
2803 AbstractMetaFunction *fn = slot_funcs.at(i); 2813 AbstractMetaFunction *fn = slot_funcs.at(i);
2804 s << " index = _staticMetaObject.indexOfMethod_Cpp(__slotSignatures[" << staticId << "]);" << endl 2814 s << " index = _staticMetaObject.indexOfMethod_Cpp(__slotSignatures[" << staticId << "]);" << endl
2805 << " _staticMetaObject.addMethod(new QMetaSlot(signature!("; 2815 << " _staticMetaObject.addMethod(new QMetaSlot(signature!(";
2806 writeMetaMethodArguments(s, fn, j); 2816 writeMetaMethodArguments(s, fn, j);
2807 s << ")(\"" << fn->name() << "\"), index));" << endl << endl; 2817 s << ")(\"" << fn->name() << "\"), index));" << endl << endl;
2808 AbstractMetaArgumentList args = fn->arguments(); 2818 AbstractMetaArgumentList args = fn->arguments();
2809 if(args.size() && j<args.size()) 2819 if(args.size() && j<args.size())
2810 hasDefault = !args.at(args.size() - 1 - j)->defaultValueExpression().isEmpty(); 2820 hasDefault = !args.at(args.size() - 1 - j)->defaultValueExpression().isEmpty();
2811 else 2821 else
2812 hasDefault = false; 2822 hasDefault = false;
2813 j++; 2823 j++;
2814 staticId++; 2824 staticId++;
2815 } while (hasDefault); 2825 } while (hasDefault);
2816 } 2826 }
2817 2827
2818 s << " }" << endl << endl; 2828 s << " }" << endl << endl;
2819 2829
2820 s << INDENT << "mixin Q_OBJECT_BIND;" << endl << endl; 2830 s << INDENT << "mixin Q_OBJECT_BIND;" << endl << endl;
2821 } 2831 }
2822 2832
2823 void DGenerator::marshalFromCppToD(QTextStream &s, const ComplexTypeEntry* ctype) 2833 void DGenerator::marshalFromCppToD(QTextStream &s, const ComplexTypeEntry* ctype)
2824 { 2834 {
2825 if(ctype->isQObject()) { 2835 if(ctype->isQObject()) {
2946 Q_UNUSED(implementor); 2956 Q_UNUSED(implementor);
2947 2957
2948 if (implementor != d_function->declaringClass()) 2958 if (implementor != d_function->declaringClass())
2949 return; 2959 return;
2950 2960
2951 s << "private extern(C) ";
2952 CppImplGenerator::writeVirtualDispatchFunction(s, d_function, implementor, true); 2961 CppImplGenerator::writeVirtualDispatchFunction(s, d_function, implementor, true);
2953 s << "{" << endl; 2962 s << "{" << endl;
2954 2963
2955 const AbstractMetaClass *own_class = d_function->ownerClass(); 2964 const AbstractMetaClass *own_class = d_function->ownerClass();
2956 2965
3476 << " return __qt_clone(nativeId());" << endl 3485 << " return __qt_clone(nativeId());" << endl
3477 << " }" << endl 3486 << " }" << endl
3478 << " native " << d_class->name() << " __qt_clone(long __this_nativeId);" << endl; 3487 << " native " << d_class->name() << " __qt_clone(long __this_nativeId);" << endl;
3479 } 3488 }
3480 3489
3490 void DGenerator::writeDExport(QTextStream &s, QString retType, QString name, QString args, QString funcBody)
3491 {
3492 QString qtdExtern = "extern (C)"; // TODO: should be settable via a generator switch
3493 if (cpp_shared) {
3494 s << QString(
3495 " %5 %1 qtd_export_%2(%3) { %4 }\n"
3496 " %5 export void qtd_set_%2(VoidFunc func);\n"
3497 " static this() { qtd_set_%2(cast(VoidFunc)&qtd_export_%2); }\n")
3498 .arg(retType, name, args, funcBody, qtdExtern);
3499 } else {
3500 s << QString("%5 %1 qtd_%2(%3) { %4 }\n")
3501 .arg(retType, name, args, funcBody, qtdExtern);
3502 }
3503 }
3504
3481 ClassFromEntry* ClassFromEntry::m_instance = NULL; 3505 ClassFromEntry* ClassFromEntry::m_instance = NULL;
3482 3506
3483 ClassFromEntry::ClassFromEntry() 3507 ClassFromEntry::ClassFromEntry()
3484 { 3508 {
3485 } 3509 }
3509 } 3533 }
3510 } 3534 }
3511 3535
3512 void ClassFromEntry::print(QTextStream &s) 3536 void ClassFromEntry::print(QTextStream &s)
3513 { 3537 {
3514 s << "_fuck_" << m_instance->m_classes.size(); 3538 s << m_instance->m_classes.size();
3515 foreach (AbstractMetaClass *cls, m_instance->m_classes) { 3539 foreach (AbstractMetaClass *cls, m_instance->m_classes) {
3516 s << cls->name() << endl; 3540 s << cls->name() << endl;
3517 } 3541 }
3518 } 3542 }
3519 3543