Diagnostics

This commit is contained in:
Fangrui Song 2018-07-15 10:10:24 -07:00
parent d743743282
commit ebf07265eb
5 changed files with 39 additions and 34 deletions

View File

@ -346,15 +346,19 @@ public:
} }
} }
void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
OverloadCandidate *Candidates,
unsigned NumCandidates) override {}
CodeCompletionAllocator &getAllocator() override { return *Alloc; } CodeCompletionAllocator &getAllocator() override { return *Alloc; }
CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo;} CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo;}
}; };
void TryEnsureDocumentParsed(ClangCompleteManager* manager, void TryEnsureDocumentParsed(ClangCompleteManager *manager,
std::shared_ptr<CompletionSession> session, std::shared_ptr<CompletionSession> session,
std::unique_ptr<ClangTranslationUnit>* tu, std::unique_ptr<ClangTranslationUnit> *tu,
bool emit_diag) { bool diagnostic) {
// Nothing to do. We already have a translation unit. // Nothing to do. We already have a translation unit.
if (*tu) if (*tu)
return; return;
@ -365,7 +369,8 @@ void TryEnsureDocumentParsed(ClangCompleteManager* manager,
LOG_S(INFO) << "Creating completion session with arguments " LOG_S(INFO) << "Creating completion session with arguments "
<< StringJoin(args, " "); << StringJoin(args, " ");
*tu = ClangTranslationUnit::Create(session->file.filename, args, snapshot); *tu = ClangTranslationUnit::Create(session->file.filename, args, snapshot,
diagnostic);
} }
void CompletionPreloadMain(ClangCompleteManager* completion_manager) { void CompletionPreloadMain(ClangCompleteManager* completion_manager) {
@ -392,7 +397,7 @@ void CompletionPreloadMain(ClangCompleteManager* completion_manager) {
continue; continue;
std::unique_ptr<ClangTranslationUnit> parsing; std::unique_ptr<ClangTranslationUnit> parsing;
TryEnsureDocumentParsed(completion_manager, session, &parsing, true); TryEnsureDocumentParsed(completion_manager, session, &parsing, false);
// Activate new translation unit. // Activate new translation unit.
std::lock_guard<std::mutex> lock(tu->lock); std::lock_guard<std::mutex> lock(tu->lock);
@ -454,33 +459,30 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) {
request->position.character + 1, Remapped, request->position.character + 1, Remapped,
/*IncludeMacros=*/true, /*IncludeMacros=*/true,
/*IncludeCodePatterns=*/false, /*IncludeCodePatterns=*/false,
/*IncludeBriefComments=*/true, capture, tu->PCHCO, /*IncludeBriefComments=*/g_config->index.comments,
*Diag, LangOpts, *SrcMgr, *FileMgr, Diagnostics, capture, tu->PCHCO, *Diag, LangOpts, *SrcMgr,
TemporaryBuffers); *FileMgr, Diagnostics, TemporaryBuffers);
request->on_complete(capture.ls_items, false /*is_cached_result*/); request->on_complete(capture.ls_items, false /*is_cached_result*/);
// completion_manager->on_diagnostic_(session->file.filename, Diags.take()); // completion_manager->on_diagnostic_(session->file.filename, Diags.take());
} }
} }
} }
void DiagnosticQueryMain(ClangCompleteManager* completion_manager) { void DiagnosticQueryMain(ClangCompleteManager *manager) {
while (true) { while (true) {
// Fetching the completion request blocks until we have a request. // Fetching the completion request blocks until we have a request.
ClangCompleteManager::DiagnosticRequest request = ClangCompleteManager::DiagnosticRequest request =
completion_manager->diagnostic_request_.Dequeue(); manager->diagnostic_request_.Dequeue();
if (!g_config->diagnostics.onType) if (!g_config->diagnostics.onType)
continue; continue;
std::string path = request.document.uri.GetPath(); std::string path = request.document.uri.GetPath();
std::shared_ptr<CompletionSession> session = std::shared_ptr<CompletionSession> session = manager->TryGetSession(
completion_manager->TryGetSession(path, true /*mark_as_completion*/, path, true /*mark_as_completion*/, true /*create_if_needed*/);
true /*create_if_needed*/);
// At this point, we must have a translation unit. Block until we have one. // At this point, we must have a translation unit. Block until we have one.
std::lock_guard<std::mutex> lock(session->diagnostics.lock); std::lock_guard<std::mutex> lock(session->diagnostics.lock);
TryEnsureDocumentParsed(completion_manager, session, TryEnsureDocumentParsed(manager, session, &session->diagnostics.tu, true);
&session->diagnostics.tu,
false /*emit_diagnostics*/);
// It is possible we failed to create the document despite // It is possible we failed to create the document despite
// |TryEnsureDocumentParsed|. // |TryEnsureDocumentParsed|.
@ -489,7 +491,7 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) {
continue; continue;
WorkingFiles::Snapshot snapshot = WorkingFiles::Snapshot snapshot =
completion_manager->working_files_->AsSnapshot({StripFileType(path)}); manager->working_files_->AsSnapshot({StripFileType(path)});
llvm::CrashRecoveryContext CRC; llvm::CrashRecoveryContext CRC;
if (tu->Reparse(CRC, snapshot)) { if (tu->Reparse(CRC, snapshot)) {
LOG_S(ERROR) << "Reparsing translation unit for diagnostics failed for " LOG_S(ERROR) << "Reparsing translation unit for diagnostics failed for "
@ -497,13 +499,16 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) {
continue; continue;
} }
auto &SM = tu->Unit->getSourceManager();
auto &LangOpts = tu->Unit->getLangOpts(); auto &LangOpts = tu->Unit->getLangOpts();
std::vector<lsDiagnostic> ls_diags; std::vector<lsDiagnostic> ls_diags;
for (ASTUnit::stored_diag_iterator I = tu->Unit->stored_diag_begin(), for (ASTUnit::stored_diag_iterator I = tu->Unit->stored_diag_begin(),
E = tu->Unit->stored_diag_end(); E = tu->Unit->stored_diag_end();
I != E; ++I) { I != E; ++I) {
FullSourceLoc FLoc = I->getLocation(); 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; SourceRange R;
for (const auto &CR : I->getRanges()) { for (const auto &CR : I->getRanges()) {
auto RT = Lexer::makeFileCharRange(CR, SM, LangOpts); auto RT = Lexer::makeFileCharRange(CR, SM, LangOpts);
@ -520,11 +525,10 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) {
switch (I->getLevel()) { switch (I->getLevel()) {
case DiagnosticsEngine::Ignored: case DiagnosticsEngine::Ignored:
// llvm_unreachable // llvm_unreachable
break;
case DiagnosticsEngine::Note: case DiagnosticsEngine::Note:
case DiagnosticsEngine::Remark: case DiagnosticsEngine::Remark:
ls_diag.severity = lsDiagnosticSeverity::Information; ls_diag.severity = lsDiagnosticSeverity::Information;
break; continue;
case DiagnosticsEngine::Warning: case DiagnosticsEngine::Warning:
ls_diag.severity = lsDiagnosticSeverity::Warning; ls_diag.severity = lsDiagnosticSeverity::Warning;
break; break;
@ -543,7 +547,7 @@ void DiagnosticQueryMain(ClangCompleteManager* completion_manager) {
} }
ls_diags.push_back(ls_diag); ls_diags.push_back(ls_diag);
} }
completion_manager->on_diagnostic_(path, ls_diags); manager->on_diagnostic_(path, ls_diags);
} }
} }

View File

@ -64,14 +64,14 @@ GetRemapped(const WorkingFiles::Snapshot &snapshot) {
return Remapped; return Remapped;
} }
std::unique_ptr<ClangTranslationUnit> std::unique_ptr<ClangTranslationUnit> ClangTranslationUnit::Create(
ClangTranslationUnit::Create(const std::string &filepath, const std::string &filepath, const std::vector<std::string> &args,
const std::vector<std::string> &args, const WorkingFiles::Snapshot &snapshot, bool diagnostic) {
const WorkingFiles::Snapshot &snapshot) {
std::vector<const char *> Args; std::vector<const char *> Args;
for (auto& arg : args) for (auto& arg : args)
Args.push_back(arg.c_str()); Args.push_back(arg.c_str());
Args.push_back("-fno-spell-checking"); Args.push_back("-fno-spell-checking");
Args.push_back("-fallow-editor-placeholders");
auto ret = std::make_unique<ClangTranslationUnit>(); auto ret = std::make_unique<ClangTranslationUnit>();
IntrusiveRefCntPtr<DiagnosticsEngine> Diags( IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
@ -86,9 +86,10 @@ ClangTranslationUnit::Create(const std::string &filepath,
Args.data(), Args.data() + Args.size(), Args.data(), Args.data() + Args.size(),
/*PCHContainerOpts=*/ret->PCHCO, Diags, /*PCHContainerOpts=*/ret->PCHCO, Diags,
/*ResourceFilePath=*/"", /*OnlyLocalDecls=*/false, /*ResourceFilePath=*/"", /*OnlyLocalDecls=*/false,
/*CaptureDiagnostics=*/true, Remapped, /*CaptureDiagnostics=*/diagnostic, Remapped,
/*RemappedFilesKeepOriginalName=*/true, 1, TU_Prefix, /*RemappedFilesKeepOriginalName=*/true, 1,
/*CacheCodeCompletionResults=*/true, true, diagnostic ? TU_Complete : TU_Prefix,
/*CacheCodeCompletionResults=*/true, g_config->index.comments,
/*AllowPCHWithCompilerErrors=*/true, /*AllowPCHWithCompilerErrors=*/true,
#if LLVM_VERSION_MAJOR >= 7 #if LLVM_VERSION_MAJOR >= 7
SkipFunctionBodiesScope::None, SkipFunctionBodiesScope::None,

View File

@ -34,8 +34,8 @@ bool RunSafely(llvm::CrashRecoveryContext &CRC, Fn &&fn) {
struct ClangTranslationUnit { struct ClangTranslationUnit {
static std::unique_ptr<ClangTranslationUnit> static std::unique_ptr<ClangTranslationUnit>
Create(const std::string &filepath, const std::vector<std::string> &arguments, Create(const std::string &filepath, const std::vector<std::string> &args,
const WorkingFiles::Snapshot &snapshot); const WorkingFiles::Snapshot &snapshot, bool diagnostic);
int Reparse(llvm::CrashRecoveryContext &CRC, int Reparse(llvm::CrashRecoveryContext &CRC,
const WorkingFiles::Snapshot &snapshot); const WorkingFiles::Snapshot &snapshot);

View File

@ -1125,7 +1125,8 @@ std::vector<std::unique_ptr<IndexFile>> Index(
std::move(CI), PCHCO, Diags, IndexAction.get(), Unit.get(), std::move(CI), PCHCO, Diags, IndexAction.get(), Unit.get(),
/*Persistent=*/true, /*ResourceDir=*/"", /*Persistent=*/true, /*ResourceDir=*/"",
/*OnlyLocalDecls=*/true, /*OnlyLocalDecls=*/true,
/*CaptureDiagnostics=*/true, 0, false, false, true); /*CaptureDiagnostics=*/true, 0, false, false,
/*UserFilesAreVolatile=*/true);
}; };
if (!RunSafely(CRC, compile)) { if (!RunSafely(CRC, compile)) {
LOG_S(ERROR) << "clang crashed for " << file; LOG_S(ERROR) << "clang crashed for " << file;

View File

@ -17,11 +17,9 @@ using namespace ccls;
#include <clang/Frontend/CompilerInstance.h> #include <clang/Frontend/CompilerInstance.h>
#include <clang/Tooling/CompilationDatabase.h> #include <clang/Tooling/CompilationDatabase.h>
#include <llvm/ADT/ArrayRef.h> #include <llvm/ADT/ArrayRef.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/LineIterator.h> #include <llvm/Support/LineIterator.h>
using namespace clang; using namespace clang;
using namespace llvm; using namespace llvm;
using namespace llvm::opt;
#include <rapidjson/writer.h> #include <rapidjson/writer.h>
@ -156,7 +154,8 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
continue; 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); args.push_back("-resource-dir=" + g_config->clang.resourceDir);
if (CI->getFileSystemOpts().WorkingDir.empty()) if (CI->getFileSystemOpts().WorkingDir.empty())
args.push_back("-working-directory=" + entry.directory); args.push_back("-working-directory=" + entry.directory);