From 6244594d7111eb64fa864a1ebb09938376c6635f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 28 Jun 2020 17:16:35 -0700 Subject: [PATCH] indexer: log the number of errors and the first diagnostic Example log: ``` 15:47:45 indexer1 pipeline.cc:379 I parse /tmp/d/a.c error:1 use of undeclared identifier 'arg' clang /tmp/d/a.c --gcc-toolchain=/usr -working-directory=/tmp/d/ ``` --- src/indexer.cc | 22 ++++++++++++++++++---- src/indexer.hh | 8 +++++++- src/pipeline.cc | 35 +++++++++++++++++++++++------------ src/test.cc | 6 +++--- 4 files changed, 51 insertions(+), 20 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 7b7c1480..d24e11e7 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1203,6 +1203,17 @@ public: return std::make_unique(std::move(consumers)); } }; + +class IndexDiags : public DiagnosticConsumer { +public: + llvm::SmallString<64> message; + void HandleDiagnostic(DiagnosticsEngine::Level level, + const clang::Diagnostic &info) override { + DiagnosticConsumer::HandleDiagnostic(level, info); + if (message.empty()) + info.FormatDiagnostic(message); + } +}; } // namespace const int IndexFile::kMajorVersion = 21; @@ -1252,7 +1263,7 @@ void init() { g_config->index.multiVersionBlacklist); } -std::vector> +IndexResult index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, const std::string &opt_wdir, const std::string &main, const std::vector &args, @@ -1281,7 +1292,7 @@ index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, ci->getPreprocessorOpts().addRemappedFile(filename, bufs.back().get()); } - DiagnosticConsumer dc; + IndexDiags dc; auto clang = std::make_unique(pch); clang->setInvocation(std::move(ci)); clang->createDiagnostics(&dc, false); @@ -1355,7 +1366,10 @@ index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, return {}; } - std::vector> result; + IndexResult result; + result.n_errs = (int)dc.getNumErrors(); + // clang 7 does not implement operator std::string. + result.first_error = std::string(dc.message.data(), dc.message.size()); for (auto &it : param.uid2file) { if (!it.second.db) continue; @@ -1392,7 +1406,7 @@ index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, entry->dependencies[llvm::CachedHashStringRef(intern(path))] = file.mtime; } - result.push_back(std::move(entry)); + result.indexes.push_back(std::move(entry)); } return result; diff --git a/src/indexer.hh b/src/indexer.hh index cd4669a9..11e7133b 100644 --- a/src/indexer.hh +++ b/src/indexer.hh @@ -322,13 +322,19 @@ struct IndexFile { std::string toString(); }; +struct IndexResult { + std::vector> indexes; + int n_errs = 0; + std::string first_error; +}; + struct SemaManager; struct WorkingFiles; struct VFS; namespace idx { void init(); -std::vector> +IndexResult index(SemaManager *complete, WorkingFiles *wfiles, VFS *vfs, const std::string &opt_wdir, const std::string &file, const std::vector &args, diff --git a/src/pipeline.cc b/src/pipeline.cc index 9ebccb5d..2dc106da 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -330,17 +330,9 @@ bool indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, return true; } while (0); - if (loud) { - std::string line; - if (LOG_V_ENABLED(1)) { - line = "\n "; - for (auto &arg : entry.args) - (line += ' ') += arg; - } - LOG_S(INFO) << (deleted ? "delete " : "parse ") << path_to_index << line; - } - std::vector> indexes; + int n_errs = 0; + std::string first_error; if (deleted) { indexes.push_back(std::make_unique(request.path, "", false)); if (request.path != path_to_index) @@ -353,8 +345,12 @@ bool indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, remapped.emplace_back(path_to_index, content); } bool ok; - indexes = idx::index(completion, wfiles, vfs, entry.directory, - path_to_index, entry.args, remapped, no_linkage, ok); + auto result = + idx::index(completion, wfiles, vfs, entry.directory, path_to_index, + entry.args, remapped, no_linkage, ok); + indexes = std::move(result.indexes); + n_errs = result.n_errs; + first_error = std::move(result.first_error); if (!ok) { if (request.id.valid()) { @@ -367,6 +363,21 @@ bool indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, } } + if (loud || n_errs) { + std::string line; + SmallString<64> tmp; + SmallString<256> msg; + (Twine(deleted ? "delete " : "parse ") + path_to_index).toVector(msg); + if (n_errs) + msg += (" error:" + Twine(n_errs) + " " + first_error).toStringRef(tmp); + if (LOG_V_ENABLED(1)) { + msg += "\n "; + for (const char *arg : entry.args) + (msg += ' ') += arg; + } + LOG_S(INFO) << std::string_view(msg.data(), msg.size()); + } + for (std::unique_ptr &curr : indexes) { std::string path = curr->path; if (!matcher.matches(path)) { diff --git a/src/test.cc b/src/test.cc index 0f4708c0..d74d4496 100644 --- a/src/test.cc +++ b/src/test.cc @@ -315,15 +315,15 @@ bool runIndexTests(const std::string &filter_path, bool enable_update) { for (auto &arg : flags) cargs.push_back(arg.c_str()); bool ok; - auto dbs = ccls::idx::index(&completion, &wfiles, &vfs, "", path, cargs, - {}, true, ok); + auto result = ccls::idx::index(&completion, &wfiles, &vfs, "", path, + cargs, {}, true, ok); for (const auto &entry : all_expected_output) { const std::string &expected_path = entry.first; std::string expected_output = text_replacer.apply(entry.second); // Get output from index operation. - IndexFile *db = findDbForPathEnding(expected_path, dbs); + IndexFile *db = findDbForPathEnding(expected_path, result.indexes); std::string actual_output = "{}"; if (db) { verifySerializeToFrom(db);