summaryrefslogtreecommitdiffstats
path: root/src/qdoc/qdoc/src/qdoc/clangcodeparser.h
diff options
context:
space:
mode:
authorLuca Di Sera <luca.disera@qt.io>2024-03-03 21:30:17 +0100
committerLuca Di Sera <luca.disera@qt.io>2024-04-12 11:06:24 +0100
commita5ed3b76613c6fe5beb1fd1520bfb62b6c53d61d (patch)
tree63489d12deda87f492e6677bfaddf6f91bf08dd0 /src/qdoc/qdoc/src/qdoc/clangcodeparser.h
parentca22950607e85b3a0846ab08e692233b99361ede (diff)
QDoc: Move buildPCH out of ClangCodeParser
When QDoc processes a project, it parses its code-base to obtain and sanitize the user-provided documentation for the project. For projects that makes use of C++ code, QDoc uses Clang's APIs to obtain the required information about the code-base. Profiling shows that calls to Clang are the major bottleneck in QDoc at the current time. To reduce the time spent by Clang, QDoc is being moved to parallelize and batch certain operations that are related to Clang calls. `ClangCodeParser`, the component responsible for all of the calls to Clang libraries, is currently architectured in a way that is not usable for those optimization purposes. Hence, it is slowly being modified to be better suited for those purposes. As part of those modification, we expect `ClangCodeParser` to be split into multiple components. Currently, `ClangCodeParser` is the entry point to a series of operations that happen in different phases and have very different restriction on their scopes and their dependencies. To fullfill and simplify the parallelization efforts, those operations are being split up to so that we can reorganize their order and restrictions. When QDoc parses the code-base of a C++ project, it builds a PCH to speed up the various compilations it performs. This is done in `ClangCodeParser::buildPCH`. The PCH is then saved as an internal state of `ClangCodeParser` and reused by different parts of the code-base. Those external dependencies that the PCH create, can cause problems with regards to the ongoing parallelization efforts so that `buildPCH` is now moved outside `ClangCodeParser`. The free function version of `buildPCH` now returns a record that contains the necessary information to work with the PCH, which will later allow us to pass this information around to the required components without posing any restriction of `ClangCodeParser` or the file-parsing process. The signature of `buildPCH` was modified to obtain all the required dependencies, which were provided by instance-members of `ClangCodeParser` before, at call-site. The implementation for `buildPCH` was modified to make use of the new arguments instead of the instance members. The structure of `buildPCH` was slighly modified, in a semantic preserving manner, to be better suited to a value-returning function, compared to the previous structure which was built around the function not returning any value. The instance member of `ClangCodeParser` that stored the PCH information were removed in favor of a new member, `m_pch`, that is compatible with the new information structure. The constructor for `ClangCodeParser` was modified to be able to obtain the built PCH at instance-creation time to support the now separated `buildPCH` format. The main loop of QDoc was modified to support the new structure. The code taking care of building the PCH was modified to support the new structure and was moved around as it now should be run before an instance of `ClangCodeParser` is obtained. The construction of the currently single `ClangCodeParser` instance was modified to make use of the value obtained by a call to `buildPCH`. `buildPCH` implicitly depends on `QDocDatabase`, a mutable singleton that owns the internal representaton of a code-base that QDoc builds when parsing the PCH and other source-files. Hence, the code taking care of the initialization of `QDocDatabase` was moved around in the main loop as it needs to be processed before `buildPCH` is called. One of the operation required to initialize the `QDocDatabase` instance implicitly depends on the `Generators`, the components that take care of building and writing the final output documentation and which follow a "singleton" like lifetime, initialization. Thus, the code that initializes the generator was moved around in the main loop to respect the required order. Task-number: QTBUG-111686 Change-Id: I894f900dc507142495abdb636d68f59eafbcd194 Reviewed-by: Topi Reiniƶ <topi.reinio@qt.io>
Diffstat (limited to 'src/qdoc/qdoc/src/qdoc/clangcodeparser.h')
-rw-r--r--src/qdoc/qdoc/src/qdoc/clangcodeparser.h26
1 files changed, 22 insertions, 4 deletions
diff --git a/src/qdoc/qdoc/src/qdoc/clangcodeparser.h b/src/qdoc/qdoc/src/qdoc/clangcodeparser.h
index ea330c202..2318a048d 100644
--- a/src/qdoc/qdoc/src/qdoc/clangcodeparser.h
+++ b/src/qdoc/qdoc/src/qdoc/clangcodeparser.h
@@ -11,6 +11,8 @@
#include <QtCore/qtemporarydir.h>
#include <QtCore/QStringList>
+#include <optional>
+
typedef struct CXTranslationUnitImpl *CXTranslationUnit;
QT_BEGIN_NAMESPACE
@@ -20,10 +22,28 @@ struct ParsedCppFileIR {
std::vector<TiedDocumentation> tied;
};
+struct PCHFile {
+ QTemporaryDir dir;
+ QByteArray name;
+};
+
+std::optional<PCHFile> buildPCH(
+ QDocDatabase* qdb,
+ QString module_header,
+ const std::set<Config::HeaderFilePath>& all_headers,
+ const std::vector<QByteArray>& include_paths,
+ const QList<QByteArray>& defines
+);
+
class ClangCodeParser : public CodeParser
{
public:
- ClangCodeParser(Config&, const std::vector<QByteArray>& include_paths, const QList<QByteArray>& defines);
+ ClangCodeParser(
+ Config&,
+ const std::vector<QByteArray>& include_paths,
+ const QList<QByteArray>& defines,
+ std::optional<std::reference_wrapper<const PCHFile>> pch
+ );
~ClangCodeParser() override = default;
void initializeParser() override {}
@@ -32,18 +52,16 @@ public:
QStringList sourceFileNameFilter() override;
void parseSourceFile(const Location &, const QString &, CppCodeParser&) override {}
ParsedCppFileIR parse_cpp_file(const QString &filePath);
- void buildPCH(QString module_header);
Node *parseFnArg(const Location &location, const QString &fnSignature, const QString &idTag, QStringList context);
private:
std::set<Config::HeaderFilePath> m_allHeaders {}; // file name->path
const std::vector<QByteArray>& m_includePaths;
- QScopedPointer<QTemporaryDir> m_pchFileDir {};
- QByteArray m_pchName {};
QList<QByteArray> m_defines {};
std::vector<const char *> m_args {};
QStringList m_namespaceScope {};
QByteArray s_fn;
+ std::optional<std::reference_wrapper<const PCHFile>> m_pch;
};
QT_END_NAMESPACE