summaryrefslogtreecommitdiffstats
path: root/src/tools/moc
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/moc')
-rw-r--r--src/tools/moc/generator.cpp41
-rw-r--r--src/tools/moc/moc.cpp60
-rw-r--r--src/tools/moc/moc.h7
-rw-r--r--src/tools/moc/outputrevision.h2
-rw-r--r--src/tools/moc/preprocessor.cpp2
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));
}