diff options
author | Martin Smith <martin.smith@qt.io> | 2016-05-23 13:06:46 +0200 |
---|---|---|
committer | Martin Smith <martin.smith@qt.io> | 2017-08-10 07:32:16 +0000 |
commit | c9cc240cdc67d816aef5e65ffacf152d9313dd1b (patch) | |
tree | 0be2c9ead13ab5376fdf6ed568af1ba936dd6d6b /src/qdoc/clangcodeparser.cpp | |
parent | 21ca107f47600d729431828f562c6baca5ad4fb0 (diff) | |
download | qttools-c9cc240cdc67d816aef5e65ffacf152d9313dd1b.tar.gz |
qdoc: Reduce total clang parse time
Including the module's private headers in the PCH
database can reduce the qdoc run time for the module
by a few minutes. Apparently, including the private
headers significantly reduces the number of header
files that must be re-parsed.
This change adds the module's private headers to the
pre-compiled header database. When it finds the module's
module header, it copies that module header to the
temporary directory where it will construct the PCH.
Then it finds the module's private header subdirectory,
constructs the path to each header in that directory,
and appends it to the temporary module header. Then
it passes this augmented module header to clang to
construct the PCH.
Change-Id: Ie67485c7070ef7487345db90a8b27c64f5caa0f2
Reviewed-by: Topi Reiniƶ <topi.reinio@qt.io>
Diffstat (limited to 'src/qdoc/clangcodeparser.cpp')
-rw-r--r-- | src/qdoc/clangcodeparser.cpp | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/src/qdoc/clangcodeparser.cpp b/src/qdoc/clangcodeparser.cpp index ba270a613..3e76a9ff8 100644 --- a/src/qdoc/clangcodeparser.cpp +++ b/src/qdoc/clangcodeparser.cpp @@ -777,7 +777,7 @@ void ClangCodeParser::parseHeaderFile(const Location & /*location*/, const QStri allHeaders_.insert(fi.canonicalFilePath()); } - +#define INCLUDE_PRIVATE_HEADERS /*! Get ready to parse the C++ cpp file identified by \a filePath and add its parsed contents to the database. \a location is @@ -832,6 +832,9 @@ void ClangCodeParser::parseSourceFile(const Location& /*location*/, const QStrin if (pchFileDir_->isValid()) { const QByteArray module = qdb_->primaryTreeRoot()->tree()->camelCaseModuleName().toUtf8(); QByteArray header; +#ifdef INCLUDE_PRIVATE_HEADERS + QByteArray privateHeaderDir; +#endif // Find the path to the module's header (e.g. QtGui/QtGui) to be used // as pre-compiled header for (const auto &p : qAsConst(includePaths_)) { @@ -843,6 +846,20 @@ void ClangCodeParser::parseSourceFile(const Location& /*location*/, const QStrin } } } +#ifdef INCLUDE_PRIVATE_HEADERS + // Find the path to the module's private header directory (e.g. + // include/QtGui/5.8.0/QtGui/private) to use for including all + // the private headers in the PCH. + for (const auto &p : qAsConst(includePaths_)) { + if (p.endsWith(module)) { + QByteArray candidate = p + "/private"; + if (QFile::exists(QString::fromUtf8(candidate))) { + privateHeaderDir = candidate; + break; + } + } + } +#endif if (header.isEmpty()) { QByteArray installDocDir = Config::installDir.toUtf8(); const QByteArray candidate = installDocDir + "/../include/" + module + "/" + module; @@ -855,8 +872,35 @@ void ClangCodeParser::parseSourceFile(const Location& /*location*/, const QStrin } else { args.push_back("-xc++"); CXTranslationUnit tu; - CXErrorCode err = clang_parseTranslationUnit2( - index, header.constData(), args.data(), args.size(), nullptr, 0, +#ifdef INCLUDE_PRIVATE_HEADERS + QString tmpHeader = pchFileDir_->path() + "/" + module; + if (QFile::copy(header, tmpHeader) && !privateHeaderDir.isEmpty()) { + privateHeaderDir = QDir::cleanPath(privateHeaderDir.constData()).toLatin1(); + const char *const headerPath = privateHeaderDir.constData(); + const QStringList pheaders = QDir(headerPath).entryList(); + QFile tmpHeaderFile(tmpHeader); + if (tmpHeaderFile.open(QIODevice::Text | QIODevice::Append)) { + for (const QString &phead : pheaders) { + if (phead.endsWith("_p.h")) { + QByteArray entry; + entry = "#include \""; + entry += headerPath; + entry += QChar('/'); + entry += phead; + entry += "\"\n"; + tmpHeaderFile.write(entry); + } + } + } + } +#endif + CXErrorCode err = clang_parseTranslationUnit2(index, +#ifdef INCLUDE_PRIVATE_HEADERS + tmpHeader.toLatin1().data(), +#else + header.constData(), +#endif + args.data(), args.size(), nullptr, 0, flags | CXTranslationUnit_ForSerialization, &tu); if (!err && tu) { pchName_ = pchFileDir_->path().toUtf8() + "/" + module + ".pch"; @@ -874,7 +918,13 @@ void ClangCodeParser::parseSourceFile(const Location& /*location*/, const QStrin clang_disposeTranslationUnit(tu); } else { pchFileDir_->remove(); - qWarning() << "Could not create PCH file for " << header << " error code:" << err; + qWarning() << "Could not create PCH file for " +#ifdef INCLUDE_PRIVATE_HEADERS + << tmpHeader +#else + << header +#endif + << " error code:" << err; } args.pop_back(); // remove the "-xc++"; } |