Diagnostics

This commit is contained in:
Fangrui Song 2018-07-15 10:10:24 -07:00
parent eea1b92825
commit dd05ad9f65
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; }
CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo;}
};
void TryEnsureDocumentParsed(ClangCompleteManager* manager,
void TryEnsureDocumentParsed(ClangCompleteManager *manager,
std::shared_ptr<CompletionSession> session,
std::unique_ptr<ClangTranslationUnit>* tu,
bool emit_diag) {
std::unique_ptr<ClangTranslationUnit> *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<ClangTranslationUnit> parsing;
TryEnsureDocumentParsed(completion_manager, session, &parsing, true);
TryEnsureDocumentParsed(completion_manager, session, &parsing, false);
// Activate new translation unit.
std::lock_guard<std::mutex> 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<CompletionSession> session =
completion_manager->TryGetSession(path, true /*mark_as_completion*/,
true /*create_if_needed*/);
std::shared_ptr<CompletionSession> 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<std::mutex> 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<lsDiagnostic> 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);
}
}

View File

@ -64,14 +64,14 @@ GetRemapped(const WorkingFiles::Snapshot &snapshot) {
return Remapped;
}
std::unique_ptr<ClangTranslationUnit>
ClangTranslationUnit::Create(const std::string &filepath,
const std::vector<std::string> &args,
const WorkingFiles::Snapshot &snapshot) {
std::unique_ptr<ClangTranslationUnit> ClangTranslationUnit::Create(
const std::string &filepath, const std::vector<std::string> &args,
const WorkingFiles::Snapshot &snapshot, bool diagnostic) {
std::vector<const char *> 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<ClangTranslationUnit>();
IntrusiveRefCntPtr<DiagnosticsEngine> 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,

View File

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

View File

@ -1138,7 +1138,8 @@ std::vector<std::unique_ptr<IndexFile>> 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;

View File

@ -17,11 +17,9 @@ using namespace ccls;
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Tooling/CompilationDatabase.h>
#include <llvm/ADT/ArrayRef.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/LineIterator.h>
using namespace clang;
using namespace llvm;
using namespace llvm::opt;
#include <rapidjson/writer.h>
@ -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);