void Moc::parseFunctionArguments(FunctionDef *def) { Q_UNUSED(def); while (hasNext()) { ArgumentDef arg; arg.type = parseType(); if (arg.type.name == "void") break; if (test(IDENTIFIER)) arg.name = lexem(); while (test(LBRACK)) { arg.rightType += lexemUntil(RBRACK); } if (test(CONST) || test(VOLATILE)) { arg.rightType += ' '; arg.rightType += lexem(); } arg.normalizedType = normalizeType(arg.type.name + ' ' + arg.rightType); arg.typeNameForCast = normalizeType(noRef(arg.type.name) + "(*)" + arg.rightType); if (test(EQ)) arg.isDefault = true; def->arguments += arg; if (!until(COMMA)) break; } }
void Generator::generateSignal(FunctionDef *def,int index) { if (def->wasCloned || def->isAbstract) return; fprintf(out, "\n// SIGNAL %d\n%s %s::%s(", index, def->type.name.constData(), cdef->qualified.constData(), def->name.constData()); QByteArray thisPtr = "this"; const char *constQualifier = ""; if (def->isConst) { thisPtr = "const_cast< "; thisPtr += cdef->qualified; thisPtr += " *>(this)"; constQualifier = "const"; } if (def->arguments.isEmpty() && def->normalizedType.isEmpty()) { fprintf(out, ")%s\n{\n" " QMetaObject::activate(%s, &staticMetaObject, %d, 0);\n" "}\n", constQualifier, thisPtr.constData(), index); return; } int offset = 1; for (int j = 0; j < def->arguments.count(); ++j) { const ArgumentDef &a = def->arguments.at(j); if (j) fprintf(out, ", "); fprintf(out, "%s _t%d%s", a.type.name.constData(), offset++, a.rightType.constData()); } fprintf(out, ")%s\n{\n", constQualifier); if (def->type.name.size() && def->normalizedType.size()) fprintf(out, " %s _t0;\n", noRef(def->normalizedType).constData()); fprintf(out, " void *_a[] = { "); if (def->normalizedType.isEmpty()) { fprintf(out, "0"); } else { if (def->returnTypeIsVolatile) fprintf(out, "const_cast<void*>(reinterpret_cast<const volatile void*>(&_t0))"); else fprintf(out, "const_cast<void*>(reinterpret_cast<const void*>(&_t0))"); } int i; for (i = 1; i < offset; ++i) if (def->arguments.at(i - 1).type.isVolatile) fprintf(out, ", const_cast<void*>(reinterpret_cast<const volatile void*>(&_t%d))", i); else fprintf(out, ", const_cast<void*>(reinterpret_cast<const void*>(&_t%d))", i); fprintf(out, " };\n"); int n = 0; for (i = 0; i < def->arguments.count(); ++i) if (def->arguments.at(i).isDefault) ++n; if (n) fprintf(out, " QMetaObject::activate(%s, &staticMetaObject, %d, %d, _a);\n", thisPtr.constData(), index, index + n); else fprintf(out, " QMetaObject::activate(%s, &staticMetaObject, %d, _a);\n", thisPtr.constData(), index); if (def->normalizedType.size()) fprintf(out, " return _t0;\n"); fprintf(out, "}\n"); }
void Generator::generateMetacall() { bool isQObject = (cdef->classname == "QObject"); fprintf(out, "\nint %s::qt_metacall(QMetaObject::Call _c, int _id, void **_a)\n{\n", cdef->qualified.constData()); if (!purestSuperClass.isEmpty() && !isQObject) { QByteArray superClass = purestSuperClass; // workaround for VC6 if (superClass.contains("::")) { fprintf(out, " typedef %s QMocSuperClass;\n", superClass.constData()); superClass = "QMocSuperClass"; } fprintf(out, " _id = %s::qt_metacall(_c, _id, _a);\n", superClass.constData()); } fprintf(out, " if (_id < 0)\n return _id;\n"); fprintf(out, " "); bool needElse = false; QList<FunctionDef> methodList; methodList += cdef->signalList; methodList += cdef->slotList; methodList += cdef->methodList; if (methodList.size()) { needElse = true; fprintf(out, "if (_c == QMetaObject::InvokeMetaMethod) {\n "); fprintf(out, "switch (_id) {\n"); for (int methodindex = 0; methodindex < methodList.size(); ++methodindex) { const FunctionDef &f = methodList.at(methodindex); fprintf(out, " case %d: ", methodindex); if (f.normalizedType.size()) fprintf(out, "{ %s _r = ", noRef(f.normalizedType).constData()); if (f.inPrivateClass.size()) fprintf(out, "%s->", f.inPrivateClass.constData()); fprintf(out, "%s(", f.name.constData()); int offset = 1; for (int j = 0; j < f.arguments.count(); ++j) { const ArgumentDef &a = f.arguments.at(j); if (j) fprintf(out, ","); fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))",a.typeNameForCast.constData(), offset++); } fprintf(out, ");"); if (f.normalizedType.size()) fprintf(out, "\n if (_a[0]) *reinterpret_cast< %s*>(_a[0]) = _r; } ", noRef(f.normalizedType).constData()); fprintf(out, " break;\n"); } fprintf(out, " default: ;\n"); fprintf(out, " }\n"); } if (methodList.size()) fprintf(out, " _id -= %d;\n }", methodList.size()); if (cdef->propertyList.size()) { bool needGet = false; bool needTempVarForGet = false; bool needSet = false; bool needReset = false; bool needDesignable = false; bool needScriptable = false; bool needStored = false; bool needEditable = false; bool needUser = false; for (int i = 0; i < cdef->propertyList.size(); ++i) { const PropertyDef &p = cdef->propertyList.at(i); needGet |= !p.read.isEmpty(); if (!p.read.isEmpty()) needTempVarForGet |= (p.gspec != PropertyDef::PointerSpec && p.gspec != PropertyDef::ReferenceSpec); needSet |= !p.write.isEmpty(); needReset |= !p.reset.isEmpty(); needDesignable |= p.designable.endsWith(')'); needScriptable |= p.scriptable.endsWith(')'); needStored |= p.stored.endsWith(')'); needEditable |= p.editable.endsWith(')'); needUser |= p.user.endsWith(')'); } bool needAnything = needGet | needSet | needReset | needDesignable | needScriptable | needStored | needEditable | needUser; if (!needAnything) goto skip_properties; fprintf(out, "\n#ifndef QT_NO_PROPERTIES\n "); if (needElse) fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::ReadProperty) {\n"); if (needGet) { if (needTempVarForGet) fprintf(out, " void *_v = _a[0];\n"); fprintf(out, " switch (_id) {\n"); for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { const PropertyDef &p = cdef->propertyList.at(propindex); if (p.read.isEmpty()) continue; if (p.gspec == PropertyDef::PointerSpec) fprintf(out, " case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(%s())); break;\n", propindex, p.read.constData()); else if (p.gspec == PropertyDef::ReferenceSpec) fprintf(out, " case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(&%s())); break;\n", propindex, p.read.constData()); else if (cdef->enumDeclarations.value(p.type, false)) fprintf(out, " case %d: *reinterpret_cast<int*>(_v) = QFlag(%s()); break;\n", propindex, p.read.constData()); else fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s(); break;\n", propindex, p.type.constData(), p.read.constData()); } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::WriteProperty) {\n"); if (needSet) { fprintf(out, " void *_v = _a[0];\n"); fprintf(out, " switch (_id) {\n"); for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { const PropertyDef &p = cdef->propertyList.at(propindex); if (p.write.isEmpty()) continue; if (cdef->enumDeclarations.value(p.type, false)) { fprintf(out, " case %d: %s(QFlag(*reinterpret_cast<int*>(_v))); break;\n", propindex, p.write.constData()); } else { fprintf(out, " case %d: %s(*reinterpret_cast< %s*>(_v)); break;\n", propindex, p.write.constData(), p.type.constData()); } } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::ResetProperty) {\n"); if (needReset) { fprintf(out, " switch (_id) {\n"); for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { const PropertyDef &p = cdef->propertyList.at(propindex); if (!p.reset.endsWith(')')) continue; fprintf(out, " case %d: %s; break;\n", propindex, p.reset.constData()); } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::QueryPropertyDesignable) {\n"); if (needDesignable) { fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n"); fprintf(out, " switch (_id) {\n"); for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { const PropertyDef &p = cdef->propertyList.at(propindex); if (!p.designable.endsWith(')')) continue; fprintf(out, " case %d: *_b = %s; break;\n", propindex, p.designable.constData()); } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::QueryPropertyScriptable) {\n"); if (needScriptable) { fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n"); fprintf(out, " switch (_id) {\n"); for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { const PropertyDef &p = cdef->propertyList.at(propindex); if (!p.scriptable.endsWith(')')) continue; fprintf(out, " case %d: *_b = %s; break;\n", propindex, p.scriptable.constData()); } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::QueryPropertyStored) {\n"); if (needStored) { fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n"); fprintf(out, " switch (_id) {\n"); for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { const PropertyDef &p = cdef->propertyList.at(propindex); if (!p.stored.endsWith(')')) continue; fprintf(out, " case %d: *_b = %s; break;\n", propindex, p.stored.constData()); } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::QueryPropertyEditable) {\n"); if (needEditable) { fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n"); fprintf(out, " switch (_id) {\n"); for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { const PropertyDef &p = cdef->propertyList.at(propindex); if (!p.editable.endsWith(')')) continue; fprintf(out, " case %d: *_b = %s; break;\n", propindex, p.editable.constData()); } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::QueryPropertyUser) {\n"); if (needUser) { fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n"); fprintf(out, " switch (_id) {\n"); for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { const PropertyDef &p = cdef->propertyList.at(propindex); if (!p.user.endsWith(')')) continue; fprintf(out, " case %d: *_b = %s; break;\n", propindex, p.user.constData()); } fprintf(out, " }\n"); } fprintf(out, " _id -= %d;\n" " }", cdef->propertyList.count()); fprintf(out, "\n#endif // QT_NO_PROPERTIES"); } skip_properties: if (methodList.size() || cdef->signalList.size() || cdef->propertyList.size()) fprintf(out, "\n "); fprintf(out,"return _id;\n}\n"); }