comparison generator/dgenerator.cpp @ 384:d2f48c4cb3e3

Same behavior of shared libs on linux and windows. Minor build script fixes.
author Max Samukha <maxter@spambox.com>
date Fri, 16 Jul 2010 20:04:29 +0300
parents 7341c47790d4
children 7dddafad5a20
comparison
equal deleted inserted replaced
383:bd7f485e3573 384:d2f48c4cb3e3
37 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 37 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
38 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 38 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
39 ** 39 **
40 ****************************************************************************/ 40 ****************************************************************************/
41 41
42 #include "global.h"
42 #include "dgenerator.h" 43 #include "dgenerator.h"
43 #include "reporthandler.h" 44 #include "reporthandler.h"
44 #include "docparser.h" 45 #include "docparser.h"
45 #include "jumptable.h" 46 #include "jumptable.h"
46 #include "fileout.h" 47 #include "fileout.h"
122 123
123 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)
124 d_type = d_type->originalTemplateType(); 125 d_type = d_type->originalTemplateType();
125 126
126 QString constPrefix, constPostfix; 127 QString constPrefix, constPostfix;
127 if (d_type && d_type->isConstant() && dVersion == 2) { 128 if (d_type && d_type->isConstant() && global.dVersion == 2) {
128 constPrefix = "const("; 129 constPrefix = "const(";
129 constPostfix = ")"; 130 constPostfix = ")";
130 } 131 }
131 132
132 if (!d_type) { 133 if (!d_type) {
853 bool force_abstract = te->isComplex() && (((static_cast<const ComplexTypeEntry *>(te))->typeFlags() & ComplexTypeEntry::ForceAbstract) != 0); 854 bool force_abstract = te->isComplex() && (((static_cast<const ComplexTypeEntry *>(te))->typeFlags() & ComplexTypeEntry::ForceAbstract) != 0);
854 if (!force_abstract) { 855 if (!force_abstract) {
855 s << arg_name << " is null ? null : "; 856 s << arg_name << " is null ? null : ";
856 } // else if (value type is abstract) then we will get a null pointer exception, which is all right 857 } // else if (value type is abstract) then we will get a null pointer exception, which is all right
857 858
858 if(dVersion == 2 && type->isConstant()) 859 if(global.dVersion == 2 && type->isConstant())
859 s << "(cast(" << type->name() << ")" << arg_name << ").qtdNativeId"; 860 s << "(cast(" << type->name() << ")" << arg_name << ").qtdNativeId";
860 else 861 else
861 s << arg_name << ".qtdNativeId"; 862 s << arg_name << ".qtdNativeId";
862 } 863 }
863 } 864 }
1850 FileOut auxFile(outputDirectory() + "/" + subDirectoryForClass(d_class) + "/" + d_class->name() + "_aux.d"); 1851 FileOut auxFile(outputDirectory() + "/" + subDirectoryForClass(d_class) + "/" + d_class->name() + "_aux.d");
1851 auxFile.isDone = true; 1852 auxFile.isDone = true;
1852 auxFile.stream << "module " << auxModName << ";" << endl << endl; 1853 auxFile.stream << "module " << auxModName << ";" << endl << endl;
1853 1854
1854 bool staticInit = d_class->isQObject() || d_class->typeEntry()->isValue() 1855 bool staticInit = d_class->isQObject() || d_class->typeEntry()->isValue()
1855 || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface() && !d_class->isNamespace()); 1856 || (global.cppShared && d_class->generateShellClass() && !d_class->isInterface() && !d_class->isNamespace());
1856 if (staticInit) 1857 if (staticInit)
1857 { 1858 {
1858 auxFile.isDone = false; 1859 auxFile.isDone = false;
1859 auxFile.stream << "extern(C) void static_init_" << d_class->name() << "();" << endl; 1860 auxFile.stream << "extern(C) void static_init_" << d_class->name() << "();" << endl;
1860 auxFile.stream << "shared static this() { static_init_" << d_class->name() << "; }" << endl << endl; 1861 auxFile.stream << "shared static this() { static_init_" << d_class->name() << "; }" << endl << endl;
1984 s << "private import " << d_class->package() << ".ArrayOps2;" << endl; 1985 s << "private import " << d_class->package() << ".ArrayOps2;" << endl;
1985 1986
1986 s << "// automatic imports-------------" << endl; 1987 s << "// automatic imports-------------" << endl;
1987 writeRequiredImports(s, d_class); 1988 writeRequiredImports(s, d_class);
1988 s << endl; 1989 s << endl;
1989 if (dPhobos) 1990 if (global.dPhobos)
1990 { 1991 {
1991 s << "import std.stdio;" << endl 1992 s << "import std.stdio;" << endl
1992 << "import std.string : toStringz;" << endl 1993 << "import std.string : toStringz;" << endl
1993 << "import std.utf;" << endl 1994 << "import std.utf;" << endl
1994 << "import core.memory;" << endl; 1995 << "import core.memory;" << endl;
2546 } 2547 }
2547 2548
2548 // write static constructor 2549 // write static constructor
2549 if (staticInit) { 2550 if (staticInit) {
2550 QString initArgs; 2551 QString initArgs;
2551 if (cpp_shared && d_class->generateShellClass()) 2552 if (global.cppShared && d_class->generateShellClass())
2552 { 2553 {
2553 initArgs = "void* virtuals"; 2554 initArgs = "void* virtuals";
2554 if (d_class->name() == "QObject") 2555 if (d_class->name() == "QObject")
2555 initArgs += ", void* signals"; 2556 initArgs += ", void* signals";
2556 2557
2561 s << "extern(C) void static_init_" << d_class->name() << "() {" << endl; 2562 s << "extern(C) void static_init_" << d_class->name() << "() {" << endl;
2562 2563
2563 if (d_class->typeEntry()->isValue()) 2564 if (d_class->typeEntry()->isValue())
2564 s << INDENT << d_class->name() << ".QTypeInfo.init();" << endl; 2565 s << INDENT << d_class->name() << ".QTypeInfo.init();" << endl;
2565 2566
2566 if (cpp_shared && d_class->generateShellClass()) { 2567 if (global.cppShared && d_class->generateShellClass()) {
2567 2568
2568 AbstractMetaFunction::Options opts(AbstractMetaFunction::DeclaringClass | AbstractMetaFunction::NoExternNamespace); 2569 AbstractMetaFunction::Options opts(AbstractMetaFunction::DeclaringClass | AbstractMetaFunction::NoExternNamespace);
2569 2570
2570 // virtual functions 2571 // virtual functions
2571 s << INDENT << "void*[" << virtualFunctions.size() << "] virt_arr;" << endl; 2572 s << INDENT << "void*[" << virtualFunctions.size() << "] virt_arr;" << endl;
2686 { 2687 {
2687 s << "extern(C) QMetaObjectNative* qtd_" << d_class->name() << "_staticMetaObject();" << endl << endl 2688 s << "extern(C) QMetaObjectNative* qtd_" << d_class->name() << "_staticMetaObject();" << endl << endl
2688 << "extern(C) void qtd_" << d_class->name() << "_createEntity(void* nativeId, void* dId);" << endl << endl 2689 << "extern(C) void qtd_" << d_class->name() << "_createEntity(void* nativeId, void* dId);" << endl << endl
2689 << "extern(C) int qtd_" << d_class->name() << "_qt_metacall(void *nativeId, MetaCall _c, int _id, void **_a);" << endl; 2690 << "extern(C) int qtd_" << d_class->name() << "_qt_metacall(void *nativeId, MetaCall _c, int _id, void **_a);" << endl;
2690 2691
2691 QString prefix = cpp_shared ? "qtd_export_" : "qtd_"; 2692 QString prefix = global.cppShared ? "qtd_export_" : "qtd_";
2692 2693
2693 if (d_class->name() == "QObject") { 2694 if (d_class->name() == "QObject") {
2694 s << "extern(C) int " << prefix << "QObject_qt_metacall_dispatch(void *d_entity, MetaCall _c, int _id, void **_a) {" << endl 2695 s << "extern(C) int " << prefix << "QObject_qt_metacall_dispatch(void *d_entity, MetaCall _c, int _id, void **_a) {" << endl
2695 << " auto d_object = cast(QObject) d_entity;" << endl 2696 << " auto d_object = cast(QObject) d_entity;" << endl
2696 << " return d_object.qt_metacall(_c, _id, _a);" << endl 2697 << " return d_object.qt_metacall(_c, _id, _a);" << endl
3483 << " native " << d_class->name() << " __qt_clone(long __this_nativeId);" << endl; 3484 << " native " << d_class->name() << " __qt_clone(long __this_nativeId);" << endl;
3484 } 3485 }
3485 3486
3486 void DGenerator::writeDExport(QTextStream &s, QString retType, QString name, QString args, QString funcBody) 3487 void DGenerator::writeDExport(QTextStream &s, QString retType, QString name, QString args, QString funcBody)
3487 { 3488 {
3488 QString qtdExtern = "extern (C)"; // TODO: should be settable via a generator switch 3489 QString ext = "extern (C)";
3489 if (cpp_shared) { 3490
3491 if (global.cppShared) {
3492 QString exp;
3493 if (global.targetPlatform == Global::Win32Target)
3494 exp = "export";
3495
3490 s << QString( 3496 s << QString(
3491 " %5 %1 qtd_export_%2(%3) { %4 }\n" 3497 " %5 %1 qtd_export_%2(%3) { %4 }\n"
3492 " %5 export void qtd_set_%2(VoidFunc func);\n" 3498 " %5 %6 void qtd_set_%2(VoidFunc func);\n"
3493 " static this() { qtd_set_%2(cast(VoidFunc)&qtd_export_%2); }\n") 3499 " static this() { qtd_set_%2(cast(VoidFunc)&qtd_export_%2); }\n")
3494 .arg(retType, name, args, funcBody, qtdExtern); 3500 .arg(retType, name, args, funcBody, ext, exp);
3495 } else { 3501 } else {
3496 s << QString("%5 %1 qtd_%2(%3) { %4 }\n") 3502 s << QString("%5 %1 qtd_%2(%3) { %4 }\n")
3497 .arg(retType, name, args, funcBody, qtdExtern); 3503 .arg(retType, name, args, funcBody, ext);
3498 } 3504 }
3499 } 3505 }
3500 3506
3501 ClassFromEntry* ClassFromEntry::m_instance = NULL; 3507 ClassFromEntry* ClassFromEntry::m_instance = NULL;
3502 3508