From ebf07265eb6738deb647214b466e2be492fbad45 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 15 Jul 2018 10:10:24 -0700 Subject: [PATCH] Diagnostics --- src/clang_complete.cc | 46 +++++++++++++++++++++++-------------------- src/clang_tu.cc | 15 +++++++------- src/clang_tu.h | 4 ++-- src/indexer.cc | 3 ++- src/project.cc | 5 ++--- 5 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/clang_complete.cc b/src/clang_complete.cc index af7e936c..5328437e 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -346,15 +346,19 @@ public: } } + void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, + OverloadCandidate *Candidates, + unsigned NumCandidates) override {} + CodeCompletionAllocator &getAllocator() override { return *Alloc; } CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo;} }; -void TryEnsureDocumentParsed(ClangCompleteManager* manager, +void TryEnsureDocumentParsed(ClangCompleteManager *manager, std::shared_ptr session, - std::unique_ptr* tu, - bool emit_diag) { + std::unique_ptr *tu, + bool diagnostic) { // Nothing to do. We already have a translation unit. if (*tu) return; @@ -365,7 +369,8 @@ void TryEnsureDocumentParsed(ClangCompleteManager* manager, LOG_S(INFO) << "Creating completion session with arguments " << StringJoin(args, " "); - *tu = ClangTranslationUnit::Create(session->file.filename, args, snapshot); + *tu = ClangTranslationUnit::Create(session->file.filename, args, snapshot, + diagnostic); } void CompletionPreloadMain(ClangCompleteManager* completion_manager) { @@ -392,7 +397,7 @@ void CompletionPreloadMain(ClangCompleteManager* completion_manager) { continue; std::unique_ptr parsing; - TryEnsureDocumentParsed(completion_manager, session, &parsing, true); + TryEnsureDocumentParsed(completion_manager, session, &parsing, false); // Activate new translation unit. std::lock_guard lock(tu->lock); @@ -454,33 +459,30 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { request->position.character + 1, Remapped, /*IncludeMacros=*/true, /*IncludeCodePatterns=*/false, - /*IncludeBriefComments=*/true, capture, tu->PCHCO, - *Diag, LangOpts, *SrcMgr, *FileMgr, Diagnostics, - TemporaryBuffers); + /*IncludeBriefComments=*/g_config->index.comments, + capture, tu->PCHCO, *Diag, LangOpts, *SrcMgr, + *FileMgr, Diagnostics, TemporaryBuffers); request->on_complete(capture.ls_items, false /*is_cached_result*/); // completion_manager->on_diagnostic_(session->file.filename, Diags.take()); } } } -void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { +void DiagnosticQueryMain(ClangCompleteManager *manager) { while (true) { // Fetching the completion request blocks until we have a request. ClangCompleteManager::DiagnosticRequest request = - completion_manager->diagnostic_request_.Dequeue(); + manager->diagnostic_request_.Dequeue(); if (!g_config->diagnostics.onType) continue; std::string path = request.document.uri.GetPath(); - std::shared_ptr session = - completion_manager->TryGetSession(path, true /*mark_as_completion*/, - true /*create_if_needed*/); + std::shared_ptr session = manager->TryGetSession( + path, true /*mark_as_completion*/, true /*create_if_needed*/); // At this point, we must have a translation unit. Block until we have one. std::lock_guard lock(session->diagnostics.lock); - TryEnsureDocumentParsed(completion_manager, session, - &session->diagnostics.tu, - false /*emit_diagnostics*/); + TryEnsureDocumentParsed(manager, session, &session->diagnostics.tu, true); // It is possible we failed to create the document despite // |TryEnsureDocumentParsed|. @@ -489,7 +491,7 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { continue; WorkingFiles::Snapshot snapshot = - completion_manager->working_files_->AsSnapshot({StripFileType(path)}); + manager->working_files_->AsSnapshot({StripFileType(path)}); llvm::CrashRecoveryContext CRC; if (tu->Reparse(CRC, snapshot)) { LOG_S(ERROR) << "Reparsing translation unit for diagnostics failed for " @@ -497,13 +499,16 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { continue; } - auto &SM = tu->Unit->getSourceManager(); auto &LangOpts = tu->Unit->getLangOpts(); std::vector ls_diags; for (ASTUnit::stored_diag_iterator I = tu->Unit->stored_diag_begin(), E = tu->Unit->stored_diag_end(); I != E; ++I) { FullSourceLoc FLoc = I->getLocation(); + const auto &SM = FLoc.getManager(); + + const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(FLoc)); + if (!FE || FileName(*FE) != path) continue; SourceRange R; for (const auto &CR : I->getRanges()) { auto RT = Lexer::makeFileCharRange(CR, SM, LangOpts); @@ -520,11 +525,10 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { switch (I->getLevel()) { case DiagnosticsEngine::Ignored: // llvm_unreachable - break; case DiagnosticsEngine::Note: case DiagnosticsEngine::Remark: ls_diag.severity = lsDiagnosticSeverity::Information; - break; + continue; case DiagnosticsEngine::Warning: ls_diag.severity = lsDiagnosticSeverity::Warning; break; @@ -543,7 +547,7 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { } ls_diags.push_back(ls_diag); } - completion_manager->on_diagnostic_(path, ls_diags); + manager->on_diagnostic_(path, ls_diags); } } diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 092caab4..9e2b3ac2 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -64,14 +64,14 @@ GetRemapped(const WorkingFiles::Snapshot &snapshot) { return Remapped; } -std::unique_ptr -ClangTranslationUnit::Create(const std::string &filepath, - const std::vector &args, - const WorkingFiles::Snapshot &snapshot) { +std::unique_ptr ClangTranslationUnit::Create( + const std::string &filepath, const std::vector &args, + const WorkingFiles::Snapshot &snapshot, bool diagnostic) { std::vector Args; for (auto& arg : args) Args.push_back(arg.c_str()); Args.push_back("-fno-spell-checking"); + Args.push_back("-fallow-editor-placeholders"); auto ret = std::make_unique(); IntrusiveRefCntPtr Diags( @@ -86,9 +86,10 @@ ClangTranslationUnit::Create(const std::string &filepath, Args.data(), Args.data() + Args.size(), /*PCHContainerOpts=*/ret->PCHCO, Diags, /*ResourceFilePath=*/"", /*OnlyLocalDecls=*/false, - /*CaptureDiagnostics=*/true, Remapped, - /*RemappedFilesKeepOriginalName=*/true, 1, TU_Prefix, - /*CacheCodeCompletionResults=*/true, true, + /*CaptureDiagnostics=*/diagnostic, Remapped, + /*RemappedFilesKeepOriginalName=*/true, 1, + diagnostic ? TU_Complete : TU_Prefix, + /*CacheCodeCompletionResults=*/true, g_config->index.comments, /*AllowPCHWithCompilerErrors=*/true, #if LLVM_VERSION_MAJOR >= 7 SkipFunctionBodiesScope::None, diff --git a/src/clang_tu.h b/src/clang_tu.h index 17b4b0e2..741d9a40 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.h @@ -34,8 +34,8 @@ bool RunSafely(llvm::CrashRecoveryContext &CRC, Fn &&fn) { struct ClangTranslationUnit { static std::unique_ptr - Create(const std::string &filepath, const std::vector &arguments, - const WorkingFiles::Snapshot &snapshot); + Create(const std::string &filepath, const std::vector &args, + const WorkingFiles::Snapshot &snapshot, bool diagnostic); int Reparse(llvm::CrashRecoveryContext &CRC, const WorkingFiles::Snapshot &snapshot); diff --git a/src/indexer.cc b/src/indexer.cc index d624935b..ce4eee67 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1125,7 +1125,8 @@ std::vector> Index( std::move(CI), PCHCO, Diags, IndexAction.get(), Unit.get(), /*Persistent=*/true, /*ResourceDir=*/"", /*OnlyLocalDecls=*/true, - /*CaptureDiagnostics=*/true, 0, false, false, true); + /*CaptureDiagnostics=*/true, 0, false, false, + /*UserFilesAreVolatile=*/true); }; if (!RunSafely(CRC, compile)) { LOG_S(ERROR) << "clang crashed for " << file; diff --git a/src/project.cc b/src/project.cc index 7140e082..da24705c 100644 --- a/src/project.cc +++ b/src/project.cc @@ -17,11 +17,9 @@ using namespace ccls; #include #include #include -#include #include using namespace clang; using namespace llvm; -using namespace llvm::opt; #include @@ -156,7 +154,8 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( continue; } - if (HeaderOpts.ResourceDir.empty() && HeaderOpts.UseBuiltinIncludes) + if (!sys::path::is_absolute(HeaderOpts.ResourceDir) && + HeaderOpts.UseBuiltinIncludes) args.push_back("-resource-dir=" + g_config->clang.resourceDir); if (CI->getFileSystemOpts().WorkingDir.empty()) args.push_back("-working-directory=" + entry.directory);