summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2022-06-20 08:25:31 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2022-06-21 07:30:38 +0200
commit99c59f82575695163e45e3848a5338f2d4fadaae (patch)
tree5e25b243c64fc966bcf46972a0385e3d3bb43b18
parent367953246cd5867f1d82918ad6e1b1727d1cd783 (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 Pick-to: 6.4 6.3 Change-Id: I500353d9788e3ea20bf1cc64172ca1b640976e5e Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
-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 664e406..e1cb0c8 100644
--- a/src/activeqt/container/qaxbase.cpp
+++ b/src/activeqt/container/qaxbase.cpp
@@ -1756,6 +1756,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)
{
@@ -1812,8 +1869,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;
@@ -2166,10 +2226,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
@@ -2183,31 +2242,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 58e58ef..9471fcf 100644
--- a/tools/dumpcpp/main.cpp
+++ b/tools/dumpcpp/main.cpp
@@ -50,6 +50,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);
@@ -596,19 +597,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)
@@ -782,9 +770,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);