diff options
author | Kai Pastor <dg0yt@darc.de> | 2016-05-27 07:25:32 +0200 |
---|---|---|
committer | Jani Heikkinen <jani.heikkinen@qt.io> | 2016-05-27 08:56:15 +0000 |
commit | abcb49adcc640817b37d4ba8f0c10712a857d434 (patch) | |
tree | 64de77aa51332aa0a38f828437de0f7e6af80f94 | |
parent | e0edc350632e6f311548cac2831a60f3b9e4dbda (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.cpp | 8 | ||||
-rw-r--r-- | tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp | 17 | ||||
-rw-r--r-- | tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result | 8 |
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"/> |