diff options
author | Martin Smith <martin.smith@qt.io> | 2018-10-01 10:59:48 +0200 |
---|---|---|
committer | Martin Smith <martin.smith@qt.io> | 2018-10-23 14:15:29 +0000 |
commit | c4d02e5cea9f8657bd74f1f724d048de5c0142b1 (patch) | |
tree | 704477c141bfe18b25233a065f871701e099b5e6 | |
parent | fcdb57ed07d36b0b72f41da974550f505a162077 (diff) |
qdoc: Let qdoc print better log messages
This change enables qdoc to print better log messages. A new logging
function is added to Location, where the qdoc error and warning
functions are located. The new function is logToStdErrAlways(msg).
It always formats msg for output to stderr by prepending the current
time and the word LOG. Several LOG messages are now sent to stderr.
Also, qdoc now always tells clang to output its parsing errors to
stderr during the building of the precompiled header in the prepare
phase. These clang parser errors are easily identified in the new
LOG.
When no include paths are passed to qdoc on the command line, which
is the case for QtPlatformHeaders, qdoc guesses some reasonable include
paths from the information available and passes them to clang. It works
ok for the QtPlatformHeaders module. However, clang gets lost in some
NSOpenGL headers and prints quite a lot of useless parse errors, so
we arbitrarily turn off clang's parse errors whenever qdoc has to guess
the include paths.
The guessed include paths are printed in the LOG, and a warning that
clang does not print parse errors when the include paths are guessed
is also printed in LOG.
Change-Id: I8e5bd0cc5b27463c4c85c9cdcc01b030ac03a1c1
Reviewed-by: Martin Smith <martin.smith@qt.io>
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
-rw-r--r-- | src/qdoc/clangcodeparser.cpp | 41 | ||||
-rw-r--r-- | src/qdoc/clangcodeparser.h | 1 | ||||
-rw-r--r-- | src/qdoc/location.cpp | 12 | ||||
-rw-r--r-- | src/qdoc/location.h | 1 | ||||
-rw-r--r-- | src/qdoc/main.cpp | 20 |
5 files changed, 49 insertions, 26 deletions
diff --git a/src/qdoc/clangcodeparser.cpp b/src/qdoc/clangcodeparser.cpp index 19b6ea553..fdf56d073 100644 --- a/src/qdoc/clangcodeparser.cpp +++ b/src/qdoc/clangcodeparser.cpp @@ -1009,6 +1009,7 @@ ClangCodeParser::~ClangCodeParser() */ void ClangCodeParser::initializeParser(const Config &config) { + printParsingErrors_ = 1; const auto args = config.getStringList(CONFIG_INCLUDEPATHS); includePaths_.resize(args.size()); std::transform(args.begin(), args.end(), includePaths_.begin(), @@ -1096,6 +1097,7 @@ static const char *defaultArgs_[] = { #endif "-fno-exceptions", // Workaround for clang bug http://reviews.llvm.org/D17988 "-DQ_QDOC", + "-DQ_CLANG_QDOC", "-DQT_DISABLE_DEPRECATED_BEFORE=0", "-DQT_ANNOTATE_CLASS(type,...)=static_assert(sizeof(#__VA_ARGS__), #type);", "-DQT_ANNOTATE_CLASS2(type,a1,a2)=static_assert(sizeof(#a1, #a2), #type);", @@ -1143,6 +1145,8 @@ static QVector<QByteArray> includePathsFromHeaders(const QHash<QString, QString> void ClangCodeParser::getMoreArgs() { if (includePaths_.isEmpty()) { + Location::logToStdErrAlways("No include paths passed to qdoc"); + Location::logToStdErrAlways("Guess reasonable include paths:"); /* The include paths provided are inadequate. Make a list of reasonable places to look for include files and use @@ -1150,22 +1154,22 @@ void ClangCodeParser::getMoreArgs() */ auto forest = qdb_->searchOrder(); + printParsingErrors_ = 0; QByteArray version = qdb_->version().toUtf8(); QString basicIncludeDir = QDir::cleanPath(QString(Config::installDir + "/../include")); moreArgs_ += "-I" + basicIncludeDir.toLatin1(); moreArgs_ += includePathsFromHeaders(allHeaders_); + for (const auto p : moreArgs_) { + Location::logToStdErrAlways(p); + } +#if 0 for (const auto &s : forest) { QString module = basicIncludeDir +"/" + s->camelCaseModuleName(); moreArgs_ += QString("-I" + module).toLatin1(); moreArgs_ += QString("-I" + module + "/" + qdb_->version()).toLatin1(); moreArgs_ += QString("-I" + module + "/" + qdb_->version() + "/" + module).toLatin1(); } - for (int i=0; i<includePaths_.size(); ++i) { - if (!includePaths_.at(i).startsWith("-")) - moreArgs_ += "-I" + includePaths_.at(i); - else - moreArgs_ += includePaths_.at(i); - } +#endif } else { moreArgs_ = includePaths_; @@ -1195,6 +1199,7 @@ void ClangCodeParser::buildPCH() const QByteArray module = moduleHeader().toUtf8(); QByteArray header; QByteArray privateHeaderDir; + Location::logToStdErrAlways("Build & visit PCH for " + moduleHeader()); // 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_)) { @@ -1259,6 +1264,8 @@ void ClangCodeParser::buildPCH() } } } + if (printParsingErrors_ == 0) + Location::logToStdErrAlways("clang not printing errors; include paths were guessed"); CXErrorCode err = clang_parseTranslationUnit2(index_, tmpHeader.toLatin1().data(), args_.data(), static_cast<int>(args_.size()), nullptr, 0, @@ -1269,20 +1276,20 @@ void ClangCodeParser::buildPCH() pchName_ = pchFileDir_->path().toUtf8() + "/" + module + ".pch"; auto error = clang_saveTranslationUnit(tu, pchName_.constData(), clang_defaultSaveOptions(tu)); if (error) { - qWarning() << "(qdoc) Could not save PCH file for " << module << error; + Location::logToStdErrAlways("Could not save PCH file for " + moduleHeader()); pchName_.clear(); } - // Visit the header now, as token from pre-compiled header won't be visited later - CXCursor cur = clang_getTranslationUnitCursor(tu); - ClangVisitor visitor(qdb_, allHeaders_); - visitor.visitChildren(cur); - + else { + // Visit the header now, as token from pre-compiled header won't be visited later + CXCursor cur = clang_getTranslationUnitCursor(tu); + ClangVisitor visitor(qdb_, allHeaders_); + visitor.visitChildren(cur); + Location::logToStdErrAlways("PCH built & visited for " + moduleHeader()); + } clang_disposeTranslationUnit(tu); } else { pchFileDir_->remove(); - qWarning() << "(qdoc) Could not create PCH file for " - << tmpHeader - << " error code:" << err; + Location::logToStdErrAlways("Could not create PCH file for " + moduleHeader()); } args_.pop_back(); // remove the "-xc++"; } @@ -1301,8 +1308,8 @@ void ClangCodeParser::precompileHeaders() args_.push_back(p.constData()); flags_ = static_cast<CXTranslationUnit_Flags>(CXTranslationUnit_Incomplete | CXTranslationUnit_SkipFunctionBodies | CXTranslationUnit_KeepGoing); - // Change 2nd parameter to 1 to make clang report errors. - index_ = clang_createIndex(1, Generator::debugging() ? 1 : 0); + // 1 as 2nd parameter tells clang to report parser errors. + index_ = clang_createIndex(1, printParsingErrors_); buildPCH(); clang_disposeIndex(index_); } diff --git a/src/qdoc/clangcodeparser.h b/src/qdoc/clangcodeparser.h index b70fcc0e8..b3497608d 100644 --- a/src/qdoc/clangcodeparser.h +++ b/src/qdoc/clangcodeparser.h @@ -69,6 +69,7 @@ public: void buildPCH(); private: + int printParsingErrors_; QHash<QString, QString> allHeaders_; // file name->path QVector<QByteArray> includePaths_; QScopedPointer<QTemporaryDir> pchFileDir_; diff --git a/src/qdoc/location.cpp b/src/qdoc/location.cpp index cb12e6ea4..68e2a262a 100644 --- a/src/qdoc/location.cpp +++ b/src/qdoc/location.cpp @@ -32,6 +32,7 @@ #include "generator.h" #include <qdir.h> #include <qregexp.h> +#include <QTime> #include <stdlib.h> #include <limits.h> @@ -378,6 +379,17 @@ void Location::logToStdErr(const QString& message) } /*! + Always prints the current time and \a message to \c stderr + followed by a \c{'\n'}. + */ +void Location::logToStdErrAlways(const QString& message) +{ + QTime t = QTime::currentTime(); + fprintf(stderr, "%s LOG: %s\n", t.toString().toLatin1().data(), message.toLatin1().data()); + fflush(stderr); +} + +/*! Report a program bug, including the \a hint. */ void Location::internalError(const QString& hint) diff --git a/src/qdoc/location.h b/src/qdoc/location.h index 5c2c90f2d..16188bde1 100644 --- a/src/qdoc/location.h +++ b/src/qdoc/location.h @@ -87,6 +87,7 @@ public: static void information(const QString& message); static void internalError(const QString& hint); static void logToStdErr(const QString& message); + static void logToStdErrAlways(const QString& message); static void startLoggingProgress() { logProgress_ = true; } static void stopLoggingProgress() { logProgress_ = false; } static QString canonicalRelativePath(const QString &path); diff --git a/src/qdoc/main.cpp b/src/qdoc/main.cpp index a2ba37499..ea9dc6ed7 100644 --- a/src/qdoc/main.cpp +++ b/src/qdoc/main.cpp @@ -255,18 +255,18 @@ static void processQdocconfFile(const QString &fileName) if (!qdocGlobals.currentDir().isEmpty()) QDir::setCurrent(qdocGlobals.currentDir()); - QString phase = " in -"; + QString phase = " in "; if (Generator::singleExec()) - phase += "single exec mode, "; + phase += "single process mode, "; else - phase += "separate exec mode, "; + phase += "dual process mode, "; if (Generator::preparing()) - phase += "prepare phase "; + phase += "(prepare phase)"; else if (Generator::generating()) - phase += "generate phase "; + phase += "(generate phase)"; - QString msg = "Running qdoc for " + config.getString(CONFIG_PROJECT) + phase; - Location::logToStdErr(msg); + QString msg = "Start qdoc for " + config.getString(CONFIG_PROJECT) + phase; + Location::logToStdErrAlways(msg); /* Initialize all the classes and data structures with the @@ -461,7 +461,7 @@ static void processQdocconfFile(const QString &fileName) add it to the big tree. */ parsed = 0; - qCDebug(lcQdoc, "Parsing source files"); + Location::logToStdErrAlways("Parse source files for " + project); QMap<QString,QString>::ConstIterator s = sources.constBegin(); while (s != sources.constEnd()) { CodeParser *codeParser = CodeParser::parserForSourceFile(s.key()); @@ -472,7 +472,7 @@ static void processQdocconfFile(const QString &fileName) } ++s; } - qCDebug(lcQdoc, "Parsing done."); + Location::logToStdErrAlways("Source files parsed for " + project); /* Now the primary tree has been built from all the header and @@ -515,6 +515,8 @@ static void processQdocconfFile(const QString &fileName) if (Generator::debugging()) Generator::stopDebugging(project); + msg = "End qdoc for " + config.getString(CONFIG_PROJECT) + phase; + Location::logToStdErrAlways(msg); QDocDatabase::qdocDB()->setVersion(QString()); Generator::terminate(); CodeParser::terminate(); |