diff --git a/src/linguist/lupdate/cpp.cpp b/src/linguist/lupdate/cpp.cpp
index eb0549cee9e8ed49ccc2288bb7f1755ab7ecd7f6..9fe4ed710f0755560636f04da9e7825e40794dac 100644
--- a/src/linguist/lupdate/cpp.cpp
+++ b/src/linguist/lupdate/cpp.cpp
@@ -26,29 +26,16 @@
 **
 ****************************************************************************/
 
-#include "lupdate.h"
+#include "cpp.h"
 
 #include <translator.h>
-
 #include <QtCore/QBitArray>
-#include <QtCore/QDebug>
-#include <QtCore/QFileInfo>
-#include <QtCore/QRegExp>
 #include <QtCore/QStack>
-#include <QtCore/QString>
 #include <QtCore/QTextCodec>
 #include <QtCore/QTextStream>
-#include <QtCore/QCoreApplication>
-
-#include <iostream>
-
-#include <ctype.h>              // for isXXX()
 
 QT_BEGIN_NAMESPACE
 
-class LU {
-    Q_DECLARE_TR_FUNCTIONS(LUpdate)
-};
 
 /* qmake ignore Q_OBJECT */
 
@@ -58,18 +45,6 @@ static QString MagicComment(QLatin1String("TRANSLATOR"));
 
 //#define DIAGNOSE_RETRANSLATABILITY // FIXME: should make a runtime option of this
 
-class HashString {
-public:
-    HashString() : m_hash(0x80000000) {}
-    explicit HashString(const QString &str) : m_str(str), m_hash(0x80000000) {}
-    void setValue(const QString &str) { m_str = str; m_hash = 0x80000000; }
-    const QString &value() const { return m_str; }
-    bool operator==(const HashString &other) const { return m_str == other.m_str; }
-private:
-    QString m_str;
-    mutable uint m_hash; // We use the highest bit as a validity indicator (set => invalid)
-    friend uint qHash(const HashString &str);
-};
 
 uint qHash(const HashString &str)
 {
@@ -78,16 +53,6 @@ uint qHash(const HashString &str)
     return str.m_hash;
 }
 
-class HashStringList {
-public:
-    explicit HashStringList(const QList<HashString> &list) : m_list(list), m_hash(0x80000000) {}
-    const QList<HashString> &value() const { return m_list; }
-    bool operator==(const HashStringList &other) const { return m_list == other.m_list; }
-private:
-    QList<HashString> m_list;
-    mutable uint m_hash; // We use the highest bit as a validity indicator (set => invalid)
-    friend uint qHash(const HashStringList &list);
-};
 
 uint qHash(const HashStringList &list)
 {
@@ -102,42 +67,6 @@ uint qHash(const HashStringList &list)
     return list.m_hash;
 }
 
-typedef QList<HashString> NamespaceList;
-
-struct Namespace {
-
-    Namespace() :
-            classDef(this),
-            hasTrFunctions(false), complained(false)
-    {}
-    ~Namespace()
-    {
-        qDeleteAll(children);
-    }
-
-    QHash<HashString, Namespace *> children;
-    QHash<HashString, NamespaceList> aliases;
-    QList<HashStringList> usings;
-
-    // Class declarations set no flags and create no namespaces, so they are ignored.
-    // Class definitions may appear multiple times - but only because we are trying to
-    // "compile" all sources irrespective of build configuration.
-    // Nested classes may be forward-declared inside a definition, and defined in another file.
-    // The latter will detach the class' child list, so clones need a backlink to the original
-    // definition (either one in case of multiple definitions).
-    // Namespaces can have tr() functions as well, so we need to track parent definitions for
-    // them as well. The complication is that we may have to deal with a forrest instead of
-    // a tree - in that case the parent will be arbitrary. However, it seem likely that
-    // Q_DECLARE_TR_FUNCTIONS would be used either in "class-like" namespaces with a central
-    // header or only locally in a file.
-    Namespace *classDef;
-
-    QString trQualification;
-
-    bool hasTrFunctions;
-    bool complained; // ... that tr functions are missing.
-};
-
 static int nextFileId;
 
 class VisitRecorder {
@@ -157,37 +86,6 @@ private:
     QBitArray m_ba;
 };
 
-struct ParseResults {
-    int fileId;
-    Namespace rootNamespace;
-    QSet<const ParseResults *> includes;
-};
-
-struct IncludeCycle {
-    QSet<QString> fileNames;
-    QSet<const ParseResults *> results;
-};
-
-typedef QHash<QString, IncludeCycle *> IncludeCycleHash;
-typedef QHash<QString, const Translator *> TranslatorHash;
-
-class CppFiles {
-
-public:
-    static QSet<const ParseResults *> getResults(const QString &cleanFile);
-    static void setResults(const QString &cleanFile, const ParseResults *results);
-    static const Translator *getTranslator(const QString &cleanFile);
-    static void setTranslator(const QString &cleanFile, const Translator *results);
-    static bool isBlacklisted(const QString &cleanFile);
-    static void setBlacklisted(const QString &cleanFile);
-    static void addIncludeCycle(const QSet<QString> &fileNames);
-
-private:
-    static IncludeCycleHash &includeCycles();
-    static TranslatorHash &translatedFiles();
-    static QSet<QString> &blacklistedFiles();
-};
-
 class CppParser {
 
 public:
diff --git a/src/linguist/lupdate/cpp.h b/src/linguist/lupdate/cpp.h
new file mode 100644
index 0000000000000000000000000000000000000000..d12c5e924d5ccd3f85d957535a5d799bedfa6ca6
--- /dev/null
+++ b/src/linguist/lupdate/cpp.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Linguist of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CPP_H
+#define CPP_H
+
+#include "lupdate.h"
+
+#include <QtCore/QSet>
+
+#include <iostream>
+
+QT_BEGIN_NAMESPACE
+
+struct HashString {
+    HashString() : m_hash(0x80000000) {}
+    explicit HashString(const QString &str) : m_str(str), m_hash(0x80000000) {}
+    void setValue(const QString &str) { m_str = str; m_hash = 0x80000000; }
+    const QString &value() const { return m_str; }
+    bool operator==(const HashString &other) const { return m_str == other.m_str; }
+    QString m_str;
+
+    mutable uint m_hash; // We use the highest bit as a validity indicator (set => invalid)
+};
+
+struct HashStringList {
+    explicit HashStringList(const QList<HashString> &list) : m_list(list), m_hash(0x80000000) {}
+    const QList<HashString> &value() const { return m_list; }
+    bool operator==(const HashStringList &other) const { return m_list == other.m_list; }
+
+    QList<HashString> m_list;
+    mutable uint m_hash; // We use the highest bit as a validity indicator (set => invalid)
+};
+
+typedef QList<HashString> NamespaceList;
+
+struct Namespace {
+
+    Namespace() :
+            classDef(this),
+            hasTrFunctions(false), complained(false)
+    {}
+    ~Namespace()
+    {
+        qDeleteAll(children);
+    }
+
+    QHash<HashString, Namespace *> children;
+    QHash<HashString, NamespaceList> aliases;
+    QList<HashStringList> usings;
+
+    // Class declarations set no flags and create no namespaces, so they are ignored.
+    // Class definitions may appear multiple times - but only because we are trying to
+    // "compile" all sources irrespective of build configuration.
+    // Nested classes may be forward-declared inside a definition, and defined in another file.
+    // The latter will detach the class' child list, so clones need a backlink to the original
+    // definition (either one in case of multiple definitions).
+    // Namespaces can have tr() functions as well, so we need to track parent definitions for
+    // them as well. The complication is that we may have to deal with a forrest instead of
+    // a tree - in that case the parent will be arbitrary. However, it seem likely that
+    // Q_DECLARE_TR_FUNCTIONS would be used either in "class-like" namespaces with a central
+    // header or only locally in a file.
+    Namespace *classDef;
+
+    QString trQualification;
+
+    bool hasTrFunctions;
+    bool complained; // ... that tr functions are missing.
+};
+
+struct ParseResults {
+    int fileId;
+    Namespace rootNamespace;
+    QSet<const ParseResults *> includes;
+};
+
+struct IncludeCycle {
+    QSet<QString> fileNames;
+    QSet<const ParseResults *> results;
+};
+
+typedef QHash<QString, IncludeCycle *> IncludeCycleHash;
+typedef QHash<QString, const Translator *> TranslatorHash;
+
+class CppFiles {
+
+public:
+    static QSet<const ParseResults *> getResults(const QString &cleanFile);
+    static void setResults(const QString &cleanFile, const ParseResults *results);
+    static const Translator *getTranslator(const QString &cleanFile);
+    static void setTranslator(const QString &cleanFile, const Translator *results);
+    static bool isBlacklisted(const QString &cleanFile);
+    static void setBlacklisted(const QString &cleanFile);
+    static void addIncludeCycle(const QSet<QString> &fileNames);
+
+private:
+    static IncludeCycleHash &includeCycles();
+    static TranslatorHash &translatedFiles();
+    static QSet<QString> &blacklistedFiles();
+};
+
+QT_END_NAMESPACE
+
+#endif // CPP_H
diff --git a/src/linguist/lupdate/java.cpp b/src/linguist/lupdate/java.cpp
index 670ca8ec963c9e84faedc1d7c0c792a484226f41..3c00af40ca97acbf2344a42cc5fd7303df2a1234 100644
--- a/src/linguist/lupdate/java.cpp
+++ b/src/linguist/lupdate/java.cpp
@@ -45,10 +45,6 @@
 
 QT_BEGIN_NAMESPACE
 
-class LU {
-    Q_DECLARE_TR_FUNCTIONS(LUpdate)
-};
-
 enum { Tok_Eof, Tok_class, Tok_return, Tok_tr,
        Tok_translate, Tok_Ident, Tok_Package,
        Tok_Comment, Tok_String, Tok_Colon, Tok_Dot,
diff --git a/src/linguist/lupdate/lupdate.h b/src/linguist/lupdate/lupdate.h
index bb58cbd1e78b86b4a4129a17861c3cde88964f99..80076afbe9e091cf97d4608ea96dcef4a1e267fa 100644
--- a/src/linguist/lupdate/lupdate.h
+++ b/src/linguist/lupdate/lupdate.h
@@ -31,10 +31,12 @@
 
 #include "qglobal.h"
 
-#include <QList>
-#include <QString>
-#include <QStringList>
-#include <QHash>
+#include <QtCore/QList>
+#include <QtCore/QHash>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QTranslator>
 
 QT_BEGIN_NAMESPACE
 
@@ -137,6 +139,10 @@ private:
     mutable QHash<QString,TrFunction> m_nameToTrFunctionMap;
 };
 
+class LU {
+    Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
 QT_END_NAMESPACE
 
 extern QT_PREPEND_NAMESPACE(TrFunctionAliasManager) trFunctionAliasManager;
diff --git a/src/linguist/lupdate/lupdate.pro b/src/linguist/lupdate/lupdate.pro
index 121717f0366abb04906ea98338ebf8ae2c442d74..e69703da2360c77838f337003c28597350e4af32 100644
--- a/src/linguist/lupdate/lupdate.pro
+++ b/src/linguist/lupdate/lupdate.pro
@@ -27,6 +27,7 @@ qtHaveModule(qmldevtools-private): SOURCES += qdeclarative.cpp
 
 HEADERS += \
     lupdate.h \
+    cpp.h \
     ../shared/projectdescriptionreader.h \
     ../shared/qrcreader.h \
     ../shared/runqttool.h \
diff --git a/src/linguist/lupdate/main.cpp b/src/linguist/lupdate/main.cpp
index 8bdfff479903259afd30c6dc4364c72564f7d08c..712b955509d67921153a2f042d7c6b7b7acfc569 100644
--- a/src/linguist/lupdate/main.cpp
+++ b/src/linguist/lupdate/main.cpp
@@ -197,10 +197,6 @@ static void printErr(const QString & out)
     std::cerr << qPrintable(out);
 }
 
-class LU {
-    Q_DECLARE_TR_FUNCTIONS(LUpdate)
-};
-
 static void recursiveFileInfoList(const QDir &dir,
     const QSet<QString> &nameFilters, QDir::Filters filter,
     QFileInfoList *fileinfolist)
diff --git a/src/linguist/lupdate/merge.cpp b/src/linguist/lupdate/merge.cpp
index f413610f9a76ba108c778e780a3901fa2aa93ee9..0a5a9c1f503cb7d2aa308183e22f07de36b99561 100644
--- a/src/linguist/lupdate/merge.cpp
+++ b/src/linguist/lupdate/merge.cpp
@@ -39,10 +39,6 @@
 
 QT_BEGIN_NAMESPACE
 
-class LU {
-    Q_DECLARE_TR_FUNCTIONS(LUpdate)
-};
-
 static bool isDigitFriendly(QChar c)
 {
     return c.isPunct() || c.isSpace();
diff --git a/src/linguist/lupdate/qdeclarative.cpp b/src/linguist/lupdate/qdeclarative.cpp
index 23e8dc4518ca7dc74f903009840b60cd0186c276..216bc8329cf3146d3ad2fdc872043af711429d26 100644
--- a/src/linguist/lupdate/qdeclarative.cpp
+++ b/src/linguist/lupdate/qdeclarative.cpp
@@ -52,10 +52,6 @@
 
 QT_BEGIN_NAMESPACE
 
-class LU {
-    Q_DECLARE_TR_FUNCTIONS(LUpdate)
-};
-
 using namespace QQmlJS;
 
 static QString MagicComment(QLatin1String("TRANSLATOR"));
diff --git a/src/linguist/lupdate/ui.cpp b/src/linguist/lupdate/ui.cpp
index 417f32cc6bb61cbf7a681150c3d9314b8d4ac58a..ce4ecc04580d8a65bc514dadb37e9644ad73c776 100644
--- a/src/linguist/lupdate/ui.cpp
+++ b/src/linguist/lupdate/ui.cpp
@@ -43,10 +43,6 @@
 
 QT_BEGIN_NAMESPACE
 
-class LU {
-    Q_DECLARE_TR_FUNCTIONS(LUpdate)
-};
-
 class UiReader : public QXmlDefaultHandler
 {
 public: