aboutsummaryrefslogtreecommitdiffstats
path: root/sources
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-06-12 09:32:51 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-06-12 11:10:52 +0200
commit066957b44c83ed3cbadeda756923d1a891ecee72 (patch)
tree5b350f60682d869d00d7e43273df38dc85b5efb8 /sources
parent11c2f77015852db16dbf6355f8615413b212fcda (diff)
shiboken: Resolve typedef'ed base classes
Add a resolve function. Change-Id: If85c1de402f212e4c16b18e2ec8ad97075ac3cff Fixes: PYSIDE-1327 Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources')
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp37
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp30
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h1
3 files changed, 62 insertions, 6 deletions
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
index 310a751e0..1eaa36540 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
@@ -620,27 +620,52 @@ long clang_EnumDecl_isScoped4(BaseVisitor *bv, const CXCursor &cursor)
}
#endif // CLANG_NO_ENUMDECL_ISSCOPED
+// Resolve declaration and type of a base class
+
+struct TypeDeclaration
+{
+ CXType type;
+ CXCursor declaration;
+};
+
+static TypeDeclaration resolveBaseSpecifier(const CXCursor &cursor)
+{
+ Q_ASSERT(clang_getCursorKind(cursor) == CXCursor_CXXBaseSpecifier);
+ CXType inheritedType = clang_getCursorType(cursor);
+ CXCursor decl = clang_getTypeDeclaration(inheritedType);
+ if (inheritedType.kind != CXType_Unexposed) {
+ while (true) {
+ auto kind = clang_getCursorKind(decl);
+ if (kind != CXCursor_TypeAliasDecl && kind != CXCursor_TypedefDecl)
+ break;
+ inheritedType = clang_getTypedefDeclUnderlyingType(decl);
+ decl = clang_getTypeDeclaration(inheritedType);
+ }
+ }
+ return {inheritedType, decl};
+}
+
// Add a base class to the current class from CXCursor_CXXBaseSpecifier
void BuilderPrivate::addBaseClass(const CXCursor &cursor)
{
+ Q_ASSERT(clang_getCursorKind(cursor) == CXCursor_CXXBaseSpecifier);
// Note: spelling has "struct baseClass", use type
QString baseClassName;
- const CXType inheritedType = clang_getCursorType(cursor);
- if (inheritedType.kind == CXType_Unexposed) {
+ const auto decl = resolveBaseSpecifier(cursor);
+ if (decl.type.kind == CXType_Unexposed) {
// The type is unexposed when the base class is a template type alias:
// "class QItemSelection : public QList<X>" where QList is aliased to QVector.
// Try to resolve via code model.
- TypeInfo info = createTypeInfo(inheritedType);
+ TypeInfo info = createTypeInfo(decl.type);
auto parentScope = m_scopeStack.at(m_scopeStack.size() - 2); // Current is class.
auto resolved = TypeInfo::resolveType(info, parentScope);
if (resolved != info)
baseClassName = resolved.toString();
}
if (baseClassName.isEmpty())
- baseClassName = getTypeName(inheritedType);
+ baseClassName = getTypeName(decl.type);
- const CXCursor declCursor = clang_getTypeDeclaration(inheritedType);
- const CursorClassHash::const_iterator it = m_cursorClassHash.constFind(declCursor);
+ auto it = m_cursorClassHash.constFind(decl.declaration);
const CodeModel::AccessPolicy access = accessPolicy(clang_getCXXAccessSpecifier(cursor));
if (it == m_cursorClassHash.constEnd()) {
// Set unqualified name. This happens in cases like "class X : public std::list<...>"
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp
index f2e15fdb0..f0aa4a318 100644
--- a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp
@@ -588,4 +588,34 @@ void TestAbstractMetaClass::testIsPolymorphic()
QVERIFY(!a->isPolymorphic());
}
+void TestAbstractMetaClass::testClassTypedefedBaseClass()
+{
+ const char cppCode[] =R"CPP(
+class Base {
+};
+
+using BaseAlias1 = Base;
+using BaseAlias2 = BaseAlias1;
+
+class Derived : public BaseAlias2 {
+};
+)CPP";
+ const char xmlCode[] = R"XML(
+<typesystem package='Foo'>
+ <object-type name='Base'/>
+ <object-type name='Derived'/>
+</typesystem>
+)XML";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.count(), 2);
+ auto base = AbstractMetaClass::findClass(classes, QLatin1String("Base"));
+ QVERIFY(base);
+ auto derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived"));
+ QVERIFY(derived);
+ QCOMPARE(derived->baseClasses().value(0), base);
+}
+
QTEST_APPLESS_MAIN(TestAbstractMetaClass)
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h
index e19973625..1d9f8d8f6 100644
--- a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h
@@ -51,6 +51,7 @@ private slots:
void testAbstractClassDefaultConstructors();
void testObjectTypesMustNotHaveCopyConstructors();
void testIsPolymorphic();
+ void testClassTypedefedBaseClass();
};
#endif // TESTABSTRACTMETACLASS_H