From 77e3883a9a63b21d24ca30ac2dd63fc359727f97 Mon Sep 17 00:00:00 2001 From: Richard Goedeken Date: Mon, 21 Aug 2023 11:24:18 -0700 Subject: [PATCH 01/21] Qt6 compatibility fixes for core PythonQt library --- src/PythonQt.cpp | 5 +--- src/PythonQtClassInfo.cpp | 3 ++- src/PythonQtClassWrapper.cpp | 4 +-- src/PythonQtConversion.cpp | 41 +++++++++++++----------------- src/PythonQtConversion.h | 1 - src/PythonQtImporter.cpp | 8 +++--- src/PythonQtMethodInfo.cpp | 3 +-- src/PythonQtSlot.cpp | 2 +- src/PythonQtStdDecorators.cpp | 8 +++--- src/PythonQtStdDecorators.h | 9 ++++--- src/PythonQtVariants.h | 3 +-- src/gui/PythonQtScriptingConsole.h | 2 +- src/src.pro | 8 ++++-- 13 files changed, 47 insertions(+), 50 deletions(-) diff --git a/src/PythonQt.cpp b/src/PythonQt.cpp index af220d8d0..e24acdffc 100644 --- a/src/PythonQt.cpp +++ b/src/PythonQt.cpp @@ -122,8 +122,6 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName) } else { qRegisterMetaType("size_t"); } - int stringRefId = qRegisterMetaType("QStringRef"); - PythonQtConv::registerMetaTypeToPythonConverter(stringRefId, PythonQtConv::convertFromStringRef); int objectPtrListId = qRegisterMetaType >("QList"); PythonQtConv::registerMetaTypeToPythonConverter(objectPtrListId, PythonQtConv::convertFromQListOfPythonQtObjectPtr); @@ -239,7 +237,7 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName) PythonQtRegisterToolClassesTemplateConverterForKnownClass(QLineF); PythonQtRegisterToolClassesTemplateConverterForKnownClass(QPoint); PythonQtRegisterToolClassesTemplateConverterForKnownClass(QPointF); - PythonQtRegisterToolClassesTemplateConverterForKnownClass(QRegExp); + PythonQtRegisterToolClassesTemplateConverterForKnownClass(QRegularExpression); PythonQtRegisterToolClassesTemplateConverterForKnownClass(QFont); PythonQtRegisterToolClassesTemplateConverterForKnownClass(QPixmap); @@ -257,7 +255,6 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName) PythonQtRegisterToolClassesTemplateConverterForKnownClass(QPen); PythonQtRegisterToolClassesTemplateConverterForKnownClass(QTextLength); PythonQtRegisterToolClassesTemplateConverterForKnownClass(QTextFormat); - PythonQtRegisterToolClassesTemplateConverterForKnownClass(QMatrix); PyObject* pack = PythonQt::priv()->packageByName("QtCore"); PyObject* pack2 = PythonQt::priv()->packageByName("Qt"); diff --git a/src/PythonQtClassInfo.cpp b/src/PythonQtClassInfo.cpp index 17fb5d13c..61f3fadd2 100644 --- a/src/PythonQtClassInfo.cpp +++ b/src/PythonQtClassInfo.cpp @@ -554,7 +554,8 @@ QStringList PythonQtClassInfo::memberList() } } - return QSet::fromList(l).toList(); + QSet set(l.begin(), l.end()); + return set.values(); } const QByteArray& PythonQtClassInfo::className() const diff --git a/src/PythonQtClassWrapper.cpp b/src/PythonQtClassWrapper.cpp index 205338300..00e94a926 100644 --- a/src/PythonQtClassWrapper.cpp +++ b/src/PythonQtClassWrapper.cpp @@ -463,8 +463,8 @@ static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name) } PyObject* dict = PyDict_New(); - QSet completeSet = QSet::fromList(wrapper->classInfo()->memberList()); - completeSet.unite(QSet::fromList(wrapper->classInfo()->propertyList())); + QSet completeSet(wrapper->classInfo()->memberList().begin(), wrapper->classInfo()->memberList().end()); + completeSet.unite(QSet(wrapper->classInfo()->propertyList().begin(), wrapper->classInfo()->propertyList().end())); Q_FOREACH (QString name, completeSet) { if (name.startsWith("py_")) { diff --git a/src/PythonQtConversion.cpp b/src/PythonQtConversion.cpp index a1aaa2914..2b444cdf6 100644 --- a/src/PythonQtConversion.cpp +++ b/src/PythonQtConversion.cpp @@ -1015,17 +1015,17 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) if (wrap->classInfo()->isCPPWrapper()) { if (wrap->classInfo()->metaTypeId()>0) { // construct a new variant from the C++ object if it has a meta type (this will COPY the object!) - v = QVariant(wrap->classInfo()->metaTypeId(), wrap->_wrappedPtr); + v = QVariant(QMetaType(wrap->classInfo()->metaTypeId()), wrap->_wrappedPtr); } else { // TODOXXX we could as well check if there is a registered meta type for "classname*", so that we may pass // the pointer here... // is this worth anything? we loose the knowledge of the cpp object type - v = qVariantFromValue(wrap->_wrappedPtr); + v = QVariant::fromValue(wrap->_wrappedPtr); } } else { // this gives us a QObject pointer QObject* myObject = wrap->_obj; - v = qVariantFromValue(myObject); + v = QVariant::fromValue(myObject); } return v; } else if (val == Py_None) { @@ -1073,55 +1073,55 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) case QMetaType::Float: { float d = (float) PyObjGetDouble(val,false,ok); - if (ok) v = qVariantFromValue(d); + if (ok) v = QVariant::fromValue(d); } break; case QMetaType::Long: { long d = (long) PyObjGetLongLong(val,false,ok); - if (ok) v = qVariantFromValue(d); + if (ok) v = QVariant::fromValue(d); } break; case QMetaType::ULong: { unsigned long d = (unsigned long) PyObjGetLongLong(val,false,ok); - if (ok) v = qVariantFromValue(d); + if (ok) v = QVariant::fromValue(d); } break; case QMetaType::LongLong: { qint64 d = PyObjGetLongLong(val, false, ok); - if (ok) v = qVariantFromValue(d); + if (ok) v = QVariant::fromValue(d); } break; case QMetaType::ULongLong: { quint64 d = PyObjGetULongLong(val, false, ok); - if (ok) v = qVariantFromValue(d); + if (ok) v = QVariant::fromValue(d); } break; case QMetaType::Short: { short d = (short) PyObjGetInt(val,false,ok); - if (ok) v = qVariantFromValue(d); + if (ok) v = QVariant::fromValue(d); } break; case QMetaType::UShort: { unsigned short d = (unsigned short) PyObjGetInt(val,false,ok); - if (ok) v = qVariantFromValue(d); + if (ok) v = QVariant::fromValue(d); } break; case QMetaType::Char: { char d = (char) PyObjGetInt(val,false,ok); - if (ok) v = qVariantFromValue(d); + if (ok) v = QVariant::fromValue(d); } break; case QMetaType::UChar: { unsigned char d = (unsigned char) PyObjGetInt(val,false,ok); - if (ok) v = qVariantFromValue(d); + if (ok) v = QVariant::fromValue(d); } break; @@ -1189,7 +1189,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)val; if (wrap->classInfo()->isCPPWrapper() && wrap->classInfo()->metaTypeId() == type) { // construct a new variant from the C++ object if it has the same meta type - v = QVariant(type, wrap->_wrappedPtr); + v = QVariant(QMetaType(type), wrap->_wrappedPtr); } else { // Try to convert the object to a QVariant based on the typeName bool ok; @@ -1202,10 +1202,10 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) void* object = castWrapperTo(wrap, typeName, ok); if (ok) { if (isPtr) { - v = QVariant(type, &object); + v = QVariant(QMetaType(type), &object); } else { - v = QVariant(type, object); + v = QVariant(QMetaType(type), object); } } } @@ -1215,7 +1215,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) PythonQtConvertPythonToMetaTypeCB* converter = _pythonToMetaTypeConverters.value(type); if (converter) { // allocate a default object of the needed type: - v = QVariant(type, (const void*)nullptr); + v = QVariant(QMetaType(type), (const void*)nullptr); // now call the converter, passing the internal object of the variant ok = (*converter)(val, (void*)v.constData(), type, true); if (!ok) { @@ -1226,7 +1226,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) const PythonQtMethodInfo::ParameterInfo& info = PythonQtMethodInfo::getParameterInfoForMetaType(type); if (info.isQList && (info.innerNamePointerCount == 1)) { // allocate a default object of the needed type: - v = QVariant(type, (const void*)nullptr); + v = QVariant(QMetaType(type), (const void*)nullptr); ok = ConvertPythonListToQListOfPointerType(val, (QList*)v.constData(), info, true); if (!ok) { v = QVariant(); @@ -1461,7 +1461,7 @@ QString PythonQtConv::CPPObjectToString(int type, const void* data) { // this creates a copy, but that should not be expensive for typical simple variants // (but we do not want to do this for our won user types! if (type>0 && type < (int)QVariant::UserType) { - QVariant v(type, data); + QVariant v(QMetaType(type), data); r = v.toString(); } } @@ -1483,11 +1483,6 @@ PyObject* PythonQtConv::createCopyFromMetaType( int type, const void* data ) return (PyObject*)wrap; } -PyObject* PythonQtConv::convertFromStringRef(const void* inObject, int /*metaTypeId*/) -{ - return PythonQtConv::QStringToPyObject(((QStringRef*)inObject)->toString()); -} - QByteArray PythonQtConv::getCPPTypeName(PyObject* type) { QByteArray result; diff --git a/src/PythonQtConversion.h b/src/PythonQtConversion.h index 1ff05bee7..28bb37aa5 100644 --- a/src/PythonQtConversion.h +++ b/src/PythonQtConversion.h @@ -185,7 +185,6 @@ class PYTHONQT_EXPORT PythonQtConv { static PyObject* convertFromPythonQtSafeObjectPtr(const void* /* PythonQtObjectPtr* */ inObject, int /*metaTypeId*/); static bool convertToQListOfPythonQtObjectPtr(PyObject* obj, void* /* QList* */ outList, int /*metaTypeId*/, bool /*strict*/); static PyObject* convertFromQListOfPythonQtObjectPtr(const void* /* QList* */ inObject, int /*metaTypeId*/); - static PyObject* convertFromStringRef(const void* inObject, int /*metaTypeId*/); //! Returns the name of the equivalent CPP type (for signals and slots) static QByteArray getCPPTypeName(PyObject* type); diff --git a/src/PythonQtImporter.cpp b/src/PythonQtImporter.cpp index dfcfcb165..519c06bd6 100644 --- a/src/PythonQtImporter.cpp +++ b/src/PythonQtImporter.cpp @@ -222,7 +222,7 @@ PythonQtImporter_load_module(PyObject *obj, PyObject *args) { PythonQtImporter *self = (PythonQtImporter *)obj; PyObject *code = nullptr, *mod = nullptr, *dict = nullptr; - char *fullname; + char *fullname = NULL; if (!PyArg_ParseTuple(args, "s:PythonQtImporter.load_module", &fullname)) @@ -338,7 +338,7 @@ PythonQtImporter_load_module(PyObject *obj, PyObject *args) QVariantList list = result.toList(); if (list.count()==3) { // We prepend the full module name (including package prefix) - list.prepend(fullname); + list.prepend(QString(fullname)); #ifdef __linux #ifdef _DEBUG // imp_find_module() does not respect the debug suffix '_d' on Linux, @@ -740,7 +740,7 @@ PythonQtImport::getCodeFromData(const QString& path, int isbytecode,int /*ispack QDateTime time; time = PythonQt::importInterface()->lastModifiedDate(path); QString cacheFilename = getCacheFilename(path, /*isOptimizedFilename=*/false); - writeCompiledModule((PyCodeObject*)code, cacheFilename, time.toTime_t(), /*sourceSize=*/qdata.length()); + writeCompiledModule((PyCodeObject*)code, cacheFilename, time.toSecsSinceEpoch(), /*sourceSize=*/qdata.length()); } } return code; @@ -754,7 +754,7 @@ PythonQtImport::getMTimeOfSource(const QString& path) if (PythonQt::importInterface()->exists(path2)) { QDateTime t = PythonQt::importInterface()->lastModifiedDate(path2); if (t.isValid()) { - mtime = t.toTime_t(); + mtime = t.toSecsSinceEpoch(); } } diff --git a/src/PythonQtMethodInfo.cpp b/src/PythonQtMethodInfo.cpp index 3c8ee7ff1..2ba42b258 100644 --- a/src/PythonQtMethodInfo.cpp +++ b/src/PythonQtMethodInfo.cpp @@ -372,7 +372,7 @@ int PythonQtMethodInfo::nameToType(const char* name) _parameterTypeDict.insert("QLineF", QMetaType::QLineF); _parameterTypeDict.insert("QPoint", QMetaType::QPoint); _parameterTypeDict.insert("QPointF", QMetaType::QPointF); - _parameterTypeDict.insert("QRegExp", QMetaType::QRegExp); + _parameterTypeDict.insert("QRegularExpression", QMetaType::QRegularExpression); _parameterTypeDict.insert("QFont", QMetaType::QFont); _parameterTypeDict.insert("QPixmap", QMetaType::QPixmap); _parameterTypeDict.insert("QBrush", QMetaType::QBrush); @@ -388,7 +388,6 @@ int PythonQtMethodInfo::nameToType(const char* name) _parameterTypeDict.insert("QPen", QMetaType::QPen); _parameterTypeDict.insert("QTextLength", QMetaType::QTextLength); _parameterTypeDict.insert("QTextFormat", QMetaType::QTextFormat); - _parameterTypeDict.insert("QMatrix", QMetaType::QMatrix); _parameterTypeDict.insert("QVariant", PythonQtMethodInfo::Variant); // own special types... (none so far, could be e.g. ObjectList } diff --git a/src/PythonQtSlot.cpp b/src/PythonQtSlot.cpp index 00f053263..084df8706 100644 --- a/src/PythonQtSlot.cpp +++ b/src/PythonQtSlot.cpp @@ -540,7 +540,7 @@ meth_get__doc__(PythonQtSlotFunctionObject * m, void * /*closure*/) if (!names.at(i - 1).isEmpty()) { doc += names.at(i - 1); } else { - doc += QString('a' + i - firstArgOffset).toLatin1(); + doc += QString(QChar((char) ('a' + i - firstArgOffset))).toLatin1(); } } doc += ")"; diff --git a/src/PythonQtStdDecorators.cpp b/src/PythonQtStdDecorators.cpp index b3e281393..ca1ddcfbc 100644 --- a/src/PythonQtStdDecorators.cpp +++ b/src/PythonQtStdDecorators.cpp @@ -45,6 +45,7 @@ #include "PythonQtConversion.h" #include +#include bool PythonQtStdDecorators::connect(QObject* sender, const QByteArray& signal, PyObject* callable) { @@ -240,7 +241,7 @@ QList PythonQtStdDecorators::findChildren(QObject* parent, PyObject* t return list; } -QList PythonQtStdDecorators::findChildren(QObject* parent, PyObject* type, const QRegExp& regExp) +QList PythonQtStdDecorators::findChildren(QObject* parent, PyObject* type, const QRegularExpression& regExp) { const QMetaObject* meta = nullptr; QByteArray typeName; @@ -322,7 +323,7 @@ int PythonQtStdDecorators::findChildren(QObject* parent, const char* typeName, c return 0; } -int PythonQtStdDecorators::findChildren(QObject* parent, const char* typeName, const QMetaObject* meta, const QRegExp& regExp, QList& list) +int PythonQtStdDecorators::findChildren(QObject* parent, const char* typeName, const QMetaObject* meta, const QRegularExpression& regExp, QList& list) { const QObjectList& children = parent->children(); int i; @@ -334,7 +335,8 @@ int PythonQtStdDecorators::findChildren(QObject* parent, const char* typeName, c return -1; // Skip if the name doesn't match. - if (regExp.indexIn(obj->objectName()) == -1) + QRegularExpressionMatch match = regExp.match(obj->objectName()); + if (match.hasMatch() == false) continue; if ((typeName && obj->inherits(typeName)) || diff --git a/src/PythonQtStdDecorators.h b/src/PythonQtStdDecorators.h index b5c0ba607..cf2e7773d 100644 --- a/src/PythonQtStdDecorators.h +++ b/src/PythonQtStdDecorators.h @@ -58,6 +58,7 @@ #include #include #include +#include class PYTHONQT_EXPORT PythonQtStdDecorators : public QObject { @@ -82,7 +83,7 @@ public Q_SLOTS: const QObjectList* children(QObject* o); QObject* findChild(QObject* parent, PyObject* type, const QString& name = QString()); QList findChildren(QObject* parent, PyObject* type, const QString& name= QString()); - QList findChildren(QObject* parent, PyObject* type, const QRegExp& regExp); + QList findChildren(QObject* parent, PyObject* type, const QRegularExpression& regExp); bool setProperty(QObject* o, const char* name, const QVariant& value); QVariant property(QObject* o, const char* name); @@ -103,8 +104,8 @@ public Q_SLOTS: int static_Qt_qRound(double a) { return qRound(a); } qint64 static_Qt_qRound64(double a) { return qRound64(a); } const char* static_Qt_qVersion() { return qVersion(); } - int static_Qt_qrand() { return qrand(); } - void static_Qt_qsrand(uint a) { qsrand(a); } + int static_Qt_qrand() { return QRandomGenerator::global()->generate(); } + void static_Qt_qsrand(uint a) { QRandomGenerator::global()->seed(a); } QString tr(QObject* obj, const QString& text, const QString& ambig = QString(), int n = -1); @@ -116,7 +117,7 @@ public Q_SLOTS: private: QObject* findChild(QObject* parent, const char* typeName, const QMetaObject* meta, const QString& name); int findChildren(QObject* parent, const char* typeName, const QMetaObject* meta, const QString& name, QList& list); - int findChildren(QObject* parent, const char* typeName, const QMetaObject* meta, const QRegExp& regExp, QList& list); + int findChildren(QObject* parent, const char* typeName, const QMetaObject* meta, const QRegularExpression& regExp, QList& list); }; class PythonQtSingleShotTimer : public QTimer diff --git a/src/PythonQtVariants.h b/src/PythonQtVariants.h index 7e0691016..833f35c8a 100644 --- a/src/PythonQtVariants.h +++ b/src/PythonQtVariants.h @@ -54,7 +54,7 @@ #include #include #include -#include +#include #include #include @@ -72,7 +72,6 @@ #include #include #include -#include #endif diff --git a/src/gui/PythonQtScriptingConsole.h b/src/gui/PythonQtScriptingConsole.h index c47a0f023..26e028fa5 100644 --- a/src/gui/PythonQtScriptingConsole.h +++ b/src/gui/PythonQtScriptingConsole.h @@ -55,7 +55,7 @@ class PYTHONQT_EXPORT PythonQtScriptingConsole : public QTextEdit Q_OBJECT public: - PythonQtScriptingConsole(QWidget* parent, const PythonQtObjectPtr& context, Qt::WindowFlags i = 0); + PythonQtScriptingConsole(QWidget* parent, const PythonQtObjectPtr& context, Qt::WindowFlags i = Qt::WindowFlags()); ~PythonQtScriptingConsole() override; diff --git a/src/src.pro b/src/src.pro index 4d2627eab..4e9a78adf 100644 --- a/src/src.pro +++ b/src/src.pro @@ -4,7 +4,7 @@ # $Source$ # -------------------------------------------------- -TARGET = PythonQt-Qt5-PythonXY +TARGET = PythonQt-Qt6-PythonXY TEMPLATE = lib DESTDIR = ../lib @@ -25,12 +25,16 @@ isEmpty(PYTHONQT_STATIC) { DEFINES += PYTHONQT_CATCH_ALL_EXCEPTIONS -contains(QT_MAJOR_VERSION, 5) { +contains(QT_MAJOR_VERSION, 6) { QT += widgets core-private } INCLUDEPATH += $$PWD +macx { + QMAKE_APPLE_DEVICE_ARCHS = x86_64 arm64 +} + include ( ../build/common.prf ) include ( ../build/python.prf ) TARGET = $$replace(TARGET, PythonXY, Python$${PYTHON_VERSION}) From 10d404887e71317209b0b75dac3163d117a1212f Mon Sep 17 00:00:00 2001 From: mrbean-bremen Date: Fri, 15 Sep 2023 14:10:40 +0200 Subject: [PATCH 02/21] Bring back more Qt5 compatibility - fix iterator usage as mentioned in review --- src/PythonQt.cpp | 7 +++++++ src/PythonQtClassWrapper.cpp | 8 +++++--- src/PythonQtConversion.cpp | 35 ++++++++++++++++++++++++++--------- src/PythonQtConversion.h | 3 +++ src/PythonQtImporter.cpp | 16 ++++++++++++++-- src/PythonQtStdDecorators.h | 22 ++++++++++++++++++++-- src/src.pro | 12 +++++++----- 7 files changed, 82 insertions(+), 21 deletions(-) diff --git a/src/PythonQt.cpp b/src/PythonQt.cpp index e24acdffc..7e65273ee 100644 --- a/src/PythonQt.cpp +++ b/src/PythonQt.cpp @@ -122,6 +122,10 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName) } else { qRegisterMetaType("size_t"); } +#if QT_VERSION < 0x060000 + int stringRefId = qRegisterMetaType("QStringRef"); + PythonQtConv::registerMetaTypeToPythonConverter(stringRefId, PythonQtConv::convertFromStringRef); +#endif int objectPtrListId = qRegisterMetaType >("QList"); PythonQtConv::registerMetaTypeToPythonConverter(objectPtrListId, PythonQtConv::convertFromQListOfPythonQtObjectPtr); @@ -237,6 +241,9 @@ void PythonQt::init(int flags, const QByteArray& pythonQtModuleName) PythonQtRegisterToolClassesTemplateConverterForKnownClass(QLineF); PythonQtRegisterToolClassesTemplateConverterForKnownClass(QPoint); PythonQtRegisterToolClassesTemplateConverterForKnownClass(QPointF); +#if QT_VERSION < 0x060000 + PythonQtRegisterToolClassesTemplateConverterForKnownClass(QRegExp); +#endif PythonQtRegisterToolClassesTemplateConverterForKnownClass(QRegularExpression); PythonQtRegisterToolClassesTemplateConverterForKnownClass(QFont); diff --git a/src/PythonQtClassWrapper.cpp b/src/PythonQtClassWrapper.cpp index 00e94a926..60a7ddca7 100644 --- a/src/PythonQtClassWrapper.cpp +++ b/src/PythonQtClassWrapper.cpp @@ -462,9 +462,11 @@ static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name) return objectDict; } PyObject* dict = PyDict_New(); - - QSet completeSet(wrapper->classInfo()->memberList().begin(), wrapper->classInfo()->memberList().end()); - completeSet.unite(QSet(wrapper->classInfo()->propertyList().begin(), wrapper->classInfo()->propertyList().end())); + + auto members = wrapper->classInfo()->memberList(); + auto properties = wrapper->classInfo()->propertyList(); + QSet completeSet(members.begin(), members.end()); + completeSet.unite(QSet(properties.begin(), properties.end())); Q_FOREACH (QString name, completeSet) { if (name.startsWith("py_")) { diff --git a/src/PythonQtConversion.cpp b/src/PythonQtConversion.cpp index 2b444cdf6..1febf5ce6 100644 --- a/src/PythonQtConversion.cpp +++ b/src/PythonQtConversion.cpp @@ -967,6 +967,17 @@ void PythonQtConv::pythonToMapVariant(PyObject* val, QVariant& result) } } +namespace +{ + QVariant variantFromType(int typeId, const void *copy) + { +#if QT_VERSION >= 0x060000 + return QVariant(QMetaType(typeId), copy); +#else + return QVariant(typeId, copy); +#endif + } +} QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) { @@ -1015,7 +1026,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) if (wrap->classInfo()->isCPPWrapper()) { if (wrap->classInfo()->metaTypeId()>0) { // construct a new variant from the C++ object if it has a meta type (this will COPY the object!) - v = QVariant(QMetaType(wrap->classInfo()->metaTypeId()), wrap->_wrappedPtr); + v = variantFromType(wrap->classInfo()->metaTypeId(), wrap->_wrappedPtr); } else { // TODOXXX we could as well check if there is a registered meta type for "classname*", so that we may pass // the pointer here... @@ -1189,7 +1200,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)val; if (wrap->classInfo()->isCPPWrapper() && wrap->classInfo()->metaTypeId() == type) { // construct a new variant from the C++ object if it has the same meta type - v = QVariant(QMetaType(type), wrap->_wrappedPtr); + v = variantFromType(type, wrap->_wrappedPtr); } else { // Try to convert the object to a QVariant based on the typeName bool ok; @@ -1202,10 +1213,10 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) void* object = castWrapperTo(wrap, typeName, ok); if (ok) { if (isPtr) { - v = QVariant(QMetaType(type), &object); + v = variantFromType(type, &object); } else { - v = QVariant(QMetaType(type), object); + v = variantFromType(type, object); } } } @@ -1215,7 +1226,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) PythonQtConvertPythonToMetaTypeCB* converter = _pythonToMetaTypeConverters.value(type); if (converter) { // allocate a default object of the needed type: - v = QVariant(QMetaType(type), (const void*)nullptr); + v = variantFromType(type, (const void*)nullptr); // now call the converter, passing the internal object of the variant ok = (*converter)(val, (void*)v.constData(), type, true); if (!ok) { @@ -1226,7 +1237,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) const PythonQtMethodInfo::ParameterInfo& info = PythonQtMethodInfo::getParameterInfoForMetaType(type); if (info.isQList && (info.innerNamePointerCount == 1)) { // allocate a default object of the needed type: - v = QVariant(QMetaType(type), (const void*)nullptr); + v = variantFromType(type, (const void*)nullptr); ok = ConvertPythonListToQListOfPointerType(val, (QList*)v.constData(), info, true); if (!ok) { v = QVariant(); @@ -1459,10 +1470,9 @@ QString PythonQtConv::CPPObjectToString(int type, const void* data) { //TODO: add more printing for other variant types default: // this creates a copy, but that should not be expensive for typical simple variants - // (but we do not want to do this for our won user types! + // (but we do not want to do this for our own user types!) if (type>0 && type < (int)QVariant::UserType) { - QVariant v(QMetaType(type), data); - r = v.toString(); + r = variantFromType(type, data).toString(); } } return r; @@ -1483,6 +1493,13 @@ PyObject* PythonQtConv::createCopyFromMetaType( int type, const void* data ) return (PyObject*)wrap; } +#if QT_VERSION < 0x060000 +PyObject* PythonQtConv::convertFromStringRef(const void* inObject, int /*metaTypeId*/) +{ + return PythonQtConv::QStringToPyObject(((QStringRef*)inObject)->toString()); +} +#endif + QByteArray PythonQtConv::getCPPTypeName(PyObject* type) { QByteArray result; diff --git a/src/PythonQtConversion.h b/src/PythonQtConversion.h index 28bb37aa5..7876b652c 100644 --- a/src/PythonQtConversion.h +++ b/src/PythonQtConversion.h @@ -185,6 +185,9 @@ class PYTHONQT_EXPORT PythonQtConv { static PyObject* convertFromPythonQtSafeObjectPtr(const void* /* PythonQtObjectPtr* */ inObject, int /*metaTypeId*/); static bool convertToQListOfPythonQtObjectPtr(PyObject* obj, void* /* QList* */ outList, int /*metaTypeId*/, bool /*strict*/); static PyObject* convertFromQListOfPythonQtObjectPtr(const void* /* QList* */ inObject, int /*metaTypeId*/); +#if QT_VERSION < 0x060000 + static PyObject* convertFromStringRef(const void* inObject, int /*metaTypeId*/); +#endif //! Returns the name of the equivalent CPP type (for signals and slots) static QByteArray getCPPTypeName(PyObject* type); diff --git a/src/PythonQtImporter.cpp b/src/PythonQtImporter.cpp index 519c06bd6..0855a29f9 100644 --- a/src/PythonQtImporter.cpp +++ b/src/PythonQtImporter.cpp @@ -705,6 +705,18 @@ QString PythonQtImport::getSourceFilename(const QString& cacheFile) return pyFilename; } +namespace +{ + qint64 toSecsSinceEpoch(const QDateTime& time) + { +#if QT_VERSION < 0x060000 + return time.toTime_t(); +#else + return time.toSecsSinceEpoch(); +#endif + } +} + /* Return the code object for the module named by 'fullname' from the Zip archive as a new reference. */ PyObject * @@ -740,7 +752,7 @@ PythonQtImport::getCodeFromData(const QString& path, int isbytecode,int /*ispack QDateTime time; time = PythonQt::importInterface()->lastModifiedDate(path); QString cacheFilename = getCacheFilename(path, /*isOptimizedFilename=*/false); - writeCompiledModule((PyCodeObject*)code, cacheFilename, time.toSecsSinceEpoch(), /*sourceSize=*/qdata.length()); + writeCompiledModule((PyCodeObject*)code, cacheFilename, toSecsSinceEpoch(time), /*sourceSize=*/qdata.length()); } } return code; @@ -754,7 +766,7 @@ PythonQtImport::getMTimeOfSource(const QString& path) if (PythonQt::importInterface()->exists(path2)) { QDateTime t = PythonQt::importInterface()->lastModifiedDate(path2); if (t.isValid()) { - mtime = t.toSecsSinceEpoch(); + mtime = toSecsSinceEpoch(t); } } diff --git a/src/PythonQtStdDecorators.h b/src/PythonQtStdDecorators.h index cf2e7773d..f3f6948b4 100644 --- a/src/PythonQtStdDecorators.h +++ b/src/PythonQtStdDecorators.h @@ -58,7 +58,9 @@ #include #include #include +#if QT_VERSION >= 0x060000 #include +#endif class PYTHONQT_EXPORT PythonQtStdDecorators : public QObject { @@ -104,8 +106,24 @@ public Q_SLOTS: int static_Qt_qRound(double a) { return qRound(a); } qint64 static_Qt_qRound64(double a) { return qRound64(a); } const char* static_Qt_qVersion() { return qVersion(); } - int static_Qt_qrand() { return QRandomGenerator::global()->generate(); } - void static_Qt_qsrand(uint a) { QRandomGenerator::global()->seed(a); } + + int static_Qt_qrand() + { +#if QT_VERSION < 0x060000 + return qrand(); +#else + return QRandomGenerator::global()->generate(); +#endif + } + + void static_Qt_qsrand(uint a) + { +#if QT_VERSION < 0x060000 + qsrand(a); +#else + QRandomGenerator::global()->seed(a); +#endif + } QString tr(QObject* obj, const QString& text, const QString& ambig = QString(), int n = -1); diff --git a/src/src.pro b/src/src.pro index 4e9a78adf..0f0fd0ba8 100644 --- a/src/src.pro +++ b/src/src.pro @@ -4,7 +4,11 @@ # $Source$ # -------------------------------------------------- -TARGET = PythonQt-Qt6-PythonXY +contains(QT_MAJOR_VERSION, 6) { + TARGET = PythonQt-Qt6-PythonXY +} else { + TARGET = PythonQt-Qt5-PythonXY +} TEMPLATE = lib DESTDIR = ../lib @@ -25,10 +29,8 @@ isEmpty(PYTHONQT_STATIC) { DEFINES += PYTHONQT_CATCH_ALL_EXCEPTIONS -contains(QT_MAJOR_VERSION, 6) { - QT += widgets core-private -} - +QT += widgets core-private + INCLUDEPATH += $$PWD macx { From 6d74c14ba22e0753364852659b216694b592c474 Mon Sep 17 00:00:00 2001 From: mrbean-bremen Date: Fri, 15 Sep 2023 20:23:31 +0200 Subject: [PATCH 03/21] More Qt5 compatibility changes --- examples/CPPPyWrapperExample/CPPPyWrapperExample.pro | 4 +--- examples/PyCPPWrapperExample/PyCPPWrapperExample.pro | 4 +--- .../PyCustomMetaTypeExample/PyCustomMetaTypeExample.pro | 4 +--- examples/PyDecoratorsExample/PyDecoratorsExample.pro | 4 +--- examples/PyGettingStarted/PyGettingStarted.pro | 4 +--- examples/PyGuiExample/PyGuiExample.pro | 4 +--- examples/PyLauncher/PyLauncher.pro | 4 +--- examples/PyScriptingConsole/PyScriptingConsole.pro | 4 +--- src/PythonQtClassInfo.cpp | 4 ++++ src/PythonQtClassWrapper.cpp | 6 +++++- src/src.pro | 2 ++ tests/tests.pro | 4 +--- 12 files changed, 20 insertions(+), 28 deletions(-) diff --git a/examples/CPPPyWrapperExample/CPPPyWrapperExample.pro b/examples/CPPPyWrapperExample/CPPPyWrapperExample.pro index 9d52a9e11..164349955 100644 --- a/examples/CPPPyWrapperExample/CPPPyWrapperExample.pro +++ b/examples/CPPPyWrapperExample/CPPPyWrapperExample.pro @@ -9,9 +9,7 @@ DESTDIR = ../../lib include ( ../../build/common.prf ) include ( ../../build/PythonQt.prf ) -contains(QT_MAJOR_VERSION, 5) { - QT += widgets -} +QT += widgets SOURCES += \ CPPPyWrapperExample.cpp diff --git a/examples/PyCPPWrapperExample/PyCPPWrapperExample.pro b/examples/PyCPPWrapperExample/PyCPPWrapperExample.pro index 05fe3da92..7ada73196 100644 --- a/examples/PyCPPWrapperExample/PyCPPWrapperExample.pro +++ b/examples/PyCPPWrapperExample/PyCPPWrapperExample.pro @@ -12,9 +12,7 @@ DESTDIR = ../../lib include ( ../../build/common.prf ) include ( ../../build/PythonQt.prf ) -contains(QT_MAJOR_VERSION, 5) { - QT += widgets -} +QT += widgets HEADERS += \ CustomObjects.h diff --git a/examples/PyCustomMetaTypeExample/PyCustomMetaTypeExample.pro b/examples/PyCustomMetaTypeExample/PyCustomMetaTypeExample.pro index 69db9b5a5..952449f5a 100644 --- a/examples/PyCustomMetaTypeExample/PyCustomMetaTypeExample.pro +++ b/examples/PyCustomMetaTypeExample/PyCustomMetaTypeExample.pro @@ -12,9 +12,7 @@ DESTDIR = ../../lib include ( ../../build/common.prf ) include ( ../../build/PythonQt.prf ) -contains(QT_MAJOR_VERSION, 5) { - QT += widgets -} +QT += widgets HEADERS += \ CustomObject.h diff --git a/examples/PyDecoratorsExample/PyDecoratorsExample.pro b/examples/PyDecoratorsExample/PyDecoratorsExample.pro index 7367f2201..06bb8de4d 100644 --- a/examples/PyDecoratorsExample/PyDecoratorsExample.pro +++ b/examples/PyDecoratorsExample/PyDecoratorsExample.pro @@ -12,9 +12,7 @@ DESTDIR = ../../lib include ( ../../build/common.prf ) include ( ../../build/PythonQt.prf ) -contains(QT_MAJOR_VERSION, 5) { - QT += widgets -} +QT += widgets HEADERS += \ PyExampleDecorators.h diff --git a/examples/PyGettingStarted/PyGettingStarted.pro b/examples/PyGettingStarted/PyGettingStarted.pro index 1a5fee844..bf1d4d050 100644 --- a/examples/PyGettingStarted/PyGettingStarted.pro +++ b/examples/PyGettingStarted/PyGettingStarted.pro @@ -14,9 +14,7 @@ CONFIG += console include ( ../../build/common.prf ) include ( ../../build/PythonQt.prf ) -contains(QT_MAJOR_VERSION, 5) { - QT += widgets -} +QT += widgets SOURCES += \ main.cpp diff --git a/examples/PyGuiExample/PyGuiExample.pro b/examples/PyGuiExample/PyGuiExample.pro index 7baa529ba..bd200da05 100644 --- a/examples/PyGuiExample/PyGuiExample.pro +++ b/examples/PyGuiExample/PyGuiExample.pro @@ -11,9 +11,7 @@ mac:CONFIG -= app_bundle DESTDIR = ../../lib -contains(QT_MAJOR_VERSION, 5) { - QT += widgets -} +QT += widgets include ( ../../build/common.prf ) include ( ../../build/PythonQt.prf ) diff --git a/examples/PyLauncher/PyLauncher.pro b/examples/PyLauncher/PyLauncher.pro index f1f98b406..e8b9686b1 100644 --- a/examples/PyLauncher/PyLauncher.pro +++ b/examples/PyLauncher/PyLauncher.pro @@ -11,9 +11,7 @@ mac:CONFIG -= app_bundle DESTDIR = ../../lib -contains(QT_MAJOR_VERSION, 5) { - QT += widgets -} +QT += widgets include ( ../../build/common.prf ) include ( ../../build/PythonQt.prf ) diff --git a/examples/PyScriptingConsole/PyScriptingConsole.pro b/examples/PyScriptingConsole/PyScriptingConsole.pro index ef7a19550..b2b7b5115 100644 --- a/examples/PyScriptingConsole/PyScriptingConsole.pro +++ b/examples/PyScriptingConsole/PyScriptingConsole.pro @@ -15,9 +15,7 @@ include ( ../../build/common.prf ) include ( ../../build/PythonQt.prf ) include ( ../../build/PythonQt_QtAll.prf ) -contains(QT_MAJOR_VERSION, 5) { - QT += widgets -} +QT += widgets HEADERS += \ PyExampleObject.h diff --git a/src/PythonQtClassInfo.cpp b/src/PythonQtClassInfo.cpp index 61f3fadd2..2ab44d1fc 100644 --- a/src/PythonQtClassInfo.cpp +++ b/src/PythonQtClassInfo.cpp @@ -554,8 +554,12 @@ QStringList PythonQtClassInfo::memberList() } } +#if QT_VERSION >= 0x060000 QSet set(l.begin(), l.end()); return set.values(); +#else + return QSet::fromList(l).toList(); +#endif } const QByteArray& PythonQtClassInfo::className() const diff --git a/src/PythonQtClassWrapper.cpp b/src/PythonQtClassWrapper.cpp index 60a7ddca7..dda2bc1fd 100644 --- a/src/PythonQtClassWrapper.cpp +++ b/src/PythonQtClassWrapper.cpp @@ -465,9 +465,13 @@ static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name) auto members = wrapper->classInfo()->memberList(); auto properties = wrapper->classInfo()->propertyList(); +#if QT_VERSION >= 0x060000 QSet completeSet(members.begin(), members.end()); completeSet.unite(QSet(properties.begin(), properties.end())); - +#else + QSet completeSet = QSet::fromList(members); + completeSet.unite(QSet::fromList(properties)); +#endif Q_FOREACH (QString name, completeSet) { if (name.startsWith("py_")) { // do not expose internal slots diff --git a/src/src.pro b/src/src.pro index 0f0fd0ba8..81d1ffcca 100644 --- a/src/src.pro +++ b/src/src.pro @@ -34,7 +34,9 @@ QT += widgets core-private INCLUDEPATH += $$PWD macx { + contains(QT_MAJOR_VERSION, 6) { QMAKE_APPLE_DEVICE_ARCHS = x86_64 arm64 + } } include ( ../build/common.prf ) diff --git a/tests/tests.pro b/tests/tests.pro index 32bf0e61b..e6e26bce1 100644 --- a/tests/tests.pro +++ b/tests/tests.pro @@ -19,9 +19,7 @@ DEFINES += QT_NO_CAST_TO_ASCII gcc: QMAKE_CXXFLAGS += -pedantic -ansi -Winit-self -Wuninitialized -contains(QT_MAJOR_VERSION, 5) { - QT += widgets -} +QT += widgets include ( ../build/common.prf ) include ( ../build/PythonQt.prf ) From c40e134dfdd879f3eec82f8ef8de8b0774520d3f Mon Sep 17 00:00:00 2001 From: mrbean-bremen Date: Tue, 19 Sep 2023 20:30:41 +0200 Subject: [PATCH 04/21] Bring back QRegExp and QMatrix for Qt5 - changes after review --- src/PythonQtMethodInfo.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/PythonQtMethodInfo.cpp b/src/PythonQtMethodInfo.cpp index 2ba42b258..e5b5a41d6 100644 --- a/src/PythonQtMethodInfo.cpp +++ b/src/PythonQtMethodInfo.cpp @@ -372,6 +372,9 @@ int PythonQtMethodInfo::nameToType(const char* name) _parameterTypeDict.insert("QLineF", QMetaType::QLineF); _parameterTypeDict.insert("QPoint", QMetaType::QPoint); _parameterTypeDict.insert("QPointF", QMetaType::QPointF); +#if QT_VERSION < 0x060000 + _parameterTypeDict.insert("QRegExp", QMetaType::QRegExp); +#endif _parameterTypeDict.insert("QRegularExpression", QMetaType::QRegularExpression); _parameterTypeDict.insert("QFont", QMetaType::QFont); _parameterTypeDict.insert("QPixmap", QMetaType::QPixmap); @@ -387,6 +390,9 @@ int PythonQtMethodInfo::nameToType(const char* name) _parameterTypeDict.insert("QKeySequence", QMetaType::QKeySequence); _parameterTypeDict.insert("QPen", QMetaType::QPen); _parameterTypeDict.insert("QTextLength", QMetaType::QTextLength); +#if QT_VERSION < 0x060000 + _parameterTypeDict.insert("QMatrix", QMetaType::QMatrix); +#endif _parameterTypeDict.insert("QTextFormat", QMetaType::QTextFormat); _parameterTypeDict.insert("QVariant", PythonQtMethodInfo::Variant); // own special types... (none so far, could be e.g. ObjectList From 3c0526873862a3507219ed4c10c55109f88d15db Mon Sep 17 00:00:00 2001 From: John Bowler Date: Tue, 3 Oct 2023 00:05:18 -0700 Subject: [PATCH 05/21] Qt6: initial changes to make compilation work (#114) * Fix handling of compiler standard, (Qt6 requires support for C++17) * Remove unnecessary QStringList declaration --- build/common.prf | 3 +-- generator/generator.pri | 4 ++-- generator/parser/compiler_utils.h | 1 - src/src.pri | 2 -- tests/tests.pro | 2 +- 5 files changed, 4 insertions(+), 8 deletions(-) diff --git a/build/common.prf b/build/common.prf index 04f45c0a0..e6b396d62 100644 --- a/build/common.prf +++ b/build/common.prf @@ -70,9 +70,8 @@ PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp } VERSION = 3.2.0 -greaterThan(QT_MAJOR_VERSION, 5) | greaterThan(QT_MINOR_VERSION, 9): CONFIG += c++11 win32: CONFIG += skip_target_version_ext -gcc|win32-clang-msvc:QMAKE_CXXFLAGS += -Wno-deprecated-declarations -Wuninitialized -Winit-self -ansi -pedantic +gcc|win32-clang-msvc:QMAKE_CXXFLAGS += -Wno-deprecated-declarations -Wuninitialized -Winit-self -pedantic win32-clang-msvc:QMAKE_CXXFLAGS += -Wno-unused-command-line-argument #Do not issue warning to system includes gcc:!isEmpty(QT_INSTALL_HEADERS): QMAKE_CXXFLAGS += -isystem $$[QT_INSTALL_HEADERS] diff --git a/generator/generator.pri b/generator/generator.pri index 64dba5fcb..e399d59e3 100644 --- a/generator/generator.pri +++ b/generator/generator.pri @@ -17,7 +17,7 @@ include($$GENERATORPATH/parser/rxx.pri) include($$GENERATORPATH/parser/rpp/rpp.pri) -CONFIG += strict_c++ c++11 +CONFIG += strict_c++ win32-msvc*{ #Disable warning C4996 (deprecated declarations) QMAKE_CXXFLAGS += -wd4996 @@ -27,7 +27,7 @@ win32-msvc*{ } #Do not issue warning to Qt's system includes gcc:!isEmpty(QT_INSTALL_HEADERS): QMAKE_CXXFLAGS += -isystem $$[QT_INSTALL_HEADERS] -gcc|win32-clang-msvc:QMAKE_CXXFLAGS += -Wno-deprecated-declarations -pedantic -ansi -Winit-self -Wuninitialized +gcc|win32-clang-msvc:QMAKE_CXXFLAGS += -Wno-deprecated-declarations -pedantic -Winit-self -Wuninitialized clang|win32-clang-msvc: QMAKE_CXXFLAGS += -Wno-nested-anon-types -Wno-gnu-anonymous-struct -Wno-unused-private-field win32-clang-msvc:QMAKE_CXXFLAGS += -Wno-language-extension-token -Wno-microsoft-enum-value diff --git a/generator/parser/compiler_utils.h b/generator/parser/compiler_utils.h index 183ba94d4..01c6f9133 100644 --- a/generator/parser/compiler_utils.h +++ b/generator/parser/compiler_utils.h @@ -48,7 +48,6 @@ #include "codemodel.h" class QString; -class QStringList; struct TypeSpecifierAST; struct DeclaratorAST; class TokenStream; diff --git a/src/src.pri b/src/src.pri index 68f5bfb23..13fe1f62c 100644 --- a/src/src.pri +++ b/src/src.pri @@ -2,8 +2,6 @@ DEFINES += PYTHONQT_EXPORTS INCLUDEPATH += $$PWD -CONFIG += c++11 - gcc:!no_warn:!clang:QMAKE_CXXFLAGS += -Wno-error=missing-field-initializers *-clang*:!no_warn:QMAKE_CXXFLAGS += -Wno-error=sometimes-uninitialized diff --git a/tests/tests.pro b/tests/tests.pro index e6e26bce1..f864646d7 100644 --- a/tests/tests.pro +++ b/tests/tests.pro @@ -17,7 +17,7 @@ mingw: TEST_TARGET_DIR = . DEFINES += QT_NO_CAST_TO_ASCII -gcc: QMAKE_CXXFLAGS += -pedantic -ansi -Winit-self -Wuninitialized +gcc: QMAKE_CXXFLAGS += -pedantic -Winit-self -Wuninitialized QT += widgets From 02e4c94afdc690ee2f459618209fc05d38b8c180 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Tue, 3 Oct 2023 02:06:38 -0700 Subject: [PATCH 06/21] Replace deprecated QAtomicPointer::load() (#115) This function was deprecated in Qt 5.14 then removed in Qt6, along with 'store()'. The deprecated function information in Qt 5.15LTS says to use 'loadRelaxed', most likely on the basis that 'load' didn't guarantee better memory ordering that relaxed provides (see the standard c++ explanations of std::memory_order_relaxed etc). Signed-off-by: John Bowler --- generator/parser/codemodel_pointer.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/generator/parser/codemodel_pointer.h b/generator/parser/codemodel_pointer.h index dc99c6bb1..1e34abae5 100644 --- a/generator/parser/codemodel_pointer.h +++ b/generator/parser/codemodel_pointer.h @@ -122,16 +122,22 @@ template class CodeModelPointer # if QT_VERSION >= 0x050000 +# if QT_VERSION >= QT_VERSION_CHECK(5,14,0) +# define LOAD loadRelaxed +# else +# define LOAD load +# endif operator T * () const { - return QAtomicPointer::load(); + return QAtomicPointer::LOAD(); } inline bool operator!() const { return !(bool)*this; } operator bool () const { - return (bool)QAtomicPointer::load(); + return (bool)QAtomicPointer::LOAD(); } - inline T *operator->() { return QAtomicPointer::load(); } - inline const T *operator->() const { return QAtomicPointer::load(); } + inline T *operator->() { return QAtomicPointer::LOAD(); } + inline const T *operator->() const { return QAtomicPointer::LOAD(); } +#undef LOAD inline bool operator==(const CodeModelPointer &other) const { return (T*)*this == (T*)other; } inline bool operator!=(const CodeModelPointer &other) const { return (T*)*this != (T*)other; } inline bool operator==(const T *ptr) const { return (T*)*this == ptr; } From 3db7846da03320790ee9c9781238127b9105a670 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Tue, 3 Oct 2023 08:49:04 -0700 Subject: [PATCH 07/21] Qt6: QListoperator== requires const T::operator== (#116) - missing consta caused a g++ compile error - adding the const is safe, as it does not modify the LHS --- generator/parser/codemodel.cpp | 2 +- generator/parser/codemodel.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/generator/parser/codemodel.cpp b/generator/parser/codemodel.cpp index 4fafc76fd..32c67697c 100644 --- a/generator/parser/codemodel.cpp +++ b/generator/parser/codemodel.cpp @@ -216,7 +216,7 @@ QString TypeInfo::toString() const return tmp; } -bool TypeInfo::operator==(const TypeInfo &other) +bool TypeInfo::operator==(const TypeInfo &other) const { if (arrayElements().count() != other.arrayElements().count()) return false; diff --git a/generator/parser/codemodel.h b/generator/parser/codemodel.h index fe24df1c0..6133620b4 100644 --- a/generator/parser/codemodel.h +++ b/generator/parser/codemodel.h @@ -154,8 +154,8 @@ struct TypeInfo void setArguments(const QList &arguments); void addArgument(const TypeInfo &arg) { m_arguments.append(arg); } - bool operator==(const TypeInfo &other); - bool operator!=(const TypeInfo &other) { return !(*this==other); } + bool operator==(const TypeInfo &other) const; + bool operator!=(const TypeInfo &other) const { return !(*this==other); } // ### arrays and templates?? @@ -171,7 +171,7 @@ struct TypeInfo uint m_reference: 1; uint m_functionPointer: 1; uint m_indirections: 6; - inline bool equals(TypeInfo_flags other) { + inline bool equals(TypeInfo_flags other) const { return m_constant == other.m_constant && m_volatile == other.m_volatile && m_reference == other.m_reference From bb3d8e660ec9b375b558720a06483dee85c733e8 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Tue, 3 Oct 2023 23:26:14 -0700 Subject: [PATCH 08/21] Qt6: qSort and qStableSort removed (#117) * replace qSort and qStableSort by std::stable_sort and std::sort --- generator/generator.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/generator/generator.cpp b/generator/generator.cpp index 9dd70748a..cfcd42d92 100644 --- a/generator/generator.cpp +++ b/generator/generator.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include // for std::stable_sort, std::sort #include "generator.h" #include "reporthandler.h" #include "fileout.h" @@ -61,7 +62,7 @@ void Generator::generate() return; } - qStableSort(m_classes); + std::stable_sort(m_classes.begin(), m_classes.end()); foreach (AbstractMetaClass *cls, m_classes) { if (!shouldGenerate(cls)) @@ -85,7 +86,7 @@ void Generator::printClasses() QTextStream s(stdout); AbstractMetaClassList classes = m_classes; - qSort(classes); + std::sort(classes.begin(), classes.end()); foreach (AbstractMetaClass *cls, classes) { if (!shouldGenerate(cls)) From bf0b53cf09f58a80f570e5edfcfb49aba25c5c0d Mon Sep 17 00:00:00 2001 From: John Bowler Date: Wed, 4 Oct 2023 21:51:40 -0700 Subject: [PATCH 09/21] Qt6: qSort, toList and fromList removal (#118) This completes the qSort handling in generator/ including related changes caused by the removal of QSet<>::toList() and QSet<>::fromList() in Qt6 (obsoleted in Qt5.14). --- generator/abstractmetabuilder.cpp | 16 ++++++++++++---- generator/abstractmetalang.cpp | 6 ++++-- generator/prigenerator.cpp | 14 ++++++++++---- generator/setupgenerator.cpp | 26 +++++++++++++++++++++----- generator/shellgenerator.cpp | 20 ++++++++++++++++---- generator/shellheadergenerator.cpp | 10 ++++++---- generator/shellimplgenerator.cpp | 4 +++- 7 files changed, 72 insertions(+), 24 deletions(-) diff --git a/generator/abstractmetabuilder.cpp b/generator/abstractmetabuilder.cpp index b2e777772..07ee55462 100644 --- a/generator/abstractmetabuilder.cpp +++ b/generator/abstractmetabuilder.cpp @@ -39,6 +39,8 @@ ** ****************************************************************************/ +#include // for std::sort + #include "abstractmetabuilder.h" #include "reporthandler.h" @@ -384,7 +386,7 @@ static bool class_less_than(AbstractMetaClass *a, AbstractMetaClass *b) void AbstractMetaBuilder::sortLists() { - qSort(m_meta_classes.begin(), m_meta_classes.end(), class_less_than); + std::sort(m_meta_classes.begin(), m_meta_classes.end(), class_less_than); for (AbstractMetaClass *cls : m_meta_classes) { cls->sortFunctions(); } @@ -971,7 +973,7 @@ AbstractMetaEnum *AbstractMetaBuilder::traverseEnum(EnumModelItem enum_item, Abs meta_enum->addEnumValue(meta_enum_value); ReportHandler::debugFull(" - " + meta_enum_value->name() + " = " - + meta_enum_value->value()); + + QString::number(meta_enum_value->value())); // Add into global register... if (enclosing) @@ -1444,7 +1446,13 @@ void AbstractMetaBuilder::traverseEnums(ScopeModelItem scope_item, AbstractMetaC { EnumList enums = scope_item->enums(); for (EnumModelItem enum_item : enums) { - AbstractMetaEnum *meta_enum = traverseEnum(enum_item, meta_class, QSet::fromList(enumsDeclarations)); + AbstractMetaEnum *meta_enum = traverseEnum(enum_item, meta_class, +#if QT_VERSION < QT_VERSION_CHECK(5,14,0) + QSet::fromList(enumsDeclarations) +#else + QSet(enumsDeclarations.begin(), enumsDeclarations.end()) +#endif + ); if (meta_enum) { meta_enum->setOriginalAttributes(meta_enum->attributes()); meta_class->addEnum(meta_enum); @@ -2461,7 +2469,7 @@ AbstractMetaClassList AbstractMetaBuilder::classesTopologicalSorted() const AbstractMetaClassList res; AbstractMetaClassList classes = m_meta_classes; - qSort(classes); + std::sort(classes.begin(), classes.end()); QSet noDependency; QHash* > hash; diff --git a/generator/abstractmetalang.cpp b/generator/abstractmetalang.cpp index 6aa81dd7e..32dbf85ea 100644 --- a/generator/abstractmetalang.cpp +++ b/generator/abstractmetalang.cpp @@ -39,6 +39,8 @@ ** ****************************************************************************/ +#include // for std::sort + #include "abstractmetalang.h" #include "reporthandler.h" @@ -972,7 +974,7 @@ AbstractMetaFunctionList AbstractMetaClass::virtualOverrideFunctions() const void AbstractMetaClass::sortFunctions() { - qSort(m_functions.begin(), m_functions.end(), function_sorter); + std::sort(m_functions.begin(), m_functions.end(), function_sorter); } void AbstractMetaClass::setFunctions(const AbstractMetaFunctionList &functions) @@ -1090,7 +1092,7 @@ void AbstractMetaClass::addFunction(AbstractMetaFunction *function) if (!function->isDestructor()) { m_functions << function; // seems like this is not needed and takes a lot of performance - //qSort(m_functions.begin(), m_functions.end(), function_sorter); + //std::sort(m_functions.begin(), m_functions.end(), function_sorter); } diff --git a/generator/prigenerator.cpp b/generator/prigenerator.cpp index 3f513c84f..a1c295804 100644 --- a/generator/prigenerator.cpp +++ b/generator/prigenerator.cpp @@ -39,6 +39,8 @@ ** ****************************************************************************/ +#include // for std::sort + #include "prigenerator.h" #include "shellgenerator.h" #include "reporthandler.h" @@ -81,8 +83,12 @@ static QString combineIncludes(const QString& text) { result += line + "\n"; } } - QStringList includeList = includes.toList(); - qSort(includeList); +#if QT_VERSION < QT_VERSION_CHECK(5,14,0) + QStringList includeList = includes.toList(); +#else + QStringList includeList(includes.begin(), includes.end()); +#endif + std::sort(includeList.begin(), includeList.end()); result = includeList.join("\n") + result; return result; } @@ -129,7 +135,7 @@ void PriGenerator::generate() int idx = folder.indexOf('/'); folder = folder.left(idx); - qSort(list.begin(), list.end()); + std::sort(list.begin(), list.end()); FileOut file(m_out_dir + "/generated_cpp/" + pri.key()); // strange idea to do the file compacting so late, but it is the most effective way without patching the generator a lot @@ -146,7 +152,7 @@ void PriGenerator::generate() file.stream << "\n"; file.stream << "SOURCES += \\\n"; list = pri.value().sources; - qSort(list.begin(), list.end()); + std::sort(list.begin(), list.end()); if (compact) { list = compactFiles(list, ".cpp", m_out_dir + "/generated_cpp/" + folder, folder); } diff --git a/generator/setupgenerator.cpp b/generator/setupgenerator.cpp index 91880f3d2..9219a3845 100644 --- a/generator/setupgenerator.cpp +++ b/generator/setupgenerator.cpp @@ -39,6 +39,8 @@ ** ****************************************************************************/ +#include // for std::sort + #include "setupgenerator.h" #include "shellgenerator.h" #include "reporthandler.h" @@ -65,7 +67,13 @@ static QStringList getOperatorCodes(const AbstractMetaClass* cls) { } } QSet r; - for (QString op : operatorCodes.toList()) { + for (QString op : +# if QT_VERSION < QT_VERSION_CHECK(5,14,0) + operatorCodes.toList() +# else + QStringList(operatorCodes.begin(), operatorCodes.end()) +# endif + ) { if (op == ">" || op == "<" || op == ">=" || op == "<=" || op == "==" || op == "!=") { r.insert("PythonQt::Type_RichCompare"); } else if (op == "+") { @@ -122,8 +130,12 @@ static QStringList getOperatorCodes(const AbstractMetaClass* cls) { } - QStringList result = r.toList(); - qSort(result); +#if QT_VERSION < QT_VERSION_CHECK(5,14,0) + QStringList result = r.toList(); +#else + QStringList result(r.begin(), r.end()); +#endif + std::sort(result.begin(), result.end()); return result; } @@ -223,7 +235,7 @@ void SetupGenerator::generate() } } } - qSort(classes_with_polymorphic_id.begin(), classes_with_polymorphic_id.end(), class_less_than); + std::sort(classes_with_polymorphic_id.begin(), classes_with_polymorphic_id.end(), class_less_than); QHashIterator > pack(packHash); while (pack.hasNext()) { @@ -231,7 +243,7 @@ void SetupGenerator::generate() QList list = pack.value(); if (list.isEmpty()) continue; - qSort(list.begin(), list.end(), class_less_than); + std::sort(list.begin(), list.end(), class_less_than); QString packKey = pack.key(); QString packName = pack.key(); @@ -374,7 +386,11 @@ void SetupGenerator::generate() } s << endl; +#if QT_VERSION < QT_VERSION_CHECK(5,14,0) QStringList list = listRegistration.toList(); +#else + QStringList list(listRegistration.begin(), listRegistration.end()); +#endif list.sort(); Q_FOREACH(QString name, list) { if (name.contains("Ssl")) { diff --git a/generator/shellgenerator.cpp b/generator/shellgenerator.cpp index b725f03d1..959ba344a 100644 --- a/generator/shellgenerator.cpp +++ b/generator/shellgenerator.cpp @@ -39,6 +39,8 @@ ** ****************************************************************************/ +#include // for std::sort + #include "shellgenerator.h" #include "reporthandler.h" @@ -322,7 +324,11 @@ AbstractMetaFunctionList ShellGenerator::getFunctionsToWrap(const AbstractMetaCl AbstractMetaClass::VirtualFunctions | AbstractMetaClass::WasVisible | AbstractMetaClass::NotRemovedFromTargetLang | AbstractMetaClass::ClassImplements ); +#if QT_VERSION < QT_VERSION_CHECK(5,14,0) QSet set1 = QSet::fromList(functions); +#else + QSet set1(functions.begin(), functions.end()); +#endif for (AbstractMetaFunction* func : functions2) { set1.insert(func); } @@ -331,14 +337,20 @@ AbstractMetaFunctionList ShellGenerator::getFunctionsToWrap(const AbstractMetaCl bool hasPromoter = meta_class->typeEntry()->shouldCreatePromoter(); - for (AbstractMetaFunction* func : set1.toList()) { + for (AbstractMetaFunction* func : +# if QT_VERSION < QT_VERSION_CHECK(5,14,0) + set1.toList() +# else + QList(set1.begin(), set1.end()) +# endif + ) { if (func->implementingClass()==meta_class) { if (hasPromoter || func->wasPublic()) { resultFunctions << func; } } } - qSort(resultFunctions.begin(), resultFunctions.end(), function_sorter); + std::sort(resultFunctions.begin(), resultFunctions.end(), function_sorter); return resultFunctions; } @@ -348,7 +360,7 @@ AbstractMetaFunctionList ShellGenerator::getVirtualFunctionsForShell(const Abstr AbstractMetaClass::VirtualFunctions | AbstractMetaClass::WasVisible | AbstractMetaClass::NotRemovedFromTargetLang ); - qSort(functions.begin(), functions.end(), function_sorter); + std::sort(functions.begin(), functions.end(), function_sorter); return functions; } @@ -361,7 +373,7 @@ AbstractMetaFunctionList ShellGenerator::getProtectedFunctionsThatNeedPromotion( functions << func; } } - qSort(functions.begin(), functions.end(), function_sorter); + std::sort(functions.begin(), functions.end(), function_sorter); return functions; } diff --git a/generator/shellheadergenerator.cpp b/generator/shellheadergenerator.cpp index a8a7528bb..89cd64c52 100644 --- a/generator/shellheadergenerator.cpp +++ b/generator/shellheadergenerator.cpp @@ -39,6 +39,8 @@ ** ****************************************************************************/ +#include // for std::sort + #include "shellheadergenerator.h" #include @@ -115,7 +117,7 @@ void ShellHeaderGenerator::write(QTextStream& s, const AbstractMetaClass* meta_c s << "#include " << endl << endl; IncludeList list = meta_class->typeEntry()->extraIncludes(); - qSort(list.begin(), list.end()); + std::sort(list.begin(), list.end()); for (const Include & inc : list) { ShellGenerator::writeInclude(s, inc); } @@ -185,7 +187,7 @@ void ShellHeaderGenerator::write(QTextStream& s, const AbstractMetaClass* meta_c << " : public " << meta_class->qualifiedCppName() << endl << "{ public:" << endl; AbstractMetaEnumList enums1 = meta_class->enums(); - qSort(enums1.begin(), enums1.end(), enum_lessThan); + std::sort(enums1.begin(), enums1.end(), enum_lessThan); for (AbstractMetaEnum * enum1 : enums1) { if (enum1->wasProtected()) { s << "enum " << enum1->name() << "{" << endl; @@ -263,7 +265,7 @@ void ShellHeaderGenerator::write(QTextStream& s, const AbstractMetaClass* meta_c s << "public:" << endl; AbstractMetaEnumList enums1 = meta_class->enums(); - qSort(enums1.begin(), enums1.end(), enum_lessThan); + std::sort(enums1.begin(), enums1.end(), enum_lessThan); AbstractMetaEnumList enums; QList flags; for (AbstractMetaEnum * enum1 : enums1) { @@ -409,7 +411,7 @@ void ShellHeaderGenerator::write(QTextStream& s, const AbstractMetaClass* meta_c } AbstractMetaFieldList fields = meta_class->fields(); - qSort(fields.begin(), fields.end(), field_lessThan); + std::sort(fields.begin(), fields.end(), field_lessThan); // TODO: move "So" check to typesystem, e.g. allow star in rejection... // Field accessors diff --git a/generator/shellimplgenerator.cpp b/generator/shellimplgenerator.cpp index c508df4e9..798e96a23 100644 --- a/generator/shellimplgenerator.cpp +++ b/generator/shellimplgenerator.cpp @@ -39,6 +39,8 @@ ** ****************************************************************************/ +#include // for std::sort + #include "shellimplgenerator.h" #include "reporthandler.h" #include "fileout.h" @@ -82,7 +84,7 @@ void ShellImplGenerator::write(QTextStream &s, const AbstractMetaClass *meta_cla // return; IncludeList list = meta_class->typeEntry()->extraIncludes(); - qSort(list.begin(), list.end()); + std::sort(list.begin(), list.end()); foreach (const Include &inc, list) { ShellGenerator::writeInclude(s, inc); } From d87d01cd16f3cd39d4c08cd61f1bc972b2dfdc8f Mon Sep 17 00:00:00 2001 From: John Bowler Date: Thu, 5 Oct 2023 09:18:37 -0700 Subject: [PATCH 10/21] Qt6: QString::SkipEmptyParts moved to Qt (#119) - replaced it and added backwards compatibility --- generator/main.cpp | 2 +- generator/setupgenerator.cpp | 2 +- generator/typesystem.h | 13 ++++++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/generator/main.cpp b/generator/main.cpp index a01b968ae..22a054e91 100644 --- a/generator/main.cpp +++ b/generator/main.cpp @@ -110,7 +110,7 @@ int main(int argc, char *argv[]) FileOut::license = true; if (args.contains("rebuild-only")) { - QStringList classes = args.value("rebuild-only").split(",", QString::SkipEmptyParts); + QStringList classes = args.value("rebuild-only").split(",", Qt::SkipEmptyParts); TypeDatabase::instance()->setRebuildClasses(classes); } diff --git a/generator/setupgenerator.cpp b/generator/setupgenerator.cpp index 9219a3845..4694bab3a 100644 --- a/generator/setupgenerator.cpp +++ b/generator/setupgenerator.cpp @@ -121,7 +121,7 @@ static QStringList getOperatorCodes(const AbstractMetaClass* cls) { CodeSnipList code_snips = cls->typeEntry()->codeSnips(); for (const CodeSnip &cs : code_snips) { if (cs.language == TypeSystem::PyWrapperOperators) { - QStringList values = cs.code().split(" ", QString::SkipEmptyParts); + QStringList values = cs.code().split(" ", Qt::SkipEmptyParts); for (QString value : values) { r.insert(value); } diff --git a/generator/typesystem.h b/generator/typesystem.h index 66bfd9b9e..344427301 100644 --- a/generator/typesystem.h +++ b/generator/typesystem.h @@ -48,6 +48,16 @@ #include #include +/* QString::SkipEmptyParts was replicated in Qt::SplitBehavior in 15.4 and the + * QString original deprecated then it was removed in Qt6. This provides + * forward compatibility with Qt6 for versions of Qt prior to 15.4: + */ +#if QT_VERSION < QT_VERSION_CHECK(5,14,0) + namespace Qt { + const QString::SplitBehavior SkipEmptyParts = QString::SkipEmptyParts; + }; +#endif + class Indentor; class AbstractMetaType; @@ -1159,7 +1169,8 @@ class TypeDatabase foreach (const QString &_warning, m_suppressedWarnings) { QString warning(QString(_warning).replace("\\*", "&place_holder_for_asterisk;")); - QStringList segs = warning.split("*", QString::SkipEmptyParts); + QStringList segs = warning.split("*", Qt::SkipEmptyParts); + if (segs.size() == 0) continue ; From 319a4a78058b2849a55ea3c3f5ae84023c6041e3 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Thu, 5 Oct 2023 14:46:12 -0700 Subject: [PATCH 11/21] Qt6: QTextStream compatibility (#120) - provides compatibility with the removal of the global ::endl for use with QTextStream; Qt6 requires Qt::endl - includes Qt6 specific changes necessary to deal with the replacement of QTextCodec by QStringConverter and the slight changes to the default setup of QTextStream (to UTF-8 with auto-detect of UTF-16) --------- Signed-off-by: John Bowler --- generator/abstractmetabuilder.cpp | 9 +++++++-- generator/asttoxml.cpp | 17 +++++++++++++++-- generator/typesystem.h | 24 ++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/generator/abstractmetabuilder.cpp b/generator/abstractmetabuilder.cpp index 07ee55462..5806b2c5f 100644 --- a/generator/abstractmetabuilder.cpp +++ b/generator/abstractmetabuilder.cpp @@ -56,7 +56,9 @@ #include #include #include -#include +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) +# include +#endif #include #include @@ -402,7 +404,10 @@ bool AbstractMetaBuilder::build() return false; QTextStream stream(&file); - stream.setCodec(QTextCodec::codecForName("UTF-8")); +# if QT_VERSION < QT_VERSION_CHECK(6,0,0) + stream.setCodec(QTextCodec::codecForName("UTF-8")); + /* Note required in Qt6: see the same call in asttoxml.cpp */ +# endif QByteArray contents = stream.readAll().toUtf8(); file.close(); diff --git a/generator/asttoxml.cpp b/generator/asttoxml.cpp index c3d17dd44..eb3913b8c 100644 --- a/generator/asttoxml.cpp +++ b/generator/asttoxml.cpp @@ -47,7 +47,9 @@ #include #include -#include +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) +# include +#endif #include void astToXML(QString name) { @@ -57,7 +59,18 @@ void astToXML(QString name) { return; QTextStream stream(&file); +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) stream.setCodec(QTextCodec::codecForName("UTF-8")); +#else + /* NOTE, for Qt6: + * + * stream.setEncoding(QStringConverter::Utf8) + * + * is the default but will be overridden if the UTF-16 BOM is seen. This + * is almost certainly the correct behavior because the BOM isn't valid in + * a text stream otherwise. + */ +#endif QByteArray contents = stream.readAll().toUtf8(); file.close(); @@ -164,7 +177,7 @@ void writeOutClass(QXmlStreamWriter &s, ClassModelItem &item) { writeOutEnum(s, enumItem); } - QHash functionMap = item->functionMap(); + QMultiHash functionMap = item->functionMap(); for (FunctionModelItem funcItem : functionMap.values()) { writeOutFunction(s, funcItem); } diff --git a/generator/typesystem.h b/generator/typesystem.h index 344427301..fe12fd73b 100644 --- a/generator/typesystem.h +++ b/generator/typesystem.h @@ -48,6 +48,9 @@ #include #include +/* BEGIN: Qt6 compatibility. The following can removed when versions of Qt + * prior to 5.14 are no longer supported. + */ /* QString::SkipEmptyParts was replicated in Qt::SplitBehavior in 15.4 and the * QString original deprecated then it was removed in Qt6. This provides * forward compatibility with Qt6 for versions of Qt prior to 15.4: @@ -58,6 +61,27 @@ }; #endif +/* Global endl (::endl) is used extensively in the generator .cpp files. This + * was supported by Qt until Qt6. In Qt5.14 Qt::endl was added in anticipation + * of the Qt6 change and the use of global endl could be avoided (it does not + * seem to have been explicitly deprecated). This gives backward compatibility + * for global endl in Qt6 (not Qt5, where global endl was still available). + * + * Note that 'constexpr' is available in Qt6 because Qt6 requires C++17; + * constexpr was introduced in C++11. Likewise for decltype. Qt::endl is a + * function so ::endl is a pointer to the function and the implicit conversion + * is used; this is to cause an compiler error in the future if the base type + * of Qt::endl changes. + * + * When versions of Qt older than 5.14 are no longer supported this can be + * removed however all the 'endl' references in the code will need to be + * changed to Qt::endl. + */ +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + static const constexpr decltype (Qt::endl) *endl = Qt::endl; +#endif +/* END: Qt compatibility. */ + class Indentor; class AbstractMetaType; From 8736b53946d32d2665d756688c6a03c3b1ddb972 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Mon, 9 Oct 2023 00:04:52 -0700 Subject: [PATCH 12/21] Eliminate warnings about #warning (#122) The warnings are already only emitted with GCC so changing them to the GCC diagnostic pragma is safe. --- generator/parser/declarator_compiler.cpp | 2 +- generator/parser/name_compiler.cpp | 4 ++-- generator/parser/parser.cpp | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/generator/parser/declarator_compiler.cpp b/generator/parser/declarator_compiler.cpp index 3dff91ccd..ac71f38fb 100644 --- a/generator/parser/declarator_compiler.cpp +++ b/generator/parser/declarator_compiler.cpp @@ -135,7 +135,7 @@ void DeclaratorCompiler::visitPtrOperator(PtrOperatorAST *node) if (node->mem_ptr) { #if defined(__GNUC__) -#warning "ptr to mem -- not implemented" +#pragma GCC warning "ptr to mem -- not implemented" #endif } } diff --git a/generator/parser/name_compiler.cpp b/generator/parser/name_compiler.cpp index 75dc32479..7e136b4d5 100644 --- a/generator/parser/name_compiler.cpp +++ b/generator/parser/name_compiler.cpp @@ -80,7 +80,7 @@ void NameCompiler::visitUnqualifiedName(UnqualifiedNameAST *node) if (OperatorFunctionIdAST *op_id = node->operator_id) { #if defined(__GNUC__) -#warning "NameCompiler::visitUnqualifiedName() -- implement me" +#pragma GCC warning "NameCompiler::visitUnqualifiedName() -- implement me" #endif if (op_id->op && op_id->op->op) @@ -93,7 +93,7 @@ void NameCompiler::visitUnqualifiedName(UnqualifiedNameAST *node) else if (op_id->type_specifier) { #if defined(__GNUC__) -#warning "don't use an hardcoded string as cast' name" +#pragma GCC warning "don't use an hardcoded string as cast' name" #endif Token const &tk = _M_token_stream->token ((int) op_id->start_token); Token const &end_tk = _M_token_stream->token ((int) op_id->end_token); diff --git a/generator/parser/parser.cpp b/generator/parser/parser.cpp index 26b2dc8af..d25c4b346 100644 --- a/generator/parser/parser.cpp +++ b/generator/parser/parser.cpp @@ -840,7 +840,7 @@ bool Parser::parseAsmDefinition(DeclarationAST *&node) parseCvQualify(cv); #if defined(__GNUC__) -#warning "implement me" +#pragma GCC warning "implement me" #endif skip('(', ')'); token_stream.nextToken(); @@ -2427,7 +2427,7 @@ bool Parser::parseInitializerClause(InitializerClauseAST *&node) if (token_stream.lookAhead() == '{') { #if defined(__GNUC__) -#warning "implement me" +#pragma GCC warning "implement me" #endif if (skip('{','}')) token_stream.nextToken(); @@ -2451,7 +2451,7 @@ bool Parser::parseInitializerClause(InitializerClauseAST *&node) bool Parser::parsePtrToMember(PtrToMemberAST *&node) { #if defined(__GNUC__) -#warning "implemente me (AST)" +#pragma GCC warning "implemente me (AST)" #endif std::size_t start = token_stream.cursor(); @@ -2625,7 +2625,7 @@ bool Parser::parseStatement(StatementAST *&node) case Token_break: case Token_continue: #if defined(__GNUC__) -#warning "implement me" +#pragma GCC warning "implement me" #endif token_stream.nextToken(); ADVANCE(';', ";"); @@ -2633,7 +2633,7 @@ bool Parser::parseStatement(StatementAST *&node) case Token_goto: #if defined(__GNUC__) -#warning "implement me" +#pragma GCC warning "implement me" #endif token_stream.nextToken(); ADVANCE(Token_identifier, "identifier"); @@ -3279,7 +3279,7 @@ bool Parser::parseDeclarationInternal(DeclarationAST *&node) ADVANCE(';', ";"); #if defined(__GNUC__) -#warning "mark the ast as constant" +#pragma GCC warning "mark the ast as constant" #endif SimpleDeclarationAST *ast = CreateNode(_M_pool); ast->init_declarators = declarators; @@ -3380,7 +3380,7 @@ bool Parser::parseDeclarationInternal(DeclarationAST *&node) bool Parser::skipFunctionBody(StatementAST *&) { #if defined(__GNUC__) -#warning "Parser::skipFunctionBody() -- implement me" +#pragma GCC warning "Parser::skipFunctionBody() -- implement me" #endif Q_ASSERT(0); // ### not implemented return 0; @@ -3409,7 +3409,7 @@ bool Parser::parseTypeSpecifierOrClassSpec(TypeSpecifierAST *&node) bool Parser::parseTryBlockStatement(StatementAST *&node) { #if defined(__GNUC__) -#warning "implement me" +#pragma GCC warning "implement me" #endif CHECK(Token_try); From 5df5cbb793623813254e60b35ec905dbf62248e5 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Mon, 9 Oct 2023 00:27:44 -0700 Subject: [PATCH 13/21] Qt6: generator/typesystem.cpp: XML workround (#123) - works around the need to rewrite the XML parser in generator/typesystem.cpp by invoking the Qt5 compatibility library; this is the only thing in the generator which requires it but the alternative is a complete rewrite of the XML reading code --- generator/generator.pri | 5 +++++ generator/typesystem.cpp | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/generator/generator.pri b/generator/generator.pri index e399d59e3..c941f879b 100644 --- a/generator/generator.pri +++ b/generator/generator.pri @@ -70,6 +70,11 @@ SOURCES += \ QT += core xml +greaterThan(QT_MAJOR_VERSION, 5) { + QT += core5compat + message("WARNING: Qt module core5compat for XML handling in typesystem.cpp") +} + win32-msvc.net { QMAKE_CXXFLAGS += /Zm500 QMAKE_CXXFLAGS -= -Zm200 diff --git a/generator/typesystem.cpp b/generator/typesystem.cpp index ea9b455be..c3f6ded94 100644 --- a/generator/typesystem.cpp +++ b/generator/typesystem.cpp @@ -51,6 +51,22 @@ #include #include // Q_FALLTHROUGH +/* This file needs to be rewritten as documented here: + * + * See: https://doc.qt.io/qt-6/xml-changes-qt6.html + * + * The rewrite may be backward compatible to Qt4.3 APIs because the base + * facilites (QXmlStreamReader) used to relace the 'SAX' parser were apparently + * available then. Use of Xml5Compat is a work round until such a rewrite has + * been done. + */ +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) +# if defined(__GNUC__) +# pragma GCC warning "Qt6: implement Qt6 compatible XML reading" +# endif +# include +#endif + QString strings_Object = QLatin1String("Object"); QString strings_String = QLatin1String("String"); QString strings_Thread = QLatin1String("Thread"); From 85dee26e655f224532ba8f5e9ca0ba83cc753b1b Mon Sep 17 00:00:00 2001 From: John Bowler Date: Wed, 11 Oct 2023 03:24:07 -0700 Subject: [PATCH 14/21] Add constexpr and decltype parsing (#125) - parses constexpr (in the manner of const) and decltype (in the manner of __typeof) and adds flags for them --- .vimrc | 1 + generator/abstractmetabuilder.h | 2 +- generator/parser/codemodel.cpp | 18 +++++++++++++++++ generator/parser/codemodel.h | 31 +++++++++++++++++++++-------- generator/parser/compiler_utils.cpp | 2 ++ generator/parser/lexer.cpp | 29 +++++++++++++++++++++++++++ generator/parser/list.h | 2 +- generator/parser/name_compiler.cpp | 6 ++++++ generator/parser/parser.cpp | 22 ++++++++++++++++---- generator/parser/parser.h | 18 ++++++++--------- generator/parser/rxx_allocator.h | 16 +++++++-------- generator/parser/symbol.h | 4 ++-- generator/parser/tokens.cpp | 2 ++ generator/parser/tokens.h | 2 ++ generator/parser/type_compiler.cpp | 23 +++++++++------------ generator/parser/type_compiler.h | 4 ++-- generator/typesystem.h | 2 +- 17 files changed, 134 insertions(+), 50 deletions(-) create mode 100644 .vimrc diff --git a/.vimrc b/.vimrc new file mode 100644 index 000000000..d5a9f893c --- /dev/null +++ b/.vimrc @@ -0,0 +1 @@ +set expandtab diff --git a/generator/abstractmetabuilder.h b/generator/abstractmetabuilder.h index f4c00b112..5322b76f6 100644 --- a/generator/abstractmetabuilder.h +++ b/generator/abstractmetabuilder.h @@ -127,7 +127,7 @@ class AbstractMetaBuilder bool isEnum(const QStringList &qualified_name); void fixQObjectForScope (TypeDatabase *types, - NamespaceModelItem item); + NamespaceModelItem item); // QtScript QSet qtMetaTypeDeclaredTypeNames() const diff --git a/generator/parser/codemodel.cpp b/generator/parser/codemodel.cpp index 32c67697c..511307e48 100644 --- a/generator/parser/codemodel.cpp +++ b/generator/parser/codemodel.cpp @@ -142,7 +142,9 @@ TypeInfo TypeInfo::combine (const TypeInfo &__lhs, const TypeInfo &__rhs) TypeInfo __result = __lhs; __result.setConstant (__result.isConstant () || __rhs.isConstant ()); + __result.setConstexpr (__result.isConstexpr () || __rhs.isConstexpr ()); __result.setVolatile (__result.isVolatile () || __rhs.isVolatile ()); + __result.setMutable (__result.isMutable () || __rhs.isMutable ()); __result.setReference (__result.isReference () || __rhs.isReference ()); __result.setRvalueReference (__result.isRvalueReference () || __rhs.isRvalueReference ()); __result.setIndirections (__result.indirections () + __rhs.indirections ()); @@ -182,9 +184,15 @@ QString TypeInfo::toString() const if (isConstant()) tmp += QLatin1String(" const"); + if (isConstexpr()) + tmp += QLatin1String(" constexpr"); + if (isVolatile()) tmp += QLatin1String(" volatile"); + if (isMutable()) + tmp += QLatin1String(" mutable"); + if (indirections()) tmp += QString(indirections(), QLatin1Char('*')); @@ -917,6 +925,16 @@ void _MemberModelItem::setConstant(bool isConstant) _M_isConstant = isConstant; } +bool _MemberModelItem::isConstexpr() const +{ + return _M_isConstexpr; +} + +void _MemberModelItem::setConstexpr(bool isConstexpr) +{ + _M_isConstexpr = isConstexpr; +} + bool _MemberModelItem::isVolatile() const { return _M_isVolatile; diff --git a/generator/parser/codemodel.h b/generator/parser/codemodel.h index 6133620b4..06af94f61 100644 --- a/generator/parser/codemodel.h +++ b/generator/parser/codemodel.h @@ -132,9 +132,15 @@ struct TypeInfo bool isConstant() const { return m_flags.m_constant; } void setConstant(bool is) { m_flags.m_constant = is; } + bool isConstexpr() const { return m_flags.m_constexpr; } + void setConstexpr(bool is) { m_flags.m_constexpr = is; } + bool isVolatile() const { return m_flags.m_volatile; } void setVolatile(bool is) { m_flags.m_volatile = is; } + bool isMutable() const { return m_flags.m_mutable; } + void setMutable(bool is) { m_flags.m_mutable = is; } + bool isReference() const { return m_flags.m_reference; } void setReference(bool is) { m_flags.m_reference = is; } @@ -166,19 +172,24 @@ struct TypeInfo private: struct TypeInfo_flags { - uint m_constant: 1; - uint m_volatile: 1; - uint m_reference: 1; - uint m_functionPointer: 1; - uint m_indirections: 6; - inline bool equals(TypeInfo_flags other) const { + uint m_constant: 1; + uint m_constexpr: 1; + uint m_volatile: 1; + uint m_mutable: 1; + uint m_reference: 1; + uint m_functionPointer: 1; + uint m_indirections: 6; + inline bool equals(TypeInfo_flags other) const { + /* m_auto and m_friend don't matter here */ return m_constant == other.m_constant + && m_constexpr == other.m_constexpr && m_volatile == other.m_volatile + && m_mutable == other.m_mutable && m_reference == other.m_reference && m_functionPointer == other.m_functionPointer && m_indirections == other.m_indirections; - } - } m_flags {0, 0, 0, 0, 0}; + } + } m_flags {0, 0, 0, 0, 0, 0, 0}; QStringList m_qualifiedName; QStringList m_arrayElements; @@ -455,6 +466,9 @@ class _MemberModelItem: public _CodeModelItem bool isConstant() const; void setConstant(bool isConstant); + bool isConstexpr() const; + void setConstexpr(bool isConstexpr); + bool isVolatile() const; void setVolatile(bool isVolatile); @@ -504,6 +518,7 @@ class _MemberModelItem: public _CodeModelItem struct { uint _M_isConstant: 1; + uint _M_isConstexpr: 1; uint _M_isVolatile: 1; uint _M_isStatic: 1; uint _M_isAuto: 1; diff --git a/generator/parser/compiler_utils.cpp b/generator/parser/compiler_utils.cpp index 96de701fa..c14f22b40 100644 --- a/generator/parser/compiler_utils.cpp +++ b/generator/parser/compiler_utils.cpp @@ -58,7 +58,9 @@ TypeInfo CompilerUtils::typeDescription(TypeSpecifierAST *type_specifier, Declar TypeInfo typeInfo; typeInfo.setQualifiedName (type_cc.qualifiedName ()); typeInfo.setConstant (type_cc.isConstant ()); + typeInfo.setConstexpr (type_cc.isConstexpr ()); typeInfo.setVolatile (type_cc.isVolatile ()); + typeInfo.setMutable (type_cc.isMutable ()); typeInfo.setReference (decl_cc.isReference ()); typeInfo.setRvalueReference (decl_cc.isRvalueReference ()); typeInfo.setIndirections (decl_cc.indirection ()); diff --git a/generator/parser/lexer.cpp b/generator/parser/lexer.cpp index 0ff009260..6ccf7680f 100644 --- a/generator/parser/lexer.cpp +++ b/generator/parser/lexer.cpp @@ -1549,6 +1549,20 @@ void Lexer::scanKeyword8() } break; + case 'd': + if (*(cursor + 1) == 'e' && + *(cursor + 2) == 'c' && + *(cursor + 3) == 'l' && + *(cursor + 4) == 't' && + *(cursor + 5) == 'y' && + *(cursor + 6) == 'p' && + *(cursor + 7) == 'e') + { + token_stream[(int) index++].kind = Token_decltype; + return; + } + break; + case 'e': if (*(cursor + 1) == 'x' && *(cursor + 2) == 'p' && @@ -1680,6 +1694,21 @@ void Lexer::scanKeyword9() { switch (*cursor) { + case 'c': + if (*(cursor + 1) == 'o' && + *(cursor + 2) == 'n' && + *(cursor + 3) == 's' && + *(cursor + 4) == 't' && + *(cursor + 5) == 'e' && + *(cursor + 6) == 'x' && + *(cursor + 7) == 'p' && + *(cursor + 8) == 'r') + { + token_stream[(int) index++].kind = Token_constexpr; + return; + } + break; + case 'p': if (*(cursor + 1) == 'r' && *(cursor + 2) == 'o' && diff --git a/generator/parser/list.h b/generator/parser/list.h index 711819246..c7ef9e285 100644 --- a/generator/parser/list.h +++ b/generator/parser/list.h @@ -105,7 +105,7 @@ struct ListNode template inline const ListNode *snoc(const ListNode *list, - const Tp &element, pool *p) + const Tp &element, pool *p) { if (!list) return ListNode::create(element, p); diff --git a/generator/parser/name_compiler.cpp b/generator/parser/name_compiler.cpp index 7e136b4d5..1b70b879e 100644 --- a/generator/parser/name_compiler.cpp +++ b/generator/parser/name_compiler.cpp @@ -127,6 +127,12 @@ void NameCompiler::visitTemplateArgument(TemplateArgumentAST *node) if (type_cc.isConstant()) _M_name.last() += "const "; + /* An id can't be 'constexpr' but it may have a function type in which + * case constexpr could appear. + */ + if (type_cc.isConstexpr()) + _M_name.last() += "constexpr "; + QStringList q = type_cc.qualifiedName (); if (q.count () == 1) diff --git a/generator/parser/parser.cpp b/generator/parser/parser.cpp index d25c4b346..73e4dd711 100644 --- a/generator/parser/parser.cpp +++ b/generator/parser/parser.cpp @@ -249,7 +249,9 @@ bool Parser::skipUntilDeclaration() case Token_export: case Token_const: // cv + case Token_constexpr: // cv case Token_volatile: // cv + case Token_mutable: // cv case Token_public: case Token_protected: @@ -258,6 +260,11 @@ bool Parser::skipUntilDeclaration() case Token_slots: // Qt return true; + case Token_decltype: + case Token___typeof: + reportError("C++11 decltype/__typeof(id|expression) not handled"); + return true; + default: token_stream.nextToken(); } @@ -276,7 +283,11 @@ bool Parser::skipUntilStatement() case '{': case '}': case Token_const: + case Token_constexpr: + case Token_decltype: + case Token___typeof: case Token_volatile: + case Token_mutable: case Token_identifier: case Token_case: case Token_default: @@ -984,7 +995,8 @@ bool Parser::parseCvQualify(const ListNode *&node) int tk; while (0 != (tk = token_stream.lookAhead()) - && (tk == Token_const || tk == Token_volatile)) + && (tk == Token_const || tk == Token_constexpr || + tk == Token_volatile || tk == Token_mutable)) { node = snoc(node, token_stream.cursor(), _M_pool); token_stream.nextToken(); @@ -1032,7 +1044,8 @@ bool Parser::parseSimpleTypeSpecifier(TypeSpecifierAST *&node, { ast->integrals = integrals; } - else if (token_stream.lookAhead() == Token___typeof) + else if (token_stream.lookAhead() == Token___typeof || + token_stream.lookAhead() == Token_decltype) { ast->type_of = token_stream.cursor(); token_stream.nextToken(); @@ -1627,7 +1640,7 @@ bool Parser::parseStorageClassSpecifier(const ListNode *&node) while (0 != (tk = token_stream.lookAhead()) && (tk == Token_friend || tk == Token_auto || tk == Token_register || tk == Token_static - || tk == Token_extern || tk == Token_mutable)) + || tk == Token_extern)) { node = snoc(node, token_stream.cursor(), _M_pool); token_stream.nextToken(); @@ -3262,7 +3275,8 @@ bool Parser::parseDeclarationInternal(DeclarationAST *&node) start_decl: token_stream.rewind((int) index); - if (token_stream.lookAhead() == Token_const + if ((token_stream.lookAhead() == Token_const || + token_stream.lookAhead() == Token_constexpr) && token_stream.lookAhead(1) == Token_identifier && token_stream.lookAhead(2) == '=') { diff --git a/generator/parser/parser.h b/generator/parser/parser.h index d95fbc94a..f238e181c 100644 --- a/generator/parser/parser.h +++ b/generator/parser/parser.h @@ -100,10 +100,10 @@ class Parser bool parseEnumSpecifier(TypeSpecifierAST *&node); bool parseEnumerator(EnumeratorAST *&node); bool parseEqualityExpression(ExpressionAST *&node, - bool templArgs = false); + bool templArgs = false); bool parseExceptionSpecification(ExceptionSpecificationAST *&node); bool parseExclusiveOrExpression(ExpressionAST *&node, - bool templArgs = false); + bool templArgs = false); bool parseExpression(ExpressionAST *&node); bool parseExpressionOrDeclarationStatement(StatementAST *&node); bool parseExpressionStatement(StatementAST *&node); @@ -113,7 +113,7 @@ class Parser bool parseFunctionSpecifier(const ListNode *&node); bool parseIfStatement(StatementAST *&node); bool parseInclusiveOrExpression(ExpressionAST *&node, - bool templArgs = false); + bool templArgs = false); bool parseInitDeclarator(InitDeclaratorAST *&node); bool parseInitDeclaratorList(const ListNode *&node); bool parseInitializer(InitializerAST *&node); @@ -122,9 +122,9 @@ class Parser bool parseLinkageBody(LinkageBodyAST *&node); bool parseLinkageSpecification(DeclarationAST *&node); bool parseLogicalAndExpression(ExpressionAST *&node, - bool templArgs = false); + bool templArgs = false); bool parseLogicalOrExpression(ExpressionAST *&node, - bool templArgs = false); + bool templArgs = false); bool parseMemInitializer(MemInitializerAST *&node); bool parseMemInitializerList(const ListNode *&node); bool parseMemberSpecification(DeclarationAST *&node); @@ -148,17 +148,17 @@ class Parser bool parsePtrOperator(PtrOperatorAST *&node); bool parsePtrToMember(PtrToMemberAST *&node); bool parseRelationalExpression(ExpressionAST *&node, - bool templArgs = false); + bool templArgs = false); bool parseShiftExpression(ExpressionAST *&node); bool parseSimpleTypeSpecifier(TypeSpecifierAST *&node, - bool onlyIntegral = false); + bool onlyIntegral = false); bool parseStatement(StatementAST *&node); bool parseStorageClassSpecifier(const ListNode *&node); bool parseStringLiteral(StringLiteralAST *&node); bool parseSwitchStatement(StatementAST *&node); bool parseTemplateArgument(TemplateArgumentAST *&node); bool parseTemplateArgumentList(const ListNode *&node, - bool reportError = true); + bool reportError = true); bool parseTemplateDeclaration(DeclarationAST *&node); bool parseTemplateParameter(TemplateParameterAST *&node); bool parseTemplateParameterList(const ListNode *&node); @@ -173,7 +173,7 @@ class Parser bool parseTypedef(DeclarationAST *&node); bool parseUnaryExpression(ExpressionAST *&node); bool parseUnqualifiedName(UnqualifiedNameAST *&node, - bool parseTemplateId = true); + bool parseTemplateId = true); bool parseUsing(DeclarationAST *&node); bool parseUsingTypedef(DeclarationAST*& node); bool parseUsingDirective(DeclarationAST *&node); diff --git a/generator/parser/rxx_allocator.h b/generator/parser/rxx_allocator.h index 2081bfe51..88d8f7858 100644 --- a/generator/parser/rxx_allocator.h +++ b/generator/parser/rxx_allocator.h @@ -82,20 +82,20 @@ template class rxx_allocator { const size_type bytes = __n * sizeof(_Tp); if (_M_current_block == 0 - || _S_block_size < _M_current_index + bytes) + || _S_block_size < _M_current_index + bytes) { - ++_M_block_index; + ++_M_block_index; - _M_storage = reinterpret_cast - (::realloc(_M_storage, sizeof(char*) * (1 + _M_block_index))); + _M_storage = reinterpret_cast + (::realloc(_M_storage, sizeof(char*) * (1 + _M_block_index))); - _M_current_block = _M_storage[_M_block_index] = reinterpret_cast - (new char[_S_block_size]); + _M_current_block = _M_storage[_M_block_index] = reinterpret_cast + (new char[_S_block_size]); #if defined(RXX_ALLOCATOR_INIT_0) // ### make it a policy - ::memset(_M_current_block, 0, _S_block_size); + ::memset(_M_current_block, 0, _S_block_size); #endif - _M_current_index = 0; + _M_current_index = 0; } pointer p = reinterpret_cast diff --git a/generator/parser/symbol.h b/generator/parser/symbol.h index f9fe13725..d711e0d3a 100644 --- a/generator/parser/symbol.h +++ b/generator/parser/symbol.h @@ -117,8 +117,8 @@ class NameTable NameSymbol *name = _M_storage.value(key); if (!name) { - name = new NameSymbol(str, len); - _M_storage.insert(key, name); + name = new NameSymbol(str, len); + _M_storage.insert(key, name); } return name; diff --git a/generator/parser/tokens.cpp b/generator/parser/tokens.cpp index bbbcf1cfb..6f9c0cb96 100644 --- a/generator/parser/tokens.cpp +++ b/generator/parser/tokens.cpp @@ -69,8 +69,10 @@ static char const * const _S_token_names[] = { "compl", "concat", "const", + "constexpr", "const_cast", "continue", + "decltype", "decr", "default", "delete", diff --git a/generator/parser/tokens.h b/generator/parser/tokens.h index e850ad285..034d915be 100644 --- a/generator/parser/tokens.h +++ b/generator/parser/tokens.h @@ -71,8 +71,10 @@ enum TOKEN_KIND Token_compl, Token_concat, Token_const, + Token_constexpr, Token_const_cast, Token_continue, + Token_decltype, Token_decr, Token_default, Token_delete, diff --git a/generator/parser/type_compiler.cpp b/generator/parser/type_compiler.cpp index 4a73a7448..5c5063862 100644 --- a/generator/parser/type_compiler.cpp +++ b/generator/parser/type_compiler.cpp @@ -127,24 +127,14 @@ void TypeCompiler::visitName(NameAST *node) _M_type = name_cc.qualifiedName(); } -QStringList TypeCompiler::cvString() const +bool TypeCompiler::isConstant() const { - QStringList lst; - - foreach (int q, cv()) - { - if (q == Token_const) - lst.append(QLatin1String("const")); - else if (q == Token_volatile) - lst.append(QLatin1String("volatile")); - } - - return lst; + return _M_cv.contains(Token_const); } -bool TypeCompiler::isConstant() const +bool TypeCompiler::isConstexpr() const { - return _M_cv.contains(Token_const); + return _M_cv.contains(Token_constexpr); } bool TypeCompiler::isVolatile() const @@ -152,4 +142,9 @@ bool TypeCompiler::isVolatile() const return _M_cv.contains(Token_volatile); } +bool TypeCompiler::isMutable() const +{ + return _M_cv.contains(Token_mutable); +} + // kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/generator/parser/type_compiler.h b/generator/parser/type_compiler.h index 87e51ca99..6b706f503 100644 --- a/generator/parser/type_compiler.h +++ b/generator/parser/type_compiler.h @@ -61,9 +61,9 @@ class TypeCompiler: protected DefaultVisitor inline QList cv() const { return _M_cv; } bool isConstant() const; + bool isConstexpr() const; bool isVolatile() const; - - QStringList cvString() const; + bool isMutable() const; void run(TypeSpecifierAST *node); diff --git a/generator/typesystem.h b/generator/typesystem.h index fe12fd73b..bee5b0fc4 100644 --- a/generator/typesystem.h +++ b/generator/typesystem.h @@ -784,7 +784,7 @@ class ComplexTypeEntry : public TypeEntry public: enum TypeFlag { ForceAbstract = 0x1, - DeleteInMainThread = 0x2, + DeleteInMainThread = 0x2, Deprecated = 0x4 }; typedef QFlags TypeFlags; From b7d72e0c9805167987c4fbe060dcb658790c8739 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Thu, 12 Oct 2023 02:46:15 -0700 Subject: [PATCH 15/21] Handle constexpr, auto (#126) These changes use the new and existing support inside the parser to handle constexpr in Qt6 files and to ignore (with a warning) 'auto' functions. --- generator/abstractmetabuilder.cpp | 17 +++++++++++++++++ generator/abstractmetalang.cpp | 6 ++++++ generator/abstractmetalang.h | 9 +++++++++ 3 files changed, 32 insertions(+) diff --git a/generator/abstractmetabuilder.cpp b/generator/abstractmetabuilder.cpp index 5806b2c5f..ff520c732 100644 --- a/generator/abstractmetabuilder.cpp +++ b/generator/abstractmetabuilder.cpp @@ -1489,6 +1489,19 @@ AbstractMetaFunction *AbstractMetaBuilder::traverseFunction(FunctionModelItem fu return 0; } + if (function_item->isAuto()) { + /*TODO: it might work just to output 'auto', but this would require + * understanding what AbstractMetabuild::translateType() does and + * changing it. auto is only used once anyway. + */ + ReportHandler::warning(QString("%1: skipping auto function type '%2'") + .arg(function_name) + .arg(function_item->type().toString())); + m_rejected_functions[class_name + "::" + function_name + " " + function_item->type().toString()] = + UnmatchedReturnType; + return 0; + } + QString cast_type; if (function_name.startsWith("operator")) { @@ -1504,6 +1517,8 @@ AbstractMetaFunction *AbstractMetaBuilder::traverseFunction(FunctionModelItem fu AbstractMetaFunction *meta_function = createMetaFunction(); meta_function->setConstant(function_item->isConstant()); + meta_function->setConstexpr(function_item->isConstexpr()); + meta_function->setAuto(function_item->isAuto()); meta_function->setException(function_item->exception()); ReportHandler::debugMedium(QString(" - %2()").arg(function_name)); @@ -1707,10 +1722,12 @@ AbstractMetaType *AbstractMetaBuilder::translateType(const TypeInfo &_typei, boo //newInfo.setArguments(typei.arguments()); newInfo.setIndirections(typei.indirections()); newInfo.setConstant(typei.isConstant()); + newInfo.setConstexpr(typei.isConstexpr()); newInfo.setFunctionPointer(typei.isFunctionPointer()); newInfo.setQualifiedName(typei.qualifiedName()); newInfo.setReference(typei.isReference()); newInfo.setVolatile(typei.isVolatile()); + newInfo.setMutable(typei.isMutable()); AbstractMetaType *elementType = translateType(newInfo, ok); if (!(*ok)) diff --git a/generator/abstractmetalang.cpp b/generator/abstractmetalang.cpp index 32dbf85ea..d7128b7dd 100644 --- a/generator/abstractmetalang.cpp +++ b/generator/abstractmetalang.cpp @@ -315,6 +315,8 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const if (type()) cpy->setType(type()->copy()); cpy->setConstant(isConstant()); + cpy->setConstexpr(isConstexpr()); + cpy->setAuto(isAuto()); cpy->setException(exception()); cpy->setOriginalAttributes(originalAttributes()); @@ -366,6 +368,8 @@ QString AbstractMetaFunction::signature() const if (isConstant()) s += " const"; + if (isConstexpr()) + s += " constexpr"; return s; } @@ -657,6 +661,8 @@ QString AbstractMetaFunction::minimalSignature() const minimalSignature += ")"; if (isConstant()) minimalSignature += "const"; + if (isConstexpr()) + minimalSignature += "constexpr"; minimalSignature = TypeSystem::normalizedSignature(minimalSignature.toLocal8Bit().constData()); m_cached_minimal_signature = minimalSignature; diff --git a/generator/abstractmetalang.h b/generator/abstractmetalang.h index d1207bfc5..23c37e600 100644 --- a/generator/abstractmetalang.h +++ b/generator/abstractmetalang.h @@ -410,6 +410,7 @@ class AbstractMetaFunction : public AbstractMetaAttributes AbstractMetaFunction() : m_constant(false), + m_constexpr(false), m_invalid(false) { } @@ -487,6 +488,12 @@ class AbstractMetaFunction : public AbstractMetaAttributes bool isConstant() const { return m_constant; } void setConstant(bool constant) { m_constant = constant; } + bool isConstexpr() const { return m_constexpr; } + void setConstexpr(bool constant) { m_constexpr = constant; } + + bool isAuto() const { return m_auto; } + void setAuto(bool isAuto) { m_auto = isAuto; } + QString exception() const { return m_exception; } void setException(const QString &exception) { m_exception = exception; } QString toString() const { return m_name; } @@ -550,6 +557,8 @@ class AbstractMetaFunction : public AbstractMetaAttributes AbstractMetaArgumentList m_arguments; QString m_exception; uint m_constant : 1; + uint m_constexpr : 1; + uint m_auto : 1; uint m_invalid : 1; }; From 9b45889388cd8170264f3002d856410d1587cc10 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Fri, 13 Oct 2023 10:32:34 -0700 Subject: [PATCH 16/21] Qt6: fixes for removal of Qt5 types (#127) Also add the alternate types that are available in Qt5 to replace the types deprecated in Qt5.14 (allows Qt5.15LTS users to make changes for compatibility with Qt6.) --- generator/setupgenerator.cpp | 7 +++++++ generator/shellgenerator.cpp | 7 +++++++ src/PythonQtMethodInfo.cpp | 6 ++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/generator/setupgenerator.cpp b/generator/setupgenerator.cpp index 4694bab3a..6ac50580a 100644 --- a/generator/setupgenerator.cpp +++ b/generator/setupgenerator.cpp @@ -158,7 +158,10 @@ static QSet _builtinListTypes = QSet() << "QByteArray" << "QLineF" << "QPoint" << "QPointF" +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) << "QRegExp" +#endif +<< "QRegularExpression" << "QFont" << "QPixmap" << "QBrush" @@ -175,7 +178,11 @@ static QSet _builtinListTypes = QSet() << "QByteArray" << "QPen" << "QTextLength" << "QTextFormat" +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) << "QMatrix" +#endif +<< "QTransform" +<< "QMatrix4x4" << "QVariant"; static void addListRegistration(AbstractMetaType* type, QSet& output) { diff --git a/generator/shellgenerator.cpp b/generator/shellgenerator.cpp index 959ba344a..d9de72a4b 100644 --- a/generator/shellgenerator.cpp +++ b/generator/shellgenerator.cpp @@ -435,7 +435,11 @@ bool ShellGenerator::isBuiltIn(const QString& name) { builtIn.insert("QKeySequence"); builtIn.insert("QTextLength"); builtIn.insert("QTextFormat"); +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) builtIn.insert("QMatrix"); +#endif + builtIn.insert("QTransform"); + builtIn.insert("QMatrix4x4"); builtIn.insert("QDate"); builtIn.insert("QTime"); builtIn.insert("QDateTime"); @@ -449,7 +453,10 @@ bool ShellGenerator::isBuiltIn(const QString& name) { builtIn.insert("QLineF"); builtIn.insert("QPoint"); builtIn.insert("QPointF"); +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) builtIn.insert("QRegExp"); +#endif + builtIn.insert("QRegularExpression"); } return builtIn.contains(name); } diff --git a/src/PythonQtMethodInfo.cpp b/src/PythonQtMethodInfo.cpp index e5b5a41d6..4344be909 100644 --- a/src/PythonQtMethodInfo.cpp +++ b/src/PythonQtMethodInfo.cpp @@ -372,7 +372,7 @@ int PythonQtMethodInfo::nameToType(const char* name) _parameterTypeDict.insert("QLineF", QMetaType::QLineF); _parameterTypeDict.insert("QPoint", QMetaType::QPoint); _parameterTypeDict.insert("QPointF", QMetaType::QPointF); -#if QT_VERSION < 0x060000 +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) _parameterTypeDict.insert("QRegExp", QMetaType::QRegExp); #endif _parameterTypeDict.insert("QRegularExpression", QMetaType::QRegularExpression); @@ -390,9 +390,11 @@ int PythonQtMethodInfo::nameToType(const char* name) _parameterTypeDict.insert("QKeySequence", QMetaType::QKeySequence); _parameterTypeDict.insert("QPen", QMetaType::QPen); _parameterTypeDict.insert("QTextLength", QMetaType::QTextLength); -#if QT_VERSION < 0x060000 +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) _parameterTypeDict.insert("QMatrix", QMetaType::QMatrix); #endif + _parameterTypeDict.insert("QMatrix4x4", QMetaType::QMatrix4x4); + _parameterTypeDict.insert("QTransform", QMetaType::QTransform); _parameterTypeDict.insert("QTextFormat", QMetaType::QTextFormat); _parameterTypeDict.insert("QVariant", PythonQtMethodInfo::Variant); // own special types... (none so far, could be e.g. ObjectList From 2f657dbce799f28fbc25a127bb99f93022dad2aa Mon Sep 17 00:00:00 2001 From: John Bowler Date: Fri, 13 Oct 2023 23:31:08 -0700 Subject: [PATCH 17/21] Fix problems in Qt5.11 generator (#128) - a previous fix for Qt5.12 breaks pythonqt_generator for 5.11 - includes better checking for precompiled headers and errors out early rather than failing when linking the src/ with mysterious missing symbols. --- build/common.prf | 52 +++++++++++------------------- generator/qtscript_masterinclude.h | 31 ++++++++++++++---- 2 files changed, 44 insertions(+), 39 deletions(-) diff --git a/build/common.prf b/build/common.prf index e6b396d62..4d8f9e426 100644 --- a/build/common.prf +++ b/build/common.prf @@ -25,50 +25,36 @@ PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp_$${QT_MAJOR_VERSION}$${QT_MINOR_VERSION} !exists($$PYTHONQT_GENERATED_PATH) { - contains( QT_MAJOR_VERSION, 5 ) { - contains( QT_MINOR_VERSION, 10 ) { - PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp_56 - } - else:contains( QT_MINOR_VERSION, 11 ) { - PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp_511 - } - else:contains( QT_MINOR_VERSION, 12 ) { - PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp_511 - } - else:contains( QT_MINOR_VERSION, 1 ) { - PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp_50 - } - else:contains( QT_MINOR_VERSION, 2 ) { + # For Qt5 we know that the older generated wrappers work with the later + # versions, even (apparently) Qt5.15, so: + equals(QT_MAJOR_VERSION, 5) { + # Qt5: have 5.0, 5.3, 5.4, 5.6 and 5.11 at present: + lessThan(QT_MINOR_VERSION, 3) { # 5.1, 5.2 PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp_50 } - else:contains( QT_MINOR_VERSION, 3 ) { - PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp_53 - } - else:contains( QT_MINOR_VERSION, 4 ) { + else: lessThan(QT_MINOR_VERSION, 6) { # 5.5 PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp_54 - } - else:contains( QT_MINOR_VERSION, 5 ) { - PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp_54 - } - else:contains( QT_MINOR_VERSION, 6 ) { - PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp_56 } - else:contains( QT_MINOR_VERSION, 7 ) { + else: lessThan(QT_MINOR_VERSION, 11) { # 5.7, 5.8, 5.9, 5.10 PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp_56 } - else:contains( QT_MINOR_VERSION, 8 ) { - PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp_56 - } - else:contains( QT_MINOR_VERSION, 9 ) { - PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp_56 - } - else { - PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp_56 + else { # >5.11 + # LATEST Qt5 generated files: + PYTHONQT_GENERATED_PATH = $$PWD/../generated_cpp_511 } } + + !exists($$PYTHONQT_GENERATED_PATH) { + error("No generated sources exist for Qt$${QT_VERSION}") + } } } +!build_pass { + message("Qt version: Qt$${QT_VERSION}") + message("Using generated sources files from $${PYTHONQT_GENERATED_PATH}") +} + VERSION = 3.2.0 win32: CONFIG += skip_target_version_ext gcc|win32-clang-msvc:QMAKE_CXXFLAGS += -Wno-deprecated-declarations -Wuninitialized -Winit-self -pedantic diff --git a/generator/qtscript_masterinclude.h b/generator/qtscript_masterinclude.h index 8f96f0847..52d63c244 100644 --- a/generator/qtscript_masterinclude.h +++ b/generator/qtscript_masterinclude.h @@ -38,7 +38,6 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ - // We need to force the endianess in Qt5 #define Q_BYTE_ORDER Q_LITTLE_ENDIAN @@ -48,11 +47,31 @@ #define QOPENGLFUNCTIONS_H #define QOPENGLEXTRAFUNCTIONS_H -// our compiler can't handle the templates for singleShot (int Qt 5.12), but we can circumvent this with -// Q_CLANG_QDOC for the moment: -#define Q_CLANG_QDOC -#include -#undef Q_CLANG_QDOC +/* This must only be included after 'QT_NO_' definitions have been defined. */ +#include + +/* NOTE: Qt5.12 and later (including Qt6) uses template functions for the + * static implementations of QTimer::singleShot() (the function, not the + * property). The generator does not handle template functions. Defining + * Q_CLANG_QDOC works around this by exposing the non-template forms that + * appear in the documentation at the same time as hiding the templates. + * Without this the QTimer::singleShot functions do not appear in the PythonQt + * interface. + * + * Unfortunately the work around breaks precompilation in Qt5.11 because it + * causes duplicate definitions of some text handling functions (they really + * are duplicated if Q_CLANG_QDOC is turned on) so the change must be version + * specific. + * + * This does not work in Qt6 because Qt6 uses Q_QDOC for the documentation and + * needs other fixes. + */ +#if QT_VERSION_MAJOR == 5 && QT_VERSION_MINOR > 11 +# include // included by QtCore/QTimer +# define Q_CLANG_QDOC +# include +# undef Q_CLANG_QDOC +#endif #include #include From 9404b9a4d28a8f141a2082029d5bdd9b0e6f23be Mon Sep 17 00:00:00 2001 From: John Bowler Date: Fri, 13 Oct 2023 23:55:55 -0700 Subject: [PATCH 18/21] Use spaces instead of tabs (#129) Expand all the tabs in non-binary source files --- COPYING | 12 +- generator/LICENSE.LGPL | 14 +- generator/abstractmetalang.cpp | 2 +- generator/generator.pri | 2 +- generator/parser/control.cpp | 2 +- generator/parser/lexer.cpp | 1486 +++++++++++++++--------------- generator/parser/parser.cpp | 16 +- generator/parser/rpp/pp-main.cpp | 16 +- generator/parser/rpp/rpp.pri | 30 +- src/PythonQtClassWrapper.cpp | 4 +- 10 files changed, 792 insertions(+), 792 deletions(-) diff --git a/COPYING b/COPYING index 5ab7695ab..c00103def 100644 --- a/COPYING +++ b/COPYING @@ -1,5 +1,5 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @@ -10,7 +10,7 @@ as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] - Preamble + Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -112,7 +112,7 @@ modification follow. Pay close attention to the difference between a former contains code derived from the library, whereas the latter must be combined with the library in order to run. - GNU LESSER GENERAL PUBLIC LICENSE + GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other @@ -432,7 +432,7 @@ decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY + NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. @@ -455,7 +455,7 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - END OF TERMS AND CONDITIONS + END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries diff --git a/generator/LICENSE.LGPL b/generator/LICENSE.LGPL index 9a30e8ce8..22bc77aac 100644 --- a/generator/LICENSE.LGPL +++ b/generator/LICENSE.LGPL @@ -1,4 +1,4 @@ - GNU LESSER GENERAL PUBLIC LICENSE + GNU LESSER GENERAL PUBLIC LICENSE The Qt GUI Toolkit is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). Contact: Nokia Corporation (qt-info@nokia.com) @@ -8,8 +8,8 @@ ------------------------------------------------------------------------- - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @@ -20,7 +20,7 @@ as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] - Preamble + Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -122,7 +122,7 @@ modification follow. Pay close attention to the difference between a former contains code derived from the library, whereas the latter must be combined with the library in order to run. - GNU LESSER GENERAL PUBLIC LICENSE + GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other @@ -442,7 +442,7 @@ decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY + NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. @@ -465,7 +465,7 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - END OF TERMS AND CONDITIONS + END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries diff --git a/generator/abstractmetalang.cpp b/generator/abstractmetalang.cpp index d7128b7dd..4e2aa8cab 100644 --- a/generator/abstractmetalang.cpp +++ b/generator/abstractmetalang.cpp @@ -1203,7 +1203,7 @@ bool AbstractMetaClass::hasVirtualDestructor() const static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func) { foreach (const AbstractMetaFunction *f, l) { - if ((f->compareTo(func) & AbstractMetaFunction::PrettySimilar) == AbstractMetaFunction::PrettySimilar) + if ((f->compareTo(func) & AbstractMetaFunction::PrettySimilar) == AbstractMetaFunction::PrettySimilar) return true; } return false; diff --git a/generator/generator.pri b/generator/generator.pri index c941f879b..490e265c8 100644 --- a/generator/generator.pri +++ b/generator/generator.pri @@ -23,7 +23,7 @@ win32-msvc*{ QMAKE_CXXFLAGS += -wd4996 QMAKE_CFLAGS += -wd4996 #Disable warnings for external headers - greaterThan(QMAKE_MSC_VER, 1599):QMAKE_CXXFLAGS += -external:anglebrackets -external:W0 -external:templates- + greaterThan(QMAKE_MSC_VER, 1599):QMAKE_CXXFLAGS += -external:anglebrackets -external:W0 -external:templates- } #Do not issue warning to Qt's system includes gcc:!isEmpty(QT_INSTALL_HEADERS): QMAKE_CXXFLAGS += -isystem $$[QT_INSTALL_HEADERS] diff --git a/generator/parser/control.cpp b/generator/parser/control.cpp index a8e6a35e8..ee8963947 100644 --- a/generator/parser/control.cpp +++ b/generator/parser/control.cpp @@ -52,7 +52,7 @@ Control::Control() pushContext(); declareTypedef(findOrInsertName("__builtin_va_list", - strlen("__builtin_va_list")), 0); + strlen("__builtin_va_list")), 0); } Control::~Control() diff --git a/generator/parser/lexer.cpp b/generator/parser/lexer.cpp index 6ccf7680f..2d40a706f 100644 --- a/generator/parser/lexer.cpp +++ b/generator/parser/lexer.cpp @@ -184,13 +184,13 @@ void Lexer::initialize_scan_table() for (int i=0; i<256; ++i) { if (isspace(i)) - s_scan_table[i] = &Lexer::scan_white_spaces; + s_scan_table[i] = &Lexer::scan_white_spaces; else if (isalpha(i) || i == '_') - s_scan_table[i] = &Lexer::scan_identifier_or_keyword; + s_scan_table[i] = &Lexer::scan_identifier_or_keyword; else if (isdigit(i)) - s_scan_table[i] = &Lexer::scan_int_constant; + s_scan_table[i] = &Lexer::scan_int_constant; else - s_scan_table[i] = &Lexer::scan_invalid_input; + s_scan_table[i] = &Lexer::scan_invalid_input; } s_scan_table[int('L')] = &Lexer::scan_identifier_or_literal; @@ -254,7 +254,7 @@ void Lexer::scan_char_constant() reportError("did not expect newline"); if (*cursor == '\\') - ++cursor; + ++cursor; ++cursor; } @@ -280,7 +280,7 @@ void Lexer::scan_string_constant() reportError("did not expect newline"); if (*cursor == '\\') - ++cursor; + ++cursor; ++cursor; } @@ -309,9 +309,9 @@ void Lexer::scan_white_spaces() while (isspace(*cursor)) { if (*cursor == '\n') - scan_newline(); + scan_newline(); else - ++cursor; + ++cursor; } } @@ -348,7 +348,7 @@ void Lexer::scan_identifier_or_keyword() if (current_token->kind == Token_identifier) { current_token->extra.symbol = - control->findOrInsertName((const char*) cursor, n); + control->findOrInsertName((const char*) cursor, n); } cursor = skip; @@ -376,8 +376,8 @@ void Lexer::scan_int_constant() void Lexer::scan_not() { /* - '!' ::= not - '!=' ::= not_equal + '!' ::= not + '!=' ::= not_equal */ ++cursor; @@ -396,8 +396,8 @@ void Lexer::scan_not() void Lexer::scan_remainder() { /* - '%' ::= remainder - '%=' ::= remainder_equal + '%' ::= remainder + '%=' ::= remainder_equal */ ++cursor; @@ -416,9 +416,9 @@ void Lexer::scan_remainder() void Lexer::scan_and() { /* - '&&' ::= and_and - '&' ::= and - '&=' ::= and_equal + '&&' ::= and_and + '&' ::= and + '&=' ::= and_equal */ ++cursor; @@ -453,8 +453,8 @@ void Lexer::scan_right_paren() void Lexer::scan_star() { /* - '*' ::= star - '*=' ::= star_equal + '*' ::= star + '*=' ::= star_equal */ ++cursor; @@ -473,9 +473,9 @@ void Lexer::scan_star() void Lexer::scan_plus() { /* - '+' ::= plus - '++' ::= incr - '+=' ::= plus_equal + '+' ::= plus + '++' ::= incr + '+=' ::= plus_equal */ ++cursor; @@ -504,10 +504,10 @@ void Lexer::scan_comma() void Lexer::scan_minus() { /* - '-' ::= minus - '--' ::= decr - '-=' ::= minus_equal - '->' ::= left_arrow + '-' ::= minus + '--' ::= decr + '-=' ::= minus_equal + '->' ::= left_arrow */ ++cursor; @@ -526,10 +526,10 @@ void Lexer::scan_minus() ++cursor; token_stream[(int) index++].kind = Token_arrow; if (*cursor == '*') - { - ++cursor; - token_stream[(int) index++].kind = Token_ptrmem; - } + { + ++cursor; + token_stream[(int) index++].kind = Token_ptrmem; + } } else { @@ -540,8 +540,8 @@ void Lexer::scan_minus() void Lexer::scan_dot() { /* - '.' ::= dot - '...' ::= ellipsis + '.' ::= dot + '...' ::= ellipsis */ ++cursor; @@ -562,8 +562,8 @@ void Lexer::scan_dot() void Lexer::scan_divide() { /* - '/' ::= divide - '/=' ::= divide_equal + '/' ::= divide + '/=' ::= divide_equal */ ++cursor; @@ -602,10 +602,10 @@ void Lexer::scan_semicolon() void Lexer::scan_less() { /* - '<' ::= less - '<<' ::= left_shift - '<<=' ::= left_shift_equal - '<=' ::= less_equal + '<' ::= less + '<<' ::= left_shift + '<<=' ::= left_shift_equal + '<=' ::= less_equal */ ++cursor; @@ -618,14 +618,14 @@ void Lexer::scan_less() { ++cursor; if (*cursor == '=') - { - ++cursor; - token_stream[(int) index++].kind = Token_assign; - } + { + ++cursor; + token_stream[(int) index++].kind = Token_assign; + } else - { - token_stream[(int) index++].kind = Token_shift; - } + { + token_stream[(int) index++].kind = Token_shift; + } } else { @@ -636,8 +636,8 @@ void Lexer::scan_less() void Lexer::scan_equal() { /* - '=' ::= equal - '==' ::= equal_equal + '=' ::= equal + '==' ::= equal_equal */ ++cursor; @@ -655,10 +655,10 @@ void Lexer::scan_equal() void Lexer::scan_greater() { /* - '>' ::= greater - '>=' ::= greater_equal - '>>' ::= right_shift - '>>=' ::= right_shift_equal + '>' ::= greater + '>=' ::= greater_equal + '>>' ::= right_shift + '>>=' ::= right_shift_equal */ ++cursor; @@ -671,14 +671,14 @@ void Lexer::scan_greater() { ++cursor; if (*cursor == '=') - { - ++cursor; - token_stream[(int) index++].kind = Token_assign; - } + { + ++cursor; + token_stream[(int) index++].kind = Token_assign; + } else - { - token_stream[(int) index++].kind = Token_shift; - } + { + token_stream[(int) index++].kind = Token_shift; + } } else { @@ -707,8 +707,8 @@ void Lexer::scan_right_bracket() void Lexer::scan_xor() { /* - '^' ::= xor - '^=' ::= xor_equal + '^' ::= xor + '^=' ::= xor_equal */ ++cursor; @@ -732,9 +732,9 @@ void Lexer::scan_left_brace() void Lexer::scan_or() { /* - '|' ::= or - '|=' ::= or_equal - '||' ::= or_or + '|' ::= or + '|=' ::= or_equal + '||' ::= or_or */ ++cursor; if (*cursor == '=') @@ -779,7 +779,7 @@ void Lexer::scan_invalid_input() } void LocationTable::positionAt(std::size_t offset, int max_line, - int *line, int *column) const + int *line, int *column) const { if (!(line && column && max_line != 0)) return; @@ -797,13 +797,13 @@ void LocationTable::positionAt(std::size_t offset, int max_line, middle += half; if (lines[middle] < offset) - { - first = middle; - ++first; - len = len - half - 1; - } + { + first = middle; + ++first; + len = len - half - 1; + } else - len = half; + len = half; } *line = std::max(first, 1); @@ -826,26 +826,26 @@ void Lexer::scanKeyword2() { case 'i': if (*(cursor + 1) == 'f') - { - token_stream[(int) index++].kind = Token_if; - return; - } + { + token_stream[(int) index++].kind = Token_if; + return; + } break; case 'd': if (*(cursor + 1) == 'o') - { - token_stream[(int) index++].kind = Token_do; - return; - } + { + token_stream[(int) index++].kind = Token_do; + return; + } break; case 'o': if (*(cursor + 1) == 'r') - { - token_stream[(int) index++].kind = Token_or; - return; - } + { + token_stream[(int) index++].kind = Token_or; + return; + } break; } @@ -858,68 +858,68 @@ void Lexer::scanKeyword3() { case 'a': if (*(cursor + 1) == 'n' && - *(cursor + 2) == 'd') - { - token_stream[(int) index++].kind = Token_and; - return; - } + *(cursor + 2) == 'd') + { + token_stream[(int) index++].kind = Token_and; + return; + } if (*(cursor + 1) == 's' && - *(cursor + 2) == 'm') - { - token_stream[(int) index++].kind = Token_asm; - return; - } + *(cursor + 2) == 'm') + { + token_stream[(int) index++].kind = Token_asm; + return; + } break; case 'f': if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'r') - { - token_stream[(int) index++].kind = Token_for; - return; - } + *(cursor + 2) == 'r') + { + token_stream[(int) index++].kind = Token_for; + return; + } break; case 'i': if (*(cursor + 1) == 'n' && - *(cursor + 2) == 't') - { - token_stream[(int) index++].kind = Token_int; - return; - } + *(cursor + 2) == 't') + { + token_stream[(int) index++].kind = Token_int; + return; + } break; case 'n': if (*(cursor + 1) == 'e' && - *(cursor + 2) == 'w') - { - token_stream[(int) index++].kind = Token_new; - return; - } + *(cursor + 2) == 'w') + { + token_stream[(int) index++].kind = Token_new; + return; + } if (*(cursor + 1) == 'o' && - *(cursor + 2) == 't') - { - token_stream[(int) index++].kind = Token_not; - return; - } + *(cursor + 2) == 't') + { + token_stream[(int) index++].kind = Token_not; + return; + } break; case 't': if (*(cursor + 1) == 'r' && - *(cursor + 2) == 'y') - { - token_stream[(int) index++].kind = Token_try; - return; - } + *(cursor + 2) == 'y') + { + token_stream[(int) index++].kind = Token_try; + return; + } break; case 'x': if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'r') - { - token_stream[(int) index++].kind = Token_xor; - return; - } + *(cursor + 2) == 'r') + { + token_stream[(int) index++].kind = Token_xor; + return; + } break; } @@ -932,103 +932,103 @@ void Lexer::scanKeyword4() { case 'a': if (*(cursor + 1) == 'u' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'o') - { - token_stream[(int) index++].kind = Token_auto; - return; - } + *(cursor + 2) == 't' && + *(cursor + 3) == 'o') + { + token_stream[(int) index++].kind = Token_auto; + return; + } break; case 'c': if (*(cursor + 1) == 'a' && - *(cursor + 2) == 's' && - *(cursor + 3) == 'e') - { - token_stream[(int) index++].kind = Token_case; - return; - } + *(cursor + 2) == 's' && + *(cursor + 3) == 'e') + { + token_stream[(int) index++].kind = Token_case; + return; + } if (*(cursor + 1) == 'h' && - *(cursor + 2) == 'a' && - *(cursor + 3) == 'r') - { - token_stream[(int) index++].kind = Token_char; - return; - } + *(cursor + 2) == 'a' && + *(cursor + 3) == 'r') + { + token_stream[(int) index++].kind = Token_char; + return; + } break; case 'b': if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'o' && - *(cursor + 3) == 'l') - { - token_stream[(int) index++].kind = Token_bool; - return; - } + *(cursor + 2) == 'o' && + *(cursor + 3) == 'l') + { + token_stream[(int) index++].kind = Token_bool; + return; + } break; case 'e': if (*(cursor + 1) == 'l' && - *(cursor + 2) == 's' && - *(cursor + 3) == 'e') - { - token_stream[(int) index++].kind = Token_else; - return; - } + *(cursor + 2) == 's' && + *(cursor + 3) == 'e') + { + token_stream[(int) index++].kind = Token_else; + return; + } if (*(cursor + 1) == 'm' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 't') - { - token_stream[(int) index++].kind = Token_emit; - return; - } + *(cursor + 2) == 'i' && + *(cursor + 3) == 't') + { + token_stream[(int) index++].kind = Token_emit; + return; + } if (*(cursor + 1) == 'n' && - *(cursor + 2) == 'u' && - *(cursor + 3) == 'm') - { - token_stream[(int) index++].kind = Token_enum; - return; - } + *(cursor + 2) == 'u' && + *(cursor + 3) == 'm') + { + token_stream[(int) index++].kind = Token_enum; + return; + } break; case 'g': if (*(cursor + 1) == 'o' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'o') - { - token_stream[(int) index++].kind = Token_goto; - return; - } + *(cursor + 2) == 't' && + *(cursor + 3) == 'o') + { + token_stream[(int) index++].kind = Token_goto; + return; + } break; case 'l': if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'n' && - *(cursor + 3) == 'g') - { - token_stream[(int) index++].kind = Token_long; - return; - } + *(cursor + 2) == 'n' && + *(cursor + 3) == 'g') + { + token_stream[(int) index++].kind = Token_long; + return; + } break; case 't': if (*(cursor + 1) == 'h' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 's') - { - token_stream[(int) index++].kind = Token_this; - return; - } + *(cursor + 2) == 'i' && + *(cursor + 3) == 's') + { + token_stream[(int) index++].kind = Token_this; + return; + } break; case 'v': if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 'd') - { - token_stream[(int) index++].kind = Token_void; - return; - } + *(cursor + 2) == 'i' && + *(cursor + 3) == 'd') + { + token_stream[(int) index++].kind = Token_void; + return; + } break; } @@ -1041,138 +1041,138 @@ void Lexer::scanKeyword5() { case 'c': if (*(cursor + 1) == 'a' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'c' && - *(cursor + 4) == 'h') - { - token_stream[(int) index++].kind = Token_catch; - return; - } + *(cursor + 2) == 't' && + *(cursor + 3) == 'c' && + *(cursor + 4) == 'h') + { + token_stream[(int) index++].kind = Token_catch; + return; + } if (*(cursor + 1) == 'l' && - *(cursor + 2) == 'a' && - *(cursor + 3) == 's' && - *(cursor + 4) == 's') - { - token_stream[(int) index++].kind = Token_class; - return; - } + *(cursor + 2) == 'a' && + *(cursor + 3) == 's' && + *(cursor + 4) == 's') + { + token_stream[(int) index++].kind = Token_class; + return; + } if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'm' && - *(cursor + 3) == 'p' && - *(cursor + 4) == 'l') - { - token_stream[(int) index++].kind = Token_compl; - return; - } + *(cursor + 2) == 'm' && + *(cursor + 3) == 'p' && + *(cursor + 4) == 'l') + { + token_stream[(int) index++].kind = Token_compl; + return; + } if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'n' && - *(cursor + 3) == 's' && - *(cursor + 4) == 't') - { - token_stream[(int) index++].kind = Token_const; - return; - } + *(cursor + 2) == 'n' && + *(cursor + 3) == 's' && + *(cursor + 4) == 't') + { + token_stream[(int) index++].kind = Token_const; + return; + } break; case 'b': if (*(cursor + 1) == 'i' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'o' && - *(cursor + 4) == 'r') - { - token_stream[(int) index++].kind = Token_bitor; - return; - } + *(cursor + 2) == 't' && + *(cursor + 3) == 'o' && + *(cursor + 4) == 'r') + { + token_stream[(int) index++].kind = Token_bitor; + return; + } if (*(cursor + 1) == 'r' && - *(cursor + 2) == 'e' && - *(cursor + 3) == 'a' && - *(cursor + 4) == 'k') - { - token_stream[(int) index++].kind = Token_break; - return; - } + *(cursor + 2) == 'e' && + *(cursor + 3) == 'a' && + *(cursor + 4) == 'k') + { + token_stream[(int) index++].kind = Token_break; + return; + } break; case 'f': if (*(cursor + 1) == 'l' && - *(cursor + 2) == 'o' && - *(cursor + 3) == 'a' && - *(cursor + 4) == 't') - { - token_stream[(int) index++].kind = Token_float; - return; - } + *(cursor + 2) == 'o' && + *(cursor + 3) == 'a' && + *(cursor + 4) == 't') + { + token_stream[(int) index++].kind = Token_float; + return; + } break; case 'o': if (*(cursor + 1) == 'r' && - *(cursor + 2) == '_' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 'q') - { - token_stream[(int) index++].kind = Token_or_eq; - return; - } + *(cursor + 2) == '_' && + *(cursor + 3) == 'e' && + *(cursor + 4) == 'q') + { + token_stream[(int) index++].kind = Token_or_eq; + return; + } break; case 's': if (*(cursor + 1) == 'h' && - *(cursor + 2) == 'o' && - *(cursor + 3) == 'r' && - *(cursor + 4) == 't') - { - token_stream[(int) index++].kind = Token_short; - return; - } + *(cursor + 2) == 'o' && + *(cursor + 3) == 'r' && + *(cursor + 4) == 't') + { + token_stream[(int) index++].kind = Token_short; + return; + } if (*(cursor + 1) == 'l' && - *(cursor + 2) == 'o' && - *(cursor + 3) == 't' && - *(cursor + 4) == 's') - { - token_stream[(int) index++].kind = Token_slots; - return; - } + *(cursor + 2) == 'o' && + *(cursor + 3) == 't' && + *(cursor + 4) == 's') + { + token_stream[(int) index++].kind = Token_slots; + return; + } break; case 'u': if (*(cursor + 1) == 'n' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 'o' && - *(cursor + 4) == 'n') - { - token_stream[(int) index++].kind = Token_union; - return; - } + *(cursor + 2) == 'i' && + *(cursor + 3) == 'o' && + *(cursor + 4) == 'n') + { + token_stream[(int) index++].kind = Token_union; + return; + } if (*(cursor + 1) == 's' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 'n' && - *(cursor + 4) == 'g') - { - token_stream[(int) index++].kind = Token_using; - return; - } + *(cursor + 2) == 'i' && + *(cursor + 3) == 'n' && + *(cursor + 4) == 'g') + { + token_stream[(int) index++].kind = Token_using; + return; + } break; case 't': if (*(cursor + 1) == 'h' && - *(cursor + 2) == 'r' && - *(cursor + 3) == 'o' && - *(cursor + 4) == 'w') - { - token_stream[(int) index++].kind = Token_throw; - return; - } + *(cursor + 2) == 'r' && + *(cursor + 3) == 'o' && + *(cursor + 4) == 'w') + { + token_stream[(int) index++].kind = Token_throw; + return; + } break; case 'w': if (*(cursor + 1) == 'h' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 'l' && - *(cursor + 4) == 'e') - { - token_stream[(int) index++].kind = Token_while; - return; - } + *(cursor + 2) == 'i' && + *(cursor + 3) == 'l' && + *(cursor + 4) == 'e') + { + token_stream[(int) index++].kind = Token_while; + return; + } break; } @@ -1185,224 +1185,224 @@ void Lexer::scanKeyword6() { case 'a': if (*(cursor + 1) == 'n' && - *(cursor + 2) == 'd' && - *(cursor + 3) == '_' && - *(cursor + 4) == 'e' && - *(cursor + 5) == 'q') - { - token_stream[(int) index++].kind = Token_and_eq; - return; - } + *(cursor + 2) == 'd' && + *(cursor + 3) == '_' && + *(cursor + 4) == 'e' && + *(cursor + 5) == 'q') + { + token_stream[(int) index++].kind = Token_and_eq; + return; + } break; case 'b': if (*(cursor + 1) == 'i' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'a' && - *(cursor + 4) == 'n' && - *(cursor + 5) == 'd') - { - token_stream[(int) index++].kind = Token_bitand; - return; - } + *(cursor + 2) == 't' && + *(cursor + 3) == 'a' && + *(cursor + 4) == 'n' && + *(cursor + 5) == 'd') + { + token_stream[(int) index++].kind = Token_bitand; + return; + } break; case 'e': if (*(cursor + 1) == 'x' && - *(cursor + 2) == 'p' && - *(cursor + 3) == 'o' && - *(cursor + 4) == 'r' && - *(cursor + 5) == 't') - { - token_stream[(int) index++].kind = Token_export; - return; - } + *(cursor + 2) == 'p' && + *(cursor + 3) == 'o' && + *(cursor + 4) == 'r' && + *(cursor + 5) == 't') + { + token_stream[(int) index++].kind = Token_export; + return; + } if (*(cursor + 1) == 'x' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 'r' && - *(cursor + 5) == 'n') - { - token_stream[(int) index++].kind = Token_extern; - return; - } + *(cursor + 2) == 't' && + *(cursor + 3) == 'e' && + *(cursor + 4) == 'r' && + *(cursor + 5) == 'n') + { + token_stream[(int) index++].kind = Token_extern; + return; + } break; case 'd': if (*(cursor + 1) == 'e' && - *(cursor + 2) == 'l' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 't' && - *(cursor + 5) == 'e') - { - token_stream[(int) index++].kind = Token_delete; - return; - } + *(cursor + 2) == 'l' && + *(cursor + 3) == 'e' && + *(cursor + 4) == 't' && + *(cursor + 5) == 'e') + { + token_stream[(int) index++].kind = Token_delete; + return; + } if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'u' && - *(cursor + 3) == 'b' && - *(cursor + 4) == 'l' && - *(cursor + 5) == 'e') - { - token_stream[(int) index++].kind = Token_double; - return; - } + *(cursor + 2) == 'u' && + *(cursor + 3) == 'b' && + *(cursor + 4) == 'l' && + *(cursor + 5) == 'e') + { + token_stream[(int) index++].kind = Token_double; + return; + } break; case 'f': if (*(cursor + 1) == 'r' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 'n' && - *(cursor + 5) == 'd') - { - token_stream[(int) index++].kind = Token_friend; - return; - } + *(cursor + 2) == 'i' && + *(cursor + 3) == 'e' && + *(cursor + 4) == 'n' && + *(cursor + 5) == 'd') + { + token_stream[(int) index++].kind = Token_friend; + return; + } break; case 'i': if (*(cursor + 1) == 'n' && - *(cursor + 2) == 'l' && - *(cursor + 3) == 'i' && - *(cursor + 4) == 'n' && - *(cursor + 5) == 'e') - { - token_stream[(int) index++].kind = Token_inline; - return; - } + *(cursor + 2) == 'l' && + *(cursor + 3) == 'i' && + *(cursor + 4) == 'n' && + *(cursor + 5) == 'e') + { + token_stream[(int) index++].kind = Token_inline; + return; + } break; case 'K': if (*(cursor + 1) == '_' && - *(cursor + 2) == 'D' && - *(cursor + 3) == 'C' && - *(cursor + 4) == 'O' && - *(cursor + 5) == 'P') - { - token_stream[(int) index++].kind = Token_K_DCOP; - return; - } + *(cursor + 2) == 'D' && + *(cursor + 3) == 'C' && + *(cursor + 4) == 'O' && + *(cursor + 5) == 'P') + { + token_stream[(int) index++].kind = Token_K_DCOP; + return; + } break; case 'n': if (*(cursor + 1) == 'o' && - *(cursor + 2) == 't' && - *(cursor + 3) == '_' && - *(cursor + 4) == 'e' && - *(cursor + 5) == 'q') - { - token_stream[(int) index++].kind = Token_not_eq; - return; - } + *(cursor + 2) == 't' && + *(cursor + 3) == '_' && + *(cursor + 4) == 'e' && + *(cursor + 5) == 'q') + { + token_stream[(int) index++].kind = Token_not_eq; + return; + } break; case 'p': if (*(cursor + 1) == 'u' && - *(cursor + 2) == 'b' && - *(cursor + 3) == 'l' && - *(cursor + 4) == 'i' && - *(cursor + 5) == 'c') - { - token_stream[(int) index++].kind = Token_public; - return; - } + *(cursor + 2) == 'b' && + *(cursor + 3) == 'l' && + *(cursor + 4) == 'i' && + *(cursor + 5) == 'c') + { + token_stream[(int) index++].kind = Token_public; + return; + } break; case 's': if (*(cursor + 1) == 'i' && - *(cursor + 2) == 'g' && - *(cursor + 3) == 'n' && - *(cursor + 4) == 'e' && - *(cursor + 5) == 'd') - { - token_stream[(int) index++].kind = Token_signed; - return; - } + *(cursor + 2) == 'g' && + *(cursor + 3) == 'n' && + *(cursor + 4) == 'e' && + *(cursor + 5) == 'd') + { + token_stream[(int) index++].kind = Token_signed; + return; + } if (*(cursor + 1) == 'i' && - *(cursor + 2) == 'z' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 'o' && - *(cursor + 5) == 'f') - { - token_stream[(int) index++].kind = Token_sizeof; - return; - } + *(cursor + 2) == 'z' && + *(cursor + 3) == 'e' && + *(cursor + 4) == 'o' && + *(cursor + 5) == 'f') + { + token_stream[(int) index++].kind = Token_sizeof; + return; + } if (*(cursor + 1) == 't' && - *(cursor + 2) == 'a' && - *(cursor + 3) == 't' && - *(cursor + 4) == 'i' && - *(cursor + 5) == 'c') - { - token_stream[(int) index++].kind = Token_static; - return; - } + *(cursor + 2) == 'a' && + *(cursor + 3) == 't' && + *(cursor + 4) == 'i' && + *(cursor + 5) == 'c') + { + token_stream[(int) index++].kind = Token_static; + return; + } if (*(cursor + 1) == 't' && - *(cursor + 2) == 'r' && - *(cursor + 3) == 'u' && - *(cursor + 4) == 'c' && - *(cursor + 5) == 't') - { - token_stream[(int) index++].kind = Token_struct; - return; - } + *(cursor + 2) == 'r' && + *(cursor + 3) == 'u' && + *(cursor + 4) == 'c' && + *(cursor + 5) == 't') + { + token_stream[(int) index++].kind = Token_struct; + return; + } if (*(cursor + 1) == 'w' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 't' && - *(cursor + 4) == 'c' && - *(cursor + 5) == 'h') - { - token_stream[(int) index++].kind = Token_switch; - return; - } + *(cursor + 2) == 'i' && + *(cursor + 3) == 't' && + *(cursor + 4) == 'c' && + *(cursor + 5) == 'h') + { + token_stream[(int) index++].kind = Token_switch; + return; + } break; case 'r': if (*(cursor + 1) == 'e' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'u' && - *(cursor + 4) == 'r' && - *(cursor + 5) == 'n') - { - token_stream[(int) index++].kind = Token_return; - return; - } + *(cursor + 2) == 't' && + *(cursor + 3) == 'u' && + *(cursor + 4) == 'r' && + *(cursor + 5) == 'n') + { + token_stream[(int) index++].kind = Token_return; + return; + } break; case 't': if (*(cursor + 1) == 'y' && - *(cursor + 2) == 'p' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 'i' && - *(cursor + 5) == 'd') - { - token_stream[(int) index++].kind = Token_typeid; - return; - } + *(cursor + 2) == 'p' && + *(cursor + 3) == 'e' && + *(cursor + 4) == 'i' && + *(cursor + 5) == 'd') + { + token_stream[(int) index++].kind = Token_typeid; + return; + } break; case 'x': if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'r' && - *(cursor + 3) == '_' && - *(cursor + 4) == 'e' && - *(cursor + 5) == 'q') - { - token_stream[(int) index++].kind = Token_xor_eq; - return; - } + *(cursor + 2) == 'r' && + *(cursor + 3) == '_' && + *(cursor + 4) == 'e' && + *(cursor + 5) == 'q') + { + token_stream[(int) index++].kind = Token_xor_eq; + return; + } break; case 'k': if (*(cursor + 1) == '_' && - *(cursor + 2) == 'd' && - *(cursor + 3) == 'c' && - *(cursor + 4) == 'o' && - *(cursor + 5) == 'p') - { - token_stream[(int) index++].kind = Token_k_dcop; - return; - } + *(cursor + 2) == 'd' && + *(cursor + 3) == 'c' && + *(cursor + 4) == 'o' && + *(cursor + 5) == 'p') + { + token_stream[(int) index++].kind = Token_k_dcop; + return; + } break; case 'Q': if (*(cursor + 1) == '_' && @@ -1426,78 +1426,78 @@ void Lexer::scanKeyword7() { case 'd': if (*(cursor + 1) == 'e' && - *(cursor + 2) == 'f' && - *(cursor + 3) == 'a' && - *(cursor + 4) == 'u' && - *(cursor + 5) == 'l' && - *(cursor + 6) == 't') - { - token_stream[(int) index++].kind = Token_default; - return; - } + *(cursor + 2) == 'f' && + *(cursor + 3) == 'a' && + *(cursor + 4) == 'u' && + *(cursor + 5) == 'l' && + *(cursor + 6) == 't') + { + token_stream[(int) index++].kind = Token_default; + return; + } break; case 'm': if (*(cursor + 1) == 'u' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'a' && - *(cursor + 4) == 'b' && - *(cursor + 5) == 'l' && - *(cursor + 6) == 'e') - { - token_stream[(int) index++].kind = Token_mutable; - return; - } + *(cursor + 2) == 't' && + *(cursor + 3) == 'a' && + *(cursor + 4) == 'b' && + *(cursor + 5) == 'l' && + *(cursor + 6) == 'e') + { + token_stream[(int) index++].kind = Token_mutable; + return; + } break; case 'p': if (*(cursor + 1) == 'r' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 'v' && - *(cursor + 4) == 'a' && - *(cursor + 5) == 't' && - *(cursor + 6) == 'e') - { - token_stream[(int) index++].kind = Token_private; - return; - } + *(cursor + 2) == 'i' && + *(cursor + 3) == 'v' && + *(cursor + 4) == 'a' && + *(cursor + 5) == 't' && + *(cursor + 6) == 'e') + { + token_stream[(int) index++].kind = Token_private; + return; + } break; case 's': if (*(cursor + 1) == 'i' && - *(cursor + 2) == 'g' && - *(cursor + 3) == 'n' && - *(cursor + 4) == 'a' && - *(cursor + 5) == 'l' && - *(cursor + 6) == 's') - { - token_stream[(int) index++].kind = Token_signals; - return; - } + *(cursor + 2) == 'g' && + *(cursor + 3) == 'n' && + *(cursor + 4) == 'a' && + *(cursor + 5) == 'l' && + *(cursor + 6) == 's') + { + token_stream[(int) index++].kind = Token_signals; + return; + } break; case 't': if (*(cursor + 1) == 'y' && - *(cursor + 2) == 'p' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 'd' && - *(cursor + 5) == 'e' && - *(cursor + 6) == 'f') - { - token_stream[(int) index++].kind = Token_typedef; - return; - } + *(cursor + 2) == 'p' && + *(cursor + 3) == 'e' && + *(cursor + 4) == 'd' && + *(cursor + 5) == 'e' && + *(cursor + 6) == 'f') + { + token_stream[(int) index++].kind = Token_typedef; + return; + } break; case 'v': if (*(cursor + 1) == 'i' && - *(cursor + 2) == 'r' && - *(cursor + 3) == 't' && - *(cursor + 4) == 'u' && - *(cursor + 5) == 'a' && - *(cursor + 6) == 'l') - { - token_stream[(int) index++].kind = Token_virtual; - return; - } + *(cursor + 2) == 'r' && + *(cursor + 3) == 't' && + *(cursor + 4) == 'u' && + *(cursor + 5) == 'a' && + *(cursor + 6) == 'l') + { + token_stream[(int) index++].kind = Token_virtual; + return; + } break; case 'Q': @@ -1523,58 +1523,58 @@ void Lexer::scanKeyword8() { case '_': if (*(cursor + 1) == '_' && - *(cursor + 2) == 't' && - *(cursor + 3) == 'y' && - *(cursor + 4) == 'p' && - *(cursor + 5) == 'e' && - *(cursor + 6) == 'o' && - *(cursor + 7) == 'f') - { - token_stream[(int) index++].kind = Token___typeof; - return; - } + *(cursor + 2) == 't' && + *(cursor + 3) == 'y' && + *(cursor + 4) == 'p' && + *(cursor + 5) == 'e' && + *(cursor + 6) == 'o' && + *(cursor + 7) == 'f') + { + token_stream[(int) index++].kind = Token___typeof; + return; + } break; case 'c': if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'n' && - *(cursor + 3) == 't' && - *(cursor + 4) == 'i' && - *(cursor + 5) == 'n' && - *(cursor + 6) == 'u' && - *(cursor + 7) == 'e') - { - token_stream[(int) index++].kind = Token_continue; - return; - } + *(cursor + 2) == 'n' && + *(cursor + 3) == 't' && + *(cursor + 4) == 'i' && + *(cursor + 5) == 'n' && + *(cursor + 6) == 'u' && + *(cursor + 7) == 'e') + { + token_stream[(int) index++].kind = Token_continue; + return; + } break; case 'd': if (*(cursor + 1) == 'e' && - *(cursor + 2) == 'c' && - *(cursor + 3) == 'l' && - *(cursor + 4) == 't' && - *(cursor + 5) == 'y' && - *(cursor + 6) == 'p' && - *(cursor + 7) == 'e') - { - token_stream[(int) index++].kind = Token_decltype; - return; - } + *(cursor + 2) == 'c' && + *(cursor + 3) == 'l' && + *(cursor + 4) == 't' && + *(cursor + 5) == 'y' && + *(cursor + 6) == 'p' && + *(cursor + 7) == 'e') + { + token_stream[(int) index++].kind = Token_decltype; + return; + } break; case 'e': if (*(cursor + 1) == 'x' && - *(cursor + 2) == 'p' && - *(cursor + 3) == 'l' && - *(cursor + 4) == 'i' && - *(cursor + 5) == 'c' && - *(cursor + 6) == 'i' && - *(cursor + 7) == 't') - { - token_stream[(int) index++].kind = Token_explicit; - return; - } + *(cursor + 2) == 'p' && + *(cursor + 3) == 'l' && + *(cursor + 4) == 'i' && + *(cursor + 5) == 'c' && + *(cursor + 6) == 'i' && + *(cursor + 7) == 't') + { + token_stream[(int) index++].kind = Token_explicit; + return; + } break; case 'n': @@ -1593,97 +1593,97 @@ void Lexer::scanKeyword8() case 'o': if (*(cursor + 1) == 'p' && - *(cursor + 2) == 'e' && - *(cursor + 3) == 'r' && - *(cursor + 4) == 'a' && - *(cursor + 5) == 't' && - *(cursor + 6) == 'o' && - *(cursor + 7) == 'r') - { - token_stream[(int) index++].kind = Token_operator; - return; - } + *(cursor + 2) == 'e' && + *(cursor + 3) == 'r' && + *(cursor + 4) == 'a' && + *(cursor + 5) == 't' && + *(cursor + 6) == 'o' && + *(cursor + 7) == 'r') + { + token_stream[(int) index++].kind = Token_operator; + return; + } break; case 'Q': if (*(cursor + 1) == '_' && - *(cursor + 2) == 'O' && - *(cursor + 3) == 'B' && - *(cursor + 4) == 'J' && - *(cursor + 5) == 'E' && - *(cursor + 6) == 'C' && - *(cursor + 7) == 'T') - { - token_stream[(int) index++].kind = Token_Q_OBJECT; - return; - } + *(cursor + 2) == 'O' && + *(cursor + 3) == 'B' && + *(cursor + 4) == 'J' && + *(cursor + 5) == 'E' && + *(cursor + 6) == 'C' && + *(cursor + 7) == 'T') + { + token_stream[(int) index++].kind = Token_Q_OBJECT; + return; + } break; case 'r': if (*(cursor + 1) == 'e' && - *(cursor + 2) == 'g' && - *(cursor + 3) == 'i' && - *(cursor + 4) == 's' && - *(cursor + 5) == 't' && - *(cursor + 6) == 'e' && - *(cursor + 7) == 'r') - { - token_stream[(int) index++].kind = Token_register; - return; - } + *(cursor + 2) == 'g' && + *(cursor + 3) == 'i' && + *(cursor + 4) == 's' && + *(cursor + 5) == 't' && + *(cursor + 6) == 'e' && + *(cursor + 7) == 'r') + { + token_stream[(int) index++].kind = Token_register; + return; + } break; case 'u': if (*(cursor + 1) == 'n' && - *(cursor + 2) == 's' && - *(cursor + 3) == 'i' && - *(cursor + 4) == 'g' && - *(cursor + 5) == 'n' && - *(cursor + 6) == 'e' && - *(cursor + 7) == 'd') - { - token_stream[(int) index++].kind = Token_unsigned; - return; - } + *(cursor + 2) == 's' && + *(cursor + 3) == 'i' && + *(cursor + 4) == 'g' && + *(cursor + 5) == 'n' && + *(cursor + 6) == 'e' && + *(cursor + 7) == 'd') + { + token_stream[(int) index++].kind = Token_unsigned; + return; + } break; case 't': if (*(cursor + 1) == 'e' && - *(cursor + 2) == 'm' && - *(cursor + 3) == 'p' && - *(cursor + 4) == 'l' && - *(cursor + 5) == 'a' && - *(cursor + 6) == 't' && - *(cursor + 7) == 'e') - { - token_stream[(int) index++].kind = Token_template; - return; - } + *(cursor + 2) == 'm' && + *(cursor + 3) == 'p' && + *(cursor + 4) == 'l' && + *(cursor + 5) == 'a' && + *(cursor + 6) == 't' && + *(cursor + 7) == 'e') + { + token_stream[(int) index++].kind = Token_template; + return; + } if (*(cursor + 1) == 'y' && - *(cursor + 2) == 'p' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 'n' && - *(cursor + 5) == 'a' && - *(cursor + 6) == 'm' && - *(cursor + 7) == 'e') - { - token_stream[(int) index++].kind = Token_typename; - return; - } + *(cursor + 2) == 'p' && + *(cursor + 3) == 'e' && + *(cursor + 4) == 'n' && + *(cursor + 5) == 'a' && + *(cursor + 6) == 'm' && + *(cursor + 7) == 'e') + { + token_stream[(int) index++].kind = Token_typename; + return; + } break; case 'v': if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'l' && - *(cursor + 3) == 'a' && - *(cursor + 4) == 't' && - *(cursor + 5) == 'i' && - *(cursor + 6) == 'l' && - *(cursor + 7) == 'e') - { - token_stream[(int) index++].kind = Token_volatile; - return; - } + *(cursor + 2) == 'l' && + *(cursor + 3) == 'a' && + *(cursor + 4) == 't' && + *(cursor + 5) == 'i' && + *(cursor + 6) == 'l' && + *(cursor + 7) == 'e') + { + token_stream[(int) index++].kind = Token_volatile; + return; + } break; } @@ -1696,47 +1696,47 @@ void Lexer::scanKeyword9() { case 'c': if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'n' && - *(cursor + 3) == 's' && - *(cursor + 4) == 't' && - *(cursor + 5) == 'e' && - *(cursor + 6) == 'x' && - *(cursor + 7) == 'p' && - *(cursor + 8) == 'r') - { - token_stream[(int) index++].kind = Token_constexpr; - return; - } + *(cursor + 2) == 'n' && + *(cursor + 3) == 's' && + *(cursor + 4) == 't' && + *(cursor + 5) == 'e' && + *(cursor + 6) == 'x' && + *(cursor + 7) == 'p' && + *(cursor + 8) == 'r') + { + token_stream[(int) index++].kind = Token_constexpr; + return; + } break; case 'p': if (*(cursor + 1) == 'r' && - *(cursor + 2) == 'o' && - *(cursor + 3) == 't' && - *(cursor + 4) == 'e' && - *(cursor + 5) == 'c' && - *(cursor + 6) == 't' && - *(cursor + 7) == 'e' && - *(cursor + 8) == 'd') - { - token_stream[(int) index++].kind = Token_protected; - return; - } + *(cursor + 2) == 'o' && + *(cursor + 3) == 't' && + *(cursor + 4) == 'e' && + *(cursor + 5) == 'c' && + *(cursor + 6) == 't' && + *(cursor + 7) == 'e' && + *(cursor + 8) == 'd') + { + token_stream[(int) index++].kind = Token_protected; + return; + } break; case 'n': if (*(cursor + 1) == 'a' && - *(cursor + 2) == 'm' && - *(cursor + 3) == 'e' && - *(cursor + 4) == 's' && - *(cursor + 5) == 'p' && - *(cursor + 6) == 'a' && - *(cursor + 7) == 'c' && - *(cursor + 8) == 'e') - { - token_stream[(int) index++].kind = Token_namespace; - return; - } + *(cursor + 2) == 'm' && + *(cursor + 3) == 'e' && + *(cursor + 4) == 's' && + *(cursor + 5) == 'p' && + *(cursor + 6) == 'a' && + *(cursor + 7) == 'c' && + *(cursor + 8) == 'e') + { + token_stream[(int) index++].kind = Token_namespace; + return; + } break; } @@ -1749,18 +1749,18 @@ void Lexer::scanKeyword10() { case 'c': if (*(cursor + 1) == 'o' && - *(cursor + 2) == 'n' && - *(cursor + 3) == 's' && - *(cursor + 4) == 't' && - *(cursor + 5) == '_' && - *(cursor + 6) == 'c' && - *(cursor + 7) == 'a' && - *(cursor + 8) == 's' && - *(cursor + 9) == 't') - { - token_stream[(int) index++].kind = Token_const_cast; - return; - } + *(cursor + 2) == 'n' && + *(cursor + 3) == 's' && + *(cursor + 4) == 't' && + *(cursor + 5) == '_' && + *(cursor + 6) == 'c' && + *(cursor + 7) == 'a' && + *(cursor + 8) == 's' && + *(cursor + 9) == 't') + { + token_stream[(int) index++].kind = Token_const_cast; + return; + } break; case 'Q': @@ -1790,36 +1790,36 @@ void Lexer::scanKeyword11() { case 'Q': if (*(cursor + 1) == '_' && - *(cursor + 2) == 'I' && - *(cursor + 3) == 'N' && - *(cursor + 4) == 'V' && - *(cursor + 5) == 'O' && - *(cursor + 6) == 'K' && - *(cursor + 7) == 'A' && - *(cursor + 8) == 'B' && - *(cursor + 9) == 'L' && - *(cursor + 10) == 'E') - { - token_stream[(int) index++].kind = Token_Q_INVOKABLE; - return; - } + *(cursor + 2) == 'I' && + *(cursor + 3) == 'N' && + *(cursor + 4) == 'V' && + *(cursor + 5) == 'O' && + *(cursor + 6) == 'K' && + *(cursor + 7) == 'A' && + *(cursor + 8) == 'B' && + *(cursor + 9) == 'L' && + *(cursor + 10) == 'E') + { + token_stream[(int) index++].kind = Token_Q_INVOKABLE; + return; + } break; case 's': if (*(cursor + 1) == 't' && - *(cursor + 2) == 'a' && - *(cursor + 3) == 't' && - *(cursor + 4) == 'i' && - *(cursor + 5) == 'c' && - *(cursor + 6) == '_' && - *(cursor + 7) == 'c' && - *(cursor + 8) == 'a' && - *(cursor + 9) == 's' && - *(cursor + 10) == 't') - { - token_stream[(int) index++].kind = Token_static_cast; - return; - } + *(cursor + 2) == 'a' && + *(cursor + 3) == 't' && + *(cursor + 4) == 'i' && + *(cursor + 5) == 'c' && + *(cursor + 6) == '_' && + *(cursor + 7) == 'c' && + *(cursor + 8) == 'a' && + *(cursor + 9) == 's' && + *(cursor + 10) == 't') + { + token_stream[(int) index++].kind = Token_static_cast; + return; + } break; } @@ -1832,20 +1832,20 @@ void Lexer::scanKeyword12() { case 'd': if (*(cursor + 1) == 'y' && - *(cursor + 2) == 'n' && - *(cursor + 3) == 'a' && - *(cursor + 4) == 'm' && - *(cursor + 5) == 'i' && - *(cursor + 6) == 'c' && - *(cursor + 7) == '_' && - *(cursor + 8) == 'c' && - *(cursor + 9) == 'a' && - *(cursor + 10) == 's' && - *(cursor + 11) == 't') - { - token_stream[(int) index++].kind = Token_dynamic_cast; - return; - } + *(cursor + 2) == 'n' && + *(cursor + 3) == 'a' && + *(cursor + 4) == 'm' && + *(cursor + 5) == 'i' && + *(cursor + 6) == 'c' && + *(cursor + 7) == '_' && + *(cursor + 8) == 'c' && + *(cursor + 9) == 'a' && + *(cursor + 10) == 's' && + *(cursor + 11) == 't') + { + token_stream[(int) index++].kind = Token_dynamic_cast; + return; + } break; } @@ -1858,21 +1858,21 @@ void Lexer::scanKeyword13() { case '_': if (*(cursor + 1) == '_' && - *(cursor + 2) == 'a' && - *(cursor + 3) == 't' && - *(cursor + 4) == 't' && - *(cursor + 5) == 'r' && - *(cursor + 6) == 'i' && - *(cursor + 7) == 'b' && - *(cursor + 8) == 'u' && - *(cursor + 9) == 't' && - *(cursor + 10) == 'e' && - *(cursor + 11) == '_' && - *(cursor + 12) == '_') - { - token_stream[(int) index++].kind = Token___attribute__; - return; - } + *(cursor + 2) == 'a' && + *(cursor + 3) == 't' && + *(cursor + 4) == 't' && + *(cursor + 5) == 'r' && + *(cursor + 6) == 'i' && + *(cursor + 7) == 'b' && + *(cursor + 8) == 'u' && + *(cursor + 9) == 't' && + *(cursor + 10) == 'e' && + *(cursor + 11) == '_' && + *(cursor + 12) == '_') + { + token_stream[(int) index++].kind = Token___attribute__; + return; + } break; } token_stream[(int) index++].kind = Token_identifier; @@ -1884,22 +1884,22 @@ void Lexer::scanKeyword14() { case 'k': if (*(cursor + 1) == '_' && - *(cursor + 2) == 'd' && - *(cursor + 3) == 'c' && - *(cursor + 4) == 'o' && - *(cursor + 5) == 'p' && - *(cursor + 6) == '_' && - *(cursor + 7) == 's' && - *(cursor + 8) == 'i' && - *(cursor + 9) == 'g' && - *(cursor + 10) == 'n' && - *(cursor + 11) == 'a' && - *(cursor + 12) == 'l' && - *(cursor + 13) == 's') - { - token_stream[(int) index++].kind = Token_k_dcop_signals; - return; - } + *(cursor + 2) == 'd' && + *(cursor + 3) == 'c' && + *(cursor + 4) == 'o' && + *(cursor + 5) == 'p' && + *(cursor + 6) == '_' && + *(cursor + 7) == 's' && + *(cursor + 8) == 'i' && + *(cursor + 9) == 'g' && + *(cursor + 10) == 'n' && + *(cursor + 11) == 'a' && + *(cursor + 12) == 'l' && + *(cursor + 13) == 's') + { + token_stream[(int) index++].kind = Token_k_dcop_signals; + return; + } break; } token_stream[(int) index++].kind = Token_identifier; @@ -1911,24 +1911,24 @@ void Lexer::scanKeyword16() { case 'r': if (*(cursor + 1) == 'e' && - *(cursor + 2) == 'i' && - *(cursor + 3) == 'n' && - *(cursor + 4) == 't' && - *(cursor + 5) == 'e' && - *(cursor + 6) == 'r' && - *(cursor + 7) == 'p' && - *(cursor + 8) == 'r' && - *(cursor + 9) == 'e' && - *(cursor + 10) == 't' && - *(cursor + 11) == '_' && - *(cursor + 12) == 'c' && - *(cursor + 13) == 'a' && - *(cursor + 14) == 's' && - *(cursor + 15) == 't') - { - token_stream[(int) index++].kind = Token_reinterpret_cast; - return; - } + *(cursor + 2) == 'i' && + *(cursor + 3) == 'n' && + *(cursor + 4) == 't' && + *(cursor + 5) == 'e' && + *(cursor + 6) == 'r' && + *(cursor + 7) == 'p' && + *(cursor + 8) == 'r' && + *(cursor + 9) == 'e' && + *(cursor + 10) == 't' && + *(cursor + 11) == '_' && + *(cursor + 12) == 'c' && + *(cursor + 13) == 'a' && + *(cursor + 14) == 's' && + *(cursor + 15) == 't') + { + token_stream[(int) index++].kind = Token_reinterpret_cast; + return; + } break; } diff --git a/generator/parser/parser.cpp b/generator/parser/parser.cpp index 73e4dd711..408de0091 100644 --- a/generator/parser/parser.cpp +++ b/generator/parser/parser.cpp @@ -1308,7 +1308,7 @@ bool Parser::parseDeclarator(DeclaratorAST *&node) } if (token_stream.lookAhead() == Token___attribute__) { - parse_Attribute__(); + parse_Attribute__(); } } @@ -1837,14 +1837,14 @@ bool Parser::parse_Attribute__() { parseExpression(expr); if (token_stream.lookAhead() != ')') - { - reportError(("')' expected")); - return false; - } + { + reportError(("')' expected")); + return false; + } else - { - token_stream.nextToken(); - } + { + token_stream.nextToken(); + } return true; } diff --git a/generator/parser/rpp/pp-main.cpp b/generator/parser/rpp/pp-main.cpp index 0676a2fee..aaf09e141 100644 --- a/generator/parser/rpp/pp-main.cpp +++ b/generator/parser/rpp/pp-main.cpp @@ -142,19 +142,19 @@ int main (int, char *argv []) opt_pch = true; else if (! strcmp (arg, "-msse")) - { - pp_macro __macro; - __macro.name = pp_symbol::get ("__SSE__", 7); - env.bind (__macro.name, __macro); + { + pp_macro __macro; + __macro.name = pp_symbol::get ("__SSE__", 7); + env.bind (__macro.name, __macro); - __macro.name = pp_symbol::get ("__MMX__", 7); - env.bind (__macro.name, __macro); - } + __macro.name = pp_symbol::get ("__MMX__", 7); + env.bind (__macro.name, __macro); + } else if (! strcmp (arg, "-include")) { if (argv [1]) - include_pch_file = *++argv; + include_pch_file = *++argv; } else if (! strncmp (arg, "-o", 2)) diff --git a/generator/parser/rpp/rpp.pri b/generator/parser/rpp/rpp.pri index 8468bcf97..46f6a98af 100644 --- a/generator/parser/rpp/rpp.pri +++ b/generator/parser/rpp/rpp.pri @@ -1,20 +1,20 @@ SOURCES += \ - $$RXXPATH/rpp/preprocessor.cpp + $$RXXPATH/rpp/preprocessor.cpp HEADERS += \ - $$RXXPATH/rpp/pp-cctype.h \ - $$RXXPATH/rpp/pp-engine-bits.h \ - $$RXXPATH/rpp/pp-engine.h \ - $$RXXPATH/rpp/pp-environment.h \ - $$RXXPATH/rpp/pp-fwd.h \ - $$RXXPATH/rpp/pp-internal.h \ - $$RXXPATH/rpp/pp-iterator.h \ - $$RXXPATH/rpp/pp-macro-expander.h \ - $$RXXPATH/rpp/pp-macro.h \ - $$RXXPATH/rpp/pp-scanner.h \ - $$RXXPATH/rpp/pp-string.h \ - $$RXXPATH/rpp/pp-symbol.h \ - $$RXXPATH/rpp/pp.h \ - $$RXXPATH/rpp/preprocessor.h + $$RXXPATH/rpp/pp-cctype.h \ + $$RXXPATH/rpp/pp-engine-bits.h \ + $$RXXPATH/rpp/pp-engine.h \ + $$RXXPATH/rpp/pp-environment.h \ + $$RXXPATH/rpp/pp-fwd.h \ + $$RXXPATH/rpp/pp-internal.h \ + $$RXXPATH/rpp/pp-iterator.h \ + $$RXXPATH/rpp/pp-macro-expander.h \ + $$RXXPATH/rpp/pp-macro.h \ + $$RXXPATH/rpp/pp-scanner.h \ + $$RXXPATH/rpp/pp-string.h \ + $$RXXPATH/rpp/pp-symbol.h \ + $$RXXPATH/rpp/pp.h \ + $$RXXPATH/rpp/preprocessor.h INCLUDEPATH += $$PWD $$RXXPATH/rpp diff --git a/src/PythonQtClassWrapper.cpp b/src/PythonQtClassWrapper.cpp index dda2bc1fd..ad8f50644 100644 --- a/src/PythonQtClassWrapper.cpp +++ b/src/PythonQtClassWrapper.cpp @@ -112,8 +112,8 @@ static int PythonQtInstanceWrapper_setitem(PyObject* self, PyObject* index, PyOb PythonQtInstanceWrapper* wrapper = (PythonQtInstanceWrapper*)self; bool isSetItem = value; PythonQtMemberInfo opSlot = isSetItem ? - wrapper->classInfo()->member("__setitem__") - : wrapper->classInfo()->member("__delitem__"); + wrapper->classInfo()->member("__setitem__") + : wrapper->classInfo()->member("__delitem__"); if (opSlot._type == PythonQtMemberInfo::Slot) { PyObject* args = PyTuple_New(isSetItem?2:1); From b39d565a581c0e617045b8de88cab53d78c7cb89 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Sat, 14 Oct 2023 23:14:58 -0700 Subject: [PATCH 19/21] generator: remove anonymous structs (#121) This is a minimal change to give the three anonymous structs used in the generator names so that the code conforms to the existing C++ standards. --- generator/parser/codemodel.cpp | 60 ++++++++++++------------ generator/parser/codemodel.h | 34 +++++++------- generator/parser/rpp/pp-engine-bits.h | 6 +-- generator/parser/rpp/pp-environment.h | 4 +- generator/parser/rpp/pp-macro-expander.h | 16 +++---- generator/parser/rpp/pp-macro.h | 2 +- generator/parser/rpp/preprocessor.cpp | 2 +- 7 files changed, 62 insertions(+), 62 deletions(-) diff --git a/generator/parser/codemodel.cpp b/generator/parser/codemodel.cpp index 511307e48..a32c0614d 100644 --- a/generator/parser/codemodel.cpp +++ b/generator/parser/codemodel.cpp @@ -683,63 +683,63 @@ void _FunctionModelItem::setException(const QString &exception) bool _FunctionModelItem::isVariadics() const { - return _M_isVariadics; + return _M.isVariadics; } void _FunctionModelItem::setVariadics(bool isVariadics) { - _M_isVariadics = isVariadics; + _M.isVariadics = isVariadics; } bool _FunctionModelItem::isVirtual() const { - return _M_isVirtual; + return _M.isVirtual; } void _FunctionModelItem::setVirtual(bool isVirtual) { - _M_isVirtual = isVirtual; + _M.isVirtual = isVirtual; } bool _FunctionModelItem::isInline() const { - return _M_isInline; + return _M.isInline; } void _FunctionModelItem::setInline(bool isInline) { - _M_isInline = isInline; + _M.isInline = isInline; } bool _FunctionModelItem::isExplicit() const { - return _M_isExplicit; + return _M.isExplicit; } void _FunctionModelItem::setExplicit(bool isExplicit) { - _M_isExplicit = isExplicit; + _M.isExplicit = isExplicit; } bool _FunctionModelItem::isAbstract() const { - return _M_isAbstract; + return _M.isAbstract; } void _FunctionModelItem::setAbstract(bool isAbstract) { - _M_isAbstract = isAbstract; + _M.isAbstract = isAbstract; } // Qt bool _FunctionModelItem::isInvokable() const { - return _M_isInvokable; + return _M.isInvokable; } void _FunctionModelItem::setInvokable(bool isInvokable) { - _M_isInvokable = isInvokable; + _M.isInvokable = isInvokable; } // --------------------------------------------------------------------------- @@ -907,92 +907,92 @@ void _MemberModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy) bool _MemberModelItem::isStatic() const { - return _M_isStatic; + return _M.isStatic; } void _MemberModelItem::setStatic(bool isStatic) { - _M_isStatic = isStatic; + _M.isStatic = isStatic; } bool _MemberModelItem::isConstant() const { - return _M_isConstant; + return _M.isConstant; } void _MemberModelItem::setConstant(bool isConstant) { - _M_isConstant = isConstant; + _M.isConstant = isConstant; } bool _MemberModelItem::isConstexpr() const { - return _M_isConstexpr; + return _M.isConstexpr; } void _MemberModelItem::setConstexpr(bool isConstexpr) { - _M_isConstexpr = isConstexpr; + _M.isConstexpr = isConstexpr; } bool _MemberModelItem::isVolatile() const { - return _M_isVolatile; + return _M.isVolatile; } void _MemberModelItem::setVolatile(bool isVolatile) { - _M_isVolatile = isVolatile; + _M.isVolatile = isVolatile; } bool _MemberModelItem::isAuto() const { - return _M_isAuto; + return _M.isAuto; } void _MemberModelItem::setAuto(bool isAuto) { - _M_isAuto = isAuto; + _M.isAuto = isAuto; } bool _MemberModelItem::isFriend() const { - return _M_isFriend; + return _M.isFriend; } void _MemberModelItem::setFriend(bool isFriend) { - _M_isFriend = isFriend; + _M.isFriend = isFriend; } bool _MemberModelItem::isRegister() const { - return _M_isRegister; + return _M.isRegister; } void _MemberModelItem::setRegister(bool isRegister) { - _M_isRegister = isRegister; + _M.isRegister = isRegister; } bool _MemberModelItem::isExtern() const { - return _M_isExtern; + return _M.isExtern; } void _MemberModelItem::setExtern(bool isExtern) { - _M_isExtern = isExtern; + _M.isExtern = isExtern; } bool _MemberModelItem::isMutable() const { - return _M_isMutable; + return _M.isMutable; } void _MemberModelItem::setMutable(bool isMutable) { - _M_isMutable = isMutable; + _M.isMutable = isMutable; } // kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/generator/parser/codemodel.h b/generator/parser/codemodel.h index 06af94f61..efcee3d35 100644 --- a/generator/parser/codemodel.h +++ b/generator/parser/codemodel.h @@ -517,16 +517,16 @@ class _MemberModelItem: public _CodeModelItem { struct { - uint _M_isConstant: 1; - uint _M_isConstexpr: 1; - uint _M_isVolatile: 1; - uint _M_isStatic: 1; - uint _M_isAuto: 1; - uint _M_isFriend: 1; - uint _M_isRegister: 1; - uint _M_isExtern: 1; - uint _M_isMutable: 1; - }; + uint isConstant: 1; + uint isConstexpr: 1; + uint isVolatile: 1; + uint isStatic: 1; + uint isAuto: 1; + uint isFriend: 1; + uint isRegister: 1; + uint isExtern: 1; + uint isMutable: 1; + } _M; uint _M_flags; }; @@ -586,13 +586,13 @@ class _FunctionModelItem: public _MemberModelItem { struct { - uint _M_isVirtual: 1; - uint _M_isInline: 1; - uint _M_isAbstract: 1; - uint _M_isExplicit: 1; - uint _M_isVariadics: 1; - uint _M_isInvokable : 1; // Qt - }; + uint isVirtual: 1; + uint isInline: 1; + uint isAbstract: 1; + uint isExplicit: 1; + uint isVariadics: 1; + uint isInvokable : 1; // Qt + } _M; uint _M_flags; }; diff --git a/generator/parser/rpp/pp-engine-bits.h b/generator/parser/rpp/pp-engine-bits.h index d4ac04945..550e5bfa8 100644 --- a/generator/parser/rpp/pp-engine-bits.h +++ b/generator/parser/rpp/pp-engine-bits.h @@ -577,7 +577,7 @@ InputIterator pp::handle_define (InputIterator _first, InputIterator _last) if (_first != _last && *_first == '(') { - macro.function_like = true; + macro.is.function_like = true; macro.formals.reserve (5); _first = skip_blanks (++_first, _last); // skip '(' @@ -589,7 +589,7 @@ InputIterator pp::handle_define (InputIterator _first, InputIterator _last) if (*_first == '.') { - macro.variadics = true; + macro.is.variadics = true; while (*_first == '.') ++_first; } @@ -606,7 +606,7 @@ InputIterator pp::handle_define (InputIterator _first, InputIterator _last) if (*_first == '.') { - macro.variadics = true; + macro.is.variadics = true; while (*_first == '.') ++_first; } diff --git a/generator/parser/rpp/pp-environment.h b/generator/parser/rpp/pp-environment.h index 982fb0d24..049ff5899 100644 --- a/generator/parser/rpp/pp-environment.h +++ b/generator/parser/rpp/pp-environment.h @@ -89,7 +89,7 @@ class pp_environment inline void unbind (pp_fast_string const *_name) { if (pp_macro *m = resolve (_name)) - m->hidden = true; + m->is.hidden = true; } inline void unbind (char const *_s, std::size_t _size) @@ -103,7 +103,7 @@ class pp_environment std::size_t h = hash_code (*_name) % _M_hash_size; pp_macro *it = _M_base [h]; - while (it && it->name && it->hash_code == h && (*it->name != *_name || it->hidden)) + while (it && it->name && it->hash_code == h && (*it->name != *_name || it->is.hidden)) it = it->next; return it; diff --git a/generator/parser/rpp/pp-macro-expander.h b/generator/parser/rpp/pp-macro-expander.h index 88e580383..a52182c1a 100644 --- a/generator/parser/rpp/pp-macro-expander.h +++ b/generator/parser/rpp/pp-macro-expander.h @@ -250,7 +250,7 @@ class pp_macro_expander static bool hide_next = false; // ### remove me pp_macro *macro = env.resolve (name_buffer, name_size); - if (! macro || macro->hidden || hide_next) + if (! macro || macro->is.hidden || hide_next) { hide_next = ! strcmp (name_buffer, "defined"); @@ -278,13 +278,13 @@ class pp_macro_expander continue; } - if (! macro->function_like) + if (! macro->is.function_like) { pp_macro *m = 0; if (macro->definition) { - macro->hidden = true; + macro->is.hidden = true; std::string tmp; tmp.reserve (256); @@ -316,7 +316,7 @@ class pp_macro_expander std::copy (tmp.begin (), tmp.end (), _result); } - macro->hidden = false; + macro->is.hidden = false; } if (! m) @@ -370,15 +370,15 @@ class pp_macro_expander _first = arg_it; #if 0 // ### enable me - assert ((macro->variadics && macro->formals.size () >= actuals.size ()) + assert ((macro->is.variadics && macro->formals.size () >= actuals.size ()) || macro->formals.size() == actuals.size()); #endif pp_frame frame (macro, &actuals); pp_macro_expander expand_macro (env, &frame); - macro->hidden = true; + macro->is.hidden = true; expand_macro (macro->definition->begin (), macro->definition->end (), _result); - macro->hidden = false; + macro->is.hidden = false; generated_lines += expand_macro.lines; } else @@ -394,7 +394,7 @@ class pp_macro_expander { InputIterator arg_end = skip_argument (_first, _last); - while (_macro->variadics && _first != arg_end && arg_end != _last && *arg_end == ',' + while (_macro->is.variadics && _first != arg_end && arg_end != _last && *arg_end == ',' && (_actuals.size () + 1) == _macro->formals.size ()) { arg_end = skip_argument (++arg_end, _last); diff --git a/generator/parser/rpp/pp-macro.h b/generator/parser/rpp/pp-macro.h index 0b4d7b5e8..6342549d4 100644 --- a/generator/parser/rpp/pp-macro.h +++ b/generator/parser/rpp/pp-macro.h @@ -62,7 +62,7 @@ struct pp_macro int unsigned hidden: 1; int unsigned function_like: 1; int unsigned variadics: 1; - }; + } is; }; int lines; diff --git a/generator/parser/rpp/preprocessor.cpp b/generator/parser/rpp/preprocessor.cpp index c813a92aa..55c804809 100644 --- a/generator/parser/rpp/preprocessor.cpp +++ b/generator/parser/rpp/preprocessor.cpp @@ -143,7 +143,7 @@ QList Preprocessor::macros() const item.parameters += QString::fromLatin1(m->formals[i]->begin(), m->formals[i]->size()); } - item.isFunctionLike = m->function_like; + item.isFunctionLike = m->is.function_like; #ifdef PP_WITH_MACRO_POSITION item.fileName = QString::fromLatin1(m->file->begin(), m->file->size()); From 25f848552962e81a20f51372b132cf55b8571759 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Mon, 16 Oct 2023 10:03:29 -0700 Subject: [PATCH 20/21] generator: call Reporthandler::setContext more (#131) This adds 'context' to ReportHandler warning messages; just a string saying what is being done. --- generator/main.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/generator/main.cpp b/generator/main.cpp index 22a054e91..64161ed33 100644 --- a/generator/main.cpp +++ b/generator/main.cpp @@ -39,6 +39,8 @@ ** ****************************************************************************/ +#include + #include "main.h" #include "asttoxml.h" #include "reporthandler.h" @@ -53,6 +55,8 @@ void displayHelp(GeneratorSet *generatorSet); #include int main(int argc, char *argv[]) { + ReportHandler::setContext("Arguments"); + QScopedPointer gs(GeneratorSet::getInstance()); QString default_file = ":/trolltech/generator/qtscript_masterinclude.h"; @@ -135,11 +139,13 @@ int main(int argc, char *argv[]) printf("Please wait while source files are being generated...\n"); printf("Parsing typesystem file [%s]\n", qPrintable(typesystemFileName)); + ReportHandler::setContext("Typesystem"); if (!TypeDatabase::instance()->parseFile(typesystemFileName)) qFatal("Cannot parse file: '%s'", qPrintable(typesystemFileName)); printf("PreProcessing - Generate [%s] using [%s] and include-paths [%s]\n", qPrintable(pp_file), qPrintable(fileName), qPrintable(args.value("include-paths"))); + ReportHandler::setContext("Preprocess"); if (!Preprocess::preprocess(fileName, pp_file, args.value("include-paths"))) { fprintf(stderr, "Preprocessor failed on file: '%s'\n", qPrintable(fileName)); return 1; @@ -148,16 +154,19 @@ int main(int argc, char *argv[]) if (args.contains("ast-to-xml")) { printf("Running ast-to-xml on file [%s] using pp_file [%s] and include-paths [%s]\n", qPrintable(fileName), qPrintable(pp_file), qPrintable(args.value("include-paths"))); + ReportHandler::setContext(QString("AST-to-XML")); astToXML(pp_file); return 0; } printf("Building model using [%s]\n", qPrintable(pp_file)); + ReportHandler::setContext("Build"); gs->buildModel(pp_file); if (args.contains("dump-object-tree")) { gs->dumpObjectTree(); return 0; } + ReportHandler::setContext("Generate"); printf("%s\n", qPrintable(gs->generate())); printf("Done, %d warnings (%d known issues)\n", ReportHandler::warningCount(), From 38979b78a324494f2603ae009922dc13e776069f Mon Sep 17 00:00:00 2001 From: John Bowler Date: Mon, 16 Oct 2023 23:00:50 -0700 Subject: [PATCH 21/21] generator: AbstractMetaClassList: correct sorting (#132) In some places the list was sorted by pointer (resulting in a random sort) in other cases by name, sometimes with stable_sort, sometimes not. Now sort by name and maintain do a stable_sort. --- generator/abstractmetabuilder.cpp | 12 ++---------- generator/abstractmetalang.cpp | 8 +++++++- generator/abstractmetalang.h | 6 ++++++ generator/generator.cpp | 5 ++--- generator/setupgenerator.cpp | 11 +++-------- 5 files changed, 20 insertions(+), 22 deletions(-) diff --git a/generator/abstractmetabuilder.cpp b/generator/abstractmetabuilder.cpp index ff520c732..0d68fe918 100644 --- a/generator/abstractmetabuilder.cpp +++ b/generator/abstractmetabuilder.cpp @@ -39,8 +39,6 @@ ** ****************************************************************************/ -#include // for std::sort - #include "abstractmetabuilder.h" #include "reporthandler.h" @@ -380,15 +378,9 @@ void AbstractMetaBuilder::fixQObjectForScope(TypeDatabase *types, } } -static bool class_less_than(AbstractMetaClass *a, AbstractMetaClass *b) -{ - return a->name() < b->name(); -} - - void AbstractMetaBuilder::sortLists() { - std::sort(m_meta_classes.begin(), m_meta_classes.end(), class_less_than); + m_meta_classes.sort(); for (AbstractMetaClass *cls : m_meta_classes) { cls->sortFunctions(); } @@ -2491,7 +2483,7 @@ AbstractMetaClassList AbstractMetaBuilder::classesTopologicalSorted() const AbstractMetaClassList res; AbstractMetaClassList classes = m_meta_classes; - std::sort(classes.begin(), classes.end()); + classes.sort(); QSet noDependency; QHash* > hash; diff --git a/generator/abstractmetalang.cpp b/generator/abstractmetalang.cpp index 4e2aa8cab..45703f846 100644 --- a/generator/abstractmetalang.cpp +++ b/generator/abstractmetalang.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include // for std::sort +#include // for std::stable_sort #include "abstractmetalang.h" #include "reporthandler.h" @@ -2023,3 +2023,9 @@ AbstractMetaClass *AbstractMetaClassList::findClass(const QString &name) const return 0; } + + +void AbstractMetaClassList::sort(void) +{ + std::stable_sort(begin(), end(), AbstractMetaClass::less_than); +} diff --git a/generator/abstractmetalang.h b/generator/abstractmetalang.h index 23c37e600..7ceda45d4 100644 --- a/generator/abstractmetalang.h +++ b/generator/abstractmetalang.h @@ -71,6 +71,7 @@ class AbstractMetaClassList : public QList AbstractMetaClass *findClass(const QString &name) const; AbstractMetaEnumValue *findEnumValue(const QString &string) const; AbstractMetaEnum *findEnum(const EnumTypeEntry *entry) const; + void sort(); }; @@ -835,6 +836,11 @@ class AbstractMetaClass : public AbstractMetaAttributes return qualifiedCppName() < a.qualifiedCppName(); } + static bool less_than(const AbstractMetaClass *cl, + const AbstractMetaClass *cr) { + return cl->name() < cr->name(); + } + private: uint m_namespace : 1; uint m_qobject : 1; diff --git a/generator/generator.cpp b/generator/generator.cpp index cfcd42d92..0babb9059 100644 --- a/generator/generator.cpp +++ b/generator/generator.cpp @@ -39,7 +39,6 @@ ** ****************************************************************************/ -#include // for std::stable_sort, std::sort #include "generator.h" #include "reporthandler.h" #include "fileout.h" @@ -62,7 +61,7 @@ void Generator::generate() return; } - std::stable_sort(m_classes.begin(), m_classes.end()); + m_classes.sort(); foreach (AbstractMetaClass *cls, m_classes) { if (!shouldGenerate(cls)) @@ -86,7 +85,7 @@ void Generator::printClasses() QTextStream s(stdout); AbstractMetaClassList classes = m_classes; - std::sort(classes.begin(), classes.end()); + classes.sort(); foreach (AbstractMetaClass *cls, classes) { if (!shouldGenerate(cls)) diff --git a/generator/setupgenerator.cpp b/generator/setupgenerator.cpp index 6ac50580a..54bf78536 100644 --- a/generator/setupgenerator.cpp +++ b/generator/setupgenerator.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include // for std::sort +#include // for std::sort, std::stable_sort #include "setupgenerator.h" #include "shellgenerator.h" @@ -139,11 +139,6 @@ static QStringList getOperatorCodes(const AbstractMetaClass* cls) { return result; } -static bool class_less_than(const AbstractMetaClass *a, const AbstractMetaClass *b) -{ - return a->name() < b->name(); -} - static QSet _builtinListTypes = QSet() << "QByteArray" << "QDate" << "QTime" @@ -242,7 +237,7 @@ void SetupGenerator::generate() } } } - std::sort(classes_with_polymorphic_id.begin(), classes_with_polymorphic_id.end(), class_less_than); + classes_with_polymorphic_id.sort(); QHashIterator > pack(packHash); while (pack.hasNext()) { @@ -250,7 +245,7 @@ void SetupGenerator::generate() QList list = pack.value(); if (list.isEmpty()) continue; - std::sort(list.begin(), list.end(), class_less_than); + std::stable_sort(list.begin(), list.end(), AbstractMetaClass::less_than); QString packKey = pack.key(); QString packName = pack.key();