diff options
-rw-r--r-- | sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp | 93 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp | 38 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/parser/codemodel.h | 4 |
3 files changed, 82 insertions, 53 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 3b2ecf8e1..58618d923 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -2071,6 +2071,34 @@ static inline QString msgVoidParameterType(const ArgumentModelItem &arg, int n) return result; } +static inline AbstractMetaFunction::FunctionType functionTypeFromCodeModel(CodeModel::FunctionType ft) +{ + AbstractMetaFunction::FunctionType result = AbstractMetaFunction::NormalFunction; + switch (ft) { + case CodeModel::Constructor: + result = AbstractMetaFunction::ConstructorFunction; + break; + case CodeModel::CopyConstructor: + result = AbstractMetaFunction::CopyConstructorFunction; + break; + case CodeModel::MoveConstructor: + result = AbstractMetaFunction::MoveConstructorFunction; + break; + case CodeModel::Destructor: + result = AbstractMetaFunction::DestructorFunction; + break; + case CodeModel::Normal: + break; + case CodeModel::Signal: + result = AbstractMetaFunction::SignalFunction; + break; + case CodeModel::Slot: + result = AbstractMetaFunction::SlotFunction; + break; + } + return result; +} + AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModelItem functionItem) { if (!functionItem->templateParameters().isEmpty()) @@ -2104,14 +2132,12 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel return 0; } - Q_ASSERT(functionItem->functionType() == CodeModel::Normal - || functionItem->functionType() == CodeModel::Signal - || functionItem->functionType() == CodeModel::Slot); - if (functionItem->isFriend()) return 0; AbstractMetaFunction *metaFunction = q->createMetaFunction(); + // Additional check for assignment/move assignment down below + metaFunction->setFunctionType(functionTypeFromCodeModel(functionItem->functionType())); metaFunction->setConstant(functionItem->isConstant()); if (ReportHandler::isDebug(ReportHandler::MediumDebug)) @@ -2145,31 +2171,24 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel else *metaFunction += AbstractMetaAttributes::Protected; - - QString strippedClassName = className; - int cc_pos = strippedClassName.lastIndexOf(colonColon()); - if (cc_pos > 0) - strippedClassName = strippedClassName.mid(cc_pos + 2); - - TypeInfo functionType = functionItem->type(); - - if (TypeDatabase::instance()->isReturnTypeRejected(className, functionType.toString(), &rejectReason)) { - m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled); - delete metaFunction; - return nullptr; - } - - if (functionName.startsWith(QLatin1Char('~'))) { - metaFunction->setFunctionType(AbstractMetaFunction::DestructorFunction); - metaFunction->setInvalid(true); - } else if (stripTemplateArgs(functionName) == strippedClassName) { - metaFunction->setFunctionType(AbstractMetaFunction::ConstructorFunction); - // Check for Copy/Move down below + switch (metaFunction->functionType()) { + case AbstractMetaFunction::DestructorFunction: + break; + case AbstractMetaFunction::ConstructorFunction: metaFunction->setExplicit(functionItem->isExplicit()); metaFunction->setName(m_currentClass->name()); - } else { + break; + default: { + TypeInfo returnType = functionItem->type(); + + if (TypeDatabase::instance()->isReturnTypeRejected(className, returnType.toString(), &rejectReason)) { + m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled); + delete metaFunction; + return nullptr; + } + bool ok; - AbstractMetaType* type = translateType(functionType, &ok); + AbstractMetaType *type = translateType(returnType, &ok); if (!ok) { Q_ASSERT(type == 0); @@ -2183,11 +2202,8 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel } metaFunction->setType(type); - - if (functionItem->functionType() == CodeModel::Signal) - metaFunction->setFunctionType(AbstractMetaFunction::SignalFunction); - else if (functionItem->functionType() == CodeModel::Slot) - metaFunction->setFunctionType(AbstractMetaFunction::SlotFunction); + } + break; } ArgumentList arguments = functionItem->arguments(); @@ -2303,20 +2319,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel if (m_currentClass && metaFunction->arguments().size() == 1) { const AbstractMetaType *argType = metaFunction->arguments().first()->type(); if (argType->typeEntry() == m_currentClass->typeEntry() && argType->indirections() == 0) { - if (metaFunction->isConstructor()) { - switch (argType->referenceType()) { - case NoReference: - metaFunction->setFunctionType(AbstractMetaFunction::CopyConstructorFunction); - break; - case LValueReference: - if (argType->isConstant()) - metaFunction->setFunctionType(AbstractMetaFunction::CopyConstructorFunction); - break; - case RValueReference: - metaFunction->setFunctionType(AbstractMetaFunction::MoveConstructorFunction); - break; - } - } else if (metaFunction->name() == QLatin1String("operator=")) { + if (metaFunction->name() == QLatin1String("operator=")) { switch (argType->referenceType()) { case NoReference: metaFunction->setFunctionType(AbstractMetaFunction::AssignmentOperatorFunction); diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp index dc0c59dd5..a739756a7 100644 --- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp +++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp @@ -159,8 +159,7 @@ public: bool addClass(const CXCursor &cursor, CodeModel::ClassType t); FunctionModelItem createFunction(const CXCursor &cursor, CodeModel::FunctionType t = CodeModel::Normal) const; - FunctionModelItem createMemberFunction(const CXCursor &cursor, - CodeModel::FunctionType t = CodeModel::Normal) const; + FunctionModelItem createMemberFunction(const CXCursor &cursor) const; void qualifyConstructor(const CXCursor &cursor); TypeInfo createTypeInfo(const CXType &type) const; TypeInfo createTypeInfo(const CXCursor &cursor) const @@ -245,16 +244,39 @@ FunctionModelItem BuilderPrivate::createFunction(const CXCursor &cursor, return result; } -FunctionModelItem BuilderPrivate::createMemberFunction(const CXCursor &cursor, - CodeModel::FunctionType t) const +static inline CodeModel::FunctionType functionTypeFromCursor(const CXCursor &cursor) { - FunctionModelItem result = createFunction(cursor, t); + CodeModel::FunctionType result = CodeModel::Normal; + switch (cursor.kind) { + case CXCursor_Constructor: + if (clang_CXXConstructor_isCopyConstructor(cursor) != 0) + result = CodeModel::CopyConstructor; + else if (clang_CXXConstructor_isMoveConstructor(cursor) != 0) + result = CodeModel::MoveConstructor; + else + result = CodeModel::Constructor; + break; + case CXCursor_Destructor: + result = CodeModel::Destructor; + break; + default: + break; + } + return result; +} + +FunctionModelItem BuilderPrivate::createMemberFunction(const CXCursor &cursor) const +{ + const CodeModel::FunctionType functionType = + m_currentFunctionType == CodeModel::Signal || m_currentFunctionType == CodeModel::Slot + ? m_currentFunctionType // by annotation + : functionTypeFromCursor(cursor); + FunctionModelItem result = createFunction(cursor, functionType); result->setAccessPolicy(accessPolicy(clang_getCXXAccessSpecifier(cursor))); result->setConstant(clang_CXXMethod_isConst(cursor) != 0); result->setStatic(clang_CXXMethod_isStatic(cursor) != 0); result->setVirtual(clang_CXXMethod_isVirtual(cursor) != 0); result->setAbstract(clang_CXXMethod_isPureVirtual(cursor) != 0); - result->setFunctionType(m_currentFunctionType); return result; } @@ -609,7 +631,7 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor) // Skip inline member functions outside class, only go by declarations inside class if (!withinClassDeclaration(cursor)) return Skip; - d->m_currentFunction = d->createMemberFunction(cursor, CodeModel::Normal); + d->m_currentFunction = d->createMemberFunction(cursor); d->m_scopeStack.back()->addFunction(d->m_currentFunction); break; // Not fully supported, currently, seen as normal function @@ -618,7 +640,7 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor) const CXCursor semParent = clang_getCursorSemanticParent(cursor); if (isClassCursor(semParent)) { if (semParent == clang_getCursorLexicalParent(cursor)) { - d->m_currentFunction = d->createMemberFunction(cursor, CodeModel::Normal); + d->m_currentFunction = d->createMemberFunction(cursor); d->m_scopeStack.back()->addFunction(d->m_currentFunction); break; } else { diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.h b/sources/shiboken2/ApiExtractor/parser/codemodel.h index ea16e6912..4d6bfd06a 100644 --- a/sources/shiboken2/ApiExtractor/parser/codemodel.h +++ b/sources/shiboken2/ApiExtractor/parser/codemodel.h @@ -56,6 +56,10 @@ public: enum FunctionType { Normal, + Constructor, + CopyConstructor, + MoveConstructor, + Destructor, Signal, Slot }; |