diff options
-rw-r--r-- | src/qdoc/clangcodeparser.cpp | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/src/qdoc/clangcodeparser.cpp b/src/qdoc/clangcodeparser.cpp index c369b1c02..60ce615be 100644 --- a/src/qdoc/clangcodeparser.cpp +++ b/src/qdoc/clangcodeparser.cpp @@ -38,7 +38,7 @@ static CXTranslationUnit_Flags flags_ = static_cast<CXTranslationUnit_Flags>(0); static CXIndex index_ = nullptr; QByteArray ClangCodeParser::s_fn; -constexpr const char *fnDummyFileName = "/fn_dummyfile.cpp"; +constexpr const char fnDummyFileName[] = "/fn_dummyfile.cpp"; #ifndef QT_NO_DEBUG_STREAM template<class T> @@ -166,6 +166,48 @@ static Access fromCX_CXXAccessSpecifier(CX_CXXAccessSpecifier spec) /*! Returns the spelling in the file for a source range */ + +struct FileCacheEntry +{ + QByteArray fileName; + QByteArray content; +}; + +static inline QString fromCache(const QByteArray &cache, + unsigned int offset1, unsigned int offset2) +{ + return QString::fromUtf8(cache.mid(offset1, offset2 - offset1)); +} + +static QString readFile(CXFile cxFile, unsigned int offset1, unsigned int offset2) +{ + using FileCache = QList<FileCacheEntry>; + static FileCache cache; + + CXString cxFileName = clang_getFileName(cxFile); + const QByteArray fileName = clang_getCString(cxFileName); + clang_disposeString(cxFileName); + + for (const auto &entry : std::as_const(cache)) { + if (fileName == entry.fileName) + return fromCache(entry.content, offset1, offset2); + } + + // "fn_dummyfile.cpp" comes with varying cxFile values + if (fileName == fnDummyFileName) + return fromCache(ClangCodeParser::fn(), offset1, offset2); + + QFile file(QString::fromUtf8(fileName)); + if (file.open(QIODeviceBase::ReadOnly)) { // binary to match clang offsets + FileCacheEntry entry{fileName, file.readAll()}; + cache.prepend(entry); + while (cache.size() > 5) + cache.removeLast(); + return fromCache(entry.content, offset1, offset2); + } + return {}; +} + static QString getSpelling(CXSourceRange range) { auto start = clang_getRangeStart(range); @@ -177,14 +219,8 @@ static QString getSpelling(CXSourceRange range) if (file1 != file2 || offset2 <= offset1) return QString(); - QFile file(fromCXString(clang_getFileName(file1))); - if (!file.open(QFile::ReadOnly)) { - if (file.fileName() == fnDummyFileName) - return QString::fromUtf8(ClangCodeParser::fn().mid(offset1, offset2 - offset1)); - return QString(); - } - file.seek(offset1); - return QString::fromUtf8(file.read(offset2 - offset1)); + + return readFile(file1, offset1, offset2); } /*! |