aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/generator/shiboken2/headergenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/generator/shiboken2/headergenerator.cpp')
-rw-r--r--sources/shiboken2/generator/shiboken2/headergenerator.cpp232
1 files changed, 132 insertions, 100 deletions
diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.cpp b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
index e47c37523..107e28a4a 100644
--- a/sources/shiboken2/generator/shiboken2/headergenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
@@ -45,7 +45,7 @@ QString HeaderGenerator::fileNameSuffix() const
return QLatin1String("_wrapper.h");
}
-QString HeaderGenerator::fileNameForContext(GeneratorContext &context) const
+QString HeaderGenerator::fileNameForContext(const GeneratorContext &context) const
{
const AbstractMetaClass *metaClass = context.metaClass();
if (!context.forSmartPointer()) {
@@ -61,9 +61,9 @@ QString HeaderGenerator::fileNameForContext(GeneratorContext &context) const
void HeaderGenerator::writeCopyCtor(QTextStream &s, const AbstractMetaClass *metaClass) const
{
s << INDENT << wrapperName(metaClass) << "(const " << metaClass->qualifiedCppName() << "& self)";
- s << " : " << metaClass->qualifiedCppName() << "(self)" << endl;
- s << INDENT << "{" << endl;
- s << INDENT << "}" << endl << endl;
+ s << " : " << metaClass->qualifiedCppName() << "(self)\n";
+ s << INDENT << "{\n";
+ s << INDENT << "}\n\n";
}
void HeaderGenerator::writeProtectedFieldAccessors(QTextStream &s, const AbstractMetaField *field) const
@@ -84,18 +84,17 @@ void HeaderGenerator::writeProtectedFieldAccessors(QTextStream &s, const Abstrac
<< (useReference ? " *" : " ")
<< ' ' << protectedFieldGetterName(field) << "()"
<< " { return "
- << (useReference ? " &" : " ") << "this->" << fieldName << "; }" << endl;
+ << (useReference ? " &" : " ") << "this->" << fieldName << "; }\n";
// Set function
s << INDENT << "inline void " << protectedFieldSetterName(field) << '(' << fieldType << " value)"
- << " { " << fieldName << " = value; }" << endl;
+ << " { " << fieldName << " = value; }\n";
}
-void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
+void HeaderGenerator::generateClass(QTextStream &s, const GeneratorContext &classContextIn)
{
- AbstractMetaClass *metaClass = classContext.metaClass();
- if (ReportHandler::isDebug(ReportHandler::SparseDebug))
- qCDebug(lcShiboken) << "Generating header for " << metaClass->fullName();
+ GeneratorContext classContext = classContextIn;
+ const AbstractMetaClass *metaClass = classContext.metaClass();
m_inheritedOverloads.clear();
Indentation indent(INDENT);
@@ -104,45 +103,58 @@ void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classConte
QString wrapperName;
if (!classContext.forSmartPointer()) {
- wrapperName = HeaderGenerator::wrapperName(metaClass);
+ wrapperName = classContext.useWrapper()
+ ? classContext.wrapperName() : metaClass->qualifiedCppName();
} else {
- wrapperName = HeaderGenerator::wrapperName(classContext.preciseType());
+ wrapperName = classContext.smartPointerWrapperName();
}
QString outerHeaderGuard = getFilteredCppSignatureString(wrapperName).toUpper();
QString innerHeaderGuard;
// Header
- s << "#ifndef SBK_" << outerHeaderGuard << "_H" << endl;
- s << "#define SBK_" << outerHeaderGuard << "_H" << endl << endl;
+ s << "#ifndef SBK_" << outerHeaderGuard << "_H\n";
+ s << "#define SBK_" << outerHeaderGuard << "_H\n\n";
if (!avoidProtectedHack())
- s << "#define protected public" << endl << endl;
+ s << "#define protected public\n\n";
//Includes
- s << metaClass->typeEntry()->include() << endl;
+ auto typeEntry = metaClass->typeEntry();
+ s << typeEntry->include() << '\n';
+ if (classContext.useWrapper() && !typeEntry->extraIncludes().isEmpty()) {
+ s << "\n// Extra includes\n";
+ for (const Include &inc : typeEntry->extraIncludes())
+ s << inc.toString() << '\n';
+ }
- if (shouldGenerateCppWrapper(metaClass) &&
- usePySideExtensions() && metaClass->isQObject())
+ if (classContext.useWrapper() && usePySideExtensions() && metaClass->isQObject())
s << "namespace PySide { class DynamicQMetaObject; }\n\n";
- while (shouldGenerateCppWrapper(metaClass)) {
+ while (classContext.useWrapper()) {
if (!innerHeaderGuard.isEmpty()) {
- s << "# ifndef SBK_" << innerHeaderGuard << "_H" << endl;
- s << "# define SBK_" << innerHeaderGuard << "_H" << endl << endl;
- s << "// Inherited base class:" << endl;
+ s << "# ifndef SBK_" << innerHeaderGuard << "_H\n";
+ s << "# define SBK_" << innerHeaderGuard << "_H\n\n";
+ s << "// Inherited base class:\n";
}
// Class
s << "class " << wrapperName;
s << " : public " << metaClass->qualifiedCppName();
- s << endl << '{' << endl << "public:" << endl;
+ s << "\n{\npublic:\n";
const AbstractMetaFunctionList &funcs = filterFunctions(metaClass);
+ int maxOverrides = 0;
for (AbstractMetaFunction *func : funcs) {
- if ((func->attributes() & AbstractMetaAttributes::FinalCppMethod) == 0)
+ if ((func->attributes() & AbstractMetaAttributes::FinalCppMethod) == 0) {
writeFunction(s, func);
+ // PYSIDE-803: Build a boolean cache for unused overrides.
+ if (shouldWriteVirtualMethodNative(func))
+ maxOverrides++;
+ }
}
+ if (!maxOverrides)
+ maxOverrides = 1;
if (avoidProtectedHack() && metaClass->hasProtectedFields()) {
const AbstractMetaFieldList &fields = metaClass->fields();
@@ -160,31 +172,37 @@ void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classConte
s << INDENT;
if (avoidProtectedHack() && metaClass->hasPrivateDestructor())
s << "// C++11: need to declare (unimplemented) destructor because "
- "the base class destructor is private." << endl;
- s << '~' << wrapperName << "();" << endl;
+ "the base class destructor is private.\n";
+ s << '~' << wrapperName << "();\n";
}
- writeCodeSnips(s, metaClass->typeEntry()->codeSnips(), TypeSystem::CodeSnipPositionDeclaration, TypeSystem::NativeCode);
+ writeClassCodeSnips(s, metaClass->typeEntry()->codeSnips(),
+ TypeSystem::CodeSnipPositionDeclaration, TypeSystem::NativeCode,
+ classContext);
if ((!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
&& usePySideExtensions() && metaClass->isQObject()) {
s << "public:\n";
- s << INDENT << "int qt_metacall(QMetaObject::Call call, int id, void **args) override;" << endl;
- s << INDENT << "void *qt_metacast(const char *_clname) override;" << endl;
+ s << INDENT << "int qt_metacall(QMetaObject::Call call, int id, void **args) override;\n";
+ s << INDENT << "void *qt_metacast(const char *_clname) override;\n";
}
if (!m_inheritedOverloads.isEmpty()) {
- s << INDENT << "// Inherited overloads, because the using keyword sux" << endl;
+ s << INDENT << "// Inherited overloads, because the using keyword sux\n";
writeInheritedOverloads(s);
m_inheritedOverloads.clear();
}
if (usePySideExtensions())
- s << INDENT << "static void pysideInitQtMetaTypes();" << endl;
+ s << INDENT << "static void pysideInitQtMetaTypes();\n";
+
+ s << INDENT << "void resetPyMethodCache();\n";
+ s << "private:\n";
+ s << INDENT << "mutable bool m_PyMethodCache[" << maxOverrides << "];\n";
- s << "};" << endl << endl;
+ s << "};\n\n";
if (!innerHeaderGuard.isEmpty())
- s << "# endif // SBK_" << innerHeaderGuard << "_H" << endl << endl;
+ s << "# endif // SBK_" << innerHeaderGuard << "_H\n\n";
// PYSIDE-500: Use also includes for inherited wrapper classes, because
// without the protected hack, we sometimes need to cast inherited wrappers.
@@ -193,16 +211,17 @@ void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classConte
metaClass = metaClass->baseClass();
if (!metaClass || !avoidProtectedHack())
break;
- classContext = GeneratorContext(metaClass);
+ classContext = contextForClass(metaClass);
if (!classContext.forSmartPointer()) {
- wrapperName = HeaderGenerator::wrapperName(metaClass);
+ wrapperName = classContext.useWrapper()
+ ? classContext.wrapperName() : metaClass->qualifiedCppName();
} else {
- wrapperName = HeaderGenerator::wrapperName(classContext.preciseType());
+ wrapperName = classContext.smartPointerWrapperName();
}
innerHeaderGuard = getFilteredCppSignatureString(wrapperName).toUpper();
}
- s << "#endif // SBK_" << outerHeaderGuard << "_H" << endl << endl;
+ s << "#endif // SBK_" << outerHeaderGuard << "_H\n\n";
}
void HeaderGenerator::writeFunction(QTextStream &s, const AbstractMetaFunction *func)
@@ -220,7 +239,8 @@ void HeaderGenerator::writeFunction(QTextStream &s, const AbstractMetaFunction *
s << INDENT << "inline " << (func->isStatic() ? "static " : "");
s << functionSignature(func, QString(), QLatin1String("_protected"), Generator::EnumAsInts|Generator::OriginalTypeDescription)
<< " { ";
- s << (func->type() ? "return " : "");
+ if (!func->isVoid())
+ s << "return ";
if (!func->isAbstract())
s << func->ownerClass()->qualifiedCppName() << "::";
s << func->originalName() << '(';
@@ -238,7 +258,7 @@ void HeaderGenerator::writeFunction(QTextStream &s, const AbstractMetaFunction *
args << argName;
}
s << args.join(QLatin1String(", ")) << ')';
- s << "; }" << endl;
+ s << "; }\n";
}
// pure virtual functions need a default implementation
@@ -263,7 +283,7 @@ void HeaderGenerator::writeFunction(QTextStream &s, const AbstractMetaFunction *
if (virtualFunc)
s << " override";
- s << ';' << endl;
+ s << ";\n";
// Check if this method hide other methods in base classes
const AbstractMetaFunctionList &ownerFuncs = func->ownerClass()->functions();
for (const AbstractMetaFunction *f : ownerFuncs) {
@@ -326,15 +346,16 @@ void HeaderGenerator::writeTypeIndexValueLine(QTextStream &s, const TypeEntry *t
void HeaderGenerator::writeTypeIndexValueLines(QTextStream &s, const AbstractMetaClass *metaClass)
{
- if (!metaClass->typeEntry()->generateCode())
+ auto typeEntry = metaClass->typeEntry();
+ if (!typeEntry->generateCode())
return;
- writeTypeIndexValueLine(s, metaClass->typeEntry());
- const AbstractMetaEnumList &enums = metaClass->enums();
- for (const AbstractMetaEnum *metaEnum : enums) {
- if (metaEnum->isPrivate())
- continue;
- writeTypeIndexValueLine(s, metaEnum->typeEntry());
+ // enum indices are required for invisible namespaces as well.
+ for (const AbstractMetaEnum *metaEnum : metaClass->enums()) {
+ if (!metaEnum->isPrivate())
+ writeTypeIndexValueLine(s, metaEnum->typeEntry());
}
+ if (NamespaceTypeEntry::isVisibleScope(typeEntry))
+ writeTypeIndexValueLine(s, metaClass->typeEntry());
}
// Format the typedefs for the typedef entries to be generated
@@ -377,22 +398,25 @@ bool HeaderGenerator::finishGeneration()
QString protectedEnumSurrogates;
QTextStream protEnumsSurrogates(&protectedEnumSurrogates);
+ const auto snips = TypeDatabase::instance()->defaultTypeSystemType()->codeSnips();
+ if (!snips.isEmpty()) {
+ writeCodeSnips(macrosStream, snips, TypeSystem::CodeSnipPositionDeclaration,
+ TypeSystem::TargetLangCode);
+ }
+
Indentation indent(INDENT);
macrosStream << "// Type indices\nenum : int {\n";
- AbstractMetaEnumList globalEnums = this->globalEnums();
AbstractMetaClassList classList = classes();
std::sort(classList.begin(), classList.end(), [](AbstractMetaClass *a, AbstractMetaClass *b) {
return a->typeEntry()->sbkIndex() < b->typeEntry()->sbkIndex();
});
- for (const AbstractMetaClass *metaClass : classList) {
+ for (const AbstractMetaClass *metaClass : classList)
writeTypeIndexValueLines(macrosStream, metaClass);
- lookForEnumsInClassesNotToBeGenerated(globalEnums, metaClass);
- }
- for (const AbstractMetaEnum *metaEnum : qAsConst(globalEnums))
+ for (const AbstractMetaEnum *metaEnum : globalEnums())
writeTypeIndexValueLine(macrosStream, metaEnum->typeEntry());
// Write the smart pointer define indexes.
@@ -400,9 +424,17 @@ bool HeaderGenerator::finishGeneration()
int smartPointerCount = 0;
const QVector<const AbstractMetaType *> &instantiatedSmartPtrs = instantiatedSmartPointers();
for (const AbstractMetaType *metaType : instantiatedSmartPtrs) {
- _writeTypeIndexValue(macrosStream, getTypeIndexVariableName(metaType),
- smartPointerCountIndex);
- macrosStream << ", // " << metaType->cppSignature() << endl;
+ QString indexName = getTypeIndexVariableName(metaType);
+ _writeTypeIndexValue(macrosStream, indexName, smartPointerCountIndex);
+ macrosStream << ", // " << metaType->cppSignature() << Qt::endl;
+ // Add a the same value for const pointees (shared_ptr<const Foo>).
+ const auto ptrName = metaType->typeEntry()->entryName();
+ int pos = indexName.indexOf(ptrName, 0, Qt::CaseInsensitive);
+ if (pos >= 0) {
+ indexName.insert(pos + ptrName.size() + 1, QLatin1String("CONST"));
+ _writeTypeIndexValue(macrosStream, indexName, smartPointerCountIndex);
+ macrosStream << ", // (const)\n";
+ }
++smartPointerCountIndex;
++smartPointerCount;
}
@@ -412,12 +444,12 @@ bool HeaderGenerator::finishGeneration()
getMaxTypeIndex() + smartPointerCount);
macrosStream << "\n};\n";
- macrosStream << "// This variable stores all Python types exported by this module." << endl;
- macrosStream << "extern PyTypeObject **" << cppApiVariableName() << ';' << endl << endl;
- macrosStream << "// This variable stores the Python module object exported by this module." << endl;
- macrosStream << "extern PyObject *" << pythonModuleObjectName() << ';' << endl << endl;
- macrosStream << "// This variable stores all type converters exported by this module." << endl;
- macrosStream << "extern SbkConverter **" << convertersVariableName() << ';' << endl << endl;
+ macrosStream << "// This variable stores all Python types exported by this module.\n";
+ macrosStream << "extern PyTypeObject **" << cppApiVariableName() << ";\n\n";
+ macrosStream << "// This variable stores the Python module object exported by this module.\n";
+ macrosStream << "extern PyObject *" << pythonModuleObjectName() << ";\n\n";
+ macrosStream << "// This variable stores all type converters exported by this module.\n";
+ macrosStream << "extern SbkConverter **" << convertersVariableName() << ";\n\n";
// TODO-CONVERTER ------------------------------------------------------------------------------
// Using a counter would not do, a fix must be made to APIExtractor's getTypeIndex().
@@ -438,7 +470,7 @@ bool HeaderGenerator::finishGeneration()
const QVector<const AbstractMetaType *> &containers = instantiatedContainers();
for (const AbstractMetaType *container : containers) {
_writeTypeIndexValue(macrosStream, getTypeIndexVariableName(container), pCount);
- macrosStream << ", // " << container->cppSignature() << endl;
+ macrosStream << ", // " << container->cppSignature() << Qt::endl;
pCount++;
}
@@ -453,18 +485,17 @@ bool HeaderGenerator::finishGeneration()
// TODO-CONVERTER ------------------------------------------------------------------------------
- macrosStream << "// Macros for type check" << endl;
+ macrosStream << "// Macros for type check\n";
if (usePySideExtensions()) {
- typeFunctions << "QT_WARNING_PUSH" << endl;
- typeFunctions << "QT_WARNING_DISABLE_DEPRECATED" << endl;
+ typeFunctions << "QT_WARNING_PUSH\n";
+ typeFunctions << "QT_WARNING_DISABLE_DEPRECATED\n";
}
- for (const AbstractMetaEnum *cppEnum : qAsConst(globalEnums)) {
- if (cppEnum->isAnonymous() || cppEnum->isPrivate())
- continue;
- includes << cppEnum->typeEntry()->include();
- writeProtectedEnumSurrogate(protEnumsSurrogates, cppEnum);
- writeSbkTypeFunction(typeFunctions, cppEnum);
+ for (const AbstractMetaEnum *cppEnum : globalEnums()) {
+ if (!cppEnum->isAnonymous()) {
+ includes << cppEnum->typeEntry()->include();
+ writeSbkTypeFunction(typeFunctions, cppEnum);
+ }
}
for (AbstractMetaClass *metaClass : classList) {
@@ -475,8 +506,7 @@ bool HeaderGenerator::finishGeneration()
const TypeEntry *classType = metaClass->typeEntry();
includes << classType->include();
- const AbstractMetaEnumList &enums = metaClass->enums();
- for (const AbstractMetaEnum *cppEnum : enums) {
+ for (const AbstractMetaEnum *cppEnum : metaClass->enums()) {
if (cppEnum->isAnonymous() || cppEnum->isPrivate())
continue;
EnumTypeEntry *enumType = cppEnum->typeEntry();
@@ -495,7 +525,7 @@ bool HeaderGenerator::finishGeneration()
writeSbkTypeFunction(typeFunctions, metaType);
}
if (usePySideExtensions())
- typeFunctions << "QT_WARNING_POP" << endl;
+ typeFunctions << "QT_WARNING_POP\n";
QString moduleHeaderFileName(outputDirectory()
+ QDir::separator() + subDirectoryForPackage(packageName())
@@ -506,61 +536,61 @@ bool HeaderGenerator::finishGeneration()
FileOut file(moduleHeaderFileName);
QTextStream &s = file.stream;
// write license comment
- s << licenseComment() << endl << endl;
+ s << licenseComment() << Qt::endl << Qt::endl;
- s << "#ifndef " << includeShield << endl;
- s << "#define " << includeShield << endl<< endl;
+ s << "#ifndef " << includeShield << Qt::endl;
+ s << "#define " << includeShield << Qt::endl << Qt::endl;
if (!avoidProtectedHack()) {
- s << "//workaround to access protected functions" << endl;
- s << "#define protected public" << endl << endl;
+ s << "//workaround to access protected functions\n";
+ s << "#define protected public\n\n";
}
- s << "#include <sbkpython.h>" << endl;
- s << "#include <sbkconverter.h>" << endl;
+ s << "#include <sbkpython.h>\n";
+ s << "#include <sbkconverter.h>\n";
QStringList requiredTargetImports = TypeDatabase::instance()->requiredTargetImports();
if (!requiredTargetImports.isEmpty()) {
- s << "// Module Includes" << endl;
+ s << "// Module Includes\n";
for (const QString &requiredModule : qAsConst(requiredTargetImports))
- s << "#include <" << getModuleHeaderFileName(requiredModule) << ">" << endl;
- s << endl;
+ s << "#include <" << getModuleHeaderFileName(requiredModule) << ">\n";
+ s << Qt::endl;
}
- s << "// Binded library includes" << endl;
+ s << "// Bound library includes\n";
for (const Include &include : qAsConst(includes))
s << include;
if (!primitiveTypes().isEmpty()) {
- s << "// Conversion Includes - Primitive Types" << endl;
+ s << "// Conversion Includes - Primitive Types\n";
const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes();
for (const PrimitiveTypeEntry *ptype : primitiveTypeList)
s << ptype->include();
- s << endl;
+ s << Qt::endl;
}
if (!containerTypes().isEmpty()) {
- s << "// Conversion Includes - Container Types" << endl;
+ s << "// Conversion Includes - Container Types\n";
const ContainerTypeEntryList &containerTypeList = containerTypes();
for (const ContainerTypeEntry *ctype : containerTypeList)
s << ctype->include();
- s << endl;
+ s << Qt::endl;
}
- s << macros << endl;
+ s << macros << Qt::endl;
if (!protectedEnumSurrogates.isEmpty()) {
- s << "// Protected enum surrogates" << endl;
- s << protectedEnumSurrogates << endl;
+ s << "// Protected enum surrogates\n";
+ s << protectedEnumSurrogates << Qt::endl;
}
- s << "namespace Shiboken" << endl << '{' << endl << endl;
+ s << "namespace Shiboken\n{\n\n";
s << "// PyType functions, to get the PyObjectType for a type T\n";
- s << sbkTypeFunctions << endl;
+ s << sbkTypeFunctions << Qt::endl;
- s << "} // namespace Shiboken" << endl << endl;
+ s << "} // namespace Shiboken\n\n";
- s << "#endif // " << includeShield << endl << endl;
+ s << "#endif // " << includeShield << Qt::endl << Qt::endl;
return file.done() != FileOut::Failure;
}
@@ -568,7 +598,7 @@ bool HeaderGenerator::finishGeneration()
void HeaderGenerator::writeProtectedEnumSurrogate(QTextStream &s, const AbstractMetaEnum *cppEnum)
{
if (avoidProtectedHack() && cppEnum->isProtected())
- s << "enum " << protectedEnumSurrogateName(cppEnum) << " {};" << endl;
+ s << "enum " << protectedEnumSurrogateName(cppEnum) << " {};\n";
}
void HeaderGenerator::writeSbkTypeFunction(QTextStream &s, const AbstractMetaEnum *cppEnum)
@@ -608,8 +638,10 @@ void HeaderGenerator::writeInheritedOverloads(QTextStream &s)
{
for (const AbstractMetaFunction *func : qAsConst(m_inheritedOverloads)) {
s << INDENT << "inline ";
- s << functionSignature(func, QString(), QString(), Generator::EnumAsInts|Generator::OriginalTypeDescription) << " { ";
- s << (func->type() ? "return " : "");
+ s << functionSignature(func, QString(), QString(), Generator::EnumAsInts|Generator::OriginalTypeDescription)
+ << " { ";
+ if (!func->isVoid())
+ s << "return ";
s << func->ownerClass()->qualifiedCppName() << "::" << func->originalName() << '(';
QStringList args;
const AbstractMetaArgumentList &arguments = func->arguments();
@@ -625,6 +657,6 @@ void HeaderGenerator::writeInheritedOverloads(QTextStream &s)
args << argName;
}
s << args.join(QLatin1String(", ")) << ')';
- s << "; }" << endl;
+ s << "; }\n";
}
}