aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/ApiExtractor/typedatabase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/ApiExtractor/typedatabase.cpp')
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.cpp189
1 files changed, 157 insertions, 32 deletions
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp
index 4f8887bd2..9fcf474c6 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp
@@ -144,6 +144,25 @@ IncludeList TypeDatabase::extraIncludes(const QString& className) const
return typeEntry ? typeEntry->extraIncludes() : IncludeList();
}
+void TypeDatabase::addSystemInclude(const QString &name)
+{
+ m_systemIncludes.append(name.toUtf8());
+}
+
+// Add a lookup for the short name excluding inline namespaces
+// so that "std::shared_ptr" finds "std::__1::shared_ptr" as well.
+// Note: This inserts duplicate TypeEntry * into m_entries.
+void TypeDatabase::addInlineNamespaceLookups(const NamespaceTypeEntry *n)
+{
+ QVector<TypeEntry *> additionalEntries; // Store before modifying the hash
+ for (TypeEntry *entry : m_entries) {
+ if (entry->isChildOf(n))
+ additionalEntries.append(entry);
+ }
+ for (const auto &ae : additionalEntries)
+ m_entries.insert(ae->shortName(), ae);
+}
+
ContainerTypeEntry* TypeDatabase::findContainerType(const QString &name) const
{
QString template_name = name;
@@ -166,7 +185,7 @@ static bool inline useType(const TypeEntry *t)
FunctionTypeEntry* TypeDatabase::findFunctionType(const QString& name) const
{
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (entry->type() == TypeEntry::FunctionType && useType(entry))
return static_cast<FunctionTypeEntry*>(entry);
@@ -201,7 +220,7 @@ QString TypeDatabase::defaultPackageName() const
TypeEntry* TypeDatabase::findType(const QString& name) const
{
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (useType(entry))
return entry;
@@ -209,7 +228,53 @@ TypeEntry* TypeDatabase::findType(const QString& name) const
return nullptr;
}
-TypeEntryMultiMapConstIteratorRange TypeDatabase::findTypes(const QString &name) const
+template <class Predicate>
+TypeEntries TypeDatabase::findTypesHelper(const QString &name, Predicate pred) const
+{
+ TypeEntries result;
+ const auto entries = findTypeRange(name);
+ for (TypeEntry *entry : entries) {
+ if (pred(entry))
+ result.append(entry);
+ }
+ return result;
+}
+
+TypeEntries TypeDatabase::findTypes(const QString &name) const
+{
+ return findTypesHelper(name, useType);
+}
+
+static bool useCppType(const TypeEntry *t)
+{
+ bool result = false;
+ switch (t->type()) {
+ case TypeEntry::PrimitiveType:
+ case TypeEntry::VoidType:
+ case TypeEntry::FlagsType:
+ case TypeEntry::EnumType:
+ case TypeEntry::TemplateArgumentType:
+ case TypeEntry::BasicValueType:
+ case TypeEntry::ContainerType:
+ case TypeEntry::ObjectType:
+ case TypeEntry::ArrayType:
+ case TypeEntry::CustomType:
+ case TypeEntry::SmartPointerType:
+ case TypeEntry::TypedefType:
+ result = useType(t);
+ break;
+ default:
+ break;
+ }
+ return result;
+}
+
+TypeEntries TypeDatabase::findCppTypes(const QString &name) const
+{
+ return findTypesHelper(name, useCppType);
+}
+
+TypeEntryMultiMapConstIteratorRange TypeDatabase::findTypeRange(const QString &name) const
{
const auto range = m_entries.equal_range(name);
return {range.first, range.second};
@@ -322,11 +387,10 @@ TypeEntry *TypeDatabase::resolveTypeDefEntry(TypedefEntry *typedefEntry,
if (lessThanPos != -1)
sourceName.truncate(lessThanPos);
ComplexTypeEntry *source = nullptr;
- for (TypeEntry *e : findTypes(sourceName)) {
+ for (TypeEntry *e : findTypeRange(sourceName)) {
switch (e->type()) {
case TypeEntry::BasicValueType:
case TypeEntry::ContainerType:
- case TypeEntry::InterfaceType:
case TypeEntry::ObjectType:
case TypeEntry::SmartPointerType:
source = dynamic_cast<ComplexTypeEntry *>(e);
@@ -362,6 +426,17 @@ bool TypeDatabase::addType(TypeEntry *e, QString *errorMessage)
return true;
}
+// Add a dummy value entry for non-type template parameters
+ConstantValueTypeEntry *
+ TypeDatabase::addConstantValueTypeEntry(const QString &value,
+ const TypeEntry *parent)
+{
+ auto result = new ConstantValueTypeEntry(value, parent);
+ result->setCodeGeneration(TypeEntry::GenerateNothing);
+ addType(result);
+ return result;
+}
+
bool TypeDatabase::isFunctionRejected(const QString& className, const QString& functionName,
QString *reason) const
{
@@ -493,17 +568,25 @@ bool TypeDatabase::addSuppressedWarning(const QString &warning, QString *errorMe
return true;
}
-bool TypeDatabase::isSuppressedWarning(const QString& s) const
+template <class String> // QString, QStringRef
+bool TypeDatabase::isSuppressedWarningHelper(const String &s) const
{
if (!m_suppressWarnings)
return false;
+ return std::any_of(m_suppressedWarnings.cbegin(), m_suppressedWarnings.end(),
+ [&s] (const QRegularExpression &e) {
+ return e.match(s).hasMatch();
+ });
+}
- for (const QRegularExpression &warning : m_suppressedWarnings) {
- if (warning.match(s).hasMatch())
- return true;
- }
+bool TypeDatabase::isSuppressedWarning(const QString &s) const
+{
+ return isSuppressedWarningHelper(s);
+}
- return false;
+bool TypeDatabase::isSuppressedWarning(const QStringRef &s) const
+{
+ return isSuppressedWarningHelper(s);
}
QString TypeDatabase::modifiedTypesystemFilepath(const QString& tsFile, const QString &currentPath) const
@@ -557,15 +640,8 @@ bool TypeDatabase::parseFile(const QString &filename, const QString &currentPath
return false;
}
- int count = m_entries.size();
bool ok = parseFile(&file, generate);
m_parsedTypesystemFiles[filepath] = ok;
- int newCount = m_entries.size();
-
- if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
- qCDebug(lcShiboken)
- << QStringLiteral("Parsed: '%1', %2 new entries").arg(filename).arg(newCount - count);
- }
return ok;
}
@@ -581,7 +657,7 @@ bool TypeDatabase::parseFile(QIODevice* device, bool generate)
PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const
{
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (entry->isPrimitive()) {
auto *pe = static_cast<PrimitiveTypeEntry *>(entry);
@@ -595,7 +671,7 @@ PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const
ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name) const
{
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (entry->isComplex() && useType(entry))
return static_cast<ComplexTypeEntry*>(entry);
@@ -605,7 +681,7 @@ ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name) const
ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const
{
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (entry && entry->isObject() && useType(entry))
return static_cast<ObjectTypeEntry*>(entry);
@@ -616,7 +692,7 @@ ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const
NamespaceTypeEntryList TypeDatabase::findNamespaceTypes(const QString& name) const
{
NamespaceTypeEntryList result;
- const auto entries = findTypes(name);
+ const auto entries = findTypeRange(name);
for (TypeEntry *entry : entries) {
if (entry->isNamespace())
result.append(static_cast<NamespaceTypeEntry*>(entry));
@@ -698,6 +774,35 @@ static void _computeTypeIndexes()
computeTypeIndexes = false;
}
+// Build the C++ name excluding any inline namespaces
+// ("std::__1::shared_ptr" -> "std::shared_ptr"
+QString TypeEntry::shortName() const
+{
+ if (m_cachedShortName.isEmpty()) {
+ QVarLengthArray<const TypeEntry *> parents;
+ bool foundInlineNamespace = false;
+ for (auto p = m_parent; p != nullptr && p->type() != TypeEntry::TypeSystemType; p = p->parent()) {
+ if (p->type() == TypeEntry::NamespaceType
+ && static_cast<const NamespaceTypeEntry *>(p)->isInlineNamespace()) {
+ foundInlineNamespace = true;
+ } else {
+ parents.append(p);
+ }
+ }
+ if (foundInlineNamespace) {
+ m_cachedShortName.reserve(m_name.size());
+ for (int i = parents.size() - 1; i >= 0; --i) {
+ m_cachedShortName.append(parents.at(i)->entryName());
+ m_cachedShortName.append(QLatin1String("::"));
+ }
+ m_cachedShortName.append(m_entryName);
+ } else {
+ m_cachedShortName = m_name;
+ }
+ }
+ return m_cachedShortName;
+}
+
void TypeEntry::setRevision(int r)
{
if (m_revision != r) {
@@ -746,14 +851,15 @@ bool TypeDatabase::setApiVersion(const QString& packageWildcardPattern, const QS
}
bool TypeDatabase::checkApiVersion(const QString &package,
- const QVersionNumber &versionNumber)
+ const VersionRange &vr)
{
const ApiVersions &versions = *apiVersions();
if (versions.isEmpty()) // Nothing specified: use latest.
return true;
for (int i = 0, size = versions.size(); i < size; ++i) {
if (versions.at(i).first.match(package).hasMatch())
- return versions.at(i).second >= versionNumber;
+ return versions.at(i).second >= vr.since
+ && versions.at(i).second <= vr.until;
}
return false;
}
@@ -792,8 +898,8 @@ void TypeEntry::formatDebug(QDebug &d) const
d << '"' << m_name << '"';
if (m_name != cppName)
d << "\", cppName=\"" << cppName << '"';
- d << ", type=" << m_type << ", codeGeneration=0x"
- << hex << m_codeGeneration << dec;
+ d << ", type=" << m_type << ", codeGeneration="
+ << m_codeGeneration << ", target=\"" << targetLangName() << '"';
FORMAT_NONEMPTY_STRING("package", m_targetLangPackage)
FORMAT_BOOL("stream", m_stream)
FORMAT_LIST_SIZE("codeSnips", m_codeSnips)
@@ -812,7 +918,6 @@ void TypeEntry::formatDebug(QDebug &d) const
void ComplexTypeEntry::formatDebug(QDebug &d) const
{
TypeEntry::formatDebug(d);
- FORMAT_NONEMPTY_STRING("targetLangName", m_targetLangName)
FORMAT_BOOL("polymorphicBase", m_polymorphicBase)
FORMAT_BOOL("genericClass", m_genericClass)
FORMAT_BOOL("deleteInMainThread", m_deleteInMainThread)
@@ -822,7 +927,6 @@ void ComplexTypeEntry::formatDebug(QDebug &d) const
<< ", except=" << int(m_exceptionHandling);
FORMAT_NONEMPTY_STRING("defaultSuperclass", m_defaultSuperclass)
FORMAT_NONEMPTY_STRING("polymorphicIdValue", m_polymorphicIdValue)
- FORMAT_NONEMPTY_STRING("lookupName", m_lookupName)
FORMAT_NONEMPTY_STRING("targetType", m_targetType)
FORMAT_NONEMPTY_STRING("hash", m_hashFunction)
FORMAT_LIST_SIZE("addedFunctions", m_addedFunctions)
@@ -840,9 +944,6 @@ void TypedefEntry::formatDebug(QDebug &d) const
void EnumTypeEntry::formatDebug(QDebug &d) const
{
TypeEntry::formatDebug(d);
- FORMAT_NONEMPTY_STRING("package", m_packageName)
- FORMAT_NONEMPTY_STRING("qualifier", m_qualifier)
- FORMAT_NONEMPTY_STRING("targetLangName", m_targetLangName)
if (m_flags)
d << ", flags=(" << m_flags << ')';
}
@@ -852,12 +953,26 @@ void NamespaceTypeEntry::formatDebug(QDebug &d) const
ComplexTypeEntry::formatDebug(d);
auto pattern = m_filePattern.pattern();
FORMAT_NONEMPTY_STRING("pattern", pattern)
+ d << ",visibility=" << m_visibility;
+ if (m_inlineNamespace)
+ d << "[inline]";
}
void ContainerTypeEntry::formatDebug(QDebug &d) const
{
ComplexTypeEntry::formatDebug(d);
- d << ", type=" << m_type << ",\"" << typeName() << '"';
+ d << ", type=" << m_containerKind << ",\"" << typeName() << '"';
+}
+
+void SmartPointerTypeEntry::formatDebug(QDebug &d) const
+{
+ ComplexTypeEntry::formatDebug(d);
+ if (!m_instantiations.isEmpty()) {
+ d << ", instantiations[" << m_instantiations.size() << "]=(";
+ for (auto i : m_instantiations)
+ d << i->name() << ',';
+ d << ')';
+ }
}
QDebug operator<<(QDebug d, const TypeEntry *te)
@@ -895,6 +1010,16 @@ void TypeDatabase::formatDebug(QDebug &d) const
<< "entries[" << m_entries.size() << "]=";
for (auto it = m_entries.cbegin(), end = m_entries.cend(); it != end; ++it)
d << " " << it.value() << '\n';
+ if (!m_typedefEntries.isEmpty()) {
+ d << "typedefs[" << m_typedefEntries.size() << "]=(";
+ const auto begin = m_typedefEntries.cbegin();
+ for (auto it = begin, end = m_typedefEntries.cend(); it != end; ++it) {
+ if (it != begin)
+ d << ", ";
+ d << " " << it.value() << '\n';
+ }
+ d << ")\n";
+ }
if (!m_templates.isEmpty()) {
d << "templates[" << m_templates.size() << "]=(";
const auto begin = m_templates.cbegin();