aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/ApiExtractor/apiextractor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/ApiExtractor/apiextractor.cpp')
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractor.cpp436
1 files changed, 284 insertions, 152 deletions
diff --git a/sources/shiboken6/ApiExtractor/apiextractor.cpp b/sources/shiboken6/ApiExtractor/apiextractor.cpp
index d18758fe8..83ee4437e 100644
--- a/sources/shiboken6/ApiExtractor/apiextractor.cpp
+++ b/sources/shiboken6/ApiExtractor/apiextractor.cpp
@@ -3,7 +3,6 @@
#include "apiextractor.h"
#include "apiextractorresult.h"
-#include "apiextractorresultdata_p.h"
#include "abstractmetaargument.h"
#include "abstractmetabuilder.h"
#include "abstractmetaenum.h"
@@ -12,8 +11,9 @@
#include "abstractmetalang.h"
#include "codesnip.h"
#include "exception.h"
-#include "fileout.h"
+#include "messages.h"
#include "modifications.h"
+#include "optionsparser.h"
#include "reporthandler.h"
#include "typedatabase.h"
#include "customconversion.h"
@@ -21,6 +21,7 @@
#include "primitivetypeentry.h"
#include "smartpointertypeentry.h"
#include "typedefentry.h"
+#include "namespacetypeentry.h"
#include "typesystemtypeentry.h"
#include "qtcompat.h"
@@ -40,136 +41,250 @@ struct InstantiationCollectContext
AbstractMetaTypeList instantiatedContainers;
InstantiatedSmartPointers instantiatedSmartPointers;
QStringList instantiatedContainersNames;
- QList<const TypeEntry *> m_synthesizedTypeEntries;
};
-struct ApiExtractorPrivate
+struct ApiExtractorOptions
{
- bool runHelper(ApiExtractorFlags flags);
-
- static QString getSimplifiedContainerTypeName(const AbstractMetaType &type);
- void addInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context,
- const AbstractMetaType &type,
- const QString &contextName);
- void collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context,
- const AbstractMetaFunctionCPtr &func);
- void collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context,
- const AbstractMetaClass *metaClass);
- void collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context);
- void collectInstantiatedOpqaqueContainers(InstantiationCollectContext &context);
- void collectContainerTypesFromSnippets(InstantiationCollectContext &context);
- void collectContainerTypesFromConverterMacros(InstantiationCollectContext &context,
- const QString &code,
- bool toPythonMacro);
- void addInstantiatedSmartPointer(InstantiationCollectContext &context,
- const AbstractMetaType &type);
-
QString m_typeSystemFileName;
QFileInfoList m_cppFileNames;
HeaderPaths m_includePaths;
QStringList m_clangOptions;
- AbstractMetaBuilder* m_builder = nullptr;
QString m_logDirectory;
LanguageLevel m_languageLevel = LanguageLevel::Default;
bool m_skipDeprecated = false;
};
-ApiExtractor::ApiExtractor() :
- d(new ApiExtractorPrivate)
+static inline QString languageLevelDescription()
{
- // Environment TYPESYSTEMPATH
- QString envTypesystemPaths = QFile::decodeName(qgetenv("TYPESYSTEMPATH"));
- if (!envTypesystemPaths.isEmpty())
- TypeDatabase::instance()->addTypesystemPath(envTypesystemPaths);
+ return u"C++ Language level (c++11..c++17, default="_s
+ + QLatin1StringView(clang::languageLevelOption(clang::emulatedCompilerLanguageLevel()))
+ + u')';
}
-ApiExtractor::~ApiExtractor()
+QList<OptionDescription> ApiExtractor::options()
{
- delete d->m_builder;
- delete d;
+ return {
+ {u"use-global-header"_s,
+ u"Use the global headers in generated code."_s},
+ {u"clang-option"_s,
+ u"Option to be passed to clang"_s},
+ {u"clang-options"_s,
+ u"A comma-separated list of options to be passed to clang"_s},
+ {u"skip-deprecated"_s,
+ u"Skip deprecated functions"_s},
+ {u"-F<path>"_s, {} },
+ {u"framework-include-paths="_s + OptionsParser::pathSyntax(),
+ u"Framework include paths used by the C++ parser"_s},
+ {u"-isystem<path>"_s, {} },
+ {u"system-include-paths="_s + OptionsParser::pathSyntax(),
+ u"System include paths used by the C++ parser"_s},
+ {u"language-level=, -std=<level>"_s,
+ languageLevelDescription()},
+ };
}
-void ApiExtractor::addTypesystemSearchPath (const QString& path)
+class ApiExtractorOptionsParser : public OptionsParser
{
- TypeDatabase::instance()->addTypesystemPath(path);
-}
+public:
+ explicit ApiExtractorOptionsParser(ApiExtractorOptions *o) : m_options(o) {}
-void ApiExtractor::addTypesystemSearchPath(const QStringList& paths)
+ bool handleBoolOption(const QString &key, OptionSource source) override;
+ bool handleOption(const QString &key, const QString &value,
+ OptionSource source) override;
+
+private:
+ void parseIncludePathOption(const QString &value, HeaderType headerType);
+ void parseIncludePathOption(const QStringList &values, HeaderType headerType);
+ void setLanguageLevel(const QString &value);
+
+ ApiExtractorOptions *m_options;
+};
+
+void ApiExtractorOptionsParser::parseIncludePathOption(const QString &value,
+ HeaderType headerType)
{
- for (const QString &path : paths)
- addTypesystemSearchPath(path);
+ if (value.isEmpty())
+ throw Exception(u"Empty value passed to include path option"_s);
+ const auto path = QFile::encodeName(QDir::cleanPath(value));
+ m_options->m_includePaths.append(HeaderPath{path, headerType});
}
-void ApiExtractor::setTypesystemKeywords(const QStringList &keywords)
+void ApiExtractorOptionsParser::parseIncludePathOption(const QStringList &values,
+ HeaderType headerType)
{
- TypeDatabase::instance()->setTypesystemKeywords(keywords);
+ for (const auto &value : values)
+ parseIncludePathOption(value, headerType);
}
-void ApiExtractor::addIncludePath(const HeaderPath& path)
+void ApiExtractorOptionsParser::setLanguageLevel(const QString &value)
{
- d->m_includePaths << path;
+ const QByteArray languageLevelBA = value.toLatin1();
+ const LanguageLevel level = clang::languageLevelFromOption(languageLevelBA.constData());
+ if (level == LanguageLevel::Default)
+ throw Exception(msgInvalidLanguageLevel(value));
+ m_options->m_languageLevel = level;
}
-void ApiExtractor::addIncludePath(const HeaderPaths& paths)
+bool ApiExtractorOptionsParser::handleBoolOption(const QString &key, OptionSource source)
{
- d->m_includePaths << paths;
+ static const auto isystemOption = "isystem"_L1;
+
+ switch (source) {
+ case OptionSource::CommandLine:
+ case OptionSource::ProjectFile:
+ if (key == u"use-global-header") {
+ AbstractMetaBuilder::setUseGlobalHeader(true);
+ return true;
+ }
+ if (key == u"skip-deprecated") {
+ m_options->m_skipDeprecated = true;
+ return true;
+ }
+ break;
+
+ case OptionSource::CommandLineSingleDash:
+ if (key.startsWith(u'I')) { // Shorthand path arguments -I/usr/include...
+ parseIncludePathOption(key.sliced(1), HeaderType::Standard);
+ return true;
+ }
+ if (key.startsWith(u'F')) {
+ parseIncludePathOption(key.sliced(1), HeaderType::Framework);
+ return true;
+ }
+ if (key.startsWith(isystemOption)) {
+ parseIncludePathOption(key.sliced(isystemOption.size()), HeaderType::System);
+ return true;
+ }
+ break;
+ }
+ return false;
}
-HeaderPaths ApiExtractor::includePaths() const
+bool ApiExtractorOptionsParser::handleOption(const QString &key, const QString &value,
+ OptionSource source)
{
- return d->m_includePaths;
+ if (source == OptionSource::CommandLineSingleDash) {
+ if (key == u"std") {
+ setLanguageLevel(value);
+ return true;
+ }
+ return false;
+ }
+
+ if (key == u"clang-option") {
+ m_options->m_clangOptions.append(value);
+ return true;
+ }
+ if (key == u"clang-options") {
+ m_options->m_clangOptions.append(value.split(u',', Qt::SkipEmptyParts));
+ return true;
+ }
+ if (key == u"include-paths") {
+ parseIncludePathOption(value.split(QDir::listSeparator(), Qt::SkipEmptyParts),
+ HeaderType::Standard);
+ return true;
+ }
+ if (key == u"framework-include-paths") {
+ parseIncludePathOption(value.split(QDir::listSeparator(), Qt::SkipEmptyParts),
+ HeaderType::Framework);
+ return true;
+ }
+ if (key == u"system-include-paths") {
+ parseIncludePathOption(value.split(QDir::listSeparator(), Qt::SkipEmptyParts),
+ HeaderType::System);
+ return true;
+ }
+ if (key == u"language-level") {
+ setLanguageLevel(value);
+ return true;
+ }
+
+ if (source == OptionSource::ProjectFile) {
+ if (key == u"include-path") {
+ parseIncludePathOption(value, HeaderType::Standard);
+ return true;
+ }
+ if (key == u"framework-include-path") {
+ parseIncludePathOption(value, HeaderType::Framework);
+ return true;
+ }
+ if (key == u"system-include-path") {
+ parseIncludePathOption(value, HeaderType::System);
+ return true;
+ }
+ }
+
+ return false;
}
-void ApiExtractor::setLogDirectory(const QString& logDir)
+std::shared_ptr<OptionsParser> ApiExtractor::createOptionsParser()
{
- d->m_logDirectory = logDir;
+ return std::make_shared<ApiExtractorOptionsParser>(d);
}
-void ApiExtractor::setCppFileNames(const QFileInfoList &cppFileName)
+struct ApiExtractorPrivate : public ApiExtractorOptions
{
- d->m_cppFileNames = cppFileName;
-}
+ bool runHelper(ApiExtractorFlags flags);
-QFileInfoList ApiExtractor::cppFileNames() const
+ static QString getSimplifiedContainerTypeName(const AbstractMetaType &type);
+ void addInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context,
+ const AbstractMetaType &type,
+ const QString &contextName);
+ void collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context,
+ const AbstractMetaFunctionCPtr &func);
+ void collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context,
+ const AbstractMetaClassCPtr &metaClass);
+ void collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context);
+ void collectInstantiatedOpqaqueContainers(InstantiationCollectContext &context);
+ void collectContainerTypesFromSnippets(InstantiationCollectContext &context);
+ void collectContainerTypesFromConverterMacros(InstantiationCollectContext &context,
+ const QString &code,
+ bool toPythonMacro);
+ void addInstantiatedSmartPointer(InstantiationCollectContext &context,
+ const AbstractMetaType &type);
+
+ AbstractMetaBuilder *m_builder = nullptr;
+};
+
+ApiExtractor::ApiExtractor() :
+ d(new ApiExtractorPrivate)
{
- return d->m_cppFileNames;
}
-void ApiExtractor::setTypeSystem(const QString& typeSystemFileName)
+ApiExtractor::~ApiExtractor()
{
- d->m_typeSystemFileName = typeSystemFileName;
+ delete d->m_builder;
+ delete d;
}
-QString ApiExtractor::typeSystem() const
+HeaderPaths ApiExtractor::includePaths() const
{
- return d->m_typeSystemFileName;
+ return d->m_includePaths;
}
-void ApiExtractor::setSkipDeprecated(bool value)
+void ApiExtractor::setLogDirectory(const QString& logDir)
{
- d->m_skipDeprecated = value;
- if (d->m_builder)
- d->m_builder->setSkipDeprecated(d->m_skipDeprecated);
+ d->m_logDirectory = logDir;
}
-void ApiExtractor::setSuppressWarnings ( bool value )
+void ApiExtractor::setCppFileNames(const QFileInfoList &cppFileName)
{
- TypeDatabase::instance()->setSuppressWarnings(value);
+ d->m_cppFileNames = cppFileName;
}
-void ApiExtractor::setSilent ( bool value )
+QFileInfoList ApiExtractor::cppFileNames() const
{
- ReportHandler::setSilent(value);
+ return d->m_cppFileNames;
}
-bool ApiExtractor::setApiVersion(const QString& package, const QString &version)
+void ApiExtractor::setTypeSystem(const QString& typeSystemFileName)
{
- return TypeDatabase::setApiVersion(package, version);
+ d->m_typeSystemFileName = typeSystemFileName;
}
-void ApiExtractor::setDropTypeEntries(const QStringList &dropEntries)
+QString ApiExtractor::typeSystem() const
{
- TypeDatabase::instance()->setDropTypeEntries(dropEntries);
+ return d->m_typeSystemFileName;
}
const AbstractMetaEnumList &ApiExtractor::globalEnums() const
@@ -225,8 +340,7 @@ bool ApiExtractorPrivate::runHelper(ApiExtractorFlags flags)
}
const QString pattern = QDir::tempPath() + u'/'
- + m_cppFileNames.constFirst().baseName()
- + QStringLiteral("_XXXXXX.hpp");
+ + m_cppFileNames.constFirst().baseName() + "_XXXXXX.hpp"_L1;
QTemporaryFile ppFile(pattern);
bool autoRemove = !qEnvironmentVariableIsSet("KEEP_TEMP_FILES");
// make sure that a tempfile can be written
@@ -235,7 +349,7 @@ bool ApiExtractorPrivate::runHelper(ApiExtractorFlags flags)
<< ": " << qPrintable(ppFile.errorString()) << '\n';
return false;
}
- for (const auto &cppFileName : qAsConst(m_cppFileNames)) {
+ for (const auto &cppFileName : std::as_const(m_cppFileNames)) {
ppFile.write("#include \"");
ppFile.write(cppFileName.absoluteFilePath().toLocal8Bit());
ppFile.write("\"\n");
@@ -264,18 +378,18 @@ bool ApiExtractorPrivate::runHelper(ApiExtractorFlags flags)
arguments.append(m_clangOptions.at(i).toUtf8());
}
- for (const HeaderPath &headerPath : qAsConst(m_includePaths))
+ for (const HeaderPath &headerPath : std::as_const(m_includePaths))
arguments.append(HeaderPath::includeOption(headerPath));
+ if (flags.testFlag(ApiExtractorFlag::UsePySideExtensions))
+ addPySideExtensions(&arguments);
arguments.append(QFile::encodeName(preprocessedCppFileName));
+
if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
qCInfo(lcShiboken).noquote().nospace()
<< "clang language level: " << int(m_languageLevel)
<< "\nclang arguments: " << arguments;
}
- if (flags.testFlag(ApiExtractorFlag::UsePySideExtensions))
- addPySideExtensions(&arguments);
-
const bool result = m_builder->build(arguments, flags, addCompilerSupportArguments,
m_languageLevel);
if (!result)
@@ -300,19 +414,17 @@ std::optional<ApiExtractorResult> ApiExtractor::run(ApiExtractorFlags flags)
InstantiationCollectContext collectContext;
d->collectInstantiatedContainersAndSmartPointers(collectContext);
- auto *data = new ApiExtractorResultData;
-
- classListToCList(d->m_builder->takeClasses(), &data->m_metaClasses);
- classListToCList(d->m_builder->takeTemplates(), &data->m_templates);
- classListToCList(d->m_builder->takeSmartPointers(), &data->m_smartPointers);
- data->m_globalFunctions = d->m_builder->globalFunctions();
- data->m_globalEnums = d->m_builder->globalEnums();
- data->m_enums = d->m_builder->typeEntryToEnumsHash();
- data->m_flags = flags;
- qSwap(data->m_instantiatedContainers, collectContext.instantiatedContainers);
- qSwap(data->m_instantiatedSmartPointers, collectContext.instantiatedSmartPointers);
- qSwap(data->m_synthesizedTypeEntries, collectContext.m_synthesizedTypeEntries);
- return ApiExtractorResult(data);
+ ApiExtractorResult result;
+ classListToCList(d->m_builder->takeClasses(), &result.m_metaClasses);
+ classListToCList(d->m_builder->takeSmartPointers(), &result.m_smartPointers);
+ result.m_globalFunctions = d->m_builder->globalFunctions();
+ result.m_globalEnums = d->m_builder->globalEnums();
+ result.m_enums = d->m_builder->typeEntryToEnumsHash();
+ result.m_flags = flags;
+ result.m_typedefTargetToName = d->m_builder->typedefTargetToName();
+ qSwap(result.m_instantiatedContainers, collectContext.instantiatedContainers);
+ qSwap(result.m_instantiatedSmartPointers, collectContext.instantiatedSmartPointers);
+ return result;
}
LanguageLevel ApiExtractor::languageLevel() const
@@ -320,26 +432,11 @@ LanguageLevel ApiExtractor::languageLevel() const
return d->m_languageLevel;
}
-void ApiExtractor::setLanguageLevel(LanguageLevel languageLevel)
-{
- d->m_languageLevel = languageLevel;
-}
-
QStringList ApiExtractor::clangOptions() const
{
return d->m_clangOptions;
}
-void ApiExtractor::setClangOptions(const QStringList &co)
-{
- d->m_clangOptions = co;
-}
-
-void ApiExtractor::setUseGlobalHeader(bool h)
-{
- AbstractMetaBuilder::setUseGlobalHeader(h);
-}
-
AbstractMetaFunctionPtr
ApiExtractor::inheritTemplateFunction(const AbstractMetaFunctionCPtr &function,
const AbstractMetaTypeList &templateTypes)
@@ -350,15 +447,15 @@ AbstractMetaFunctionPtr
AbstractMetaFunctionPtr
ApiExtractor::inheritTemplateMember(const AbstractMetaFunctionCPtr &function,
const AbstractMetaTypeList &templateTypes,
- const AbstractMetaClass *templateClass,
- AbstractMetaClass *subclass)
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaClassPtr &subclass)
{
return AbstractMetaBuilder::inheritTemplateMember(function, templateTypes,
templateClass, subclass);
}
-AbstractMetaClass *ApiExtractor::inheritTemplateClass(ComplexTypeEntry *te,
- const AbstractMetaClass *templateClass,
+AbstractMetaClassPtr ApiExtractor::inheritTemplateClass(const ComplexTypeEntryPtr &te,
+ const AbstractMetaClassCPtr &templateClass,
const AbstractMetaTypeList &templateTypes,
InheritTemplateFlags flags)
{
@@ -409,7 +506,7 @@ AbstractMetaType canonicalSmartPtrInstantiation(const AbstractMetaType &type)
return fixedType;
}
-static inline const TypeEntry *pointeeTypeEntry(const AbstractMetaType &smartPtrType)
+static inline TypeEntryCPtr pointeeTypeEntry(const AbstractMetaType &smartPtrType)
{
return smartPtrType.instantiations().constFirst().typeEntry();
}
@@ -437,12 +534,12 @@ ApiExtractorPrivate::addInstantiatedContainersAndSmartPointers(InstantiationColl
return;
}
if (type.hasTemplateChildren()) {
- QString piece = isContainer ? QStringLiteral("container") : QStringLiteral("smart pointer");
+ const auto piece = isContainer ? "container"_L1 : "smart pointer"_L1;
QString warning =
QString::fromLatin1("Skipping instantiation of %1 '%2' because it has template"
" arguments.").arg(piece, type.originalTypeDescription());
if (!contextName.isEmpty())
- warning.append(QStringLiteral(" Calling context: ") + contextName);
+ warning.append(" Calling context: "_L1 + contextName);
qCWarning(lcShiboken).noquote().nospace() << warning;
return;
@@ -485,12 +582,12 @@ static FunctionModification invalidateArgMod(const AbstractMetaFunctionCPtr &f,
}
static void addOwnerModification(const AbstractMetaFunctionCList &functions,
- ComplexTypeEntry *typeEntry)
+ const ComplexTypeEntryPtr &typeEntry)
{
for (const auto &f : functions) {
if (!f->arguments().isEmpty()
&& f->arguments().constFirst().type().indirections() > 0) {
- qSharedPointerConstCast<AbstractMetaFunction>(f)->clearModificationsCache();
+ std::const_pointer_cast<AbstractMetaFunction>(f)->clearModificationsCache();
typeEntry->addFunctionModification(invalidateArgMod(f));
}
}
@@ -500,22 +597,45 @@ void ApiExtractorPrivate::addInstantiatedSmartPointer(InstantiationCollectContex
const AbstractMetaType &type)
{
InstantiatedSmartPointer smp;
- smp.type = simplifiedType(type);
+ smp.type = canonicalSmartPtrInstantiation(type);
smp.smartPointer = AbstractMetaClass::findClass(m_builder->smartPointers(),
type.typeEntry());
Q_ASSERT(smp.smartPointer);
const auto &instantiatedType = type.instantiations().constFirst();
- auto *ste = static_cast<const SmartPointerTypeEntry *>(smp.smartPointer->typeEntry());
- auto *typedefEntry = new TypedefEntry(SmartPointerTypeEntry::getTargetName(smp.type),
- ste->name(), ste->version(), ste->parent());
+ const auto ste = std::static_pointer_cast<const SmartPointerTypeEntry>(smp.smartPointer->typeEntry());
+ QString name = ste->getTargetName(smp.type);
+ auto parentTypeEntry = ste->parent();
+ InheritTemplateFlags flags;
+
+ auto colonPos = name.lastIndexOf(u"::");
+ const bool withinNameSpace = colonPos != -1;
+ if (withinNameSpace) { // user defined
+ const QString nameSpace = name.left(colonPos);
+ name.remove(0, colonPos + 2);
+ const auto nameSpaces = TypeDatabase::instance()->findNamespaceTypes(nameSpace);
+ if (nameSpaces.isEmpty())
+ throw Exception(msgNamespaceNotFound(name));
+ parentTypeEntry = nameSpaces.constFirst();
+ } else {
+ flags.setFlag(InheritTemplateFlag::SetEnclosingClass);
+ }
+
+ TypedefEntryPtr typedefEntry(new TypedefEntry(name, ste->name(), ste->version(),
+ parentTypeEntry));
typedefEntry->setTargetLangPackage(ste->targetLangPackage());
- auto *instantiationEntry = TypeDatabase::initializeTypeDefEntry(typedefEntry, ste);
+ auto instantiationEntry = TypeDatabase::initializeTypeDefEntry(typedefEntry, ste);
smp.specialized = ApiExtractor::inheritTemplateClass(instantiationEntry, smp.smartPointer,
- {instantiatedType},
- InheritTemplateFlag::SetEnclosingClass);
+ {instantiatedType}, flags);
Q_ASSERT(smp.specialized);
+ if (withinNameSpace) { // move class to desired namespace
+ const auto enclClass = AbstractMetaClass::findClass(m_builder->classes(), parentTypeEntry);
+ Q_ASSERT(enclClass);
+ auto specialized = std::const_pointer_cast<AbstractMetaClass>(smp.specialized);
+ specialized->setEnclosingClass(enclClass);
+ enclClass->addInnerClass(specialized);
+ }
if (instantiationEntry->isComplex()) {
addOwnerModification(smp.specialized->queryFunctions(FunctionQueryOption::Constructors),
@@ -527,8 +647,6 @@ void ApiExtractorPrivate::addInstantiatedSmartPointer(InstantiationCollectContex
}
context.instantiatedSmartPointers.append(smp);
- context.m_synthesizedTypeEntries.append(typedefEntry);
- context.m_synthesizedTypeEntries.append(instantiationEntry);
}
void
@@ -536,22 +654,34 @@ ApiExtractorPrivate::collectInstantiatedContainersAndSmartPointers(Instantiation
const AbstractMetaFunctionCPtr &func)
{
addInstantiatedContainersAndSmartPointers(context, func->type(), func->signature());
- for (const AbstractMetaArgument &arg : func->arguments())
- addInstantiatedContainersAndSmartPointers(context, arg.type(), func->signature());
+ for (const AbstractMetaArgument &arg : func->arguments()) {
+ const auto argType = arg.type();
+ const auto type = argType.viewOn() != nullptr ? *argType.viewOn() : argType;
+ addInstantiatedContainersAndSmartPointers(context, type, func->signature());
+ }
}
void
ApiExtractorPrivate::collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context,
- const AbstractMetaClass *metaClass)
+ const AbstractMetaClassCPtr &metaClass)
{
if (!metaClass->typeEntry()->generateCode())
return;
for (const auto &func : metaClass->functions())
collectInstantiatedContainersAndSmartPointers(context, func);
+ for (const auto &func : metaClass->userAddedPythonOverrides())
+ collectInstantiatedContainersAndSmartPointers(context, func);
for (const AbstractMetaField &field : metaClass->fields())
addInstantiatedContainersAndSmartPointers(context, field.type(), field.name());
- for (auto *innerClass : metaClass->innerClasses())
- collectInstantiatedContainersAndSmartPointers(context, innerClass);
+
+ // The list of inner classes might be extended when smart pointer
+ // instantiations are specified to be in namespaces.
+ const auto &innerClasses = metaClass->innerClasses();
+ for (auto i = innerClasses.size() - 1; i >= 0; --i) {
+ const auto innerClass = innerClasses.at(i);
+ if (!innerClass->typeEntry()->isSmartPointer())
+ collectInstantiatedContainersAndSmartPointers(context, innerClass);
+ }
}
void
@@ -560,7 +690,7 @@ ApiExtractorPrivate::collectInstantiatedContainersAndSmartPointers(Instantiation
collectInstantiatedOpqaqueContainers(context);
for (const auto &func : m_builder->globalFunctions())
collectInstantiatedContainersAndSmartPointers(context, func);
- for (auto metaClass : m_builder->classes())
+ for (const auto &metaClass : m_builder->classes())
collectInstantiatedContainersAndSmartPointers(context, metaClass);
collectContainerTypesFromSnippets(context);
}
@@ -569,12 +699,12 @@ ApiExtractorPrivate::collectInstantiatedContainersAndSmartPointers(Instantiation
// the current package or, for primitive types, if the container is in the
// current package.
static bool generateOpaqueContainer(const AbstractMetaType &type,
- const TypeSystemTypeEntry *moduleEntry)
+ const TypeSystemTypeEntryCPtr &moduleEntry)
{
- auto *te = type.instantiations().constFirst().typeEntry();
- auto *typeModuleEntry = te->typeSystemTypeEntry();
+ auto te = type.instantiations().constFirst().typeEntry();
+ auto typeModuleEntry = typeSystemTypeEntry(te);
return typeModuleEntry == moduleEntry
- || (te->isPrimitive() && type.typeEntry()->typeSystemTypeEntry() == moduleEntry);
+ || (te->isPrimitive() && typeSystemTypeEntry(type.typeEntry()) == moduleEntry);
}
void ApiExtractorPrivate::collectInstantiatedOpqaqueContainers(InstantiationCollectContext &context)
@@ -582,13 +712,12 @@ void ApiExtractorPrivate::collectInstantiatedOpqaqueContainers(InstantiationColl
// Add all instantiations of opaque containers for types from the current
// module.
auto *td = TypeDatabase::instance();
- const auto *moduleEntry = TypeDatabase::instance()->defaultTypeSystemType();
+ const auto moduleEntry = TypeDatabase::instance()->defaultTypeSystemType();
const auto &containers = td->containerTypes();
- for (const auto *container : containers) {
+ for (const auto &container : containers) {
for (const auto &oc : container->opaqueContainers()) {
QString errorMessage;
- const QString typeName = container->qualifiedCppName() + u'<'
- + oc.instantiation + u'>';
+ const QString typeName = container->qualifiedCppName() + oc.templateParameters();
auto typeOpt = AbstractMetaType::fromString(typeName, &errorMessage);
if (typeOpt.has_value()
&& generateOpaqueContainer(typeOpt.value(), moduleEntry)) {
@@ -601,15 +730,18 @@ void ApiExtractorPrivate::collectInstantiatedOpqaqueContainers(InstantiationColl
static void getCode(QStringList &code, const CodeSnipList &codeSnips)
{
- for (const CodeSnip &snip : qAsConst(codeSnips))
+ for (const CodeSnip &snip : std::as_const(codeSnips))
code.append(snip.code());
}
-static void getCode(QStringList &code, const TypeEntry *type)
+static void getCode(QStringList &code, const TypeEntryCPtr &type)
{
- getCode(code, type->codeSnips());
+ if (type->isComplex())
+ getCode(code, std::static_pointer_cast<const ComplexTypeEntry>(type)->codeSnips());
+ else if (type->isTypeSystem())
+ getCode(code, std::static_pointer_cast<const TypeSystemTypeEntry>(type)->codeSnips());
- CustomConversion *customConversion = type->customConversion();
+ auto customConversion = CustomConversion::getCustomConversion(type);
if (!customConversion)
return;
@@ -620,31 +752,31 @@ static void getCode(QStringList &code, const TypeEntry *type)
if (toCppConversions.isEmpty())
return;
- for (CustomConversion::TargetToNativeConversion *toNative : qAsConst(toCppConversions))
- code.append(toNative->conversion());
+ for (const auto &toNative : std::as_const(toCppConversions))
+ code.append(toNative.conversion());
}
void ApiExtractorPrivate::collectContainerTypesFromSnippets(InstantiationCollectContext &context)
{
QStringList snips;
auto *td = TypeDatabase::instance();
- const PrimitiveTypeEntryList &primitiveTypeList = td->primitiveTypes();
- for (const PrimitiveTypeEntry *type : primitiveTypeList)
+ const PrimitiveTypeEntryCList &primitiveTypeList = td->primitiveTypes();
+ for (const auto &type : primitiveTypeList)
getCode(snips, type);
- const ContainerTypeEntryList &containerTypeList = td->containerTypes();
- for (const ContainerTypeEntry *type : containerTypeList)
+ const ContainerTypeEntryCList &containerTypeList = td->containerTypes();
+ for (const auto &type : containerTypeList)
getCode(snips, type);
- for (auto metaClass : m_builder->classes())
+ for (const auto &metaClass : m_builder->classes())
getCode(snips, metaClass->typeEntry());
- const TypeSystemTypeEntry *moduleEntry = td->defaultTypeSystemType();
+ const auto moduleEntry = td->defaultTypeSystemType();
Q_ASSERT(moduleEntry);
getCode(snips, moduleEntry);
for (const auto &func : m_builder->globalFunctions())
getCode(snips, func->injectedCodeSnips());
- for (const QString &code : qAsConst(snips)) {
+ for (const QString &code : std::as_const(snips)) {
collectContainerTypesFromConverterMacros(context, code, true);
collectContainerTypesFromConverterMacros(context, code, false);
}
@@ -656,8 +788,8 @@ ApiExtractorPrivate::collectContainerTypesFromConverterMacros(InstantiationColle
bool toPythonMacro)
{
QString convMacro = toPythonMacro ? u"%CONVERTTOPYTHON["_s : u"%CONVERTTOCPP["_s;
- int offset = toPythonMacro ? sizeof("%CONVERTTOPYTHON") : sizeof("%CONVERTTOCPP");
- int start = 0;
+ const qsizetype offset = toPythonMacro ? sizeof("%CONVERTTOPYTHON") : sizeof("%CONVERTTOCPP");
+ qsizetype start = 0;
QString errorMessage;
while ((start = code.indexOf(convMacro, start)) != -1) {
int end = code.indexOf(u']', start);