From 8d1514a95f27199b9a8dc850752bb645bda1bb3e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 28 Sep 2022 13:27:54 +0200 Subject: shiboken6: Add an option to print primitive type entries This is useful for checking type resolution. Complements 92943cbb530edb4fd8b7292b3b0ea964d7a6fdde. Task-number: PYSIDE-2065 Change-Id: Ia1427787221ac90cf7f923b3eac4972ee206677e Reviewed-by: Cristian Maureira-Fredes --- sources/shiboken6/ApiExtractor/typedatabase.cpp | 87 ++++++++++++++++++++++ sources/shiboken6/ApiExtractor/typedatabase.h | 1 + sources/shiboken6/doc/shibokengenerator.rst | 3 + sources/shiboken6/generator/main.cpp | 11 +++ .../shiboken6/tests/samplebinding/CMakeLists.txt | 2 +- 5 files changed, 103 insertions(+), 1 deletion(-) diff --git a/sources/shiboken6/ApiExtractor/typedatabase.cpp b/sources/shiboken6/ApiExtractor/typedatabase.cpp index 50f20b1f3..fc1e935a7 100644 --- a/sources/shiboken6/ApiExtractor/typedatabase.cpp +++ b/sources/shiboken6/ApiExtractor/typedatabase.cpp @@ -138,6 +138,7 @@ struct TypeDatabasePrivate bool isSuppressedWarningHelper(const String &s) const; bool resolveSmartPointerInstantiations(const TypeDatabaseParserContextPtr &context); void formatDebug(QDebug &d) const; + void formatBuiltinTypes(QDebug &d) const; bool m_suppressWarnings = true; TypeEntryMultiMap m_entries; // Contains duplicate entries (cf addInlineNamespaceLookups). @@ -1298,6 +1299,92 @@ void TypeDatabasePrivate::formatDebug(QDebug &d) const d << ')'; } +// Helpers for dumping out primitive type info + +struct formatPrimitiveEntry +{ + explicit formatPrimitiveEntry(const PrimitiveTypeEntry *e) : m_pe(e) {} + + const PrimitiveTypeEntry *m_pe; +}; + +QDebug operator<<(QDebug debug, const formatPrimitiveEntry &fe) +{ + QDebugStateSaver saver(debug); + debug.noquote(); + debug.nospace(); + const QString &name = fe.m_pe->name(); + const QString &targetLangName = fe.m_pe->targetLangApiName(); + debug << '"' << name << '"'; + if (name != targetLangName) + debug << " (\"" << targetLangName << "\")"; + if (fe.m_pe->isBuiltIn()) + debug << " [builtin]"; + if (fe.m_pe->isExtendedCppPrimitive()) { + debug << " ["; + if (!fe.m_pe->isCppPrimitive()) + debug << "extended "; + debug << "C++]"; + } + return debug; +} + +// Sort primitive types for displaying; base type and typedef'ed types +struct PrimitiveFormatListEntry +{ + const PrimitiveTypeEntry *baseType; + PrimitiveTypeEntryList typedefs; +}; + +static bool operator<(const PrimitiveFormatListEntry &e1, const PrimitiveFormatListEntry &e2) +{ + return e1.baseType->name() < e2.baseType->name(); +} + +using PrimitiveFormatListEntries = QList; + +static qsizetype indexOf(const PrimitiveFormatListEntries &e, const PrimitiveTypeEntry *needle) +{ + for (qsizetype i = 0, size = e.size(); i < size; ++i) { + if (e.at(i).baseType == needle) + return i; + } + return -1; +} + +void TypeDatabase::formatBuiltinTypes(QDebug debug) const +{ + QDebugStateSaver saver(debug); + debug.noquote(); + debug.nospace(); + + // Determine base types and their typedef'ed types + QList primitiveEntries; + for (auto *e : qAsConst(d->m_entries)) { + if (e->isPrimitive()) { + auto *pe = static_cast(e); + auto *basic = pe->basicReferencedTypeEntry(); + if (basic != pe) { + const auto idx = indexOf(primitiveEntries, basic); + if (idx != -1) + primitiveEntries[idx].typedefs.append(pe); + else + primitiveEntries.append(PrimitiveFormatListEntry{basic, {pe}}); + } else { + primitiveEntries.append(PrimitiveFormatListEntry{pe, {}}); + } + } + } + + std::sort(primitiveEntries.begin(), primitiveEntries.end()); + + for (const auto &e : qAsConst(primitiveEntries)) { + debug << "Primitive: " << formatPrimitiveEntry(e.baseType) << '\n'; + for (auto *pe : e.typedefs) + debug << " " << formatPrimitiveEntry(pe) << '\n'; + } +} + void TypeDatabasePrivate::addBuiltInType(TypeEntry *e) { e->setBuiltIn(true); diff --git a/sources/shiboken6/ApiExtractor/typedatabase.h b/sources/shiboken6/ApiExtractor/typedatabase.h index af53971a1..2cf0070a1 100644 --- a/sources/shiboken6/ApiExtractor/typedatabase.h +++ b/sources/shiboken6/ApiExtractor/typedatabase.h @@ -200,6 +200,7 @@ public: #ifndef QT_NO_DEBUG_STREAM void formatDebug(QDebug &d) const; #endif + void formatBuiltinTypes(QDebug debug) const; private: TypeDatabasePrivate *d; diff --git a/sources/shiboken6/doc/shibokengenerator.rst b/sources/shiboken6/doc/shibokengenerator.rst index ddb95feec..6fb0948db 100644 --- a/sources/shiboken6/doc/shibokengenerator.rst +++ b/sources/shiboken6/doc/shibokengenerator.rst @@ -258,6 +258,9 @@ Options ``--help`` Display this help and exit. +``--print-builtin-types`` + Print information about builtin types + .. _version: ``--version`` diff --git a/sources/shiboken6/generator/main.cpp b/sources/shiboken6/generator/main.cpp index e9fcd0571..eca3b164b 100644 --- a/sources/shiboken6/generator/main.cpp +++ b/sources/shiboken6/generator/main.cpp @@ -50,6 +50,7 @@ static inline QString diffOption() { return QStringLiteral("diff"); } static inline QString useGlobalHeaderOption() { return QStringLiteral("use-global-header"); } static inline QString dryrunOption() { return QStringLiteral("dry-run"); } static inline QString skipDeprecatedOption() { return QStringLiteral("skip-deprecated"); } +static inline QString printBuiltinTypesOption() { return QStringLiteral("print-builtin-types"); } static const char helpHint[] = "Note: use --help or -h for more information.\n"; @@ -390,6 +391,8 @@ void printUsage() {u"-T"_s, {} }, {u"typesystem-paths="_s + pathSyntax, u"Paths used when searching for typesystems"_s}, + {printBuiltinTypesOption(), + u"Print information about builtin types"_s}, {u"version"_s, u"Output version information and exit"_s} }; @@ -620,6 +623,11 @@ int shibokenMain(int argc, char *argv[]) args.options.erase(ait); } + ait = args.options.find(printBuiltinTypesOption()); + const bool printBuiltinTypes = ait != args.options.end(); + if (printBuiltinTypes) + args.options.erase(ait); + ait = args.options.find(compilerPathOption()); if (ait != args.options.end()) { clang::setCompilerPath(ait.value().toString()); @@ -735,6 +743,9 @@ int shibokenMain(int argc, char *argv[]) << "\n\nType datase:\n" << *TypeDatabase::instance(); } + if (printBuiltinTypes) + TypeDatabase::instance()->formatBuiltinTypes(qInfo()); + for (const GeneratorPtr &g : qAsConst(generators)) { g->setOutputDirectory(outputDirectory); g->setLicenseComment(licenseComment); diff --git a/sources/shiboken6/tests/samplebinding/CMakeLists.txt b/sources/shiboken6/tests/samplebinding/CMakeLists.txt index 7576f6734..7480ed04f 100644 --- a/sources/shiboken6/tests/samplebinding/CMakeLists.txt +++ b/sources/shiboken6/tests/samplebinding/CMakeLists.txt @@ -145,7 +145,7 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/sample-binding.txt.in" add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log" BYPRODUCTS ${sample_SRC} -COMMAND Shiboken6::shiboken6 --project-file=${CMAKE_CURRENT_BINARY_DIR}/sample-binding.txt ${GENERATOR_EXTRA_FLAGS} +COMMAND Shiboken6::shiboken6 --print-builtin-types --project-file=${CMAKE_CURRENT_BINARY_DIR}/sample-binding.txt ${GENERATOR_EXTRA_FLAGS} DEPENDS ${sample_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h Shiboken6::shiboken6 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Running generator for 'sample' test binding..." -- cgit v1.2.3