summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKai Pastor <dg0yt@darc.de>2016-05-27 07:25:32 +0200
committerJani Heikkinen <jani.heikkinen@qt.io>2016-05-27 08:56:15 +0000
commitabcb49adcc640817b37d4ba8f0c10712a857d434 (patch)
tree64de77aa51332aa0a38f828437de0f7e6af80f94
parente0edc350632e6f311548cac2831a60f3b9e4dbda (diff)
lupdate: Fix parsing of class template specializations
4ea581c95ae9704b250591c5d4d9b0517f5b62f2 introduced a bug where class template specialization would lead to contexts not being properly cleaned up on '}'. The occurrence of class template specializations lead to a massive slowdown in parsing following includes because they were treated as direct (in-namespace) and parsed more often than normally needed. Unfortunately the bug was not discovered early by the auto tests, but eventually the slowdown appeared in CI when merging to dev. This change adds a test for class template specializations. It would discover the cause (broken context) which triggers the slowdown but doesn't depend on includes. Task-number: QTBUG-53644 Change-Id: I94cce58702b53dfb5e0f9c92585222dd3f938593 Reviewed-by: Liang Qi <liang.qi@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
-rw-r--r--src/linguist/lupdate/cpp.cpp8
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp17
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result8
3 files changed, 29 insertions, 4 deletions
diff --git a/src/linguist/lupdate/cpp.cpp b/src/linguist/lupdate/cpp.cpp
index 02a667320..e53994c76 100644
--- a/src/linguist/lupdate/cpp.cpp
+++ b/src/linguist/lupdate/cpp.cpp
@@ -1848,16 +1848,16 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac
}
}
- if (yyTok == Tok_Colon) {
- // Skip any token until '{' since we might do things wrong if we find
- // a '::' token here.
+ if (yyTok == Tok_Colon || yyTok == Tok_Other) {
+ // Skip any token until '{' or ';' since we might do things wrong if we find
+ // a '::' or ':' token here.
do {
yyTok = getToken();
if (yyTok == Tok_Eof)
goto goteof;
if (yyTok == Tok_Cancel)
goto case_default;
- } while (yyTok != Tok_LeftBrace);
+ } while (yyTok != Tok_LeftBrace && yyTok != Tok_Semicolon);
} else {
if (yyTok != Tok_LeftBrace) {
// Obviously a forward declaration. We skip those, as they
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp
index 5b6645689..e6b966418 100644
--- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp
@@ -627,3 +627,20 @@ TemplateClass::TemplateClass(int) :
tr("[unsupported] TemplateClass(int) out-of-class body");
}
+
+
+// Related to QTBUG-53644, adapted from qglobal.h.
+// Namespace Private must be parsed correctly for TranslatedAfterPrivate to work.
+namespace Private {
+ template <class T> struct Class1 { T t; };
+ template <class T> struct Class1<T &> : Class1<T> {};
+ template <class T> struct Class2 { enum { Value = sizeof(T) }; };
+} // namespace Private
+class TranslatedAfterPrivate
+{
+ Q_OBJECT
+ TranslatedAfterPrivate()
+ {
+ tr("Must be in context TranslatedAfterPrivate");
+ }
+};
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result
index d72026b1c..e0a30c3be 100644
--- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result
@@ -555,6 +555,14 @@ backslashed \ stuff.</source>
</message>
</context>
<context>
+ <name>TranslatedAfterPrivate</name>
+ <message>
+ <location filename="main.cpp" line="644"/>
+ <source>Must be in context TranslatedAfterPrivate</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>YetAnotherTest</name>
<message>
<location filename="main.cpp" line="239"/>