From: Friedemann Kleint Date: Thu, 27 Apr 2023 12:44:10 +0200 Subject: shiboken2/clang: Record scope resolution of arguments/function return Add a flag indicating whether a type was specified with a leading "::" (scope resolution). Such parameters previously caused the function to rejected due to the "::TypeName" not being found. The type resolution added for clang 16 strips these qualifiers though, so, the information needs to be stored. Task-number: PYSIDE-2288 Pick-to: 6.5 5.15 Change-Id: I27d27c94ec43bcc4cb3b79e6e9ce6706c749a1e9 Reviewed-by: Christian Tismer (cherry picked from commit 075d8ad4660f05e6d2583ff1c05e9987ad624bfe) --- .../ApiExtractor/clangparser/clangbuilder.cpp | 8 ++++++-- .../ApiExtractor/clangparser/clangutils.cpp | 11 ++++++++++ .../ApiExtractor/clangparser/clangutils.h | 1 + .../shiboken2/ApiExtractor/parser/codemodel.cpp | 24 ++++++++++++++++++++++ sources/shiboken2/ApiExtractor/parser/codemodel.h | 8 ++++++++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp index ed1e15d..1b5cc5c 100644 --- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp +++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp @@ -294,7 +294,9 @@ FunctionModelItem BuilderPrivate::createFunction(const CXCursor &cursor, name = fixTypeName(name); FunctionModelItem result(new _FunctionModelItem(m_model, name)); setFileName(cursor, result.data()); - result->setType(createTypeInfoHelper(clang_getCursorResultType(cursor))); + const auto type = clang_getCursorResultType(cursor); + result->setType(createTypeInfoHelper(type)); + result->setScopeResolution(hasScopeResolution(type)); result->setFunctionType(t); result->setScope(m_scope); result->setStatic(clang_Cursor_getStorageClass(cursor) == CX_SC_Static); @@ -1031,7 +1033,9 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor) if (d->m_currentArgument.isNull() && !d->m_currentFunction.isNull()) { const QString name = getCursorSpelling(cursor); d->m_currentArgument.reset(new _ArgumentModelItem(d->m_model, name)); - d->m_currentArgument->setType(d->createTypeInfo(cursor)); + const auto type = clang_getCursorType(cursor); + d->m_currentArgument->setScopeResolution(hasScopeResolution(type)); + d->m_currentArgument->setType(d->createTypeInfo(type)); d->m_currentFunction->addArgument(d->m_currentArgument); QString defaultValueExpression = d->cursorValueExpression(this, cursor); if (!defaultValueExpression.isEmpty()) { diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp index 295ede3..ec6d228 100644 --- a/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp +++ b/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp @@ -155,6 +155,17 @@ QString getTypeName(const CXType &type) return result; } +// Quick check for "::Type" +bool hasScopeResolution(const CXType &type) +{ + CXString typeSpelling = clang_getTypeSpelling(type); + const QString spelling = QString::fromUtf8(clang_getCString(typeSpelling)); + const bool result = spelling.startsWith(QLatin1String("::")) + || spelling.contains(QLatin1String(" ::")); + clang_disposeString(typeSpelling); + return result; +} + // Resolve elaborated types occurring with clang 16 QString getResolvedTypeName(const CXType &type) { diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.h b/sources/shiboken2/ApiExtractor/clangparser/clangutils.h index aacaf63..33f362c 100644 --- a/sources/shiboken2/ApiExtractor/clangparser/clangutils.h +++ b/sources/shiboken2/ApiExtractor/clangparser/clangutils.h @@ -52,6 +52,7 @@ QString getCursorKindName(CXCursorKind cursorKind); QString getCursorSpelling(const CXCursor &cursor); QString getCursorDisplayName(const CXCursor &cursor); QString getTypeName(const CXType &type); +bool hasScopeResolution(const CXType &type); QString getResolvedTypeName(const CXType &type); inline QString getCursorTypeName(const CXCursor &cursor) { return getTypeName(clang_getCursorType(cursor)); } diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp index dea0812..ba07a01 100644 --- a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp +++ b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp @@ -1121,11 +1121,23 @@ void _ArgumentModelItem::setDefaultValue(bool defaultValue) m_defaultValue = defaultValue; } +bool _ArgumentModelItem::scopeResolution() const +{ + return m_scopeResolution; +} + +void _ArgumentModelItem::setScopeResolution(bool v) +{ + m_scopeResolution = v; +} + #ifndef QT_NO_DEBUG_STREAM void _ArgumentModelItem::formatDebug(QDebug &d) const { _CodeModelItem::formatDebug(d); d << ", type=" << m_type; + if (m_scopeResolution) + d << ", [m_scope resolution]"; if (m_defaultValue) d << ", defaultValue=\"" << m_defaultValueExpression << '"'; } @@ -1200,6 +1212,16 @@ void _FunctionModelItem::setVariadics(bool isVariadics) m_isVariadics = isVariadics; } +bool _FunctionModelItem::scopeResolution() const +{ + return m_scopeResolution; +} + +void _FunctionModelItem::setScopeResolution(bool v) +{ + m_scopeResolution = v; +} + bool _FunctionModelItem::isNoExcept() const { return m_exceptionSpecification == ExceptionSpecification::NoExcept; @@ -1343,6 +1365,8 @@ void _FunctionModelItem::formatDebug(QDebug &d) const d << " [explicit]"; if (m_isInvokable) d << " [invokable]"; + if (m_scopeResolution) + d << " [scope resolution]"; formatModelItemList(d, ", arguments=", m_arguments); if (m_isVariadics) d << ",..."; diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.h b/sources/shiboken2/ApiExtractor/parser/codemodel.h index b990ad9..85f298c 100644 --- a/sources/shiboken2/ApiExtractor/parser/codemodel.h +++ b/sources/shiboken2/ApiExtractor/parser/codemodel.h @@ -499,6 +499,10 @@ public: QString defaultValueExpression() const { return m_defaultValueExpression; } void setDefaultValueExpression(const QString &expr) { m_defaultValueExpression = expr; } + // Argument type has scope resolution "::ArgumentType" + bool scopeResolution() const; + void setScopeResolution(bool v); + #ifndef QT_NO_DEBUG_STREAM void formatDebug(QDebug &d) const override; #endif @@ -507,6 +511,7 @@ private: TypeInfo m_type; QString m_defaultValueExpression; bool m_defaultValue = false; + bool m_scopeResolution = false; }; class _MemberModelItem: public _CodeModelItem @@ -623,6 +628,8 @@ public: bool isVariadics() const; void setVariadics(bool isVariadics); + bool scopeResolution() const; // Return type has scope resolution "::ReturnType" + void setScopeResolution(bool v); bool isSimilar(const FunctionModelItem &other) const; @@ -652,6 +659,7 @@ private: uint m_isExplicit: 1; uint m_isVariadics: 1; uint m_isInvokable : 1; // Qt + uint m_scopeResolution: 1; }; uint m_flags; };