summaryrefslogtreecommitdiffstats
path: root/src/linguist/lupdate/cpp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/linguist/lupdate/cpp.cpp')
-rw-r--r--src/linguist/lupdate/cpp.cpp64
1 files changed, 35 insertions, 29 deletions
diff --git a/src/linguist/lupdate/cpp.cpp b/src/linguist/lupdate/cpp.cpp
index 96ef9625b..4c2075d21 100644
--- a/src/linguist/lupdate/cpp.cpp
+++ b/src/linguist/lupdate/cpp.cpp
@@ -5,7 +5,6 @@
#include <translator.h>
#include <QtCore/QBitArray>
-#include <QtCore/QStack>
#include <QtCore/QTextStream>
#include <QtCore/QRegularExpression>
@@ -59,15 +58,6 @@ private:
QBitArray m_ba;
};
-struct CppParserState
-{
- NamespaceList namespaces;
- QStack<qsizetype> namespaceDepths;
- NamespaceList functionContext;
- QString functionContextUnresolved;
- QString pendingContext;
-};
-
class CppParser : private CppParserState {
public:
@@ -1154,6 +1144,23 @@ void CppParser::truncateNamespaces(NamespaceList *namespaces, int length)
Functions for processing include files.
*/
+size_t qHash(const CppParserState &s, size_t seed)
+{
+ seed = qHash(s.namespaces, seed);
+ seed = qHash(s.namespaceDepths, seed);
+ seed = qHash(s.functionContext, seed);
+ seed = qHash(s.functionContextUnresolved, seed);
+ seed = qHash(s.pendingContext, seed);
+ return seed;
+}
+
+size_t qHash(const ResultsCacheKey &key, size_t seed)
+{
+ seed = qHash(key.cleanFile, seed);
+ seed = qHash(key.parserState, seed);
+ return seed;
+}
+
IncludeCycleHash &CppFiles::includeCycles()
{
static IncludeCycleHash cycles;
@@ -1175,9 +1182,9 @@ QSet<QString> &CppFiles::blacklistedFiles()
return blacklisted;
}
-QSet<const ParseResults *> CppFiles::getResults(const QString &cleanFile)
+QSet<const ParseResults *> CppFiles::getResults(const ResultsCacheKey &key)
{
- IncludeCycle * const cycle = includeCycles().value(cleanFile);
+ IncludeCycle * const cycle = includeCycles().value(key);
if (cycle)
return cycle->results;
@@ -1185,16 +1192,16 @@ QSet<const ParseResults *> CppFiles::getResults(const QString &cleanFile)
return QSet<const ParseResults *>();
}
-void CppFiles::setResults(const QString &cleanFile, const ParseResults *results)
+void CppFiles::setResults(const ResultsCacheKey &key, const ParseResults *results)
{
- IncludeCycle *cycle = includeCycles().value(cleanFile);
+ IncludeCycle *cycle = includeCycles().value(key);
if (!cycle) {
cycle = new IncludeCycle;
- includeCycles().insert(cleanFile, cycle);
+ includeCycles().insert(key, cycle);
}
- cycle->fileNames.insert(cleanFile);
+ cycle->fileNames.insert(key.cleanFile);
cycle->results.insert(results);
}
@@ -1218,14 +1225,15 @@ void CppFiles::setBlacklisted(const QString &cleanFile)
blacklistedFiles().insert(cleanFile);
}
-void CppFiles::addIncludeCycle(const QSet<QString> &fileNames)
+void CppFiles::addIncludeCycle(const QSet<QString> &fileNames, const CppParserState &parserState)
{
IncludeCycle * const cycle = new IncludeCycle;
cycle->fileNames = fileNames;
QSet<IncludeCycle *> intersectingCycles;
for (const QString &fileName : fileNames) {
- IncludeCycle *intersectingCycle = includeCycles().value(fileName);
+ const ResultsCacheKey key = { fileName, parserState };
+ IncludeCycle *intersectingCycle = includeCycles().value(key);
if (intersectingCycle && !intersectingCycles.contains(intersectingCycle)) {
intersectingCycles.insert(intersectingCycle);
@@ -1237,7 +1245,7 @@ void CppFiles::addIncludeCycle(const QSet<QString> &fileNames)
qDeleteAll(intersectingCycles);
for (const QString &fileName : std::as_const(cycle->fileNames))
- includeCycles().insert(fileName, cycle);
+ includeCycles().insert({ fileName, parserState }, cycle);
}
static bool isHeader(const QString &name)
@@ -1251,29 +1259,27 @@ void CppParser::processInclude(const QString &file, ConversionData &cd, const QS
{
QString cleanFile = QDir::cleanPath(file);
- for (const QString &ex : std::as_const(cd.m_excludes)) {
- QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(ex));
+ for (const QRegularExpression &rx : std::as_const(cd.m_excludes)) {
if (rx.match(cleanFile).hasMatch())
return;
}
const int index = includeStack.indexOf(cleanFile);
if (index != -1) {
- CppFiles::addIncludeCycle(QSet<QString>(includeStack.cbegin() + index, includeStack.cend()));
+ CppFiles::addIncludeCycle(QSet<QString>(includeStack.cbegin() + index, includeStack.cend()),
+ *this);
return;
}
- // If the #include is in any kind of namespace, has been blacklisted previously,
+ // If the #include has been blacklisted previously,
// or is not a header file (stdc++ extensionless or *.h*), then really include
// it. Otherwise it is safe to process it stand-alone and re-use the parsed
// namespace data for inclusion into other files.
bool isIndirect = false;
- if (namespaces.size() == 1 && functionContext.size() == 1
- && functionContextUnresolved.isEmpty() && pendingContext.isEmpty()
- && !CppFiles::isBlacklisted(cleanFile)
+ if (!CppFiles::isBlacklisted(cleanFile)
&& isHeader(cleanFile)) {
- QSet<const ParseResults *> res = CppFiles::getResults(cleanFile);
+ QSet<const ParseResults *> res = CppFiles::getResults(ResultsCacheKey(cleanFile, *this));
if (!res.isEmpty()) {
results->includes.unite(res);
return;
@@ -2245,7 +2251,7 @@ const ParseResults *CppParser::recordResults(bool isHeader)
results->fileId = nextFileId++;
pr = results;
}
- CppFiles::setResults(yyFileName, pr);
+ CppFiles::setResults(ResultsCacheKey(yyFileName, *this), pr);
return pr;
} else {
delete results;
@@ -2258,7 +2264,7 @@ void loadCPP(Translator &translator, const QStringList &filenames, ConversionDat
QStringConverter::Encoding e = cd.m_sourceIsUtf16 ? QStringConverter::Utf16 : QStringConverter::Utf8;
for (const QString &filename : filenames) {
- if (!CppFiles::getResults(filename).isEmpty() || CppFiles::isBlacklisted(filename))
+ if (!CppFiles::getResults(ResultsCacheKey(filename)).isEmpty() || CppFiles::isBlacklisted(filename))
continue;
QFile file(filename);