summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/qdoc/clangcodeparser.cpp54
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);
}
/*!