diff options
author | Luca Di Sera <luca.disera@qt.io> | 2024-03-03 21:30:17 +0100 |
---|---|---|
committer | Luca Di Sera <luca.disera@qt.io> | 2024-04-12 11:06:24 +0100 |
commit | a5ed3b76613c6fe5beb1fd1520bfb62b6c53d61d (patch) | |
tree | 63489d12deda87f492e6677bfaddf6f91bf08dd0 /src/qdoc/qdoc/src/qdoc/clangcodeparser.h | |
parent | ca22950607e85b3a0846ab08e692233b99361ede (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.h | 26 |
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 |