Mercurial > projects > qtd
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 |