diff --git a/index_tests/_empty_test.cc b/index_tests/_empty_test.cc index d1ae7a6c..228b2674 100644 --- a/index_tests/_empty_test.cc +++ b/index_tests/_empty_test.cc @@ -1,10 +1,4 @@ /* OUTPUT: -{ - "includes": [], - "skipped_ranges": [], - "usr2func": [], - "usr2type": [], - "usr2var": [] -} +{} */ diff --git a/src/clang_complete.cc b/src/clang_complete.cc index 3cd01988..cc15089a 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -21,7 +21,6 @@ limitations under the License. #include "platform.h" #include -#include #include #include #include @@ -397,10 +396,6 @@ public: } } - void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, - OverloadCandidate *Candidates, - unsigned NumCandidates) override {} - CodeCompletionAllocator &getAllocator() override { return *Alloc; } CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; } @@ -484,30 +479,10 @@ public: } }; -std::unique_ptr -buildCompilerInvocation(const std::vector &args, - IntrusiveRefCntPtr VFS) { - std::vector cargs; - for (auto &arg : args) - cargs.push_back(arg.c_str()); - IntrusiveRefCntPtr Diags( - CompilerInstance::createDiagnostics(new DiagnosticOptions)); - std::unique_ptr CI = - createInvocationFromCommandLine(cargs, Diags, VFS); - if (CI) { - CI->getFrontendOpts().DisableFree = false; - CI->getLangOpts()->CommentOpts.ParseAllComments = true; - CI->getLangOpts()->SpellChecking = false; - } - return CI; -} - -std::unique_ptr -BuildCompilerInstance(CompletionSession &session, - std::unique_ptr CI, - DiagnosticConsumer &DC, - const WorkingFiles::Snapshot &snapshot, - std::vector> &Bufs) { +std::unique_ptr BuildCompilerInstance( + CompletionSession &session, std::unique_ptr CI, + DiagnosticConsumer &DC, const WorkingFiles::Snapshot &snapshot, + std::vector> &Bufs) { for (auto &file : snapshot.files) { Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content)); if (file.filename == session.file.filename) { @@ -570,7 +545,7 @@ void CompletionPreloadMain(ClangCompleteManager *completion_manager) { LOG_S(INFO) << "create completion session for " << session->file.filename; if (std::unique_ptr CI = - buildCompilerInvocation(args, session->FS)) + BuildCompilerInvocation(args, session->FS)) session->BuildPreamble(*CI); } } @@ -595,10 +570,12 @@ void CompletionQueryMain(ClangCompleteManager *completion_manager) { true /*create_if_needed*/); std::unique_ptr CI = - buildCompilerInvocation(session->file.args, session->FS); + BuildCompilerInvocation(session->file.args, session->FS); if (!CI) continue; + CI->getDiagnosticOpts().IgnoreWarnings = true; clang::CodeCompleteOptions CCOpts; + CCOpts.IncludeBriefComments = true; #if LLVM_VERSION_MAJOR >= 7 CCOpts.IncludeFixIts = true; #endif @@ -608,6 +585,8 @@ void CompletionQueryMain(ClangCompleteManager *completion_manager) { FOpts.CodeCompletionAt.FileName = session->file.filename; FOpts.CodeCompletionAt.Line = request->position.line + 1; FOpts.CodeCompletionAt.Column = request->position.character + 1; + FOpts.SkipFunctionBodies = true; + CI->getLangOpts()->CommentOpts.ParseAllComments = true; StoreDiags DC; WorkingFiles::Snapshot snapshot = @@ -641,7 +620,7 @@ void DiagnosticQueryMain(ClangCompleteManager *manager) { path, true /*mark_as_completion*/, true /*create_if_needed*/); std::unique_ptr CI = - buildCompilerInvocation(session->file.args, session->FS); + BuildCompilerInvocation(session->file.args, session->FS); if (!CI) continue; StoreDiags DC; @@ -701,6 +680,7 @@ void CompletionSession::BuildPreamble(CompilerInvocation &CI) { if (OldP && OldP->Preamble.CanReuse(CI, Buf.get(), Bounds, FS.get())) return; CI.getFrontendOpts().SkipFunctionBodies = true; + CI.getLangOpts()->CommentOpts.ParseAllComments = true; #if LLVM_VERSION_MAJOR >= 7 CI.getPreprocessorOpts().WriteCommentListToPCH = false; #endif diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 3cb09e0e..be2f1679 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -63,3 +63,20 @@ Range FromTokenRange(const SourceManager &SM, const LangOptions &LangOpts, return FromCharSourceRange(SM, LangOpts, CharSourceRange::getTokenRange(R), UniqueID); } + +std::unique_ptr +BuildCompilerInvocation(const std::vector &args, + IntrusiveRefCntPtr VFS) { + std::vector cargs; + for (auto &arg : args) + cargs.push_back(arg.c_str()); + IntrusiveRefCntPtr Diags( + CompilerInstance::createDiagnostics(new DiagnosticOptions)); + std::unique_ptr CI = + createInvocationFromCommandLine(cargs, Diags, VFS); + if (CI) { + CI->getFrontendOpts().DisableFree = false; + CI->getLangOpts()->SpellChecking = false; + } + return CI; +} diff --git a/src/clang_tu.h b/src/clang_tu.h index 7d2b4b73..ec4b5770 100644 --- a/src/clang_tu.h +++ b/src/clang_tu.h @@ -18,6 +18,7 @@ limitations under the License. #include #include +#include #include @@ -33,3 +34,7 @@ Range FromCharRange(const clang::SourceManager &SM, Range FromTokenRange(const clang::SourceManager &SM, const clang::LangOptions &LangOpts, clang::SourceRange R, llvm::sys::fs::UniqueID *UniqueID = nullptr); + +std::unique_ptr +BuildCompilerInvocation(const std::vector &args, + llvm::IntrusiveRefCntPtr VFS); diff --git a/src/indexer.cc b/src/indexer.cc index 5c899342..ae53369f 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -22,8 +22,6 @@ limitations under the License. using ccls::Intern; #include -#include -#include #include #include #include @@ -57,13 +55,10 @@ struct IndexParam { }; std::unordered_map Decl2Info; - ASTUnit &Unit; ASTContext *Ctx; - FileConsumer *file_consumer = nullptr; - IndexParam(ASTUnit &Unit, FileConsumer *file_consumer) - : Unit(Unit), file_consumer(file_consumer) {} + IndexParam(FileConsumer *file_consumer) : file_consumer(file_consumer) {} IndexFile *ConsumeFile(const FileEntry &File) { IndexFile *db = file_consumer->TryConsumeFile(File, &file_contents); @@ -1173,21 +1168,15 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, if (!g_config->index.enabled) return {}; - std::vector Args; - for (auto &arg : args) - Args.push_back(arg.c_str()); - auto PCHCO = std::make_shared(); - IntrusiveRefCntPtr Diags( - CompilerInstance::createDiagnostics(new DiagnosticOptions)); - std::shared_ptr CI = - createInvocationFromCommandLine(Args, Diags); + auto PCH = std::make_shared(); + llvm::IntrusiveRefCntPtr FS = vfs::getRealFileSystem(); + std::shared_ptr CI = BuildCompilerInvocation(args, FS); if (!CI) return {}; // -fparse-all-comments enables documentation in the indexer and in // code completion. if (g_config->index.comments > 1) CI->getLangOpts()->CommentOpts.ParseAllComments = true; - CI->getLangOpts()->SpellChecking = false; { // FileSystemOptions& FSOpts = CI->getFileSystemOpts(); // if (FSOpts.WorkingDir.empty()) @@ -1200,20 +1189,18 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, // HSOpts.ResourceDir = g_config->clang.resourceDir; } - std::vector> BufOwner; - for (auto &c : file_contents) { - std::unique_ptr MB = - llvm::MemoryBuffer::getMemBufferCopy(c.content, c.path); - CI->getPreprocessorOpts().addRemappedFile(c.path, MB.get()); - BufOwner.push_back(std::move(MB)); - } - - auto Unit = ASTUnit::create(CI, Diags, true, true); - if (!Unit) + DiagnosticConsumer DC; + auto Clang = std::make_unique(PCH); + Clang->setInvocation(std::move(CI)); + Clang->setVirtualFileSystem(FS); + Clang->createDiagnostics(&DC, false); + Clang->setTarget(TargetInfo::CreateTargetInfo( + Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); + if (!Clang->hasTarget()) return {}; FileConsumer file_consumer(vfs, file); - IndexParam param(*Unit, &file_consumer); + IndexParam param(&file_consumer); auto DataConsumer = std::make_shared(param); index::IndexingOptions IndexOpts; @@ -1224,36 +1211,30 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, IndexOpts.IndexImplicitInstantiation = true; #endif - std::unique_ptr IndexAction = createIndexingAction( + std::unique_ptr Action = createIndexingAction( DataConsumer, IndexOpts, std::make_unique(param)); - DiagnosticErrorTrap DiagTrap(*Diags); - llvm::CrashRecoveryContext CRC; - auto compile = [&]() { - ASTUnit::LoadFromCompilerInvocationAction( - std::move(CI), PCHCO, Diags, IndexAction.get(), Unit.get(), - /*Persistent=*/true, /*ResourceDir=*/"", - /*OnlyLocalDecls=*/true, - /*CaptureDiagnostics=*/true, 0, false, false, - /*UserFilesAreVolatile=*/true); - }; - if (!CRC.RunSafely(compile)) { - LOG_S(ERROR) << "clang crashed for " << file; - return {}; + bool ok = false; + { + llvm::CrashRecoveryContext CRC; + auto parse = [&]() { + if (!Action->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) + return; + if (!Action->Execute()) + return; + Action->EndSourceFile(); + ok = true; + }; + if (!CRC.RunSafely(parse)) { + LOG_S(ERROR) << "clang crashed for " << file; + return {}; + } } - if (!Unit) { + if (!ok) { LOG_S(ERROR) << "failed to index " << file; return {}; } - const SourceManager &SM = Unit->getSourceManager(); - const FileEntry *FE = SM.getFileEntryForID(SM.getMainFileID()); - IndexFile *main_file = param.ConsumeFile(*FE); - std::unordered_map inc_to_line; - if (main_file) - for (auto &inc : main_file->includes) - inc_to_line[inc.resolved_path] = inc.line; - auto result = param.file_consumer->TakeLocalState(); for (std::unique_ptr &entry : result) { entry->import_file = file; @@ -1276,22 +1257,6 @@ Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, for (auto &it : entry->usr2var) Uniquify(it.second.uses); - if (main_file) { - // If there are errors, show at least one at the include position. - auto it = inc_to_line.find(entry->path); - if (it != inc_to_line.end()) { - int line = it->second; - for (auto ls_diagnostic : entry->diagnostics_) { - if (ls_diagnostic.severity != lsDiagnosticSeverity::Error) - continue; - ls_diagnostic.range = - lsRange{lsPosition{line, 10}, lsPosition{line, 10}}; - main_file->diagnostics_.push_back(ls_diagnostic); - break; - } - } - } - // Update file contents and modification time. entry->last_write_time = param.file2write_time[entry->path]; diff --git a/src/indexer.h b/src/indexer.h index 151bb0b0..70a407a5 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -263,8 +263,6 @@ struct IndexFile { std::unordered_map usr2type; std::unordered_map usr2var; - // Diagnostics found when indexing this file. Not serialized. - std::vector diagnostics_; // File contents at the time of index. Not serialized. std::string file_contents; diff --git a/src/pipeline.cc b/src/pipeline.cc index 1754540a..e6f9b750 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -255,12 +255,6 @@ bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files, } for (std::unique_ptr &curr : indexes) { - // Only emit diagnostics for non-interactive sessions, which makes it easier - // to identify indexing problems. For interactive sessions, diagnostics are - // handled by code completion. - if (!request.is_interactive) - diag_pub->Publish(working_files, curr->path, curr->diagnostics_); - std::string path = curr->path; if (!(vfs->Stamp(path, curr->last_write_time) || path == path_to_index)) continue; diff --git a/src/project.cc b/src/project.cc index 581a8a1b..d7d6e3a5 100644 --- a/src/project.cc +++ b/src/project.cc @@ -128,9 +128,6 @@ struct ProjectProcessor { args.push_back("-resource-dir=" + g_config->clang.resourceDir); args.push_back("-working-directory=" + entry.directory); - // There could be a clang version mismatch between what the project uses and - // what ccls uses. Make sure we do not emit warnings for mismatched options. - args.push_back("-Wno-unknown-warning-option"); if (!command_set.insert(hash).second) { entry.args = std::move(args); diff --git a/src/test.cc b/src/test.cc index d2fb971a..b93a21b9 100644 --- a/src/test.cc +++ b/src/test.cc @@ -307,42 +307,8 @@ bool RunIndexTests(const std::string &filter_path, bool enable_update) { const std::string &expected_path = entry.first; std::string expected_output = text_replacer.Apply(entry.second); - // FIXME: promote to utils, find and remove duplicates (ie, - // ccls_call_tree.cc, maybe something in project.cc). - auto basename = [](const std::string &path) -> std::string { - size_t last_index = path.find_last_of('/'); - if (last_index == std::string::npos) - return path; - return path.substr(last_index + 1); - }; - // Get output from index operation. IndexFile *db = FindDbForPathEnding(expected_path, dbs); - if (db && !db->diagnostics_.empty()) { - printf("For %s\n", path.c_str()); - for (const lsDiagnostic &diagnostic : db->diagnostics_) { - printf(" "); - if (diagnostic.severity) - switch (*diagnostic.severity) { - case lsDiagnosticSeverity::Error: - printf("error "); - break; - case lsDiagnosticSeverity::Warning: - printf("warning "); - break; - case lsDiagnosticSeverity::Information: - printf("information "); - break; - case lsDiagnosticSeverity::Hint: - printf("hint "); - break; - } - printf("%s:%s-%s:%s\n", basename(db->path).c_str(), - diagnostic.range.start.ToString().c_str(), - diagnostic.range.end.ToString().c_str(), - diagnostic.message.c_str()); - } - } std::string actual_output = "{}"; if (db) { VerifySerializeToFrom(db);