summaryrefslogtreecommitdiffstats
path: root/tools/dumpcpp/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/dumpcpp/main.cpp')
-rw-r--r--tools/dumpcpp/main.cpp521
1 files changed, 36 insertions, 485 deletions
diff --git a/tools/dumpcpp/main.cpp b/tools/dumpcpp/main.cpp
index 1545a39..d50c65d 100644
--- a/tools/dumpcpp/main.cpp
+++ b/tools/dumpcpp/main.cpp
@@ -26,10 +26,13 @@
**
****************************************************************************/
+#include "moc.h"
+
#include <QAxObject>
#include <QFile>
#include <QMetaObject>
#include <QMetaEnum>
+#include <QDebug>
#include <QTextStream>
#include <QSettings>
#include <QStringList>
@@ -85,17 +88,8 @@ void writeEnums(QTextStream &out, const QMetaObject *mo)
{
// enums
for (int ienum = mo->enumeratorOffset(); ienum < mo->enumeratorCount(); ++ienum) {
- QMetaEnum metaEnum = mo->enumerator(ienum);
- out << " enum " << metaEnum.name() << " {" << Qt::endl;
- for (int k = 0; k < metaEnum.keyCount(); ++k) {
- QByteArray key(metaEnum.key(k));
- out << " " << key.leftJustified(24) << "= " << metaEnum.value(k);
- if (k < metaEnum.keyCount() - 1)
- out << ',';
- out << Qt::endl;
- }
- out << " };" << Qt::endl;
- out << Qt::endl;
+ formatCppEnum(out, mo->enumerator(ienum));
+ out << '\n';
}
}
@@ -184,9 +178,12 @@ static void formatConstructorSignature(QTextStream &out, ObjectCategories catego
out << ')';
}
-static void formatConstructorBody(QTextStream &out, const QByteArray &className,
+static void formatConstructorBody(QTextStream &out, const QByteArray &nameSpace,
+ const QByteArray &className,
const QString &controlID, ObjectCategories category)
{
+ if (!nameSpace.isEmpty())
+ out << nameSpace << "::";
out << className << "::" << className;
formatConstructorSignature(out, category, false);
out << " :" << Qt::endl << " ";
@@ -258,21 +255,8 @@ void generateClassDecl(QTextStream &out, const QMetaObject *mo,
functions << className;
// enums
- if (nameSpace.isEmpty() && !(category & OnlyInlines)) {
- for (int ienum = mo->enumeratorOffset(); ienum < mo->enumeratorCount(); ++ienum) {
- QMetaEnum metaEnum = mo->enumerator(ienum);
- out << " enum " << metaEnum.name() << " {" << Qt::endl;
- for (int k = 0; k < metaEnum.keyCount(); ++k) {
- QByteArray key(metaEnum.key(k));
- out << " " << key.leftJustified(24) << "= " << metaEnum.value(k);
- if (k < metaEnum.keyCount() - 1)
- out << ',';
- out << Qt::endl;
- }
- out << " };" << Qt::endl;
- out << Qt::endl;
- }
- }
+ if (nameSpace.isEmpty() && !(category & OnlyInlines))
+ writeEnums(out, mo);
// QAxBase public virtual functions.
QByteArrayList axBase_vfuncs;
axBase_vfuncs.append("metaObject");
@@ -366,13 +350,7 @@ void generateClassDecl(QTextStream &out, const QMetaObject *mo,
functions << propertyName;
if (property.isWritable()) {
- QByteArray setter(propertyName);
- if (isupper(setter.at(0))) {
- setter = "Set" + setter;
- } else {
- setter[0] = char(toupper(setter[0]));
- setter = "set" + setter;
- }
+ const QByteArray setter = setterName(propertyName);
out << indent << "inline " << "void ";
if (category & OnlyInlines)
@@ -558,168 +536,10 @@ void generateClassDecl(QTextStream &out, const QMetaObject *mo,
}
}
-#define addStringIdx(string) \
- out << stridx(string) << ", ";
-
-// The following functions were copied from moc generator with only some minor changes
-void strreg(const QByteArray &s)
-{
- if (!stringIndex.contains(s)) {
- stringIndex.insert(s, strings.size());
- strings.append(s);
- }
-}
-
-void strDetachAndRegister(QByteArray s)
-{
- s.detach();
- strreg(s);
-}
-
-int stridx(const QByteArray &s)
-{
- int i = stringIndex.value(s);
- Q_ASSERT_X(i != -1, Q_FUNC_INFO, "We forgot to register some strings");
- return i;
-}
-
-const char *metaTypeEnumValueString(int type)
-{
-#define RETURN_METATYPENAME_STRING(MetaTypeName, MetaTypeId, RealType) \
- case QMetaType::MetaTypeName: return #MetaTypeName;
-
- switch (type) {
-QT_FOR_EACH_STATIC_TYPE(RETURN_METATYPENAME_STRING)
- }
-#undef RETURN_METATYPENAME_STRING
- return nullptr;
-}
-
-int nameToBuiltinType(const QByteArray &name)
-{
- if (name.isEmpty())
- return 0;
-
- const int tp = QMetaType::type(name.constData());
- return tp < QMetaType::User ? tp : QMetaType::UnknownType;
-}
-
-void copyFileToStream(QFile *file, QTextStream *stream)
-{
- file->seek(0);
- QByteArray buffer;
- const int bufferSize = 4096 * 1024;
- buffer.resize(bufferSize);
- while (!file->atEnd()) {
- const int bytesRead = static_cast<int>(file->read(buffer.data(), bufferSize));
- if (bytesRead < bufferSize) {
- buffer.resize(bytesRead);
- *stream << buffer;
- buffer.resize(bufferSize);
- } else {
- *stream << buffer;
- }
- }
-}
-
-void generateTypeInfo(QTextStream &out, const QByteArray &typeName)
-{
- if (QtPrivate::isBuiltinType(typeName)) {
- int type;
- QByteArray valueString;
- if (typeName == "qreal") {
- type = QMetaType::UnknownType;
- valueString = "QReal";
- } else {
- type = nameToBuiltinType(typeName);
- valueString = metaTypeEnumValueString(type);
- }
- if (!valueString.isEmpty()) {
- out << "QMetaType::" << valueString;
- } else {
- Q_ASSERT(type != QMetaType::UnknownType);
- out << type;
- }
- } else {
- Q_ASSERT(!typeName.isEmpty());
- out << "0x80000000 | " << stridx(typeName);
- }
-}
-// End functions copied from moc generator
-
-void generateMethods(QTextStream &out, const QMetaObject *mo, const QMetaMethod::MethodType funcType, int &paramsIndex)
-{
- out << "// ";
- MethodFlags funcTypeFlag;
- if (funcType == QMetaMethod::Signal) {
- out << "signal";
- funcTypeFlag = MethodSignal;
- } else {
- out << "slot";
- funcTypeFlag = MethodSlot;
- }
- out << ": name, argc, parameters, tag, flags" << Qt::endl;
-
- int methodCount = mo->methodCount();
- for (int i = mo->methodOffset(); i < methodCount; ++i) {
- const QMetaMethod method(mo->method(i));
- if (method.methodType() != funcType)
- continue;
- out << " ";
- addStringIdx(method.name());
- out << method.parameterCount() << ", ";
- out << paramsIndex << ", ";
- addStringIdx(method.tag());
- out << (AccessProtected | method.attributes() | funcTypeFlag) << ',' << Qt::endl;
- paramsIndex += 1 + method.parameterCount() * 2;
- }
- out << Qt::endl;
-}
-
-void generateMethodParameters(QTextStream &out, const QMetaObject *mo, const QMetaMethod::MethodType funcType)
-{
- out << "// ";
- if (funcType == QMetaMethod::Signal)
- out << "signal";
- else if (funcType == QMetaMethod::Slot)
- out << "slot";
- out << ": parameters" << Qt::endl;
-
- int methodCount = mo->methodCount();
- for (int i = mo->methodOffset(); i < methodCount; ++i) {
- const QMetaMethod method(mo->method(i));
- if (method.methodType() != funcType)
- continue;
-
- out << " ";
-
- int argsCount = method.parameterCount();
-
- // Return type
- generateTypeInfo(out, method.typeName());
- out << ',';
-
- // Parameter types
- const auto parameterTypes = method.parameterTypes();
- for (int j = 0; j < argsCount; ++j) {
- out << ' ';
- generateTypeInfo(out, parameterTypes.at(j));
- out << ',';
- }
-
- // Parameter names
- const auto parameterNames = method.parameterNames();
- for (int j = 0; j < argsCount; ++j)
- out << ' ' << stridx(parameterNames.at(j)) << ',';
-
- out << Qt::endl;
- }
- out << Qt::endl;
-}
-
-void generateClassImpl(QTextStream &out, const QMetaObject *mo, const QByteArray &className,
+bool generateClassImpl(QTextStream &out, const QMetaObject *mo, const QByteArray &className,
const QString &controlID,
- const QByteArray &nameSpace, ObjectCategories category)
+ const QByteArray &nameSpace, ObjectCategories category,
+ QString *errorString)
{
Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 8, "dumpcpp should generate the same version as moc");
@@ -727,203 +547,20 @@ void generateClassImpl(QTextStream &out, const QMetaObject *mo, const QByteArray
if (!nameSpace.isEmpty())
qualifiedClassName = nameSpace + "::";
qualifiedClassName += className;
- QByteArray qualifiedClassNameIdentifier = qualifiedClassName;
- qualifiedClassNameIdentifier.replace(':', '_');
-
- int allClassInfoCount = mo->classInfoCount();
- int allMethodCount = mo->methodCount();
- int allPropertyCount = mo->propertyCount();
- int allEnumCount = mo->enumeratorCount();
-
- int thisClassInfoCount = allClassInfoCount - mo->classInfoOffset();
- int thisEnumCount = allEnumCount - mo->enumeratorOffset();
- int thisMethodCount = allMethodCount - mo->methodOffset();
- int thisPropertyCount = allPropertyCount - mo->propertyOffset();
-
- int signalCount = 0;
- int slotCount = 0;
- int combinedParameterCount = 0;
- int enumStart = MetaObjectPrivateFieldCount;
-
- // Register strings
- strreg(qualifiedClassName);
- for (int i = mo->classInfoOffset(); i < allClassInfoCount; ++i) {
- const QMetaClassInfo classInfo = mo->classInfo(i);
- strreg(classInfo.name());
- strreg(classInfo.value());
- }
- for (int i = mo->methodOffset(); i < allMethodCount; ++i) {
- const QMetaMethod method(mo->method(i));
- if (method.methodType() == QMetaMethod::Signal)
- signalCount++;
- if (method.methodType() == QMetaMethod::Slot)
- slotCount++;
- int argsCount = method.parameterCount();
- combinedParameterCount += argsCount;
-
- strDetachAndRegister(method.name());
- QByteArray typeName = method.typeName();
- if (!QtPrivate::isBuiltinType(typeName))
- strreg(typeName);
- strreg(method.tag());
-
- const auto parameterNames = method.parameterNames();
- const auto parameterTypes = method.parameterTypes();
- for (int j = 0; j < argsCount; ++j) {
- if (!QtPrivate::isBuiltinType(parameterTypes.at(j)))
- strDetachAndRegister(parameterTypes.at(j));
- strDetachAndRegister(parameterNames.at(j));
- }
- }
- for (int i = mo->propertyOffset(); i < allPropertyCount; ++i) {
- const QMetaProperty property = mo->property(i);
- strreg(property.name());
- if (!QtPrivate::isBuiltinType(property.typeName()))
- strreg(property.typeName());
- }
- for (int i = mo->enumeratorOffset(); i < allEnumCount; ++i) {
- const QMetaEnum enumerator = mo->enumerator(i);
- strreg(enumerator.name());
- for (int j = 0; j < enumerator.keyCount(); ++j)
- strreg(enumerator.key(j));
- }
-
- // Build data array
- out << "static const uint qt_meta_data_" << qualifiedClassNameIdentifier << "[] = {" << Qt::endl;
- out << Qt::endl;
- out << " // content:" << Qt::endl;
- out << " 7, // revision" << Qt::endl;
- out << " ";
- addStringIdx(qualifiedClassName);
- out << " // classname" << Qt::endl;
- out << " " << thisClassInfoCount << ", " << (thisClassInfoCount ? enumStart : 0) << ", // classinfo" << Qt::endl;
- enumStart += thisClassInfoCount * 2;
- out << " " << thisMethodCount << ", " << (thisMethodCount ? enumStart : 0) << ", // methods" << Qt::endl;
- enumStart += thisMethodCount * 5;
- int paramsIndex = enumStart;
- enumStart += (combinedParameterCount * 2); // parameter types + names
- enumStart += thisMethodCount; // return types
- out << " " << thisPropertyCount << ", " << (thisPropertyCount ? enumStart : 0) << ", // properties" << Qt::endl;
- enumStart += thisPropertyCount * 3;
- out << " " << thisEnumCount << ", " << (thisEnumCount ? enumStart : 0) << ", // enums/sets" << Qt::endl;
- out << " 0, 0, // constructors" << Qt::endl;
- out << " 0, // flags" << Qt::endl;
- out << " " << signalCount << ", // signal count" << Qt::endl;
- out << Qt::endl;
-
- if (thisClassInfoCount) {
- out << " // classinfo: key, value" << Qt::endl;
- for (int i = mo->classInfoOffset(); i < allClassInfoCount; ++i) {
- QMetaClassInfo classInfo = mo->classInfo(i);
- out << " ";
- addStringIdx(classInfo.name());
- addStringIdx(classInfo.value());
- out << Qt::endl;
- }
- out << Qt::endl;
- }
-
- // Signal/Slot arrays
- if (signalCount)
- generateMethods(out, mo, QMetaMethod::Signal, paramsIndex);
- if (slotCount)
- generateMethods(out, mo, QMetaMethod::Slot, paramsIndex);
-
- // Method parameter arrays
- if (signalCount)
- generateMethodParameters(out, mo, QMetaMethod::Signal);
- if (slotCount)
- generateMethodParameters(out, mo, QMetaMethod::Slot);
-
- if (thisPropertyCount) {
- out << " // properties: name, type, flags" << Qt::endl;
- for (int i = mo->propertyOffset(); i < allPropertyCount; ++i) {
- QMetaProperty property = mo->property(i);
- out << " ";
- addStringIdx(property.name());
- generateTypeInfo(out, property.typeName());
- out << ", ";
-
- uint flags = 0;
- const auto vartype = property.type();
- if (vartype != QVariant::Invalid && vartype != QVariant::UserType)
- flags = uint(vartype) << 24;
-
- if (property.isReadable())
- flags |= Readable;
- if (property.isWritable())
- flags |= Writable;
- if (property.isEnumType())
- flags |= EnumOrFlag;
- if (property.isDesignable())
- flags |= Designable;
- if (property.isScriptable())
- flags |= Scriptable;
- if (property.isStored())
- flags |= Stored;
- if (property.isEditable())
- flags |= Editable;
-
- out << "0x" << QString::number(flags, 16).rightJustified(8, QLatin1Char('0'))
- << ", \t\t // " << property.typeName() << ' ' << property.name()
- << Qt::endl;
- }
- out << Qt::endl;
- }
-
- if (thisEnumCount) {
- out << " // enums: name, flags, count, data" << Qt::endl;
- enumStart += thisEnumCount * 4;
- for (int i = mo->enumeratorOffset(); i < allEnumCount; ++i) {
- QMetaEnum enumerator = mo->enumerator(i);
- out << " ";
- addStringIdx(enumerator.name());
- out << (enumerator.isFlag() ? "0x1" : "0x0") << ", " << enumerator.keyCount() << ", " << enumStart << ", " << Qt::endl;
- enumStart += enumerator.keyCount() * 2;
- }
- out << Qt::endl;
- out << " // enum data: key, value" << Qt::endl;
- for (int i = mo->enumeratorOffset(); i < allEnumCount; ++i) {
- QMetaEnum enumerator = mo->enumerator(i);
- for (int j = 0; j < enumerator.keyCount(); ++j) {
- out << " ";
- addStringIdx(enumerator.key(j));
- out << "uint(";
- if (nameSpace.isEmpty())
- out << className << "::";
- else
- out << nameSpace << "::";
- out << enumerator.key(j) << ")," << Qt::endl;
- }
- }
+ const QString moCode = mocCode(mo, QLatin1String(qualifiedClassName),
+ category.testFlag(ActiveX) ? QLatin1String("QWidget") : QLatin1String("QObject"),
+ errorString);
+ if (moCode.isEmpty()) {
+ out << "#error moc error\n";
+ return false;
}
- out << " 0 // eod" << Qt::endl;
- out << "};" << Qt::endl;
- out << Qt::endl;
- formatConstructorBody(out, className, controlID, category);
+ out << moCode << "\n\n";
- out << "const QMetaObject " << className << "::staticMetaObject = {" << Qt::endl;
- if (category & ActiveX)
- out << "{ &QWidget::staticMetaObject," << Qt::endl;
- else
- out << "{ &QObject::staticMetaObject," << Qt::endl;
- out << "qt_meta_stringdata_all.data," << Qt::endl;
- out << "qt_meta_data_" << qualifiedClassNameIdentifier << ", nullptr, nullptr, nullptr }" << Qt::endl;
- out << "};" << Qt::endl;
- out << Qt::endl;
+ formatConstructorBody(out, nameSpace, className, controlID, category);
- out << "void *" << className << "::qt_metacast(const char *_clname)" << Qt::endl;
- out << '{' << Qt::endl;
- out << " if (!_clname) return nullptr;" << Qt::endl;
- out << " if (!strcmp(_clname, \"" << qualifiedClassName << "\"))" << Qt::endl;
- out << " return static_cast<void*>(const_cast<" << className << "*>(this));" << Qt::endl;
- if (category & ActiveX)
- out << " return QAxWidget::qt_metacast(_clname);" << Qt::endl;
- else
- out << " return QAxObject::qt_metacast(_clname);" << Qt::endl;
- out << '}' << Qt::endl;
+ return true;
}
static void formatCommentBlockFooter(const QString &typeLibFile, QTextStream &str)
@@ -1020,12 +657,8 @@ bool generateTypeLibrary(QString typeLibFile, QString outname,
QMetaObject *namespaceObject = qax_readEnumInfo(typelib, nullptr);
- QTemporaryFile classImplFile;
- if (!classImplFile.open()) {
- qWarning("dumpcpp: Cannot open temporary file.");
- return false;
- }
- QTextStream classImplOut(&classImplFile);
+ QString classImpl;
+ QTextStream classImplOut(&classImpl);
QFile implFile(outname + QLatin1String(".cpp"));
QTextStream implOut(&implFile);
if (!(category & (NoMetaObject|NoImplementation))) {
@@ -1043,8 +676,6 @@ bool generateTypeLibrary(QString typeLibFile, QString outname,
implOut << "#include \"" << outname << ".h\"" << Qt::endl;
implOut << "#include <OAIdl.h>" << Qt::endl; // For IDispatch
implOut << Qt::endl;
- implOut << "using namespace " << libName << ';' << Qt::endl;
- implOut << Qt::endl;
}
QFile declFile(outname + QLatin1String(".h"));
@@ -1129,7 +760,6 @@ bool generateTypeLibrary(QString typeLibFile, QString outname,
default:
break;
}
-
qax_deleteMetaObject(metaObject);
typeinfo->ReleaseTypeAttr(typeattr);
typeinfo->Release();
@@ -1282,9 +912,14 @@ bool generateTypeLibrary(QString typeLibFile, QString outname,
object_category | OnlyInlines);
inlinesOut << Qt::endl;
}
- if (implFile.isOpen())
- generateClassImpl(classImplOut, metaObject, className, guid.toString(), libNameBa,
- object_category);
+ if (implFile.isOpen()) {
+ QString errorString;
+ if (!generateClassImpl(classImplOut, metaObject, className, guid.toString(), libNameBa,
+ object_category, &errorString)) {
+ qWarning("%s", qPrintable(errorString));
+ return false;
+ }
+ }
}
currentTypeInfo = nullptr;
}
@@ -1297,93 +932,9 @@ bool generateTypeLibrary(QString typeLibFile, QString outname,
// String table generation logic was ported from moc generator, with some modifications
// required to split large stringdata arrays.
- if (!strings.isEmpty() && implFile.isOpen()) {
- //
- // Build stringdata struct
- //
- implOut << "struct qt_meta_stringdata_all_t {" << Qt::endl;
- implOut << " uint data[" << strings.size() * 2 << "];" << Qt::endl;
-
- QVector<QByteArrayList> listVector;
- QByteArrayList currentList;
-
- int currentTableLen = 0;
- for (const auto &s : strings) {
- currentTableLen += s.length() + 1;
- currentList.append(s);
- // Split strings into chunks less than 64k to work around compiler limits.
- if (currentTableLen > 60000) {
- implOut << " char stringdata" << listVector.size() << '[' << currentTableLen + 1 << "];" << Qt::endl;
- listVector.append(currentList);
- currentList.clear();
- currentTableLen = 0;
- }
- }
- implOut << " char stringdata" << listVector.size() << '[' << currentTableLen + 1 << "];" << Qt::endl;
- implOut << "};" << Qt::endl;
- listVector.append(currentList);
-
- implOut << "#define QT_MOC_LITERAL(ofs, len, table) \\" << Qt::endl
- << " uint(offsetof(qt_meta_stringdata_all_t, stringdata##table) + ofs), len," << Qt::endl;
-
- implOut << "static const qt_meta_stringdata_all_t qt_meta_stringdata_all = {" << Qt::endl;
- implOut << " {" << Qt::endl;
-
- int totalStringCount = 0;
- for (int i = 0; i < listVector.size(); ++i) {
- int idx = 0;
- for (int j = 0; j < listVector[i].size(); j++) {
- if (totalStringCount)
- implOut << ',' << Qt::endl;
- const QByteArray &str = listVector[i].at(j);
- implOut << "QT_MOC_LITERAL(" << idx << ", " << str.length() << ", " << i << ')';
- idx += str.length() + 1;
- }
- }
- implOut << Qt::endl << " }";
-
- //
- // Build stringdata arrays
- //
- for (const auto &l : listVector) {
- int col = 0;
- int len = 0;
- implOut << ',' << Qt::endl;
- implOut << " \"";
- for (const auto &s : l) {
- len = s.length();
- if (col && col + len >= 150) {
- implOut << '"' << Qt::endl << " \"";
- col = 0;
- } else if (len && s.at(0) >= '0' && s.at(0) <= '9') {
- implOut << "\"\"";
- len += 2;
- }
- int idx = 0;
- while (idx < s.length()) {
- if (idx > 0) {
- col = 0;
- implOut << '"' << Qt::endl << " \"";
- }
- int spanLen = qMin(150, s.length() - idx);
- implOut << s.mid(idx, spanLen);
- idx += spanLen;
- col += spanLen;
- }
-
- implOut << "\\0";
- col += len + 2;
- }
- implOut << '"';
- }
- // Terminate stringdata struct
- implOut << Qt::endl << "};" << Qt::endl;
-
- implOut << "#undef QT_MOC_LITERAL" << Qt::endl << Qt::endl;
-
+ if (implFile.isOpen()) {
classImplOut.flush();
- copyFileToStream(&classImplFile, &implOut);
- implOut << Qt::endl;
+ implOut << classImpl << Qt::endl;
}
qax_deleteMetaObject(namespaceObject);