Alien-SmokeQt
view release on metacpan or search on metacpan
generator/generators/smoke/writeSmokeDataFile.cpp view on Meta::CPAN
}
}
// build class index here because the list needs to be sorted
int i = 1;
for (QMap<QString, int>::iterator iter = classIndex.begin(); iter != classIndex.end(); iter++) {
iter.value() = i++;
}
}
bool SmokeDataFile::isClassUsed(const Class* klass)
{
for (QSet<Type*>::const_iterator it = usedTypes.constBegin(); it != usedTypes.constEnd(); it++) {
if ((*it)->getClass() == klass)
return true;
}
return false;
}
QString SmokeDataFile::getTypeFlags(const Type *t, int *classIdx)
{
if (t->getTypedef()) {
Type resolved = t->getTypedef()->resolve();
return getTypeFlags(&resolved, classIdx);
}
QString flags = "0";
if (Options::voidpTypes.contains(t->name())) {
// support some of the weird quirks the kalyptus code has
flags += "|Smoke::t_voidp";
} else if (t->getClass()) {
if (t->getClass()->isTemplate()) {
if (Options::qtMode && t->getClass()->name() == "QFlags" && !t->isRef() && t->pointerDepth() == 0) {
flags += "|Smoke::t_uint";
} else {
flags += "|Smoke::t_voidp";
}
} else {
flags += "|Smoke::t_class";
*classIdx = classIndex.value(t->getClass()->toString(), 0);
}
} else if (t->isIntegral() && t->name() != "void" && t->pointerDepth() == 0 && !t->isRef()) {
flags += "|Smoke::t_";
QString typeName = t->name();
// replace the unsigned stuff, look the type up in Util::typeMap and if
// necessary, add a 'u' for unsigned types at the beginning again
bool _unsigned = false;
if (typeName.startsWith("unsigned ")) {
typeName.replace("unsigned ", "");
_unsigned = true;
}
typeName.replace("signed ", "");
typeName = Util::typeMap.value(typeName, typeName);
if (_unsigned)
typeName.prepend('u');
flags += typeName;
} else if (t->getEnum()) {
flags += "|Smoke::t_enum";
if (t->getEnum()->parent()) {
*classIdx = classIndex.value(t->getEnum()->parent()->toString(), 0);
} else if (!t->getEnum()->nameSpace().isEmpty()) {
*classIdx = classIndex.value(t->getEnum()->nameSpace(), 0);
} else {
*classIdx = classIndex.value("QGlobalSpace", 0);
}
} else {
flags += "|Smoke::t_voidp";
}
if (t->isRef())
flags += "|Smoke::tf_ref";
if (t->pointerDepth() > 0)
flags += "|Smoke::tf_ptr";
if (!t->isRef() && t->pointerDepth() == 0)
flags += "|Smoke::tf_stack";
if (t->isConst())
flags += "|Smoke::tf_const";
flags.replace("0|", "");
return flags;
}
void SmokeDataFile::write()
{
qDebug("writing out smokedata.cpp [%s]", qPrintable(Options::module));
QFile smokedata(Options::outputDir.filePath("smokedata.cpp"));
smokedata.open(QFile::ReadWrite | QFile::Truncate);
QTextStream out(&smokedata);
foreach (const QFileInfo& file, Options::headerList)
out << "#include <" << file.fileName() << ">\n";
out << "\n#include <smoke.h>\n";
out << "#include <" << Options::module << "_smoke.h>\n\n";
QString smokeNamespaceName = "__smoke" + Options::module;
out << "namespace " << smokeNamespaceName << " {\n\n";
// write out Options::module_cast() function
out << "static void *cast(void *xptr, Smoke::Index from, Smoke::Index to) {\n";
out << " switch(from) {\n";
for (QMap<QString, int>::const_iterator iter = classIndex.constBegin(); iter != classIndex.constEnd(); iter++) {
const Class& klass = classes[iter.key()];
if (klass.isNameSpace())
continue;
QSet<int> indices; // avoid duplicate case values (diamond-shaped inheritance)
out << " case " << iter.value() << ": //" << iter.key() << "\n";
out << " switch(to) {\n";
foreach (const Class* base, Util::superClassList(&klass)) {
QString className = base->toString();
if (includedClasses.contains(className) || externalClasses.contains((Class *) base)) {
int index = classIndex[className];
if (indices.contains(index))
continue;
indices << index;
out << QString(" case %1: return (void*)(%2*)(%3*)xptr;\n")
.arg(index).arg(className).arg(klass.toString());
generator/generators/smoke/writeSmokeDataFile.cpp view on Meta::CPAN
out << " }\n";
}
out << " default: return xptr;\n";
out << " }\n";
out << "}\n\n";
// write out the inheritance list
QHash<QVector<int>, int> inheritanceList;
QHash<const Class*, int> inheritanceIndex;
out << "// Group of Indexes (0 separated) used as super class lists.\n";
out << "// Classes with super classes have an index into this array.\n";
out << "static Smoke::Index inheritanceList[] = {\n";
out << " 0,\t// 0: (no super class)\n";
int currentIdx = 1;
for (QMap<QString, int>::const_iterator iter = classIndex.constBegin(); iter != classIndex.constEnd(); iter++) {
Class& klass = classes[iter.key()];
if (!klass.baseClasses().count() || externalClasses.contains(&klass))
continue;
QVector<int> indices;
QStringList comment;
foreach (const Class::BaseClassSpecifier& base, klass.baseClasses()) {
if (base.access == Access_private)
continue;
QString className = base.baseClass->toString();
indices << classIndex[className];
comment << className;
}
if (indices.count() == 0)
continue;
int idx = 0;
if (!inheritanceList.contains(indices)) {
idx = currentIdx;
inheritanceList[indices] = idx;
out << " ";
for (int i = 0; i < indices.count(); i++) {
if (i > 0) out << ", ";
out << indices[i];
currentIdx++;
}
currentIdx++;
out << ", 0,\t// " << idx << ": " << comment.join(", ") << "\n";
} else {
idx = inheritanceList[indices];
}
// store the index into inheritanceList for the class
inheritanceIndex[&klass] = idx;
}
out << "};\n\n";
// xenum functions
out << "// These are the xenum functions for manipulating enum pointers\n";
QSet<QString> enumClassesHandled;
for (QHash<QString, Enum>::const_iterator it = enums.constBegin(); it != enums.constEnd(); it++) {
if (!it.value().isValid())
continue;
QString smokeClassName;
if (it.value().parent()) {
smokeClassName = it.value().parent()->toString();
} else {
smokeClassName = it.value().nameSpace();
}
if (!smokeClassName.isEmpty() && includedClasses.contains(smokeClassName) && it.value().access() != Access_private) {
if (enumClassesHandled.contains(smokeClassName) || Options::voidpTypes.contains(smokeClassName))
continue;
enumClassesHandled << smokeClassName;
smokeClassName.replace("::", "__");
out << "void xenum_" << smokeClassName << "(Smoke::EnumOperation, Smoke::Index, void*&, long&);\n";
} else if (smokeClassName.isEmpty() && it.value().access() != Access_private) {
if (enumClassesHandled.contains("QGlobalSpace"))
continue;
out << "void xenum_QGlobalSpace(Smoke::EnumOperation, Smoke::Index, void*&, long&);\n";
enumClassesHandled << "QGlobalSpace";
}
}
// xcall functions
out << "\n// Those are the xcall functions defined in each x_*.cpp file, for dispatching method calls\n";
for (QMap<QString, int>::const_iterator iter = classIndex.constBegin(); iter != classIndex.constEnd(); iter++) {
Class& klass = classes[iter.key()];
if (externalClasses.contains(&klass) || klass.isTemplate())
continue;
QString smokeClassName = QString(klass.toString()).replace("::", "__");
out << "void xcall_" << smokeClassName << "(Smoke::Index, void*, Smoke::Stack);\n";
}
// classes table
out << "\n// List of all classes\n";
out << "// Name, external, index into inheritanceList, method dispatcher, enum dispatcher, class flags, size\n";
out << "static Smoke::Class classes[] = {\n";
out << " { 0L, false, 0, 0, 0, 0, 0 },\t// 0 (no class)\n";
int classCount = 0;
for (QMap<QString, int>::const_iterator iter = classIndex.constBegin(); iter != classIndex.constEnd(); iter++) {
if (!iter.value())
continue;
Class* klass = &classes[iter.key()];
if (externalClasses.contains(klass)) {
out << " { \"" << iter.key() << "\", true, 0, 0, 0, 0, 0 },\t//" << iter.value() << "\n";
} else {
QString smokeClassName = QString(iter.key()).replace("::", "__");
out << " { \"" << iter.key() << "\", false" << ", "
<< inheritanceIndex.value(klass, 0) << ", xcall_" << smokeClassName << ", "
<< (enumClassesHandled.contains(iter.key()) ? QString("xenum_").append(smokeClassName) : "0") << ", ";
QString flags = "0";
if (!klass->isNameSpace()) {
if (Util::canClassBeInstanciated(klass)) flags += "|Smoke::cf_constructor";
if (Util::canClassBeCopied(klass)) flags += "|Smoke::cf_deepcopy";
if (Util::hasClassVirtualDestructor(klass)) flags += "|Smoke::cf_virtual";
flags.replace("0|", ""); // beautify
} else {
flags = "Smoke::cf_namespace";
}
out << flags << ", ";
if (!klass->isNameSpace())
out << "sizeof(" << iter.key() << ")";
else
generator/generators/smoke/writeSmokeDataFile.cpp view on Meta::CPAN
// comment
out << " // " << klass->toString() << "::" << member->name();
const Method* meth = 0;
if ((meth = dynamic_cast<const Method*>(member))) {
out << '(';
for (int j = 0; j < meth->parameters().count(); j++) {
if (j > 0) out << ", ";
out << meth->parameters()[j].type()->toString();
}
out << ')';
if (meth->isConst()) out << " const";
}
out << "\n";
}
out << " 0,\n";
ambigiousIds[klass][munged_it.key()] = i;
i += munged_it.value().size() + 1;
}
}
out << "};\n\n";
int methodMapCount = 1;
out << "// Class ID, munged name ID (index into methodNames), method def (see methods) if >0 or number of overloads if <0\n";
out << "static Smoke::MethodMap methodMaps[] = {\n";
out << " {0, 0, 0},\t//0 (no method)\n";
for (QMap<QString, int>::const_iterator iter = classIndex.constBegin(); iter != classIndex.constEnd(); iter++) {
Class* klass = &classes[iter.key()];
if (externalClasses.contains(klass))
continue;
QMap<QString, QList<const Member*> >& map = classMungedNames[klass];
for (QMap<QString, QList<const Member*> >::const_iterator munged_it = map.constBegin(); munged_it != map.constEnd(); munged_it++) {
// class index, munged name index
out << " {" << classIndex[iter.key()] << ", " << methodNames[munged_it.key()] << ", ";
// if there's only one matching method for this class and the munged name, insert the index into methodss
if (munged_it.value().size() == 1) {
out << methodIdx[munged_it.value().first()];
} else {
// negative index into ambigious methods list
out << '-' << ambigiousIds[klass][munged_it.key()];
}
out << "},";
// comment
out << "\t// " << klass->toString() << "::" << munged_it.key();
out << "\n";
methodMapCount++;
}
}
out << "};\n\n";
out << "}\n\n";
out << "extern \"C\" {\n\n";
for (int j = 0; j < Options::parentModules.count(); j++) {
out << "SMOKE_IMPORT void init_" << Options::parentModules[j] << "_Smoke();\n";
if (j == Options::parentModules.count() - 1)
out << "\n";
}
out << "static bool initialized = false;\n";
out << "Smoke *" << Options::module << "_Smoke = 0;\n\n";
out << "// Create the Smoke instance encapsulating all the above.\n";
out << "void init_" << Options::module << "_Smoke() {\n";
foreach (const QString& str, Options::parentModules) {
out << " init_" << str << "_Smoke();\n";
}
out << " if (initialized) return;\n";
out << " " << Options::module << "_Smoke = new Smoke(\n";
out << " \"" << Options::module << "\",\n";
out << " " << smokeNamespaceName << "::classes, " << classCount << ",\n";
out << " " << smokeNamespaceName << "::methods, " << methodCount << ",\n";
out << " " << smokeNamespaceName << "::methodMaps, " << methodMapCount << ",\n";
out << " " << smokeNamespaceName << "::methodNames, " << methodNames.count() << ",\n";
out << " " << smokeNamespaceName << "::types, " << typeIndex.count() << ",\n";
out << " " << smokeNamespaceName << "::inheritanceList,\n";
out << " " << smokeNamespaceName << "::argumentList,\n";
out << " " << smokeNamespaceName << "::ambiguousMethodList,\n";
out << " " << smokeNamespaceName << "::cast );\n";
out << " initialized = true;\n";
out << "}\n\n";
out << "void delete_" << Options::module << "_Smoke() { delete " << Options::module << "_Smoke; }\n\n";
out << "}\n";
smokedata.close();
}
( run in 2.705 seconds using v1.01-cache-2.11-cpan-140bd7fdf52 )