diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 18fc897d..97ad5c65 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -294,7 +294,8 @@ void EnsureDocumentParsed(ClangCompleteManager* manager, NonElidedVector ls_diagnostics; unsigned num_diagnostics = clang_getNumDiagnostics((*tu)->cx_tu); for (unsigned i = 0; i < num_diagnostics; ++i) { - optional diagnostic = BuildAndDisposeDiagnostic(clang_getDiagnostic((*tu)->cx_tu, i)); + optional diagnostic = BuildAndDisposeDiagnostic( + clang_getDiagnostic((*tu)->cx_tu, i), session->file.filename); if (diagnostic) ls_diagnostics.push_back(*diagnostic); } @@ -404,20 +405,18 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) { request->on_complete(ls_result, false /*is_cached_result*/); timer.ResetAndPrint("[complete] Running user-given completion func"); - /* unsigned num_diagnostics = clang_codeCompleteGetNumDiagnostics(cx_results); NonElidedVector ls_diagnostics; std::cerr << "!! There are " + std::to_string(num_diagnostics) + " diagnostics to build\n"; for (unsigned i = 0; i < num_diagnostics; ++i) { std::cerr << "!! Building diagnostic " + std::to_string(i) + "\n"; CXDiagnostic cx_diag = clang_codeCompleteGetDiagnostic(cx_results, i); - optional diagnostic = BuildAndDisposeDiagnostic(cx_diag); + optional diagnostic = BuildAndDisposeDiagnostic(cx_diag, path); if (diagnostic) ls_diagnostics.push_back(*diagnostic); } completion_manager->on_diagnostic_(session->file.filename, ls_diagnostics); timer.ResetAndPrint("[complete] Build diagnostics"); - */ } // Make sure |ls_results| is destroyed before clearing |cx_results|. diff --git a/src/clang_utils.cc b/src/clang_utils.cc index 70aac896..cd3de430 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -21,22 +21,22 @@ lsRange GetLsRangeForFixIt(const CXSourceRange& range) { } // namespace -optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic) { - // Skip diagnostics in system headers. - CXSourceLocation diag_loc = clang_getDiagnosticLocation(diagnostic); - if (clang_equalLocations(diag_loc, clang_getNullLocation()) || - clang_Location_isInSystemHeader(diag_loc)) { +optional BuildAndDisposeDiagnostic( + CXDiagnostic diagnostic, const std::string& path) { + // Get diagnostic location. + CXFile file; + unsigned int line, column; + clang_getSpellingLocation( + clang_getDiagnosticLocation(diagnostic), &file, &line, &column, nullptr); + + // Only report diagnostics in the same file. Using + // clang_Location_isInSystemHeader causes crashes for some reason. + if (path != FileName(file)) { clang_disposeDiagnostic(diagnostic); return nullopt; } - // Get db so we can attribute diagnostic to the right indexed file. - CXFile file; - unsigned int line, column; - clang_getSpellingLocation(diag_loc, &file, &line, &column, nullptr); - // Build diagnostic. - lsDiagnostic ls_diagnostic; // TODO: consider using clang_getDiagnosticRange diff --git a/src/clang_utils.h b/src/clang_utils.h index 5e3494ea..dcc2d87a 100644 --- a/src/clang_utils.h +++ b/src/clang_utils.h @@ -9,7 +9,8 @@ using namespace std::experimental; -optional BuildAndDisposeDiagnostic(CXDiagnostic diagnostic); +optional BuildAndDisposeDiagnostic( + CXDiagnostic diagnostic, const std::string& path); // Returns the absolute path to |file|. std::string FileName(CXFile file); diff --git a/src/indexer.cc b/src/indexer.cc index 00daf3ab..c8ddc4c0 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -373,7 +373,7 @@ void diagnostic(CXClientData client_data, for (unsigned i = 0; i < clang_getNumDiagnosticsInSet(diagnostics); ++i) { CXDiagnostic diagnostic = clang_getDiagnosticInSet(diagnostics, i); - + // Skip diagnostics in system headers. CXSourceLocation diag_loc = clang_getDiagnosticLocation(diagnostic); if (clang_Location_isInSystemHeader(diag_loc)) @@ -386,9 +386,10 @@ void diagnostic(CXClientData client_data, IndexFile* db = ConsumeFile(param, file); if (!db) continue; - + // Build diagnostic. - optional ls_diagnostic = BuildAndDisposeDiagnostic(diagnostic); + optional ls_diagnostic = + BuildAndDisposeDiagnostic(diagnostic, db->path); if (ls_diagnostic) db->diagnostics_.push_back(*ls_diagnostic); }