summaryrefslogtreecommitdiff
path: root/src/qdoc/clangcodeparser.cpp
diff options
context:
space:
mode:
authorMartin Smith <martin.smith@qt.io>2016-05-23 13:06:46 +0200
committerMartin Smith <martin.smith@qt.io>2017-08-10 07:32:16 +0000
commitc9cc240cdc67d816aef5e65ffacf152d9313dd1b (patch)
tree0be2c9ead13ab5376fdf6ed568af1ba936dd6d6b /src/qdoc/clangcodeparser.cpp
parent21ca107f47600d729431828f562c6baca5ad4fb0 (diff)
downloadqttools-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.cpp58
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++";
}