summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2022-06-20 08:25:31 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-06-21 05:49:14 +0000
commitf5bf8f131654c06aa6dfcc3901f8e72979cdcdd3 (patch)
tree685d5649037eb64233816d78ac4ca5f25c8e48ae
parent7dc64a372bec95d43c9384b752456c7ab1e0db47 (diff)
dumpcpp: Completely specify enums from referenced typelibs
Forward-declaring enums causes problems with the moc-generated code. Introduce a variable to qaxbase storing the preformatted value string. Task-number: QTBUG-100145 Change-Id: I500353d9788e3ea20bf1cc64172ca1b640976e5e Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit 99c59f82575695163e45e3848a5338f2d4fadaae) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/activeqt/container/qaxbase.cpp101
-rw-r--r--tools/dumpcpp/main.cpp27
2 files changed, 83 insertions, 45 deletions
diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp
index c97ad9a..a0a4dda 100644
--- a/src/activeqt/container/qaxbase.cpp
+++ b/src/activeqt/container/qaxbase.cpp
@@ -1803,6 +1803,63 @@ MetaObjectGenerator::~MetaObjectGenerator()
bool qax_dispatchEqualsIDispatch = true;
QByteArrayList qax_qualified_usertypes;
+// Value strings for enums
+QHash<QByteArray, QByteArray> qax_enum_values;
+
+// Read enum values
+QList<QPair<QByteArray, int> > qax_readEnumValues(ITypeLib *typelib, UINT index)
+{
+ QList<QPair<QByteArray, int> > result;
+
+ // Get the type information for the enum
+ ITypeInfo *enuminfo = nullptr;
+ typelib->GetTypeInfo(index, &enuminfo);
+ if (!enuminfo)
+ return result;
+
+ // Get the attributes of the enum type
+ TYPEATTR *typeattr = nullptr;
+ enuminfo->GetTypeAttr(&typeattr);
+ if (typeattr == nullptr) {
+ enuminfo->Release();
+ return result;
+ }
+
+ // Get all values of the enumeration
+ result.reserve(typeattr->cVars);
+ for (UINT vd = 0; vd < typeattr->cVars; ++vd) {
+ VARDESC *vardesc = nullptr;
+ enuminfo->GetVarDesc(vd, &vardesc);
+ if (vardesc != nullptr) {
+ if (vardesc->varkind == VAR_CONST) {
+ const int value = vardesc->lpvarValue->lVal;
+ QByteArray valueName = qaxTypeInfoName(enuminfo, vardesc->memid);
+ result.append({valueName, value});
+ }
+ enuminfo->ReleaseVarDesc(vardesc);
+ }
+ }
+ enuminfo->ReleaseTypeAttr(typeattr);
+ enuminfo->Release();
+ return result;
+}
+
+// Format enum values into a string v1=1, v2=2,...
+static QByteArray enumValueString(ITypeLib *typelib, UINT index)
+{
+ QByteArray result;
+ const auto enumValues = qax_readEnumValues(typelib, index);
+ const auto last = enumValues.size() - 1;
+ for (qsizetype i = 0; i <= last; ++i) {
+ const auto &enumValue = enumValues.at(i);
+ result += " " + enumValue.first + '='
+ + QByteArray::number(enumValue.second);
+ if (i < last)
+ result += ',';
+ result += '\n';
+ }
+ return result;
+}
QByteArray MetaObjectGenerator::usertypeToString(const TYPEDESC &tdesc, ITypeInfo *info, const QByteArray &function)
{
@@ -1859,8 +1916,11 @@ QByteArray MetaObjectGenerator::usertypeToString(const TYPEDESC &tdesc, ITypeInf
}
break;
case TKIND_ENUM:
- if (typeLibName != current_typelib)
+ if (typeLibName != current_typelib) {
userTypeName.prepend(typeLibName + "::");
+ // For dumpcpp
+ qax_enum_values.insert(userTypeName, enumValueString(usertypelib, index));
+ }
if (!qax_qualified_usertypes.contains("enum " + userTypeName))
qax_qualified_usertypes << "enum " + userTypeName;
break;
@@ -2213,10 +2273,9 @@ void MetaObjectGenerator::readEnumInfo()
TYPEKIND typekind;
typelib->GetTypeInfoType(i, &typekind);
if (typekind == TKIND_ENUM) {
- // Get the type information for the enum
- ITypeInfo *enuminfo = nullptr;
- typelib->GetTypeInfo(i, &enuminfo);
- if (!enuminfo)
+ // Get the values of the enum
+ const auto values = qax_readEnumValues(typelib, i);
+ if (values.isEmpty())
continue;
// Get the name of the enumeration
@@ -2230,31 +2289,15 @@ void MetaObjectGenerator::readEnumInfo()
}
// Get the attributes of the enum type
- TYPEATTR *typeattr = nullptr;
- enuminfo->GetTypeAttr(&typeattr);
- if (typeattr) {
- // Get all values of the enumeration
- for (UINT vd = 0; vd < typeattr->cVars; ++vd) {
- VARDESC *vardesc = nullptr;
- enuminfo->GetVarDesc(vd, &vardesc);
- if (vardesc && vardesc->varkind == VAR_CONST) {
- int value = vardesc->lpvarValue->lVal;
- int memid = vardesc->memid;
- // Get the name of the value
- QByteArray valueName = qaxTypeInfoName(enuminfo, memid);
- if (valueName.isEmpty())
- valueName = "value" + QByteArray::number(valueindex++);
- if (clashCheck.contains(QString::fromLatin1(valueName)))
- valueName += QByteArray::number(++clashIndex);
-
- clashCheck.insert(QString::fromLatin1(valueName));
- addEnumValue(enumName, valueName, value);
- }
- enuminfo->ReleaseVarDesc(vardesc);
- }
+ for (const auto &value : values) {
+ QByteArray valueName = value.first;
+ if (valueName.isEmpty())
+ valueName = "value" + QByteArray::number(valueindex++);
+ if (clashCheck.contains(QString::fromLatin1(valueName)))
+ valueName += QByteArray::number(++clashIndex);
+ clashCheck.insert(QString::fromLatin1(valueName));
+ addEnumValue(enumName, valueName, value.second);
}
- enuminfo->ReleaseTypeAttr(typeattr);
- enuminfo->Release();
}
}
diff --git a/tools/dumpcpp/main.cpp b/tools/dumpcpp/main.cpp
index 8dbdf3e..556073e 100644
--- a/tools/dumpcpp/main.cpp
+++ b/tools/dumpcpp/main.cpp
@@ -75,6 +75,7 @@ extern QMetaObject *qax_readEnumInfo(ITypeLib *typeLib, const QMetaObject *paren
extern QMetaObject *qax_readClassInfo(ITypeLib *typeLib, ITypeInfo *typeInfo, const QMetaObject *parentObject);
extern QMetaObject *qax_readInterfaceInfo(ITypeLib *typeLib, ITypeInfo *typeInfo, const QMetaObject *parentObject);
extern QByteArrayList qax_qualified_usertypes;
+extern QHash<QByteArray, QByteArray> qax_enum_values;
extern QString qax_docuFromName(ITypeInfo *typeInfo, const QString &name);
extern bool qax_dispatchEqualsIDispatch;
extern void qax_deleteMetaObject(QMetaObject *mo);
@@ -621,19 +622,6 @@ static QByteArrayList vTableOnlyStubsFromTypeLib(ITypeLib *typelib, const QStrin
return result;
}
-static void writeForwardDeclaration(QTextStream &declOut, const QByteArray &className)
-{
- if (className.startsWith("enum ")) {
- declOut << "#ifndef Q_CC_MINGW\n"
- << " " << className << ';' << Qt::endl // Only MSVC accepts this
- << "#else\n"
- << " " << className << " {};" << Qt::endl
- << "#endif\n";
- } else {
- declOut << " " << className << ';' << Qt::endl;
- }
-}
-
static const QMetaObject *baseMetaObject(ObjectCategories c)
{
return c.testFlag(ActiveX)
@@ -807,9 +795,16 @@ bool generateTypeLibrary(QString typeLibFile, QString outname,
if (libName != QLatin1String(nspace)) {
declOut << "namespace " << nspace << " {" << Qt::endl;
for (const auto &className : it.value()) {
- if (className.contains(' ')) {
- writeForwardDeclaration(declOut, className);
- namespaceForType.insert(className.mid(className.indexOf(' ') + 1), nspace);
+ const auto spacePos = className.indexOf(' ');
+ if (spacePos != -1) {
+ const QByteArray name = className.mid(spacePos + 1);
+ if (className.startsWith("enum ")) {
+ declOut << " " << className << " {\n"
+ << qax_enum_values.value(nspace + "::" + name) << " };\n";
+ } else {
+ declOut << " " << className << ";\n";
+ }
+ namespaceForType.insert(name, nspace);
} else {
declOut << " class " << className << ';' << Qt::endl;
opaquePointerTypes.append(nspace + "::" + className);