diff options
6 files changed, 77 insertions, 74 deletions
diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp index 0b6c87ffc..71c474391 100644 --- a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp +++ b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp @@ -206,7 +206,7 @@ public: template <class Item> void qualifyTypeDef(const CXCursor &typeRefCursor, const QSharedPointer<Item> &item) const; - bool visitHeader(const char *cFileName) const; + bool visitHeader(const QString &fileName) const; void setFileName(const CXCursor &cursor, _CodeModelItem *item); @@ -230,8 +230,8 @@ public: ArgumentModelItem m_currentArgument; VariableModelItem m_currentField; TemplateTypeAliasModelItem m_currentTemplateTypeAlias; - QByteArrayList m_systemIncludes; // files, like "memory" - QByteArrayList m_systemIncludePaths; // paths, like "/usr/include/Qt/" + QStringList m_systemIncludes; // files, like "memory" + QStringList m_systemIncludePaths; // paths, like "/usr/include/Qt/" QString m_usingTypeRef; // Base classes in "using Base::member;" bool m_withinUsingDeclaration = false; @@ -809,100 +809,62 @@ Builder::~Builder() delete d; } -static const char *cBaseName(const char *fileName) +static QString baseName(QString path) { - const char *lastSlash = std::strrchr(fileName, '/'); + qsizetype lastSlash = path.lastIndexOf(u'/'); #ifdef Q_OS_WIN - if (lastSlash == nullptr) - lastSlash = std::strrchr(fileName, '\\'); + if (lastSlash < 0) + lastSlash = path.lastIndexOf(u'\\'); #endif - return lastSlash != nullptr ? (lastSlash + 1) : fileName; + if (lastSlash > 0) + path.remove(0, lastSlash + 1); + return path; } -static inline bool cCompareFileName(const char *f1, const char *f2) -{ -#ifdef Q_OS_WIN - return _stricmp(f1, f2) == 0; -#else - return std::strcmp(f1, f2) == 0; -#endif -} - -#ifdef Q_OS_UNIX -template<size_t N> -static bool cStringStartsWith(const char *str, const char (&prefix)[N]) -{ - return std::strncmp(prefix, str, N - 1) == 0; -} -#endif - -static bool cStringStartsWith(const char *str, const QByteArray &prefix) -{ - return std::strncmp(prefix.constData(), str, int(prefix.size())) == 0; -} - -bool BuilderPrivate::visitHeader(const char *cFileName) const +bool BuilderPrivate::visitHeader(const QString &fileName) const { // Resolve OpenGL typedefs although the header is considered a system header. - const char *baseName = cBaseName(cFileName); - if (cCompareFileName(baseName, "gl.h")) + const QString baseName = clang::baseName(fileName); + if (baseName == u"gl.h") return true; #if defined(Q_OS_LINUX) || defined(Q_OS_MACOS) - if (cStringStartsWith(cFileName, "/usr/include/stdint.h")) + if (fileName == u"/usr/include/stdint.h") return true; #endif #ifdef Q_OS_LINUX - if (cStringStartsWith(cFileName, "/usr/include/stdlib.h") - || cStringStartsWith(cFileName, "/usr/include/sys/types.h")) { + if (fileName == u"/usr/include/stdlib.h" || baseName == u"types.h") return true; - } #endif // Q_OS_LINUX #ifdef Q_OS_MACOS // Parse the following system headers to get the correct typdefs for types like // int32_t, which are used in the macOS implementation of OpenGL framework. - if (cCompareFileName(baseName, "gltypes.h") - || cStringStartsWith(cFileName, "/usr/include/_types") - || cStringStartsWith(cFileName, "/usr/include/_types") - || cStringStartsWith(cFileName, "/usr/include/sys/_types")) { + if (baseName == u"gltypes.h" + || fileName.startsWith(u"/usr/include/_types") + || fileName.startsWith(u"/usr/include/_types") + || fileName.startsWith(u"/usr/include/sys/_types")) { return true; } #endif // Q_OS_MACOS - if (baseName) { - for (const auto &systemInclude : m_systemIncludes) { - if (systemInclude == baseName) - return true; - } + for (const auto &systemInclude : m_systemIncludes) { + if (systemInclude == baseName) + return true; } for (const auto &systemIncludePath : m_systemIncludePaths) { - if (cStringStartsWith(cFileName, systemIncludePath)) + if (fileName.startsWith(systemIncludePath)) return true; } return false; } -bool Builder::visitLocation(const CXSourceLocation &location) const +bool Builder::visitLocation(const QString &fileName, LocationType locationType) const { - if (clang_Location_isInSystemHeader(location) == 0) - return true; - CXFile file; // void * - unsigned line; - unsigned column; - unsigned offset; - clang_getExpansionLocation(location, &file, &line, &column, &offset); - const CXString cxFileName = clang_getFileName(file); - // Has been observed to be 0 for invalid locations - bool result = false; - if (const char *cFileName = clang_getCString(cxFileName)) { - result = d->visitHeader(cFileName); - clang_disposeString(cxFileName); - } - return result; + return locationType != LocationType::System || d->visitHeader(fileName); } -void Builder::setSystemIncludes(const QByteArrayList &systemIncludes) +void Builder::setSystemIncludes(const QStringList &systemIncludes) { for (const auto &i : systemIncludes) { - if (i.endsWith('/')) + if (i.endsWith(u'/')) d->m_systemIncludePaths.append(i); else d->m_systemIncludes.append(i); diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.h b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.h index dc37dff0f..c84ffa356 100644 --- a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.h +++ b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.h @@ -44,9 +44,9 @@ public: Builder(); ~Builder(); - void setSystemIncludes(const QByteArrayList &systemIncludes); + void setSystemIncludes(const QStringList &systemIncludes); - bool visitLocation(const CXSourceLocation &location) const override; + bool visitLocation(const QString &fileName, LocationType locationType) const override; StartTokenResult startToken(const CXCursor &cursor) override; bool endToken(const CXCursor &cursor) override; diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangparser.cpp b/sources/shiboken6/ApiExtractor/clangparser/clangparser.cpp index 8cf35641b..15be8f5a4 100644 --- a/sources/shiboken6/ApiExtractor/clangparser/clangparser.cpp +++ b/sources/shiboken6/ApiExtractor/clangparser/clangparser.cpp @@ -108,9 +108,9 @@ std::string_view SourceFileCache::getCodeSnippet(const CXCursor &cursor, BaseVisitor::BaseVisitor() = default; BaseVisitor::~BaseVisitor() = default; -bool BaseVisitor::visitLocation(const CXSourceLocation &location) const +bool BaseVisitor::visitLocation(const QString &, LocationType locationType) const { - return clang_Location_isFromMainFile(location) != 0; + return locationType != LocationType::System; } BaseVisitor::StartTokenResult BaseVisitor::cbHandleStartToken(const CXCursor &cursor) @@ -148,6 +148,34 @@ std::string_view BaseVisitor::getCodeSnippet(const CXCursor &cursor) return result; } +bool BaseVisitor::_handleVisitLocation(const CXSourceLocation &location) +{ + CXFile cxFile; // void * + unsigned line; + unsigned column; + unsigned offset; + clang_getExpansionLocation(location, &cxFile, &line, &column, &offset); + + if (cxFile == m_currentCxFile) // Same file? + return m_visitCurrent; + + const QString fileName = getFileName(cxFile); + + LocationType locationType = LocationType::Unknown; + if (!fileName.isEmpty()) { + if (clang_Location_isFromMainFile(location) != 0) + locationType = LocationType::Main; + else if (clang_Location_isInSystemHeader(location) != 0) + locationType = LocationType::System; + else + locationType = LocationType::Other; + } + + m_currentCxFile = cxFile; + m_visitCurrent = visitLocation(fileName, locationType); + return m_visitCurrent; +} + QString BaseVisitor::getCodeSnippetString(const CXCursor &cursor) { const std::string_view result = getCodeSnippet(cursor); @@ -162,7 +190,7 @@ static CXChildVisitResult auto *bv = reinterpret_cast<BaseVisitor *>(clientData); const CXSourceLocation location = clang_getCursorLocation(cursor); - if (!bv->visitLocation(location)) + if (!bv->_handleVisitLocation(location)) return CXChildVisit_Continue; const BaseVisitor::StartTokenResult startResult = bv->cbHandleStartToken(cursor); diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangparser.h b/sources/shiboken6/ApiExtractor/clangparser/clangparser.h index d95ada602..81b40ae6f 100644 --- a/sources/shiboken6/ApiExtractor/clangparser/clangparser.h +++ b/sources/shiboken6/ApiExtractor/clangparser/clangparser.h @@ -56,6 +56,14 @@ private: FileNameCache m_fileNameCache; }; +enum class LocationType +{ + Main, // Main header parsed for bindings + Other, // A header parsed for bindings + System, // A system header + Unknown // Clang internal +}; + class BaseVisitor { Q_DISABLE_COPY(BaseVisitor) public: @@ -68,7 +76,7 @@ public: // Whether location should be visited. // defaults to clang_Location_isFromMainFile() - virtual bool visitLocation(const CXSourceLocation &location) const; + virtual bool visitLocation(const QString &fileName, LocationType locationType) const; virtual StartTokenResult startToken(const CXCursor &cursor) = 0; virtual bool endToken(const CXCursor &cursor) = 0; @@ -84,9 +92,14 @@ public: void setDiagnostics(const Diagnostics &d); void appendDiagnostic(const Diagnostic &d); + // For usage by the parser + bool _handleVisitLocation( const CXSourceLocation &location); + private: SourceFileCache m_fileCache; Diagnostics m_diagnostics; + CXFile m_currentCxFile{}; + bool m_visitCurrent = true; }; bool parse(const QByteArrayList &clangArgs, diff --git a/sources/shiboken6/ApiExtractor/typedatabase.cpp b/sources/shiboken6/ApiExtractor/typedatabase.cpp index 81784c098..6345dcbc5 100644 --- a/sources/shiboken6/ApiExtractor/typedatabase.cpp +++ b/sources/shiboken6/ApiExtractor/typedatabase.cpp @@ -250,7 +250,7 @@ IncludeList TypeDatabase::extraIncludes(const QString& className) const void TypeDatabase::addSystemInclude(const QString &name) { - m_systemIncludes.append(name.toUtf8()); + m_systemIncludes.append(name); } // Add a lookup for the short name excluding inline namespaces diff --git a/sources/shiboken6/ApiExtractor/typedatabase.h b/sources/shiboken6/ApiExtractor/typedatabase.h index 347401968..06bc90b9a 100644 --- a/sources/shiboken6/ApiExtractor/typedatabase.h +++ b/sources/shiboken6/ApiExtractor/typedatabase.h @@ -120,7 +120,7 @@ public: IncludeList extraIncludes(const QString &className) const; - const QByteArrayList &systemIncludes() const { return m_systemIncludes; } + const QStringList &systemIncludes() const { return m_systemIncludes; } void addSystemInclude(const QString &name); void addInlineNamespaceLookups(const NamespaceTypeEntry *n); @@ -240,7 +240,7 @@ private: QList<TypeRejection> m_rejections; QStringList m_dropTypeEntries; - QByteArrayList m_systemIncludes; + QStringList m_systemIncludes; }; #ifndef QT_NO_DEBUG_STREAM |