aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/ApiExtractor/parser
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/ApiExtractor/parser')
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel.cpp1608
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel.h814
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel_enums.h64
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h85
-rw-r--r--sources/shiboken6/ApiExtractor/parser/enumvalue.cpp76
-rw-r--r--sources/shiboken6/ApiExtractor/parser/enumvalue.h71
6 files changed, 2718 insertions, 0 deletions
diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel.cpp b/sources/shiboken6/ApiExtractor/parser/codemodel.cpp
new file mode 100644
index 000000000..76ce333ed
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel.cpp
@@ -0,0 +1,1608 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "codemodel.h"
+
+#include <sourcelocation.h>
+#include <clangparser/clangutils.h>
+
+#include <algorithm>
+#include <functional>
+#include <iostream>
+#include <QDebug>
+#include <QDir>
+#include <QtCore/QStack>
+
+// Predicate to find an item by name in a list of QSharedPointer<Item>
+template <class T> class ModelItemNamePredicate
+{
+public:
+ explicit ModelItemNamePredicate(const QString &name) : m_name(name) {}
+ bool operator()(const QSharedPointer<T> &item) const { return item->name() == m_name; }
+
+private:
+ const QString m_name;
+};
+
+template <class T>
+static QSharedPointer<T> findModelItem(const QVector<QSharedPointer<T> > &list, const QString &name)
+{
+ const auto it = std::find_if(list.cbegin(), list.cend(), ModelItemNamePredicate<T>(name));
+ return it != list.cend() ? *it : QSharedPointer<T>();
+}
+
+// ---------------------------------------------------------------------------
+
+CodeModel::CodeModel() : m_globalNamespace(new _NamespaceModelItem(this))
+{
+}
+
+CodeModel::~CodeModel() = default;
+
+NamespaceModelItem CodeModel::globalNamespace() const
+{
+ return m_globalNamespace;
+}
+
+void CodeModel::addFile(const FileModelItem &item)
+{
+ m_files.append(item);
+}
+
+FileModelItem CodeModel::findFile(const QString &name) const
+{
+ return findModelItem(m_files, name);
+}
+
+static CodeModelItem findRecursion(const ScopeModelItem &scope,
+ const QStringList &qualifiedName, int segment = 0)
+{
+ const QString &nameSegment = qualifiedName.at(segment);
+ if (segment == qualifiedName.size() - 1) { // Leaf item
+ if (ClassModelItem cs = scope->findClass(nameSegment))
+ return cs;
+ if (EnumModelItem es = scope->findEnum(nameSegment))
+ return es;
+ if (TypeDefModelItem tp = scope->findTypeDef(nameSegment))
+ return tp;
+ if (TemplateTypeAliasModelItem tta = scope->findTemplateTypeAlias(nameSegment))
+ return tta;
+ return CodeModelItem();
+ }
+ if (auto nestedClass = scope->findClass(nameSegment))
+ return findRecursion(nestedClass, qualifiedName, segment + 1);
+ if (auto namespaceItem = qSharedPointerDynamicCast<_NamespaceModelItem>(scope)) {
+ for (const auto &nestedNamespace : namespaceItem->namespaces()) {
+ if (nestedNamespace->name() == nameSegment) {
+ if (auto item = findRecursion(nestedNamespace, qualifiedName, segment + 1))
+ return item;
+ }
+ }
+ }
+ return CodeModelItem();
+}
+
+CodeModelItem CodeModel::findItem(const QStringList &qualifiedName, const ScopeModelItem &scope) const
+{
+ return findRecursion(scope, qualifiedName);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const CodeModel *m)
+{
+ QDebugStateSaver s(d);
+ d.noquote();
+ d.nospace();
+ d << "CodeModel(";
+ if (m) {
+ const NamespaceModelItem globalNamespaceP = m->globalNamespace();
+ if (globalNamespaceP.data())
+ globalNamespaceP->formatDebug(d);
+ } else {
+ d << '0';
+ }
+ d << ')';
+ return d;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+// ---------------------------------------------------------------------------
+TypeInfo TypeInfo::combine(const TypeInfo &__lhs, const TypeInfo &__rhs)
+{
+ TypeInfo __result = __lhs;
+
+ __result.setConstant(__result.isConstant() || __rhs.isConstant());
+ __result.setVolatile(__result.isVolatile() || __rhs.isVolatile());
+ if (__rhs.referenceType() > __result.referenceType())
+ __result.setReferenceType(__rhs.referenceType());
+ __result.m_indirections.append(__rhs.m_indirections);
+ __result.setArrayElements(__result.arrayElements() + __rhs.arrayElements());
+ __result.m_instantiations.append(__rhs.m_instantiations);
+
+ return __result;
+}
+
+bool TypeInfo::isVoid() const
+{
+ return m_indirections.isEmpty() && m_referenceType == NoReference
+ && m_arguments.isEmpty() && m_arrayElements.isEmpty()
+ && m_instantiations.isEmpty()
+ && m_qualifiedName.size() == 1
+ && m_qualifiedName.constFirst() == QLatin1String("void");
+}
+
+TypeInfo TypeInfo::resolveType(TypeInfo const &__type, const ScopeModelItem &__scope)
+{
+ CodeModel *__model = __scope->model();
+ Q_ASSERT(__model != nullptr);
+
+ return TypeInfo::resolveType(__model->findItem(__type.qualifiedName(), __scope), __type, __scope);
+}
+
+TypeInfo TypeInfo::resolveType(CodeModelItem __item, TypeInfo const &__type, const ScopeModelItem &__scope)
+{
+ // Copy the type and replace with the proper qualified name. This
+ // only makes sence to do if we're actually getting a resolved
+ // type with a namespace. We only get this if the returned type
+ // has more than 2 entries in the qualified name... This test
+ // could be improved by returning if the type was found or not.
+ TypeInfo otherType(__type);
+ if (__item && __item->qualifiedName().size() > 1) {
+ otherType.setQualifiedName(__item->qualifiedName());
+ }
+
+ if (TypeDefModelItem __typedef = qSharedPointerDynamicCast<_TypeDefModelItem>(__item)) {
+ const TypeInfo combined = TypeInfo::combine(__typedef->type(), otherType);
+ const CodeModelItem nextItem = __scope->model()->findItem(combined.qualifiedName(), __scope);
+ if (!nextItem)
+ return combined;
+ // PYSIDE-362, prevent recursion on opaque structs like
+ // typedef struct xcb_connection_t xcb_connection_t;
+ if (nextItem.data() ==__item.data()) {
+ std::cerr << "** WARNING Bailing out recursion of " << __FUNCTION__
+ << "() on " << qPrintable(__type.qualifiedName().join(QLatin1String("::")))
+ << std::endl;
+ return otherType;
+ }
+ return resolveType(nextItem, combined, __scope);
+ }
+
+ if (TemplateTypeAliasModelItem templateTypeAlias = qSharedPointerDynamicCast<_TemplateTypeAliasModelItem>(__item)) {
+
+ TypeInfo combined = TypeInfo::combine(templateTypeAlias->type(), otherType);
+ // For the alias "template<typename T> using QList = QVector<T>" with
+ // other="QList<int>", replace the instantiations to obtain "QVector<int>".
+ auto aliasInstantiations = templateTypeAlias->type().instantiations();
+ auto concreteInstantiations = otherType.instantiations();
+ const int count = qMin(aliasInstantiations.size(), concreteInstantiations.size());
+ for (int i = 0; i < count; ++i)
+ aliasInstantiations[i] = concreteInstantiations[i];
+ combined.setInstantiations(aliasInstantiations);
+ const CodeModelItem nextItem = __scope->model()->findItem(combined.qualifiedName(), __scope);
+ if (!nextItem)
+ return combined;
+ return resolveType(nextItem, combined, __scope);
+ }
+
+ return otherType;
+}
+
+// Handler for clang::parseTemplateArgumentList() that populates
+// TypeInfo::m_instantiations
+class TypeInfoTemplateArgumentHandler
+{
+public:
+ explicit TypeInfoTemplateArgumentHandler(TypeInfo *t)
+ {
+ m_parseStack.append(t);
+ }
+
+ void operator()(int level, QStringView name)
+ {
+ if (level > m_parseStack.size()) {
+ Q_ASSERT(!top()->m_instantiations.isEmpty());
+ m_parseStack.push(&top()->m_instantiations.back());
+ }
+ while (level < m_parseStack.size())
+ m_parseStack.pop();
+ TypeInfo instantiation;
+ instantiation.setQualifiedName(qualifiedName(name));
+ top()->addInstantiation(instantiation);
+ }
+
+private:
+ TypeInfo *top() const { return m_parseStack.back(); }
+
+ static QStringList qualifiedName(QStringView name)
+ {
+ QStringList result;
+ const auto nameParts = name.split(u"::");
+ result.reserve(nameParts.size());
+ for (const auto &p : nameParts)
+ result.append(p.toString());
+ return result;
+ }
+
+ QStack<TypeInfo *> m_parseStack;
+};
+
+QPair<int, int> TypeInfo::parseTemplateArgumentList(const QString &l, int from)
+{
+ return clang::parseTemplateArgumentList(l, clang::TemplateArgumentHandler(TypeInfoTemplateArgumentHandler(this)), from);
+}
+
+QString TypeInfo::toString() const
+{
+ QString tmp;
+ if (isConstant())
+ tmp += QLatin1String("const ");
+
+ if (isVolatile())
+ tmp += QLatin1String("volatile ");
+
+ tmp += m_qualifiedName.join(QLatin1String("::"));
+
+ if (const int instantiationCount = m_instantiations.size()) {
+ tmp += QLatin1Char('<');
+ for (int i = 0; i < instantiationCount; ++i) {
+ if (i)
+ tmp += QLatin1String(", ");
+ tmp += m_instantiations.at(i).toString();
+ }
+ if (tmp.endsWith(QLatin1Char('>')))
+ tmp += QLatin1Char(' ');
+ tmp += QLatin1Char('>');
+ }
+
+ for (Indirection i : m_indirections)
+ tmp.append(indirectionKeyword(i));
+
+ switch (referenceType()) {
+ case NoReference:
+ break;
+ case LValueReference:
+ tmp += QLatin1Char('&');
+ break;
+ case RValueReference:
+ tmp += QLatin1String("&&");
+ break;
+ }
+
+ if (isFunctionPointer()) {
+ tmp += QLatin1String(" (*)(");
+ for (int i = 0; i < m_arguments.count(); ++i) {
+ if (i != 0)
+ tmp += QLatin1String(", ");
+
+ tmp += m_arguments.at(i).toString();
+ }
+ tmp += QLatin1Char(')');
+ }
+
+ for (const QString &elt : m_arrayElements) {
+ tmp += QLatin1Char('[');
+ tmp += elt;
+ tmp += QLatin1Char(']');
+ }
+
+ return tmp;
+}
+
+bool TypeInfo::operator==(const TypeInfo &other) const
+{
+ if (arrayElements().count() != other.arrayElements().count())
+ return false;
+
+#if defined (RXX_CHECK_ARRAY_ELEMENTS) // ### it'll break
+ for (int i = 0; i < arrayElements().count(); ++i) {
+ QString elt1 = arrayElements().at(i).trimmed();
+ QString elt2 = other.arrayElements().at(i).trimmed();
+
+ if (elt1 != elt2)
+ return false;
+ }
+#endif
+
+ return flags == other.flags
+ && m_qualifiedName == other.m_qualifiedName
+ && (!m_functionPointer || m_arguments == other.m_arguments)
+ && m_instantiations == other.m_instantiations;
+}
+
+QString TypeInfo::indirectionKeyword(Indirection i)
+{
+ return i == Indirection::Pointer
+ ? QStringLiteral("*") : QStringLiteral("*const");
+}
+
+static inline QString constQualifier() { return QStringLiteral("const"); }
+static inline QString volatileQualifier() { return QStringLiteral("volatile"); }
+
+bool TypeInfo::stripLeadingConst(QString *s)
+{
+ return stripLeadingQualifier(constQualifier(), s);
+}
+
+bool TypeInfo::stripLeadingVolatile(QString *s)
+{
+ return stripLeadingQualifier(volatileQualifier(), s);
+}
+
+bool TypeInfo::stripLeadingQualifier(const QString &qualifier, QString *s)
+{
+ // "const int x"
+ const int qualifierSize = qualifier.size();
+ if (s->size() < qualifierSize + 1 || !s->startsWith(qualifier)
+ || !s->at(qualifierSize).isSpace()) {
+ return false;
+ }
+ s->remove(0, qualifierSize + 1);
+ while (!s->isEmpty() && s->at(0).isSpace())
+ s->remove(0, 1);
+ return true;
+}
+
+// Strip all const/volatile/*/&
+void TypeInfo::stripQualifiers(QString *s)
+{
+ stripLeadingConst(s);
+ stripLeadingVolatile(s);
+ while (s->endsWith(QLatin1Char('&')) || s->endsWith(QLatin1Char('*'))
+ || s->endsWith(QLatin1Char(' '))) {
+ s->chop(1);
+ }
+}
+
+// Helper functionality to simplify a raw standard type as returned by
+// clang_getCanonicalType() for g++ standard containers from
+// "std::__cxx11::list<int, std::allocator<int> >" or
+// "std::__1::list<int, std::allocator<int> >" -> "std::list<int>".
+
+bool TypeInfo::isStdType() const
+{
+ return m_qualifiedName.size() > 1
+ && m_qualifiedName.constFirst() == QLatin1String("std");
+}
+
+static inline bool discardStdType(const QString &name)
+{
+ return name == QLatin1String("allocator") || name == QLatin1String("less");
+}
+
+void TypeInfo::simplifyStdType()
+{
+ if (isStdType()) {
+ if (m_qualifiedName.at(1).startsWith(QLatin1String("__")))
+ m_qualifiedName.removeAt(1);
+ for (int t = m_instantiations.size() - 1; t >= 0; --t) {
+ if (m_instantiations.at(t).isStdType()) {
+ if (discardStdType(m_instantiations.at(t).m_qualifiedName.constLast()))
+ m_instantiations.removeAt(t);
+ else
+ m_instantiations[t].simplifyStdType();
+ }
+ }
+ }
+}
+
+void TypeInfo::formatTypeSystemSignature(QTextStream &str) const
+{
+ if (m_constant)
+ str << "const ";
+ str << m_qualifiedName.join(QLatin1String("::"));
+ switch (m_referenceType) {
+ case NoReference:
+ break;
+ case LValueReference:
+ str << '&';
+ break;
+ case RValueReference:
+ str << "&&";
+ break;
+ }
+ for (auto i : m_indirections) {
+ switch (i) {
+ case Indirection::Pointer:
+ str << '*';
+ break;
+ case Indirection::ConstPointer:
+ str << "* const";
+ break;
+ }
+ }
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+template <class It>
+void formatSequence(QDebug &d, It i1, It i2, const char *separator=", ")
+{
+ for (It i = i1; i != i2; ++i) {
+ if (i != i1)
+ d << separator;
+ d << *i;
+ }
+}
+
+void TypeInfo::formatDebug(QDebug &d) const
+{
+ d << '"';
+ formatSequence(d, m_qualifiedName.begin(), m_qualifiedName.end(), "\", \"");
+ d << '"';
+ if (m_constant)
+ d << ", [const]";
+ if (m_volatile)
+ d << ", [volatile]";
+ if (!m_indirections.isEmpty()) {
+ d << ", indirections=";
+ for (auto i : m_indirections)
+ d << ' ' << TypeInfo::indirectionKeyword(i);
+ }
+ switch (m_referenceType) {
+ case NoReference:
+ break;
+ case LValueReference:
+ d << ", [ref]";
+ break;
+ case RValueReference:
+ d << ", [rvalref]";
+ break;
+ }
+ if (!m_instantiations.isEmpty()) {
+ d << ", template<";
+ formatSequence(d, m_instantiations.begin(), m_instantiations.end());
+ d << '>';
+ }
+ if (m_functionPointer) {
+ d << ", function ptr(";
+ formatSequence(d, m_arguments.begin(), m_arguments.end());
+ d << ')';
+ }
+ if (!m_arrayElements.isEmpty()) {
+ d << ", array[" << m_arrayElements.size() << "][";
+ formatSequence(d, m_arrayElements.begin(), m_arrayElements.end());
+ d << ']';
+ }
+}
+
+QDebug operator<<(QDebug d, const TypeInfo &t)
+{
+ QDebugStateSaver s(d);
+ const int verbosity = d.verbosity();
+ d.noquote();
+ d.nospace();
+ d << "TypeInfo(";
+ if (verbosity > 2)
+ t.formatDebug(d);
+ else
+ d << t.toString();
+ d << ')';
+ return d;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+// ---------------------------------------------------------------------------
+_CodeModelItem::_CodeModelItem(CodeModel *model, int kind)
+ : m_model(model),
+ m_kind(kind),
+ m_startLine(0),
+ m_startColumn(0),
+ m_endLine(0),
+ m_endColumn(0)
+{
+}
+
+_CodeModelItem::_CodeModelItem(CodeModel *model, const QString &name, int kind)
+ : m_model(model),
+ m_kind(kind),
+ m_startLine(0),
+ m_startColumn(0),
+ m_endLine(0),
+ m_endColumn(0),
+ m_name(name)
+{
+}
+
+_CodeModelItem::~_CodeModelItem() = default;
+
+int _CodeModelItem::kind() const
+{
+ return m_kind;
+}
+
+QStringList _CodeModelItem::qualifiedName() const
+{
+ QStringList q = scope();
+
+ if (!name().isEmpty())
+ q += name();
+
+ return q;
+}
+
+QString _CodeModelItem::name() const
+{
+ return m_name;
+}
+
+void _CodeModelItem::setName(const QString &name)
+{
+ m_name = name;
+}
+
+QStringList _CodeModelItem::scope() const
+{
+ return m_scope;
+}
+
+void _CodeModelItem::setScope(const QStringList &scope)
+{
+ m_scope = scope;
+}
+
+QString _CodeModelItem::fileName() const
+{
+ return m_fileName;
+}
+
+void _CodeModelItem::setFileName(const QString &fileName)
+{
+ m_fileName = fileName;
+}
+
+FileModelItem _CodeModelItem::file() const
+{
+ return model()->findFile(fileName());
+}
+
+void _CodeModelItem::getStartPosition(int *line, int *column)
+{
+ *line = m_startLine;
+ *column = m_startColumn;
+}
+
+void _CodeModelItem::setStartPosition(int line, int column)
+{
+ m_startLine = line;
+ m_startColumn = column;
+}
+
+void _CodeModelItem::getEndPosition(int *line, int *column)
+{
+ *line = m_endLine;
+ *column = m_endColumn;
+}
+
+void _CodeModelItem::setEndPosition(int line, int column)
+{
+ m_endLine = line;
+ m_endColumn = column;
+}
+
+SourceLocation _CodeModelItem::sourceLocation() const
+{
+ return SourceLocation(m_fileName, m_startLine);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+template <class It>
+static void formatPtrSequence(QDebug &d, It i1, It i2, const char *separator=", ")
+{
+ for (It i = i1; i != i2; ++i) {
+ if (i != i1)
+ d << separator;
+ d << i->data();
+ }
+}
+
+void _CodeModelItem::formatKind(QDebug &d, int k)
+{
+ switch (k) {
+ case Kind_Argument:
+ d << "ArgumentModelItem";
+ break;
+ case Kind_Class:
+ d << "ClassModelItem";
+ break;
+ case Kind_Enum:
+ d << "EnumModelItem";
+ break;
+ case Kind_Enumerator:
+ d << "EnumeratorModelItem";
+ break;
+ case Kind_File:
+ d << "FileModelItem";
+ break;
+ case Kind_Function:
+ d << "FunctionModelItem";
+ break;
+ case Kind_Member:
+ d << "MemberModelItem";
+ break;
+ case Kind_Namespace:
+ d << "NamespaceModelItem";
+ break;
+ case Kind_Variable:
+ d << "VariableModelItem";
+ break;
+ case Kind_Scope:
+ d << "ScopeModelItem";
+ break;
+ case Kind_TemplateParameter:
+ d << "TemplateParameter";
+ break;
+ case Kind_TypeDef:
+ d << "TypeDefModelItem";
+ break;
+ case Kind_TemplateTypeAlias:
+ d << "TemplateTypeAliasModelItem";
+ break;
+ default:
+ d << "CodeModelItem";
+ break;
+ }
+}
+
+void _CodeModelItem::formatDebug(QDebug &d) const
+{
+ d << "(\"" << name() << '"';
+ if (!m_scope.isEmpty()) {
+ d << ", scope=";
+ formatSequence(d, m_scope.cbegin(), m_scope.cend(), "::");
+ }
+ if (!m_fileName.isEmpty()) {
+ d << ", file=\"" << QDir::toNativeSeparators(m_fileName);
+ if (m_startLine > 0)
+ d << ':' << m_startLine;
+ d << '"';
+ }
+}
+
+QDebug operator<<(QDebug d, const _CodeModelItem *t)
+{
+ QDebugStateSaver s(d);
+ d.noquote();
+ d.nospace();
+ if (!t) {
+ d << "CodeModelItem(0)";
+ return d;
+ }
+ _CodeModelItem::formatKind(d, t->kind());
+ t->formatDebug(d);
+ switch (t->kind()) {
+ case _CodeModelItem::Kind_Class:
+ d << " /* class " << t->name() << " */";
+ break;
+ case _CodeModelItem::Kind_Namespace:
+ d << " /* namespace " << t->name() << " */";
+ break;
+ }
+ d << ')';
+ return d;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+// ---------------------------------------------------------------------------
+_ClassModelItem::~_ClassModelItem() = default;
+
+TemplateParameterList _ClassModelItem::templateParameters() const
+{
+ return m_templateParameters;
+}
+
+void _ClassModelItem::setTemplateParameters(const TemplateParameterList &templateParameters)
+{
+ m_templateParameters = templateParameters;
+}
+
+void _ClassModelItem::addBaseClass(const QString &name, CodeModel::AccessPolicy accessPolicy)
+{
+ _ClassModelItem::BaseClass baseClass;
+ baseClass.name = name;
+ baseClass.accessPolicy = accessPolicy;
+ m_baseClasses.append(baseClass);
+}
+
+bool _ClassModelItem::extendsClass(const QString &name) const
+{
+ for (const BaseClass &bc : m_baseClasses) {
+ if (bc.name == name)
+ return true;
+ }
+ return false;
+}
+
+void _ClassModelItem::setClassType(CodeModel::ClassType type)
+{
+ m_classType = type;
+}
+
+CodeModel::ClassType _ClassModelItem::classType() const
+{
+ return m_classType;
+}
+
+void _ClassModelItem::addPropertyDeclaration(const QString &propertyDeclaration)
+{
+ m_propertyDeclarations << propertyDeclaration;
+}
+
+bool _ClassModelItem::isEmpty() const
+{
+ return _ScopeModelItem::isEmpty() && m_propertyDeclarations.isEmpty();
+}
+
+bool _ClassModelItem::isTemplate() const
+{
+ return !m_templateParameters.isEmpty();
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+template <class List>
+static void formatModelItemList(QDebug &d, const char *prefix, const List &l,
+ const char *separator = ", ")
+{
+ if (const int size = l.size()) {
+ d << prefix << '[' << size << "](";
+ for (int i = 0; i < size; ++i) {
+ if (i)
+ d << separator;
+ l.at(i)->formatDebug(d);
+ }
+ d << ')';
+ }
+}
+
+void _ClassModelItem::formatDebug(QDebug &d) const
+{
+ _ScopeModelItem::formatDebug(d);
+ if (!m_baseClasses.isEmpty()) {
+ if (m_final)
+ d << " [final]";
+ d << ", inherits=";
+ d << ", inherits=";
+ for (int i = 0, size = m_baseClasses.size(); i < size; ++i) {
+ if (i)
+ d << ", ";
+ d << m_baseClasses.at(i).name << " (" << m_baseClasses.at(i).accessPolicy << ')';
+ }
+ }
+ formatModelItemList(d, ", templateParameters=", m_templateParameters);
+ formatScopeItemsDebug(d);
+ if (!m_propertyDeclarations.isEmpty())
+ d << ", Properties=" << m_propertyDeclarations;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+// ---------------------------------------------------------------------------
+FunctionModelItem _ScopeModelItem::declaredFunction(const FunctionModelItem &item)
+{
+ for (const FunctionModelItem &fun : qAsConst(m_functions)) {
+ if (fun->name() == item->name() && fun->isSimilar(item))
+ return fun;
+
+ }
+ return FunctionModelItem();
+}
+
+_ScopeModelItem::~_ScopeModelItem() = default;
+
+void _ScopeModelItem::addEnumsDeclaration(const QString &enumsDeclaration)
+{
+ m_enumsDeclarations << enumsDeclaration;
+}
+
+void _ScopeModelItem::addClass(const ClassModelItem &item)
+{
+ m_classes.append(item);
+}
+
+void _ScopeModelItem::addFunction(const FunctionModelItem &item)
+{
+ m_functions.append(item);
+}
+
+void _ScopeModelItem::addVariable(const VariableModelItem &item)
+{
+ m_variables.append(item);
+}
+
+void _ScopeModelItem::addTypeDef(const TypeDefModelItem &item)
+{
+ m_typeDefs.append(item);
+}
+
+void _ScopeModelItem::addTemplateTypeAlias(const TemplateTypeAliasModelItem &item)
+{
+ m_templateTypeAliases.append(item);
+}
+
+void _ScopeModelItem::addEnum(const EnumModelItem &item)
+{
+ m_enums.append(item);
+}
+
+void _ScopeModelItem::appendScope(const _ScopeModelItem &other)
+{
+ m_classes += other.m_classes;
+ m_enums += other.m_enums;
+ m_typeDefs += other.m_typeDefs;
+ m_templateTypeAliases += other.m_templateTypeAliases;
+ m_variables += other.m_variables;
+ m_functions += other.m_functions;
+ m_enumsDeclarations += other.m_enumsDeclarations;
+}
+
+bool _ScopeModelItem::isEmpty() const
+{
+ return m_classes.isEmpty() && m_enums.isEmpty()
+ && m_typeDefs.isEmpty() && m_templateTypeAliases.isEmpty()
+ && m_variables.isEmpty() && m_functions.isEmpty()
+ && m_enumsDeclarations.isEmpty();
+}
+
+/* This function removes MSVC export declarations of non-type template
+ * specializations (see below code from photon.h) for which
+ * clang_isCursorDefinition() returns true, causing them to be added as
+ * definitions of empty classes shadowing the template definition depending
+ * on QHash seed values.
+
+template <int N> class Tpl
+{
+public:
+...
+};
+
+#ifdef WIN32
+template class LIBSAMPLE_EXPORT Tpl<54>;
+*/
+void _ScopeModelItem::purgeClassDeclarations()
+{
+ for (int i = m_classes.size() - 1; i >= 0; --i) {
+ auto klass = m_classes.at(i);
+ // For an empty class, check if there is a matching template
+ // definition, and remove it if this is the case.
+ if (!klass->isTemplate() && klass->isEmpty()) {
+ const QString definitionPrefix = klass->name() + QLatin1Char('<');
+ const bool definitionFound =
+ std::any_of(m_classes.cbegin(), m_classes.cend(),
+ [definitionPrefix] (const ClassModelItem &c) {
+ return c->isTemplate() && !c->isEmpty()
+ && c->name().startsWith(definitionPrefix);
+ });
+ if (definitionFound)
+ m_classes.removeAt(i);
+ }
+ }
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+template <class Hash>
+static void formatScopeHash(QDebug &d, const char *prefix, const Hash &h,
+ const char *separator = ", ",
+ bool trailingNewLine = false)
+{
+ if (!h.isEmpty()) {
+ d << prefix << '[' << h.size() << "](";
+ const auto begin = h.cbegin();
+ for (auto it = begin, end = h.cend(); it != end; ++it) { // Omit the names as they are repeated
+ if (it != begin)
+ d << separator;
+ d << it.value().data();
+ }
+ d << ')';
+ if (trailingNewLine)
+ d << '\n';
+ }
+}
+
+template <class List>
+static void formatScopeList(QDebug &d, const char *prefix, const List &l,
+ const char *separator = ", ",
+ bool trailingNewLine = false)
+{
+ if (!l.isEmpty()) {
+ d << prefix << '[' << l.size() << "](";
+ formatPtrSequence(d, l.begin(), l.end(), separator);
+ d << ')';
+ if (trailingNewLine)
+ d << '\n';
+ }
+}
+
+void _ScopeModelItem::formatScopeItemsDebug(QDebug &d) const
+{
+ formatScopeList(d, ", classes=", m_classes, "\n", true);
+ formatScopeList(d, ", enums=", m_enums, "\n", true);
+ formatScopeList(d, ", aliases=", m_typeDefs, "\n", true);
+ formatScopeList(d, ", template type aliases=", m_templateTypeAliases, "\n", true);
+ formatScopeList(d, ", functions=", m_functions, "\n", true);
+ formatScopeList(d, ", variables=", m_variables);
+}
+
+void _ScopeModelItem::formatDebug(QDebug &d) const
+{
+ _CodeModelItem::formatDebug(d);
+ formatScopeItemsDebug(d);
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+namespace {
+// Predicate to match a non-template class name against the class list.
+// "Vector" should match "Vector" as well as "Vector<T>" (as seen for methods
+// from within the class "Vector").
+class ClassNamePredicate
+{
+public:
+ explicit ClassNamePredicate(const QString &name) : m_name(name) {}
+ bool operator()(const ClassModelItem &item) const
+ {
+ const QString &itemName = item->name();
+ if (!itemName.startsWith(m_name))
+ return false;
+ return itemName.size() == m_name.size() || itemName.at(m_name.size()) == QLatin1Char('<');
+ }
+
+private:
+ const QString m_name;
+};
+} // namespace
+
+ClassModelItem _ScopeModelItem::findClass(const QString &name) const
+{
+ // A fully qualified template is matched by name only
+ const ClassList::const_iterator it = name.contains(QLatin1Char('<'))
+ ? std::find_if(m_classes.begin(), m_classes.end(), ModelItemNamePredicate<_ClassModelItem>(name))
+ : std::find_if(m_classes.begin(), m_classes.end(), ClassNamePredicate(name));
+ return it != m_classes.end() ? *it : ClassModelItem();
+}
+
+VariableModelItem _ScopeModelItem::findVariable(const QString &name) const
+{
+ return findModelItem(m_variables, name);
+}
+
+TypeDefModelItem _ScopeModelItem::findTypeDef(const QString &name) const
+{
+ return findModelItem(m_typeDefs, name);
+}
+
+TemplateTypeAliasModelItem _ScopeModelItem::findTemplateTypeAlias(const QString &name) const
+{
+ return findModelItem(m_templateTypeAliases, name);
+}
+
+EnumModelItem _ScopeModelItem::findEnum(const QString &name) const
+{
+ return findModelItem(m_enums, name);
+}
+
+FunctionList _ScopeModelItem::findFunctions(const QString &name) const
+{
+ FunctionList result;
+ for (const FunctionModelItem &func : m_functions) {
+ if (func->name() == name)
+ result.append(func);
+ }
+ return result;
+}
+
+// ---------------------------------------------------------------------------
+_NamespaceModelItem::~_NamespaceModelItem()
+{
+}
+
+void _NamespaceModelItem::addNamespace(NamespaceModelItem item)
+{
+ m_namespaces.append(item);
+}
+
+NamespaceModelItem _NamespaceModelItem::findNamespace(const QString &name) const
+{
+ return findModelItem(m_namespaces, name);
+}
+
+_FileModelItem::~_FileModelItem() = default;
+
+void _NamespaceModelItem::appendNamespace(const _NamespaceModelItem &other)
+{
+ appendScope(other);
+ m_namespaces += other.m_namespaces;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+void _NamespaceModelItem::formatDebug(QDebug &d) const
+{
+ _ScopeModelItem::formatDebug(d);
+ switch (m_type) {
+ case NamespaceType::Default:
+ break;
+ case NamespaceType::Anonymous:
+ d << ", anonymous";
+ break;
+ case NamespaceType::Inline:
+ d << ", inline";
+ break;
+ }
+ formatScopeList(d, ", namespaces=", m_namespaces);
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+// ---------------------------------------------------------------------------
+_ArgumentModelItem::~_ArgumentModelItem()
+{
+}
+
+TypeInfo _ArgumentModelItem::type() const
+{
+ return m_type;
+}
+
+void _ArgumentModelItem::setType(const TypeInfo &type)
+{
+ m_type = type;
+}
+
+bool _ArgumentModelItem::defaultValue() const
+{
+ return m_defaultValue;
+}
+
+void _ArgumentModelItem::setDefaultValue(bool defaultValue)
+{
+ m_defaultValue = defaultValue;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+void _ArgumentModelItem::formatDebug(QDebug &d) const
+{
+ _CodeModelItem::formatDebug(d);
+ d << ", type=" << m_type;
+ if (m_defaultValue)
+ d << ", defaultValue=\"" << m_defaultValueExpression << '"';
+}
+#endif // !QT_NO_DEBUG_STREAM
+// ---------------------------------------------------------------------------
+_FunctionModelItem::~_FunctionModelItem() = default;
+
+bool _FunctionModelItem::isSimilar(const FunctionModelItem &other) const
+{
+ if (name() != other->name())
+ return false;
+
+ if (isConstant() != other->isConstant())
+ return false;
+
+ if (isVariadics() != other->isVariadics())
+ return false;
+
+ if (arguments().count() != other->arguments().count())
+ return false;
+
+ // ### check the template parameters
+
+ for (int i = 0; i < arguments().count(); ++i) {
+ ArgumentModelItem arg1 = arguments().at(i);
+ ArgumentModelItem arg2 = other->arguments().at(i);
+
+ if (arg1->type() != arg2->type())
+ return false;
+ }
+
+ return true;
+}
+
+ArgumentList _FunctionModelItem::arguments() const
+{
+ return m_arguments;
+}
+
+void _FunctionModelItem::addArgument(const ArgumentModelItem& item)
+{
+ m_arguments.append(item);
+}
+
+CodeModel::FunctionType _FunctionModelItem::functionType() const
+{
+ return m_functionType;
+}
+
+void _FunctionModelItem::setFunctionType(CodeModel::FunctionType functionType)
+{
+ m_functionType = functionType;
+}
+
+bool _FunctionModelItem::isVariadics() const
+{
+ return m_isVariadics;
+}
+
+void _FunctionModelItem::setVariadics(bool isVariadics)
+{
+ m_isVariadics = isVariadics;
+}
+
+bool _FunctionModelItem::isNoExcept() const
+{
+ return m_exceptionSpecification == ExceptionSpecification::NoExcept;
+}
+
+ExceptionSpecification _FunctionModelItem::exceptionSpecification() const
+{
+ return m_exceptionSpecification;
+}
+
+void _FunctionModelItem::setExceptionSpecification(ExceptionSpecification e)
+{
+ m_exceptionSpecification = e;
+}
+
+bool _FunctionModelItem::isDeleted() const
+{
+ return m_isDeleted;
+}
+
+void _FunctionModelItem::setDeleted(bool d)
+{
+ m_isDeleted = d;
+}
+
+bool _FunctionModelItem::isDeprecated() const
+{
+ return m_isDeprecated;
+}
+
+void _FunctionModelItem::setDeprecated(bool d)
+{
+ m_isDeprecated = d;
+}
+
+bool _FunctionModelItem::isVirtual() const
+{
+ return m_isVirtual;
+}
+
+void _FunctionModelItem::setVirtual(bool isVirtual)
+{
+ m_isVirtual = isVirtual;
+}
+
+bool _FunctionModelItem::isInline() const
+{
+ return m_isInline;
+}
+
+bool _FunctionModelItem::isOverride() const
+{
+ return m_isOverride;
+}
+
+void _FunctionModelItem::setOverride(bool o)
+{
+ m_isOverride = o;
+}
+
+bool _FunctionModelItem::isFinal() const
+{
+ return m_isFinal;
+}
+
+void _FunctionModelItem::setFinal(bool f)
+{
+ m_isFinal = f;
+}
+
+void _FunctionModelItem::setInline(bool isInline)
+{
+ m_isInline = isInline;
+}
+
+bool _FunctionModelItem::isExplicit() const
+{
+ return m_isExplicit;
+}
+
+void _FunctionModelItem::setExplicit(bool isExplicit)
+{
+ m_isExplicit = isExplicit;
+}
+
+bool _FunctionModelItem::isAbstract() const
+{
+ return m_isAbstract;
+}
+
+void _FunctionModelItem::setAbstract(bool isAbstract)
+{
+ m_isAbstract = isAbstract;
+}
+
+// Qt
+bool _FunctionModelItem::isInvokable() const
+{
+ return m_isInvokable;
+}
+
+void _FunctionModelItem::setInvokable(bool isInvokable)
+{
+ m_isInvokable = isInvokable;
+}
+
+QString _FunctionModelItem::typeSystemSignature() const // For dumping out type system files
+{
+ QString result;
+ QTextStream str(&result);
+ str << name() << '(';
+ for (int a = 0, size = m_arguments.size(); a < size; ++a) {
+ if (a)
+ str << ',';
+ m_arguments.at(a)->type().formatTypeSystemSignature(str);
+ }
+ str << ')';
+ return result;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+void _FunctionModelItem::formatDebug(QDebug &d) const
+{
+ _MemberModelItem::formatDebug(d);
+ d << ", type=" << m_functionType << ", exspec=" << int(m_exceptionSpecification);
+ if (m_isDeleted)
+ d << " [deleted!]";
+ if (m_isInline)
+ d << " [inline]";
+ if (m_isVirtual)
+ d << " [virtual]";
+ if (m_isOverride)
+ d << " [override]";
+ if (m_isDeprecated)
+ d << " [deprecated]";
+ if (m_isFinal)
+ d << " [final]";
+ if (m_isAbstract)
+ d << " [abstract]";
+ if (m_isExplicit)
+ d << " [explicit]";
+ if (m_isInvokable)
+ d << " [invokable]";
+ formatModelItemList(d, ", arguments=", m_arguments);
+ if (m_isVariadics)
+ d << ",...";
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+// ---------------------------------------------------------------------------
+TypeInfo _TypeDefModelItem::type() const
+{
+ return m_type;
+}
+
+void _TypeDefModelItem::setType(const TypeInfo &type)
+{
+ m_type = type;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+void _TypeDefModelItem::formatDebug(QDebug &d) const
+{
+ _CodeModelItem::formatDebug(d);
+ d << ", type=" << m_type;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+// ---------------------------------------------------------------------------
+
+_TemplateTypeAliasModelItem::_TemplateTypeAliasModelItem(CodeModel *model, int kind)
+ : _CodeModelItem(model, kind) {}
+
+_TemplateTypeAliasModelItem::_TemplateTypeAliasModelItem(CodeModel *model, const QString &name, int kind)
+ : _CodeModelItem(model, name, kind) {}
+
+TemplateParameterList _TemplateTypeAliasModelItem::templateParameters() const
+{
+ return m_templateParameters;
+}
+
+void _TemplateTypeAliasModelItem::addTemplateParameter(const TemplateParameterModelItem &templateParameter)
+{
+ m_templateParameters.append(templateParameter);
+}
+
+TypeInfo _TemplateTypeAliasModelItem::type() const
+{
+ return m_type;
+}
+
+void _TemplateTypeAliasModelItem::setType(const TypeInfo &type)
+{
+ m_type = type;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+void _TemplateTypeAliasModelItem::formatDebug(QDebug &d) const
+{
+ _CodeModelItem::formatDebug(d);
+ d << ", <";
+ for (int i = 0, count = m_templateParameters.size(); i < count; ++i) {
+ if (i)
+ d << ", ";
+ d << m_templateParameters.at(i)->name();
+ }
+ d << ">, type=" << m_type;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+// ---------------------------------------------------------------------------
+CodeModel::AccessPolicy _EnumModelItem::accessPolicy() const
+{
+ return m_accessPolicy;
+}
+
+_EnumModelItem::~_EnumModelItem() = default;
+
+void _EnumModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy)
+{
+ m_accessPolicy = accessPolicy;
+}
+
+EnumeratorList _EnumModelItem::enumerators() const
+{
+ return m_enumerators;
+}
+
+void _EnumModelItem::addEnumerator(const EnumeratorModelItem &item)
+{
+ m_enumerators.append(item);
+}
+
+bool _EnumModelItem::isSigned() const
+{
+ return m_signed;
+}
+
+void _EnumModelItem::setSigned(bool s)
+{
+ m_signed = s;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+void _EnumModelItem::formatDebug(QDebug &d) const
+{
+ _CodeModelItem::formatDebug(d);
+ switch (m_enumKind) {
+ case CEnum:
+ break;
+ case AnonymousEnum:
+ d << " (anonymous)";
+ break;
+ case EnumClass:
+ d << " (class)";
+ break;
+ }
+ if (!m_signed)
+ d << " (unsigned)";
+ formatModelItemList(d, ", enumerators=", m_enumerators);
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+// ---------------------------------------------------------------------------
+_EnumeratorModelItem::~_EnumeratorModelItem() = default;
+
+QString _EnumeratorModelItem::stringValue() const
+{
+ return m_stringValue;
+}
+
+void _EnumeratorModelItem::setStringValue(const QString &value)
+{
+ m_stringValue = value;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+void _EnumeratorModelItem::formatDebug(QDebug &d) const
+{
+ _CodeModelItem::formatDebug(d);
+ d << ", value=" << m_value << ", stringValue=\"" << m_stringValue << '"';
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+// ---------------------------------------------------------------------------
+_TemplateParameterModelItem::~_TemplateParameterModelItem() = default;
+
+TypeInfo _TemplateParameterModelItem::type() const
+{
+ return m_type;
+}
+
+void _TemplateParameterModelItem::setType(const TypeInfo &type)
+{
+ m_type = type;
+}
+
+bool _TemplateParameterModelItem::defaultValue() const
+{
+ return m_defaultValue;
+}
+
+void _TemplateParameterModelItem::setDefaultValue(bool defaultValue)
+{
+ m_defaultValue = defaultValue;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+void _TemplateParameterModelItem::formatDebug(QDebug &d) const
+{
+ _CodeModelItem::formatDebug(d);
+ d << ", type=" << m_type;
+ if (m_defaultValue)
+ d << " [defaultValue]";
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+// ---------------------------------------------------------------------------
+TypeInfo _MemberModelItem::type() const
+{
+ return m_type;
+}
+
+void _MemberModelItem::setType(const TypeInfo &type)
+{
+ m_type = type;
+}
+
+CodeModel::AccessPolicy _MemberModelItem::accessPolicy() const
+{
+ return m_accessPolicy;
+}
+
+_MemberModelItem::~_MemberModelItem() = default;
+
+void _MemberModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy)
+{
+ m_accessPolicy = accessPolicy;
+}
+
+bool _MemberModelItem::isStatic() const
+{
+ return m_isStatic;
+}
+
+void _MemberModelItem::setStatic(bool isStatic)
+{
+ m_isStatic = isStatic;
+}
+
+bool _MemberModelItem::isConstant() const
+{
+ return m_isConstant;
+}
+
+void _MemberModelItem::setConstant(bool isConstant)
+{
+ m_isConstant = isConstant;
+}
+
+bool _MemberModelItem::isVolatile() const
+{
+ return m_isVolatile;
+}
+
+void _MemberModelItem::setVolatile(bool isVolatile)
+{
+ m_isVolatile = isVolatile;
+}
+
+bool _MemberModelItem::isAuto() const
+{
+ return m_isAuto;
+}
+
+void _MemberModelItem::setAuto(bool isAuto)
+{
+ m_isAuto = isAuto;
+}
+
+bool _MemberModelItem::isFriend() const
+{
+ return m_isFriend;
+}
+
+void _MemberModelItem::setFriend(bool isFriend)
+{
+ m_isFriend = isFriend;
+}
+
+bool _MemberModelItem::isRegister() const
+{
+ return m_isRegister;
+}
+
+void _MemberModelItem::setRegister(bool isRegister)
+{
+ m_isRegister = isRegister;
+}
+
+bool _MemberModelItem::isExtern() const
+{
+ return m_isExtern;
+}
+
+void _MemberModelItem::setExtern(bool isExtern)
+{
+ m_isExtern = isExtern;
+}
+
+bool _MemberModelItem::isMutable() const
+{
+ return m_isMutable;
+}
+
+void _MemberModelItem::setMutable(bool isMutable)
+{
+ m_isMutable = isMutable;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+void _MemberModelItem::formatDebug(QDebug &d) const
+{
+ _CodeModelItem::formatDebug(d);
+ switch (m_accessPolicy) {
+ case CodeModel::Public:
+ d << ", public";
+ break;
+ case CodeModel::Protected:
+ d << ", protected";
+ break;
+ case CodeModel::Private:
+ d << ", private";
+ break;
+ }
+ d << ", type=";
+ if (m_isConstant)
+ d << "const ";
+ if (m_isVolatile)
+ d << "volatile ";
+ if (m_isStatic)
+ d << "static ";
+ if (m_isAuto)
+ d << "auto ";
+ if (m_isFriend)
+ d << "friend ";
+ if (m_isRegister)
+ d << "register ";
+ if (m_isExtern)
+ d << "extern ";
+ if (m_isMutable)
+ d << "mutable ";
+ d << m_type;
+ formatScopeList(d, ", templateParameters", m_templateParameters);
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel.h b/sources/shiboken6/ApiExtractor/parser/codemodel.h
new file mode 100644
index 000000000..13bc7cf36
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel.h
@@ -0,0 +1,814 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef CODEMODEL_H
+#define CODEMODEL_H
+
+#include "codemodel_fwd.h"
+#include "codemodel_enums.h"
+#include "enumvalue.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QPair>
+#include <QtCore/QSet>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVector>
+
+QT_FORWARD_DECLARE_CLASS(QDebug)
+
+#define DECLARE_MODEL_NODE(k) \
+ enum { __node_kind = Kind_##k };
+
+class SourceLocation;
+
+class CodeModel
+{
+public:
+ Q_DISABLE_COPY(CodeModel)
+
+ enum AccessPolicy {
+ Public,
+ Protected,
+ Private
+ };
+
+ enum FunctionType {
+ Normal,
+ Constructor,
+ CopyConstructor,
+ MoveConstructor,
+ Destructor,
+ Signal,
+ Slot
+ };
+
+ enum ClassType {
+ Class,
+ Struct,
+ Union
+ };
+
+public:
+ CodeModel();
+ virtual ~CodeModel();
+
+ FileList files() const { return m_files; }
+ NamespaceModelItem globalNamespace() const;
+
+ void addFile(const FileModelItem &item);
+ FileModelItem findFile(const QString &name) const;
+
+ CodeModelItem findItem(const QStringList &qualifiedName, const ScopeModelItem &scope) const;
+
+private:
+ FileList m_files;
+ NamespaceModelItem m_globalNamespace;
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const CodeModel *m);
+#endif
+
+class TypeInfo
+{
+ friend class TypeParser;
+public:
+ using Indirections = QVector<Indirection>;
+
+ TypeInfo() : flags(0), m_referenceType(NoReference) {}
+
+ QStringList qualifiedName() const
+ {
+ return m_qualifiedName;
+ }
+
+ void setQualifiedName(const QStringList &qualified_name)
+ {
+ m_qualifiedName = qualified_name;
+ }
+
+ bool isVoid() const;
+
+ bool isConstant() const
+ {
+ return m_constant;
+ }
+
+ void setConstant(bool is)
+ {
+ m_constant = is;
+ }
+
+ bool isVolatile() const
+ {
+ return m_volatile;
+ }
+
+ void setVolatile(bool is)
+ {
+ m_volatile = is;
+ }
+
+ ReferenceType referenceType() const { return m_referenceType; }
+ void setReferenceType(ReferenceType r) { m_referenceType = r; }
+
+ Indirections indirectionsV() const { return m_indirections; }
+ void setIndirectionsV(const Indirections &i) { m_indirections = i; }
+ void addIndirection(Indirection i) { m_indirections.append(i); }
+
+ // "Legacy", rename?
+ int indirections() const { return m_indirections.size(); }
+
+ void setIndirections(int indirections)
+ {
+ m_indirections = Indirections(indirections, Indirection::Pointer);
+ }
+
+ bool isFunctionPointer() const
+ {
+ return m_functionPointer;
+ }
+ void setFunctionPointer(bool is)
+ {
+ m_functionPointer = is;
+ }
+
+ QStringList arrayElements() const
+ {
+ return m_arrayElements;
+ }
+ void setArrayElements(const QStringList &arrayElements)
+ {
+ m_arrayElements = arrayElements;
+ }
+
+ void addArrayElement(const QString &a) { m_arrayElements.append(a); }
+
+ QVector<TypeInfo> arguments() const { return m_arguments; }
+
+ void setArguments(const QVector<TypeInfo> &arguments);
+
+ void addArgument(const TypeInfo &arg)
+ {
+ m_arguments.append(arg);
+ }
+
+ QVector<TypeInfo> instantiations() const { return m_instantiations; }
+ void setInstantiations(const QVector<TypeInfo> &i) { m_instantiations = i; }
+ void addInstantiation(const TypeInfo &i) { m_instantiations.append(i); }
+ void clearInstantiations() { m_instantiations.clear(); }
+
+ bool isStdType() const;
+
+ QPair<int, int> parseTemplateArgumentList(const QString &l, int from = 0);
+
+ bool operator==(const TypeInfo &other) const;
+
+ bool operator!=(const TypeInfo &other) const
+ {
+ return !(*this == other);
+ }
+
+ // ### arrays and templates??
+
+ QString toString() const;
+
+ static TypeInfo combine(const TypeInfo &__lhs, const TypeInfo &__rhs);
+ static TypeInfo resolveType(TypeInfo const &__type, const ScopeModelItem &__scope);
+
+ void formatTypeSystemSignature(QTextStream &str) const;
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const;
+#endif
+
+ static QString indirectionKeyword(Indirection i);
+
+ static bool stripLeadingConst(QString *s);
+ static bool stripLeadingVolatile(QString *s);
+ static bool stripLeadingQualifier(const QString &qualifier, QString *s);
+ static void stripQualifiers(QString *s);
+
+ void simplifyStdType();
+
+private:
+ friend class TypeInfoTemplateArgumentHandler;
+
+ static TypeInfo resolveType(CodeModelItem item, TypeInfo const &__type, const ScopeModelItem &__scope);
+
+ QStringList m_qualifiedName;
+ QStringList m_arrayElements;
+ QVector<TypeInfo> m_arguments;
+ QVector<TypeInfo> m_instantiations;
+ Indirections m_indirections;
+
+ union {
+ uint flags;
+
+ struct {
+ uint m_constant: 1;
+ uint m_volatile: 1;
+ uint m_functionPointer: 1;
+ uint m_padding: 29;
+ };
+ };
+
+ ReferenceType m_referenceType;
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const TypeInfo &t);
+#endif
+
+class _CodeModelItem
+{
+ Q_DISABLE_COPY(_CodeModelItem)
+public:
+ enum Kind {
+ /* These are bit-flags resembling inheritance */
+ Kind_Scope = 0x1,
+ Kind_Namespace = 0x2 | Kind_Scope,
+ Kind_Member = 0x4,
+ Kind_Function = 0x8 | Kind_Member,
+ KindMask = 0xf,
+
+ /* These are for classes that are not inherited from */
+ FirstKind = 0x8,
+ Kind_Argument = 1 << FirstKind,
+ Kind_Class = 2 << FirstKind | Kind_Scope,
+ Kind_Enum = 3 << FirstKind,
+ Kind_Enumerator = 4 << FirstKind,
+ Kind_File = 5 << FirstKind | Kind_Namespace,
+ Kind_TemplateParameter = 7 << FirstKind,
+ Kind_TypeDef = 8 << FirstKind,
+ Kind_TemplateTypeAlias = 9 << FirstKind,
+ Kind_Variable = 10 << FirstKind | Kind_Member
+ };
+
+public:
+ virtual ~_CodeModelItem();
+
+ int kind() const;
+
+ QStringList qualifiedName() const;
+
+ QString name() const;
+ void setName(const QString &name);
+
+ QStringList scope() const;
+ void setScope(const QStringList &scope);
+
+ QString fileName() const;
+ void setFileName(const QString &fileName);
+
+ FileModelItem file() const;
+
+ void getStartPosition(int *line, int *column);
+ int startLine() const { return m_startLine; }
+ void setStartPosition(int line, int column);
+
+ void getEndPosition(int *line, int *column);
+ void setEndPosition(int line, int column);
+
+ SourceLocation sourceLocation() const;
+
+ inline CodeModel *model() const { return m_model; }
+
+#ifndef QT_NO_DEBUG_STREAM
+ static void formatKind(QDebug &d, int k);
+ virtual void formatDebug(QDebug &d) const;
+#endif
+
+protected:
+ explicit _CodeModelItem(CodeModel *model, int kind);
+ explicit _CodeModelItem(CodeModel *model, const QString &name, int kind);
+
+private:
+ CodeModel *m_model;
+ int m_kind;
+ int m_startLine;
+ int m_startColumn;
+ int m_endLine;
+ int m_endColumn;
+ QString m_name;
+ QString m_fileName;
+ QStringList m_scope;
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const _CodeModelItem *t);
+#endif
+
+class _ScopeModelItem: public _CodeModelItem
+{
+public:
+ DECLARE_MODEL_NODE(Scope)
+
+ ~_ScopeModelItem();
+
+ ClassList classes() const { return m_classes; }
+ EnumList enums() const { return m_enums; }
+ inline FunctionList functions() const { return m_functions; }
+ TypeDefList typeDefs() const { return m_typeDefs; }
+ TemplateTypeAliasList templateTypeAliases() const { return m_templateTypeAliases; }
+ VariableList variables() const { return m_variables; }
+
+ void addClass(const ClassModelItem &item);
+ void addEnum(const EnumModelItem &item);
+ void addFunction(const FunctionModelItem &item);
+ void addTypeDef(const TypeDefModelItem &item);
+ void addTemplateTypeAlias(const TemplateTypeAliasModelItem &item);
+ void addVariable(const VariableModelItem &item);
+
+ ClassModelItem findClass(const QString &name) const;
+ EnumModelItem findEnum(const QString &name) const;
+ FunctionList findFunctions(const QString &name) const;
+ TypeDefModelItem findTypeDef(const QString &name) const;
+ TemplateTypeAliasModelItem findTemplateTypeAlias(const QString &name) const;
+ VariableModelItem findVariable(const QString &name) const;
+
+ void addEnumsDeclaration(const QString &enumsDeclaration);
+ QStringList enumsDeclarations() const { return m_enumsDeclarations; }
+
+ FunctionModelItem declaredFunction(const FunctionModelItem &item);
+
+ bool isEmpty() const;
+ void purgeClassDeclarations();
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+protected:
+ explicit _ScopeModelItem(CodeModel *model, int kind = __node_kind)
+ : _CodeModelItem(model, kind) {}
+ explicit _ScopeModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
+ : _CodeModelItem(model, name, kind) {}
+
+ void appendScope(const _ScopeModelItem &other);
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatScopeItemsDebug(QDebug &d) const;
+#endif
+
+private:
+ ClassList m_classes;
+ EnumList m_enums;
+ TypeDefList m_typeDefs;
+ TemplateTypeAliasList m_templateTypeAliases;
+ VariableList m_variables;
+ FunctionList m_functions;
+
+private:
+ QStringList m_enumsDeclarations;
+};
+
+class _ClassModelItem: public _ScopeModelItem
+{
+public:
+ DECLARE_MODEL_NODE(Class)
+
+ struct BaseClass
+ {
+ QString name;
+ CodeModel::AccessPolicy accessPolicy = CodeModel::Public;
+ };
+
+ explicit _ClassModelItem(CodeModel *model, int kind = __node_kind)
+ : _ScopeModelItem(model, kind), m_classType(CodeModel::Class) {}
+ explicit _ClassModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
+ : _ScopeModelItem(model, name, kind), m_classType(CodeModel::Class) {}
+ ~_ClassModelItem();
+
+ QVector<BaseClass> baseClasses() const { return m_baseClasses; }
+
+ void addBaseClass(const QString &name, CodeModel::AccessPolicy accessPolicy);
+
+ TemplateParameterList templateParameters() const;
+ void setTemplateParameters(const TemplateParameterList &templateParameters);
+
+ bool extendsClass(const QString &name) const;
+
+ void setClassType(CodeModel::ClassType type);
+ CodeModel::ClassType classType() const;
+
+ void addPropertyDeclaration(const QString &propertyDeclaration);
+ QStringList propertyDeclarations() const { return m_propertyDeclarations; }
+
+ bool isFinal() const { return m_final; }
+ void setFinal(bool f) { m_final = f; }
+
+ bool isEmpty() const;
+ bool isTemplate() const;
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+private:
+ QVector<BaseClass> m_baseClasses;
+ TemplateParameterList m_templateParameters;
+ CodeModel::ClassType m_classType;
+
+ QStringList m_propertyDeclarations;
+ bool m_final = false;
+};
+
+class _NamespaceModelItem: public _ScopeModelItem
+{
+public:
+ DECLARE_MODEL_NODE(Namespace)
+
+ explicit _NamespaceModelItem(CodeModel *model, int kind = __node_kind)
+ : _ScopeModelItem(model, kind) {}
+ explicit _NamespaceModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
+ : _ScopeModelItem(model, name, kind) {}
+ ~_NamespaceModelItem();
+
+ const NamespaceList &namespaces() const { return m_namespaces; }
+
+ NamespaceType type() const { return m_type; }
+ void setType(NamespaceType t) { m_type = t; }
+
+ void addNamespace(NamespaceModelItem item);
+
+ NamespaceModelItem findNamespace(const QString &name) const;
+
+ void appendNamespace(const _NamespaceModelItem &other);
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+private:
+ NamespaceList m_namespaces;
+ NamespaceType m_type = NamespaceType::Default;
+};
+
+class _FileModelItem: public _NamespaceModelItem
+{
+public:
+ DECLARE_MODEL_NODE(File)
+
+ explicit _FileModelItem(CodeModel *model, int kind = __node_kind)
+ : _NamespaceModelItem(model, kind) {}
+ explicit _FileModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
+ : _NamespaceModelItem(model, name, kind) {}
+ ~_FileModelItem();
+};
+
+class _ArgumentModelItem: public _CodeModelItem
+{
+public:
+ DECLARE_MODEL_NODE(Argument)
+
+ explicit _ArgumentModelItem(CodeModel *model, int kind = __node_kind)
+ : _CodeModelItem(model, kind), m_defaultValue(false) {}
+ explicit _ArgumentModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
+ : _CodeModelItem(model, name, kind), m_defaultValue(false) {}
+ ~_ArgumentModelItem();
+
+ TypeInfo type() const;
+ void setType(const TypeInfo &type);
+
+ bool defaultValue() const;
+ void setDefaultValue(bool defaultValue);
+
+ QString defaultValueExpression() const { return m_defaultValueExpression; }
+ void setDefaultValueExpression(const QString &expr) { m_defaultValueExpression = expr; }
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+private:
+ TypeInfo m_type;
+ QString m_defaultValueExpression;
+ bool m_defaultValue;
+};
+
+class _MemberModelItem: public _CodeModelItem
+{
+public:
+ DECLARE_MODEL_NODE(Member)
+
+ explicit _MemberModelItem(CodeModel *model, int kind = __node_kind)
+ : _CodeModelItem(model, kind), m_accessPolicy(CodeModel::Public), m_flags(0) {}
+ explicit _MemberModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
+ : _CodeModelItem(model, name, kind), m_accessPolicy(CodeModel::Public), m_flags(0) {}
+ ~_MemberModelItem();
+
+ bool isConstant() const;
+ void setConstant(bool isConstant);
+
+ bool isVolatile() const;
+ void setVolatile(bool isVolatile);
+
+ bool isStatic() const;
+ void setStatic(bool isStatic);
+
+ bool isAuto() const;
+ void setAuto(bool isAuto);
+
+ bool isFriend() const;
+ void setFriend(bool isFriend);
+
+ bool isRegister() const;
+ void setRegister(bool isRegister);
+
+ bool isExtern() const;
+ void setExtern(bool isExtern);
+
+ bool isMutable() const;
+ void setMutable(bool isMutable);
+
+ CodeModel::AccessPolicy accessPolicy() const;
+ void setAccessPolicy(CodeModel::AccessPolicy accessPolicy);
+
+ TemplateParameterList templateParameters() const { return m_templateParameters; }
+ void setTemplateParameters(const TemplateParameterList &templateParameters) { m_templateParameters = templateParameters; }
+
+ TypeInfo type() const;
+ void setType(const TypeInfo &type);
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+private:
+ TemplateParameterList m_templateParameters;
+ TypeInfo m_type;
+ CodeModel::AccessPolicy m_accessPolicy;
+ union {
+ struct {
+ uint m_isConstant: 1;
+ uint m_isVolatile: 1;
+ uint m_isStatic: 1;
+ uint m_isAuto: 1;
+ uint m_isFriend: 1;
+ uint m_isRegister: 1;
+ uint m_isExtern: 1;
+ uint m_isMutable: 1;
+ };
+ uint m_flags;
+ };
+
+};
+
+class _FunctionModelItem: public _MemberModelItem
+{
+public:
+ DECLARE_MODEL_NODE(Function)
+
+ explicit _FunctionModelItem(CodeModel *model, int kind = __node_kind)
+ : _MemberModelItem(model, kind), m_functionType(CodeModel::Normal), m_flags(0) {}
+ explicit _FunctionModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
+ : _MemberModelItem(model, name, kind), m_functionType(CodeModel::Normal), m_flags(0) {}
+ ~_FunctionModelItem();
+
+ ArgumentList arguments() const;
+
+ void addArgument(const ArgumentModelItem& item);
+
+ CodeModel::FunctionType functionType() const;
+ void setFunctionType(CodeModel::FunctionType functionType);
+
+ bool isDeleted() const;
+ void setDeleted(bool d);
+
+ bool isDeprecated() const;
+ void setDeprecated(bool d);
+
+ bool isVirtual() const;
+ void setVirtual(bool isVirtual);
+
+ bool isOverride() const;
+ void setOverride(bool o);
+
+ bool isFinal() const;
+ void setFinal(bool f);
+
+ bool isInline() const;
+ void setInline(bool isInline);
+
+ bool isExplicit() const;
+ void setExplicit(bool isExplicit);
+
+ bool isInvokable() const; // Qt
+ void setInvokable(bool isInvokable); // Qt
+
+ bool isAbstract() const;
+ void setAbstract(bool isAbstract);
+
+ bool isVariadics() const;
+ void setVariadics(bool isVariadics);
+
+
+ bool isSimilar(const FunctionModelItem &other) const;
+
+ bool isNoExcept() const;
+
+ ExceptionSpecification exceptionSpecification() const;
+ void setExceptionSpecification(ExceptionSpecification e);
+
+ QString typeSystemSignature() const; // For dumping out type system files
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+private:
+ ArgumentList m_arguments;
+ CodeModel::FunctionType m_functionType;
+ union {
+ struct {
+ uint m_isDeleted: 1;
+ uint m_isVirtual: 1;
+ uint m_isOverride: 1;
+ uint m_isFinal: 1;
+ uint m_isDeprecated: 1;
+ uint m_isInline: 1;
+ uint m_isAbstract: 1;
+ uint m_isExplicit: 1;
+ uint m_isVariadics: 1;
+ uint m_isInvokable : 1; // Qt
+ };
+ uint m_flags;
+ };
+ ExceptionSpecification m_exceptionSpecification = ExceptionSpecification::Unknown;
+};
+
+class _VariableModelItem: public _MemberModelItem
+{
+public:
+ DECLARE_MODEL_NODE(Variable)
+
+ explicit _VariableModelItem(CodeModel *model, int kind = __node_kind)
+ : _MemberModelItem(model, kind) {}
+ explicit _VariableModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
+ : _MemberModelItem(model, name, kind) {}
+};
+
+class _TypeDefModelItem: public _CodeModelItem
+{
+public:
+ DECLARE_MODEL_NODE(TypeDef)
+
+ explicit _TypeDefModelItem(CodeModel *model, int kind = __node_kind)
+ : _CodeModelItem(model, kind) {}
+ explicit _TypeDefModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
+ : _CodeModelItem(model, name, kind) {}
+
+ TypeInfo type() const;
+ void setType(const TypeInfo &type);
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+private:
+ TypeInfo m_type;
+};
+
+class _TemplateTypeAliasModelItem : public _CodeModelItem
+{
+public:
+ DECLARE_MODEL_NODE(TemplateTypeAlias)
+
+ explicit _TemplateTypeAliasModelItem(CodeModel *model, int kind = __node_kind);
+ explicit _TemplateTypeAliasModelItem(CodeModel *model, const QString &name,
+ int kind = __node_kind);
+
+ TemplateParameterList templateParameters() const;
+ void addTemplateParameter(const TemplateParameterModelItem &templateParameter);
+
+ TypeInfo type() const;
+ void setType(const TypeInfo &type);
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+private:
+ TemplateParameterList m_templateParameters;
+ TypeInfo m_type;
+};
+
+class _EnumModelItem: public _CodeModelItem
+{
+public:
+ DECLARE_MODEL_NODE(Enum)
+
+ explicit _EnumModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
+ : _CodeModelItem(model, name, kind) {}
+ explicit _EnumModelItem(CodeModel *model, int kind = __node_kind)
+ : _CodeModelItem(model, kind) {}
+ ~_EnumModelItem();
+
+ CodeModel::AccessPolicy accessPolicy() const;
+ void setAccessPolicy(CodeModel::AccessPolicy accessPolicy);
+
+ bool hasValues() const { return !m_enumerators.isEmpty(); }
+ EnumeratorList enumerators() const;
+ void addEnumerator(const EnumeratorModelItem &item);
+
+ EnumKind enumKind() const { return m_enumKind; }
+ void setEnumKind(EnumKind kind) { m_enumKind = kind; }
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+ bool isSigned() const;
+ void setSigned(bool s);
+
+private:
+ CodeModel::AccessPolicy m_accessPolicy = CodeModel::Public;
+ EnumeratorList m_enumerators;
+ EnumKind m_enumKind = CEnum;
+ bool m_signed = true;
+};
+
+class _EnumeratorModelItem: public _CodeModelItem
+{
+public:
+ DECLARE_MODEL_NODE(Enumerator)
+
+ explicit _EnumeratorModelItem(CodeModel *model, int kind = __node_kind)
+ : _CodeModelItem(model, kind) {}
+ explicit _EnumeratorModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
+ : _CodeModelItem(model, name, kind) {}
+ ~_EnumeratorModelItem();
+
+ QString stringValue() const;
+ void setStringValue(const QString &stringValue);
+
+ EnumValue value() const { return m_value; }
+ void setValue(EnumValue v) { m_value = v; }
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+private:
+ QString m_stringValue;
+ EnumValue m_value;
+};
+
+class _TemplateParameterModelItem: public _CodeModelItem
+{
+public:
+ DECLARE_MODEL_NODE(TemplateParameter)
+
+ explicit _TemplateParameterModelItem(CodeModel *model, int kind = __node_kind)
+ : _CodeModelItem(model, kind), m_defaultValue(false) {}
+ explicit _TemplateParameterModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
+ : _CodeModelItem(model, name, kind), m_defaultValue(false) {}
+ ~_TemplateParameterModelItem();
+
+ TypeInfo type() const;
+ void setType(const TypeInfo &type);
+
+ bool defaultValue() const;
+ void setDefaultValue(bool defaultValue);
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+private:
+ TypeInfo m_type;
+ bool m_defaultValue;
+};
+
+#endif // CODEMODEL_H
+
+// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel_enums.h b/sources/shiboken6/ApiExtractor/parser/codemodel_enums.h
new file mode 100644
index 000000000..aebd59879
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel_enums.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CODEMODEL_ENUMS_H
+#define CODEMODEL_ENUMS_H
+
+enum ReferenceType {
+ NoReference,
+ LValueReference,
+ RValueReference
+};
+
+enum EnumKind {
+ CEnum, // Standard C: enum Foo { value1, value2 }
+ AnonymousEnum, // enum { value1, value2 }
+ EnumClass // C++ 11 : enum class Foo { value1, value2 }
+};
+
+enum class Indirection
+{
+ Pointer, // int *
+ ConstPointer // int *const
+};
+
+enum class ExceptionSpecification
+{
+ Unknown,
+ NoExcept,
+ Throws
+};
+
+enum class NamespaceType
+{
+ Default,
+ Anonymous,
+ Inline
+};
+
+#endif // CODEMODEL_ENUMS_H
diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h b/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h
new file mode 100644
index 000000000..87fea5cde
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef CODEMODEL_FWD_H
+#define CODEMODEL_FWD_H
+
+#include <QtCore/QVector>
+#include <QtCore/QSharedPointer>
+
+// forward declarations
+class CodeModel;
+class _ArgumentModelItem;
+class _ClassModelItem;
+class _CodeModelItem;
+class _EnumModelItem;
+class _EnumeratorModelItem;
+class _FileModelItem;
+class _FunctionModelItem;
+class _NamespaceModelItem;
+class _ScopeModelItem;
+class _TemplateParameterModelItem;
+class _TypeDefModelItem;
+class _TemplateTypeAliasModelItem;
+class _VariableModelItem;
+class _MemberModelItem;
+class TypeInfo;
+
+using ArgumentModelItem = QSharedPointer<_ArgumentModelItem>;
+using ClassModelItem = QSharedPointer<_ClassModelItem>;
+using CodeModelItem = QSharedPointer<_CodeModelItem>;
+using EnumModelItem = QSharedPointer<_EnumModelItem>;
+using EnumeratorModelItem = QSharedPointer<_EnumeratorModelItem>;
+using FileModelItem = QSharedPointer<_FileModelItem>;
+using FunctionModelItem = QSharedPointer<_FunctionModelItem>;
+using NamespaceModelItem = QSharedPointer<_NamespaceModelItem>;
+using ScopeModelItem = QSharedPointer<_ScopeModelItem>;
+using TemplateParameterModelItem = QSharedPointer<_TemplateParameterModelItem>;
+using TypeDefModelItem = QSharedPointer<_TypeDefModelItem>;
+using TemplateTypeAliasModelItem = QSharedPointer<_TemplateTypeAliasModelItem>;
+using VariableModelItem = QSharedPointer<_VariableModelItem>;
+using MemberModelItem = QSharedPointer<_MemberModelItem>;
+
+using ArgumentList = QVector<ArgumentModelItem>;
+using ClassList = QVector<ClassModelItem>;
+using ItemList = QVector<CodeModelItem>;
+using EnumList = QVector<EnumModelItem>;
+using EnumeratorList = QVector<EnumeratorModelItem>;
+using FileList = QVector<FileModelItem>;
+using FunctionList = QVector<FunctionModelItem>;
+using NamespaceList = QVector<NamespaceModelItem>;
+using ScopeList = QVector<ScopeModelItem>;
+using TemplateParameterList = QVector<TemplateParameterModelItem>;
+using TypeDefList = QVector<TypeDefModelItem>;
+using TemplateTypeAliasList = QVector<TemplateTypeAliasModelItem>;
+using VariableList = QVector<VariableModelItem>;
+using MemberList = QVector<MemberModelItem>;
+
+#endif // CODEMODEL_FWD_H
diff --git a/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp b/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp
new file mode 100644
index 000000000..513bb3532
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "enumvalue.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QString>
+#include <QtCore/QTextStream>
+
+QString EnumValue::toString() const
+{
+ return m_type == EnumValue::Signed
+ ? QString::number(m_value) : QString::number(m_unsignedValue);
+}
+
+void EnumValue::setValue(qint64 v)
+{
+ m_value = v;
+ m_type = Signed;
+}
+
+void EnumValue::setUnsignedValue(quint64 v)
+{
+ m_unsignedValue = v;
+ m_type = Unsigned;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d,const EnumValue &v)
+{
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d.noquote();
+ d << "EnumValue(";
+ if (v.m_type == EnumValue::Signed)
+ d << v.m_value;
+ else
+ d << v.m_unsignedValue << 'u';
+ d << ')';
+ return d;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+QTextStream &operator<<(QTextStream &s, const EnumValue &v)
+{
+ if (v.m_type == EnumValue::Signed)
+ s << v.m_value;
+ else
+ s << v.m_unsignedValue;
+ return s;
+}
diff --git a/sources/shiboken6/ApiExtractor/parser/enumvalue.h b/sources/shiboken6/ApiExtractor/parser/enumvalue.h
new file mode 100644
index 000000000..ea30c39bb
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/parser/enumvalue.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ENUMVALUE_H
+#define ENUMVALUE_H
+
+#include <QtCore/QtGlobal>
+
+QT_FORWARD_DECLARE_CLASS(QDebug)
+QT_FORWARD_DECLARE_CLASS(QString)
+QT_FORWARD_DECLARE_CLASS(QTextStream)
+
+class EnumValue
+{
+public:
+ enum Type
+ {
+ Signed,
+ Unsigned
+ };
+
+ QString toString() const;
+
+ Type type() { return m_type; }
+ qint64 value() const { return m_value; }
+ quint64 unsignedValue() const { return m_unsignedValue; }
+ bool isNullValue() const { return m_type == Signed ? m_value == 0 : m_unsignedValue == 0u; }
+
+ void setValue(qint64 v);
+ void setUnsignedValue(quint64 v);
+
+private:
+#ifndef QT_NO_DEBUG_STREAM
+ friend QDebug operator<<(QDebug, const EnumValue &);
+#endif
+ friend QTextStream &operator<<(QTextStream &, const EnumValue &);
+
+ union
+ {
+ qint64 m_value = 0;
+ quint64 m_unsignedValue;
+ };
+ Type m_type = Signed;
+};
+
+#endif // ENUMVALUE_H