From 3054c1d870eb41e3e7e922806f8f1771cb651819 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 9 Jun 2015 16:17:36 +0200 Subject: 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 --- tools/dumpcpp/main.cpp | 58 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 18 deletions(-) (limited to 'tools') 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 namespaceForType; QVector strings; QHash 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: -- cgit v1.2.1