diff options
Diffstat (limited to 'sources/shiboken2/generator/shiboken2/overloaddata.cpp')
-rw-r--r-- | sources/shiboken2/generator/shiboken2/overloaddata.cpp | 130 |
1 files changed, 63 insertions, 67 deletions
diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.cpp b/sources/shiboken2/generator/shiboken2/overloaddata.cpp index 5f74ee64d..193384853 100644 --- a/sources/shiboken2/generator/shiboken2/overloaddata.cpp +++ b/sources/shiboken2/generator/shiboken2/overloaddata.cpp @@ -30,6 +30,7 @@ #include <reporthandler.h> #include <graph.h> #include "overloaddata.h" +#include "ctypenames.h" #include "indentor.h" #include "shibokengenerator.h" @@ -37,6 +38,8 @@ #include <QtCore/QFile> #include <QtCore/QTemporaryFile> +#include <algorithm> + static const TypeEntry *getReferencedTypeEntry(const TypeEntry *typeEntry) { if (typeEntry->isPrimitive()) { @@ -54,8 +57,7 @@ static QString getTypeName(const AbstractMetaType *type) QString typeName = typeEntry->name(); if (typeEntry->isContainer()) { QStringList types; - const AbstractMetaTypeList &instantiations = type->instantiations(); - for (const AbstractMetaType *cType : instantiations) { + for (const auto *cType : type->instantiations()) { const TypeEntry *typeEntry = getReferencedTypeEntry(cType->typeEntry()); types << typeEntry->name(); } @@ -106,7 +108,7 @@ struct OverloadSortData return; map[typeName] = counter; if (!reverseMap.contains(counter)) - reverseMap[counter] = 0; + reverseMap[counter] = nullptr; counter++; } @@ -144,8 +146,7 @@ static QString getImplicitConversionTypeName(const AbstractMetaType *containerTy impConv = getTypeName(function->arguments().constFirst()->type()); QStringList types; - const AbstractMetaTypeList &instantiations = containerType->instantiations(); - for (const AbstractMetaType *otherType : instantiations) + for (const auto *otherType : containerType->instantiations()) types << (otherType == instantiation ? impConv : getTypeName(otherType)); return containerType->typeEntry()->qualifiedCppName() + QLatin1Char('<') @@ -174,6 +175,24 @@ static QString msgCyclicDependency(const QString &funcName, const QString &graph return result; } +static inline int overloadNumber(const OverloadData *o) +{ + return o->referenceFunction()->overloadNumber(); +} + +bool OverloadData::sortByOverloadNumberModification() +{ + if (std::all_of(m_nextOverloadData.cbegin(), m_nextOverloadData.cend(), + [](const OverloadData *o) { return overloadNumber(o) == TypeSystem::OverloadNumberDefault; })) { + return false; + } + std::stable_sort(m_nextOverloadData.begin(), m_nextOverloadData.end(), + [] (const OverloadData *o1, const OverloadData *o2) { + return overloadNumber(o1) < overloadNumber(o2); + }); + return true; +} + /** * Topologically sort the overloads by implicit convertion order * @@ -200,20 +219,16 @@ void OverloadData::sortNextOverloads() // Primitive types that are not int, long, short, // char and their respective unsigned counterparts. - QStringList nonIntegerPrimitives; - nonIntegerPrimitives << QLatin1String("float") << QLatin1String("double") - << QLatin1String("bool"); + static const QStringList nonIntegerPrimitives{floatT(), doubleT(), boolT()}; // Signed integer primitive types. - QStringList signedIntegerPrimitives; - signedIntegerPrimitives << QLatin1String("int") << QLatin1String("short") - << QLatin1String("long"); + static const QStringList signedIntegerPrimitives{intT(), shortT(), longT(), longLongT()}; // sort the children overloads for (OverloadData *ov : qAsConst(m_nextOverloadData)) ov->sortNextOverloads(); - if (m_nextOverloadData.size() <= 1) + if (m_nextOverloadData.size() <= 1 || sortByOverloadNumberModification()) return; // Populates the OverloadSortData object containing map and reverseMap, to map type names to ids, @@ -233,16 +248,15 @@ void OverloadData::sortNextOverloads() } else if (!checkPyBuffer && typeName == QLatin1String("PyBuffer")) { checkPyBuffer = true; pyBufferIndex = sortData.lastProcessedItemId(); - } else if (!checkQVariant && typeName == QLatin1String("QVariant")) { + } else if (!checkQVariant && typeName == qVariantT()) { checkQVariant = true; qvariantIndex = sortData.lastProcessedItemId(); - } else if (!checkQString && typeName == QLatin1String("QString")) { + } else if (!checkQString && typeName == qStringT()) { checkQString = true; qstringIndex = sortData.lastProcessedItemId(); } - const AbstractMetaTypeList &instantiations = ov->argType()->instantiations(); - for (const AbstractMetaType *instantiation : instantiations) { + for (const auto *instantiation : ov->argType()->instantiations()) { // Add dependencies for type instantiation of container. QString typeName = getTypeName(instantiation); sortData.mapType(typeName); @@ -267,23 +281,16 @@ void OverloadData::sortNextOverloads() // Create the graph of type dependencies based on implicit conversions. Graph graph(sortData.reverseMap.count()); // All C++ primitive types, add any forgotten type AT THE END OF THIS LIST! - const char *primitiveTypes[] = {"int", - "unsigned int", - "long", - "unsigned long", - "short", - "unsigned short", - "bool", - "unsigned char", - "char", - "float", - "double", - "const char*" - }; - const int numPrimitives = sizeof(primitiveTypes)/sizeof(const char *); - bool hasPrimitive[numPrimitives]; - for (int i = 0; i < numPrimitives; ++i) - hasPrimitive[i] = sortData.map.contains(QLatin1String(primitiveTypes[i])); + static const QStringList primitiveTypes{intT(), unsignedIntT(), longT(), unsignedLongT(), + shortT(), unsignedShortT(), boolT(), unsignedCharT(), charT(), floatT(), + doubleT(), constCharPtrT()}; + + QList<int> foundPrimitiveTypeIds; + for (const auto &p : primitiveTypes) { + const auto it = sortData.map.constFind(p); + if (it != sortData.map.cend()) + foundPrimitiveTypeIds.append(it.value()); + } if (checkPySequence && checkPyObject) graph.addEdge(pySeqIndex, pyobjectIndex); @@ -306,7 +313,7 @@ void OverloadData::sortNextOverloads() else convertibleType = getTypeName(function->arguments().constFirst()->type()); - if (convertibleType == QLatin1String("int") || convertibleType == QLatin1String("unsigned int")) + if (convertibleType == intT() || convertibleType == unsignedIntT()) classesWithIntegerImplicitConversion << targetTypeEntryName; if (!sortData.map.contains(convertibleType)) @@ -336,8 +343,7 @@ void OverloadData::sortNextOverloads() } // Process template instantiations - const AbstractMetaTypeList &instantiations = targetType->instantiations(); - for (const AbstractMetaType *instantiation : instantiations) { + for (const auto *instantiation : targetType->instantiations()) { if (sortData.map.contains(getTypeName(instantiation))) { int convertible = sortData.map[getTypeName(instantiation)]; @@ -379,12 +385,12 @@ void OverloadData::sortNextOverloads() // Add dependency on PyObject, so its check is the last one (too generic). graph.addEdge(targetTypeId, pyobjectIndex); } - } else if (checkQVariant && targetTypeEntryName != QLatin1String("QVariant")) { + } else if (checkQVariant && targetTypeEntryName != qVariantT()) { if (!graph.containsEdge(qvariantIndex, targetTypeId)) // Avoid cyclic dependency. graph.addEdge(targetTypeId, qvariantIndex); } else if (checkQString && ShibokenGenerator::isPointer(ov->argType()) - && targetTypeEntryName != QLatin1String("QString") - && targetTypeEntryName != QLatin1String("QByteArray") + && targetTypeEntryName != qStringT() + && targetTypeEntryName != qByteArrayT() && (!checkPyObject || targetTypeId != pyobjectIndex)) { if (!graph.containsEdge(qstringIndex, targetTypeId)) // Avoid cyclic dependency. graph.addEdge(targetTypeId, qstringIndex); @@ -392,16 +398,14 @@ void OverloadData::sortNextOverloads() if (targetType->isEnum()) { // Enum values must precede primitive types. - for (int i = 0; i < numPrimitives; ++i) { - if (hasPrimitive[i]) - graph.addEdge(targetTypeId, sortData.map[QLatin1String(primitiveTypes[i])]); - } + for (auto id : foundPrimitiveTypeIds) + graph.addEdge(targetTypeId, id); } } // QByteArray args need to be checked after QString args - if (sortData.map.contains(QLatin1String("QString")) && sortData.map.contains(QLatin1String("QByteArray"))) - graph.addEdge(sortData.map[QLatin1String("QString")], sortData.map[QLatin1String("QByteArray")]); + if (sortData.map.contains(qStringT()) && sortData.map.contains(qByteArrayT())) + graph.addEdge(sortData.map.value(qStringT()), sortData.map.value(qByteArrayT())); for (OverloadData *ov : qAsConst(m_nextOverloadData)) { const AbstractMetaType *targetType = ov->argType(); @@ -571,10 +575,8 @@ QStringList OverloadData::returnTypes() const for (const AbstractMetaFunction *func : m_overloads) { if (!func->typeReplaced(0).isEmpty()) retTypes << func->typeReplaced(0); - else if (func->type() && !func->argumentRemoved(0)) + else if (!func->argumentRemoved(0)) retTypes << func->type()->cppSignature(); - else - retTypes << QLatin1String("void"); } return retTypes.values(); } @@ -864,20 +866,17 @@ QString OverloadData::dumpGraph() const QTextStream s(&result); if (m_argPos == -1) { const AbstractMetaFunction *rfunc = referenceFunction(); - s << "digraph OverloadedFunction {" << endl; - s << INDENT << "graph [fontsize=12 fontname=freemono labelloc=t splines=true overlap=false rankdir=LR];" << endl; + s << "digraph OverloadedFunction {\n"; + s << INDENT << "graph [fontsize=12 fontname=freemono labelloc=t splines=true overlap=false rankdir=LR];\n"; // Shows all function signatures s << "legend [fontsize=9 fontname=freemono shape=rect label=\""; for (const AbstractMetaFunction *func : m_overloads) { - s << "f" << functionNumber(func) << " : "; - if (func->type()) - s << toHtml(func->type()->cppSignature()); - else - s << "void"; - s << ' ' << toHtml(func->minimalSignature()) << "\\l"; + s << "f" << functionNumber(func) << " : " + << toHtml(func->type()->cppSignature()) + << ' ' << toHtml(func->minimalSignature()) << "\\l"; } - s << "\"];" << endl; + s << "\"];\n"; // Function box title s << INDENT << '"' << rfunc->name() << "\" [shape=plaintext style=\"filled,bold\" margin=0 fontname=freemono fillcolor=white penwidth=1 "; @@ -895,12 +894,9 @@ QString OverloadData::dumpGraph() const s << "</td></tr>"; // Function return type - s << "<tr><td bgcolor=\"gray\" align=\"right\">original type</td><td bgcolor=\"gray\" align=\"left\">"; - if (rfunc->type()) - s << toHtml(rfunc->type()->cppSignature()); - else - s << "void"; - s << "</td></tr>"; + s << "<tr><td bgcolor=\"gray\" align=\"right\">original type</td><td bgcolor=\"gray\" align=\"left\">" + << toHtml(rfunc->type()->cppSignature()) + << "</td></tr>"; // Shows type changes for all function signatures for (const AbstractMetaFunction *func : m_overloads) { @@ -930,15 +926,15 @@ QString OverloadData::dumpGraph() const s << 'f' << functionNumber(func) << ' '; s << "</td></tr>"; - s << "</table>> ];" << endl; + s << "</table>> ];\n"; for (const OverloadData *pd : m_nextOverloadData) s << INDENT << '"' << rfunc->name() << "\" -> " << pd->dumpGraph(); - s << "}" << endl; + s << "}\n"; } else { QString argId = QLatin1String("arg_") + QString::number(quintptr(this)); - s << argId << ';' << endl; + s << argId << ";\n"; s << INDENT << '"' << argId << "\" [shape=\"plaintext\" style=\"filled,bold\" margin=\"0\" fontname=\"freemono\" fillcolor=\"white\" penwidth=1 "; s << "label=<<table border=\"0\" cellborder=\"0\" cellpadding=\"3\" bgcolor=\"white\">"; @@ -981,7 +977,7 @@ QString OverloadData::dumpGraph() const } } - s << "</table>>];" << endl; + s << "</table>>];\n"; for (const OverloadData *pd : m_nextOverloadData) s << INDENT << argId << " -> " << pd->dumpGraph(); |