diff options
Diffstat (limited to 'src/tools/moc')
-rw-r--r-- | src/tools/moc/generator.cpp | 41 | ||||
-rw-r--r-- | src/tools/moc/moc.cpp | 60 | ||||
-rw-r--r-- | src/tools/moc/moc.h | 7 | ||||
-rw-r--r-- | src/tools/moc/outputrevision.h | 2 | ||||
-rw-r--r-- | src/tools/moc/preprocessor.cpp | 2 |
5 files changed, 83 insertions, 29 deletions
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 54305a3..e3ce2ec 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -56,6 +56,8 @@ enum PropertyFlags { EnumOrFlag = 0x00000008, StdCppSet = 0x00000100, // Override = 0x00000200, + Constant = 0x00000400, + Final = 0x00000800, Designable = 0x00001000, ResolveDesignable = 0x00002000, Scriptable = 0x00004000, @@ -68,6 +70,7 @@ enum PropertyFlags { ResolveUser = 0x00200000, Notify = 0x00400000 }; + enum MethodFlags { AccessPrivate = 0x00, AccessProtected = 0x01, @@ -109,6 +112,14 @@ bool isVariantType(const char* type) return qvariant_nameToType(type) != 0; } +/*! + Returns true if the type is qreal. +*/ +static bool isQRealType(const char *type) +{ + return strcmp(type, "qreal") == 0; +} + Generator::Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, FILE *outfile) : out(outfile), cdef(classDef), metaTypes(metaTypes) { @@ -194,10 +205,10 @@ void Generator::generateCode() QByteArray qualifiedClassNameIdentifier = cdef->qualified; qualifiedClassNameIdentifier.replace(':', '_'); - int index = 12; + int index = 13; fprintf(out, "static const uint qt_meta_data_%s[] = {\n", qualifiedClassNameIdentifier.constData()); fprintf(out, "\n // content:\n"); - fprintf(out, " %4d, // revision\n", 2); + fprintf(out, " %4d, // revision\n", 3); fprintf(out, " %4d, // classname\n", strreg(cdef->qualified)); fprintf(out, " %4d, %4d, // classinfo\n", cdef->classInfoList.count(), cdef->classInfoList.count() ? index : 0); index += cdef->classInfoList.count() * 2; @@ -217,6 +228,9 @@ void Generator::generateCode() fprintf(out, " %4d, %4d, // constructors\n", isConstructible ? cdef->constructorList.count() : 0, isConstructible ? index : 0); + fprintf(out, " %4d, // flags\n", 0); + + // // Build classinfo array // @@ -371,7 +385,7 @@ void Generator::generateCode() if (isQt || !cdef->hasQObject) return; - fprintf(out, "\nconst QMetaObject *%s::metaObject() const\n{\n return &staticMetaObject;\n}\n", + fprintf(out, "\nconst QMetaObject *%s::metaObject() const\n{\n return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;\n}\n", cdef->qualified.constData()); // // Generate smart cast function @@ -545,7 +559,7 @@ void Generator::generateProperties() uint flags = Invalid; if (!isVariantType(p.type)) { flags |= EnumOrFlag; - } else { + } else if (!isQRealType(p.type)) { flags |= qvariant_nameToType(p.type) << 24; } if (!p.read.isEmpty()) @@ -589,10 +603,17 @@ void Generator::generateProperties() if (p.notifyId != -1) flags |= Notify; - fprintf(out, " %4d, %4d, 0x%.8x,\n", - strreg(p.name), - strreg(p.type), - flags); + if (p.constant) + flags |= Constant; + if (p.final) + flags |= Final; + + fprintf(out, " %4d, %4d, ", + strreg(p.name), + strreg(p.type)); + if (!(flags >> 24) && isQRealType(p.type)) + fprintf(out, "(QMetaType::QReal << 24) | "); + fprintf(out, "0x%.8x,\n", flags); } if(cdef->notifyableProperties) { @@ -1161,8 +1182,8 @@ void Generator::_generateFunctions(QList<FunctionDef> &list, int type) for (int j = 0; j < f.arguments.count(); ++j) { const ArgumentDef &a = f.arguments.at(j); if (j) { - sig += ","; - arguments += ","; + sig += ','; + arguments += ','; } sig += a.normalizedType; arguments += a.name; diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 61fcee5..74b1a67 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -337,11 +337,10 @@ bool Moc::testFunctionAttribute(Token tok, FunctionDef *def) bool Moc::parseFunction(FunctionDef *def, bool inMacro) { def->isVirtual = false; - while (test(INLINE) || test(STATIC) || test(VIRTUAL) - || testFunctionAttribute(def)) { - if (lookup() == VIRTUAL) - def->isVirtual = true; - } + //skip modifiers and attributes + while (test(INLINE) || test(STATIC) || + (test(VIRTUAL) && (def->isVirtual = true)) //mark as virtual + || testFunctionAttribute(def)) {} bool templateFunction = (lookup() == TEMPLATE); def->type = parseType(); if (def->type.name.isEmpty()) { @@ -429,11 +428,10 @@ bool Moc::parseFunction(FunctionDef *def, bool inMacro) bool Moc::parseMaybeFunction(const ClassDef *cdef, FunctionDef *def) { def->isVirtual = false; - while (test(EXPLICIT) || test(INLINE) || test(STATIC) || test(VIRTUAL) - || testFunctionAttribute(def)) { - if (lookup() == VIRTUAL) - def->isVirtual = true; - } + //skip modifiers and attributes + while (test(EXPLICIT) || test(INLINE) || test(STATIC) || + (test(VIRTUAL) && (def->isVirtual = true)) //mark as virtual + || testFunctionAttribute(def)) {} bool tilde = test(TILDE); def->type = parseType(); if (def->type.name.isEmpty()) @@ -752,14 +750,14 @@ void Moc::generate(FILE *out) if (!noInclude) { - if (includePath.size() && includePath.right(1) != "/") - includePath += "/"; + if (includePath.size() && !includePath.endsWith('/')) + includePath += '/'; for (int i = 0; i < includeFiles.size(); ++i) { QByteArray inc = includeFiles.at(i); if (inc[0] != '<' && inc[0] != '"') { if (includePath.size() && includePath != "./") inc.prepend(includePath); - inc = "\"" + inc + "\""; + inc = '\"' + inc + '\"'; } fprintf(out, "#include %s\n", inc.constData()); } @@ -767,6 +765,9 @@ void Moc::generate(FILE *out) if (classList.size() && classList.first().classname == "Qt") fprintf(out, "#include <QtCore/qobject.h>\n"); + if (mustIncludeQMetaTypeH) + fprintf(out, "#include <QtCore/qmetatype.h>\n"); + fprintf(out, "#if !defined(Q_MOC_OUTPUT_REVISION)\n" "#error \"The header file '%s' doesn't include <QObject>.\"\n", (const char *)fn); fprintf(out, "#elif Q_MOC_OUTPUT_REVISION != %d\n", mocOutputRevision); @@ -859,7 +860,7 @@ void Moc::parseSignals(ClassDef *def) funcDef.access = FunctionDef::Protected; parseFunction(&funcDef); if (funcDef.isVirtual) - error("Signals cannot be declared virtual"); + warning("Signals cannot be declared virtual"); if (funcDef.inlineCode) error("Not a signal declaration"); def->signalList += funcDef; @@ -898,12 +899,24 @@ void Moc::parseProperty(ClassDef *def) type = "qlonglong"; else if (type == "ULongLong") type = "qulonglong"; + else if (type == "qreal") + mustIncludeQMetaTypeH = true; + propDef.type = type; next(); propDef.name = lexem(); while (test(IDENTIFIER)) { QByteArray l = lexem(); + + if (l[0] == 'C' && l == "CONSTANT") { + propDef.constant = true; + continue; + } else if(l[0] == 'F' && l == "FINAL") { + propDef.final = true; + continue; + } + QByteArray v, v2; if (test(LPAREN)) { v = lexemUntil(RPAREN); @@ -959,7 +972,24 @@ void Moc::parseProperty(ClassDef *def) msg += " has no READ accessor function. The property will be invalid."; warning(msg.constData()); } - if(!propDef.notify.isEmpty()) + if (propDef.constant && !propDef.write.isNull()) { + QByteArray msg; + msg += "Property declaration "; + msg += propDef.name; + msg += " is both WRITEable and CONSTANT. CONSTANT will be ignored."; + propDef.constant = false; + warning(msg.constData()); + } + if (propDef.constant && !propDef.notify.isNull()) { + QByteArray msg; + msg += "Property declaration "; + msg += propDef.name; + msg += " is both NOTIFYable and CONSTANT. CONSTANT will be ignored."; + propDef.constant = false; + warning(msg.constData()); + } + + if(!propDef.notify.isEmpty()) def->notifyableProperties++; def->propertyList += propDef; diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index 43866a6..767f84e 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -115,9 +115,11 @@ struct FunctionDef struct PropertyDef { - PropertyDef():notifyId(-1), gspec(ValueSpec){} + PropertyDef():notifyId(-1), constant(false), final(false), gspec(ValueSpec){} QByteArray name, type, read, write, reset, designable, scriptable, editable, stored, user, notify; int notifyId; + bool constant; + bool final; enum Specification { ValueSpec, ReferenceSpec, PointerSpec }; Specification gspec; bool stdCppSet() const { @@ -177,13 +179,14 @@ class Moc : public Parser { public: Moc() - : noInclude(false), generatedCode(false) + : noInclude(false), generatedCode(false), mustIncludeQMetaTypeH(false) {} QByteArray filename; bool noInclude; bool generatedCode; + bool mustIncludeQMetaTypeH; QByteArray includePath; QList<QByteArray> includeFiles; QList<ClassDef> classList; diff --git a/src/tools/moc/outputrevision.h b/src/tools/moc/outputrevision.h index 0330a02..ee19885 100644 --- a/src/tools/moc/outputrevision.h +++ b/src/tools/moc/outputrevision.h @@ -43,6 +43,6 @@ #define OUTPUTREVISION_H // if the output revision changes, you MUST change it in qobjectdefs.h too -enum { mocOutputRevision = 61 }; // moc format output revision +enum { mocOutputRevision = 62 }; // moc format output revision #endif // OUTPUTREVISION_H diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index 86cac2f..bc58769 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -807,7 +807,7 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) continue; QByteArray frameworkCandidate = include.left(slashPos); frameworkCandidate.append(".framework/Headers/"); - fi.setFile(QString::fromLocal8Bit(p.path + "/" + frameworkCandidate), QString::fromLocal8Bit(include.mid(slashPos + 1))); + fi.setFile(QString::fromLocal8Bit(p.path + '/' + frameworkCandidate), QString::fromLocal8Bit(include.mid(slashPos + 1))); } else { fi.setFile(QString::fromLocal8Bit(p.path), QString::fromLocal8Bit(include)); } |