diff options
author | Friedemann Kleint <Friedemann.Kleint@theqtcompany.com> | 2015-06-09 16:17:36 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@theqtcompany.com> | 2015-06-16 09:38:09 +0000 |
commit | 3054c1d870eb41e3e7e922806f8f1771cb651819 (patch) | |
tree | 779b5aa41523ec4cef9ff17df1930ccd01c5e5eb /tools | |
parent | a486c7b0cdf727de6aeb521d7ae571d1c443c9c4 (diff) | |
download | qtactiveqt-3054c1d870eb41e3e7e922806f8f1771cb651819.tar.gz |
dumpcpp: Do not generate qRegisterMetaType<> for vtable-stubs.
vtable-stubs inherit QAxObject and can thus not be copied. When
using qRegisterMetaType<> on them, cryptic error messages are
generated:
src/activeqt/container/qaxobject.h(58) : error C2248: 'QObject::QObject' : cannot access private member declared in class 'QObject'
src/corelib/kernel/qobject.h(275) : see declaration of 'QObject::QObject'
include\qtcore\../../src/corelib/kernel/qobject.h(96) : see declaration of 'QObject'
To fix this, extract a list of the stubs at the beginning and suppress
the generation of qRegisterMetaType<> for them.
When writing out the class declaration, explicitly disable copy
for them to make error messages clearer.
Task-number: QTBUG-27792
Change-Id: Ia538a68864f3621234c1aab366b097ded881e859
Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/dumpcpp/main.cpp | 58 |
1 files changed, 40 insertions, 18 deletions
diff --git a/tools/dumpcpp/main.cpp b/tools/dumpcpp/main.cpp index 1fbcaa8..692ae67 100644 --- a/tools/dumpcpp/main.cpp +++ b/tools/dumpcpp/main.cpp @@ -82,6 +82,7 @@ extern void qax_deleteMetaObject(QMetaObject *mo); QMap<QByteArray, QByteArray> namespaceForType; QVector<QByteArray> strings; QHash<QByteArray, int> stringIndex; // Optimization, speeds up generation +QByteArrayList vTableOnlyStubs; void writeEnums(QTextStream &out, const QMetaObject *mo) { @@ -491,7 +492,8 @@ void generateClassDecl(QTextStream &out, const QString &controlID, const QMetaOb QByteArray simpleSlotTypeWithNamespace = slotType; simpleSlotTypeWithNamespace.replace('*', ""); out << indent << " qRegisterMetaType<" << simpleSlotTypeWithNamespace << "*>(\"" << simpleSlotType << "*\", &qax_result);" << endl; - out << indent << " qRegisterMetaType<" << simpleSlotTypeWithNamespace << ">(\"" << simpleSlotType << "\", qax_result);" << endl; + if (!vTableOnlyStubs.contains(simpleSlotTypeWithNamespace)) + out << indent << " qRegisterMetaType<" << simpleSlotTypeWithNamespace << ">(\"" << simpleSlotType << "\", qax_result);" << endl; if (foreignNamespace) out << "#endif" << endl; } @@ -902,6 +904,35 @@ static void formatCommentBlockFooter(const QString &typeLibFile, QTextStream &st << "****************************************************************************/\n\n"; } +static QByteArray classNameFromTypeInfo(ITypeInfo *typeinfo) +{ + BSTR bstr; + QByteArray result; + if (SUCCEEDED(typeinfo->GetDocumentation(-1, &bstr, 0, 0, 0))) { + result = QString::fromWCharArray(bstr).toLatin1(); + SysFreeString(bstr); + } + return result; +} + +// Extract a list of VTable only stubs from a ITypeLib. +static QByteArrayList vTableOnlyStubsFromTypeLib(ITypeLib *typelib, const QString &nameSpace) +{ + QByteArrayList result; + const QByteArray nameSpacePrefix = nameSpace.toLatin1() + "::"; + for (UINT i = 0, typeCount = typelib->GetTypeInfoCount(); i < typeCount; ++i) { + TYPEKIND typekind; + if (SUCCEEDED(typelib->GetTypeInfoType(i, &typekind)) && typekind == TKIND_INTERFACE) { + ITypeInfo *typeinfo = Q_NULLPTR; + if (SUCCEEDED(typelib->GetTypeInfo(i, &typeinfo) && typeinfo)) { + result.append(nameSpacePrefix + classNameFromTypeInfo(typeinfo)); + typeinfo->Release(); + } + } + } + return result; +} + bool generateTypeLibrary(QString typeLibFile, QString outname, const QString &nameSpace, ObjectCategory category) { @@ -922,6 +953,7 @@ bool generateTypeLibrary(QString typeLibFile, QString outname, SysFreeString(nameString); } } + vTableOnlyStubs = vTableOnlyStubsFromTypeLib(typelib, libName); QString libVersion(QLatin1String("1.0")); @@ -1031,12 +1063,7 @@ bool generateTypeLibrary(QString typeLibFile, QString outname, case TKIND_ENUM: case TKIND_INTERFACE: // only for forward declarations { - QByteArray className; - BSTR bstr; - if (S_OK != typeinfo->GetDocumentation(-1, &bstr, 0, 0, 0)) - break; - className = QString::fromWCharArray(bstr).toLatin1(); - SysFreeString(bstr); + QByteArray className = classNameFromTypeInfo(typeinfo); switch (typekind) { case TKIND_RECORD: className.prepend("struct "); @@ -1174,17 +1201,12 @@ bool generateTypeLibrary(QString typeLibFile, QString outname, else metaObject = qax_readInterfaceInfo(typelib, typeinfo, &QObject::staticMetaObject); break; - case TKIND_INTERFACE: // only stub - { - QByteArray className; - BSTR bstr; - if (S_OK != typeinfo->GetDocumentation(-1, &bstr, 0, 0, 0)) - break; - className = QString::fromWCharArray(bstr).toLatin1(); - SysFreeString(bstr); - - declOut << "// stub for vtable-only interface" << endl; - declOut << "class " << className << " : public QAxObject {};" << endl << endl; + case TKIND_INTERFACE: { // only stub: QTBUG-27792, explicitly disable copy in inherited + // class to make related error messages clearer + const QByteArray className = classNameFromTypeInfo(typeinfo); + declOut << "// stub for vtable-only interface\n" + << "class " << className << " : public QAxObject { Q_DISABLE_COPY(" + << className << ") };\n\n"; } break; default: |