summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2022-06-17 18:22:55 +0200
committerJoerg Bornemann <joerg.bornemann@qt.io>2022-06-23 10:40:43 +0200
commit1364c1363406eda9b462f4e48ed09248ae0cdaf8 (patch)
treedb09d01a6542022ca81186af6c09fc913a968880
parentb4c51ba393b19996726b122a4cd5fe6b1fe128d3 (diff)
downloadqttools-1364c1363406eda9b462f4e48ed09248ae0cdaf8.tar.gz
lupdate: Apply a simpler fix for static initializers
...in the old C++ parser. The fix for QTBUG-91521 was overly complicated and slow. Also it introduced the (minor) issue QTBUG-104426. Old fix: on encountering an identifier that is not a tr function, we checked - Are we on namespace level? - Is the pending context empty? - Are we not in a class declaration? If all are true, we walk up the namespace stack and check whether we're in a class declaration. Promote the prospecting to the pending context. New fix: On encountering a first level left parenthesis we promote the prospective context to pending context. On encountering the matching right parenthesis we demote the pending context to prospective context. This has the effect that the prospective context is pending between matching first-level parentheses like here: QString MyClass::member(QT_TR_NOOP("some text")); ^^^^^^^^^^^^^^^^^^^^^^^^ ^ pendingContext empty ^^^^^^^^^^^^^^^^^^^^^^^ pendingContext: "MyClass" The pending context is then picked up by handleTr. This approach fits better into the overall architecture of the parser. Task-number: QTBUG-91521 Task-number: QTBUG-104426 Change-Id: Ibc9dfe955f2a56fc13a7bede11344532537e2f5d Reviewed-by: Kai Koehne <kai.koehne@qt.io> (cherry picked from commit e4ebb97fe3bb154897394b94473848992f83cf99)
-rw-r--r--src/linguist/lupdate/cpp.cpp63
1 files changed, 29 insertions, 34 deletions
diff --git a/src/linguist/lupdate/cpp.cpp b/src/linguist/lupdate/cpp.cpp
index b0cfde5a8..adaed23de 100644
--- a/src/linguist/lupdate/cpp.cpp
+++ b/src/linguist/lupdate/cpp.cpp
@@ -84,16 +84,10 @@ private:
QBitArray m_ba;
};
-struct NamespaceStackItem
-{
- qsizetype depth = 0; // the depth of CppParser::namespaces
- int token = 0; // the token that opened the namespace or class
-};
-
struct CppParserState
{
NamespaceList namespaces;
- QStack<NamespaceStackItem> namespaceDepths;
+ QStack<qsizetype> namespaceDepths;
NamespaceList functionContext;
QString functionContextUnresolved;
QString pendingContext;
@@ -199,7 +193,6 @@ private:
void enterNamespace(NamespaceList *namespaces, const HashString &name);
void truncateNamespaces(NamespaceList *namespaces, int lenght);
Namespace *modifyNamespace(NamespaceList *namespaces, bool haveLast = true);
- bool isInClassDeclaration() const;
// Tokenizer state
QString yyFileName;
@@ -1159,14 +1152,6 @@ void CppParser::truncateNamespaces(NamespaceList *namespaces, int length)
namespaces->erase(namespaces->begin() + length, namespaces->end());
}
-bool CppParser::isInClassDeclaration() const
-{
- for (const NamespaceStackItem &item : namespaceDepths)
- if (item.token == Tok_class)
- return true;
- return false;
-}
-
/*
Functions for processing include files.
@@ -1798,10 +1783,10 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac
yyMsg() << "Ignoring definition of undeclared qualified class\n";
break;
}
- namespaceDepths.push({ namespaces.count(), Tok_class });
+ namespaceDepths.push(namespaces.count());
namespaces = nsl;
} else {
- namespaceDepths.push({ namespaces.count(), Tok_class });
+ namespaceDepths.push(namespaces.count());
}
enterNamespace(&namespaces, fct);
@@ -1834,7 +1819,7 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac
ns = HashString(text);
}
if (yyTok == Tok_LeftBrace) {
- namespaceDepths.push({ namespaces.count(), Tok_namespace });
+ namespaceDepths.push(namespaces.count());
for (const auto &nns : nestedNamespaces)
enterNamespace(&namespaces, nns);
enterNamespace(&namespaces, ns);
@@ -1867,7 +1852,7 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac
}
} else if (yyTok == Tok_LeftBrace) {
// Anonymous namespace
- namespaceDepths.push({ namespaces.count(), Tok_namespace });
+ namespaceDepths.push(namespaces.count());
metaExpected = true;
yyTok = getToken();
}
@@ -1974,15 +1959,8 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac
} else {
notrfunc:
prefix.clear();
- if (yyBraceDepth == namespaceDepths.count() && pendingContext.isEmpty() && !isInClassDeclaration()) {
- if (!prospectiveContext.isEmpty()) {
- pendingContext = prospectiveContext;
- prospectiveContext.clear();
- }
- } else {
- if (yyTok == Tok_Ident && !yyParenDepth)
- prospectiveContext.clear();
- }
+ if (yyTok == Tok_Ident && !yyParenDepth)
+ prospectiveContext.clear();
}
metaExpected = false;
break;
@@ -2018,7 +1996,7 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac
if (!yyTokColonSeen) {
if (yyBraceDepth + 1 == namespaceDepths.count()) {
// class or namespace
- truncateNamespaces(&namespaces, namespaceDepths.pop().depth);
+ truncateNamespaces(&namespaces, namespaceDepths.pop());
}
if (yyBraceDepth == namespaceDepths.count()) {
// function, class or namespace
@@ -2080,20 +2058,37 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac
yyTokColonSeen = false;
}
}
- Q_FALLTHROUGH();
+ yyTokIdentSeen = false;
+ metaExpected = true;
+ yyTok = getToken();
+ break;
case Tok_LeftParen:
+ if (!yyTokColonSeen && yyBraceDepth == namespaceDepths.count() && yyParenDepth == 1
+ && !prospectiveContext.isEmpty()) {
+ pendingContext = prospectiveContext;
+ prospectiveContext.clear();
+ }
yyTokIdentSeen = false;
- Q_FALLTHROUGH();
+ metaExpected = true;
+ yyTok = getToken();
+ break;
case Tok_Comma:
case Tok_QuestionMark:
metaExpected = true;
yyTok = getToken();
break;
case Tok_RightParen:
- if (yyParenDepth == 0)
+ if (yyParenDepth == 0) {
+ if (!yyTokColonSeen && !pendingContext.isEmpty()
+ && yyBraceDepth == namespaceDepths.count()) {
+ // Demote the pendingContext to prospectiveContext.
+ prospectiveContext = pendingContext;
+ pendingContext.clear();
+ }
metaExpected = true;
- else
+ } else {
metaExpected = false;
+ }
yyTok = getToken();
break;
default: