1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Linguist of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 
29 #ifndef CPP_H
30 #define CPP_H
31 
32 #include "lupdate.h"
33 
34 #include <QtCore/QSet>
35 
36 #include <iostream>
37 
38 QT_BEGIN_NAMESPACE
39 
40 struct HashString {
HashStringHashString41     HashString() : m_hash(0x80000000) {}
HashStringHashString42     explicit HashString(const QString &str) : m_str(str), m_hash(0x80000000) {}
setValueHashString43     void setValue(const QString &str) { m_str = str; m_hash = 0x80000000; }
valueHashString44     const QString &value() const { return m_str; }
45     bool operator==(const HashString &other) const { return m_str == other.m_str; }
46     QString m_str;
47 
48     mutable uint m_hash; // We use the highest bit as a validity indicator (set => invalid)
49 };
50 
51 struct HashStringList {
HashStringListHashStringList52     explicit HashStringList(const QList<HashString> &list) : m_list(list), m_hash(0x80000000) {}
valueHashStringList53     const QList<HashString> &value() const { return m_list; }
54     bool operator==(const HashStringList &other) const { return m_list == other.m_list; }
55 
56     QList<HashString> m_list;
57     mutable uint m_hash; // We use the highest bit as a validity indicator (set => invalid)
58 };
59 
60 typedef QList<HashString> NamespaceList;
61 
62 struct Namespace {
63 
NamespaceNamespace64     Namespace() :
65             classDef(this),
66             hasTrFunctions(false), complained(false)
67     {}
~NamespaceNamespace68     ~Namespace()
69     {
70         qDeleteAll(children);
71     }
72 
73     QHash<HashString, Namespace *> children;
74     QHash<HashString, NamespaceList> aliases;
75     QList<HashStringList> usings;
76 
77     // Class declarations set no flags and create no namespaces, so they are ignored.
78     // Class definitions may appear multiple times - but only because we are trying to
79     // "compile" all sources irrespective of build configuration.
80     // Nested classes may be forward-declared inside a definition, and defined in another file.
81     // The latter will detach the class' child list, so clones need a backlink to the original
82     // definition (either one in case of multiple definitions).
83     // Namespaces can have tr() functions as well, so we need to track parent definitions for
84     // them as well. The complication is that we may have to deal with a forrest instead of
85     // a tree - in that case the parent will be arbitrary. However, it seem likely that
86     // Q_DECLARE_TR_FUNCTIONS would be used either in "class-like" namespaces with a central
87     // header or only locally in a file.
88     Namespace *classDef;
89 
90     QString trQualification;
91 
92     bool hasTrFunctions;
93     bool complained; // ... that tr functions are missing.
94 };
95 
96 struct ParseResults {
97     int fileId;
98     Namespace rootNamespace;
99     QSet<const ParseResults *> includes;
100 };
101 
102 struct IncludeCycle {
103     QSet<QString> fileNames;
104     QSet<const ParseResults *> results;
105 };
106 
107 typedef QHash<QString, IncludeCycle *> IncludeCycleHash;
108 typedef QHash<QString, const Translator *> TranslatorHash;
109 
110 class CppFiles {
111 
112 public:
113     static QSet<const ParseResults *> getResults(const QString &cleanFile);
114     static void setResults(const QString &cleanFile, const ParseResults *results);
115     static const Translator *getTranslator(const QString &cleanFile);
116     static void setTranslator(const QString &cleanFile, const Translator *results);
117     static bool isBlacklisted(const QString &cleanFile);
118     static void setBlacklisted(const QString &cleanFile);
119     static void addIncludeCycle(const QSet<QString> &fileNames);
120 
121 private:
122     static IncludeCycleHash &includeCycles();
123     static TranslatorHash &translatedFiles();
124     static QSet<QString> &blacklistedFiles();
125 };
126 
127 QT_END_NAMESPACE
128 
129 #endif // CPP_H
130