From 304f4d7f9e576529b61b1e86262221c5f195d124 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 24 Mar 2019 23:42:00 -0700 Subject: [PATCH 1/5] Add initialization option index.initialNoLinkage: false By default, the background indexer doesn't handle names of no linkage. They are indexed when their files are opened. This saves memory and makes cache files smaller. --- src/config.hh | 18 ++++++++------ src/indexer.cc | 49 ++++++++++++++++++++------------------- src/indexer.hh | 6 +++-- src/messages/workspace.cc | 2 +- src/pipeline.cc | 29 ++++++++++++++--------- src/pipeline.hh | 2 +- src/project.cc | 6 ++--- src/query.cc | 2 +- src/serializer.cc | 5 ++-- src/test.cc | 3 ++- 10 files changed, 69 insertions(+), 53 deletions(-) diff --git a/src/config.hh b/src/config.hh index 5ac3ed4a..6f0d7bd6 100644 --- a/src/config.hh +++ b/src/config.hh @@ -255,9 +255,12 @@ struct Config { // - https://github.com/autozimu/LanguageClient-neovim/issues/224 int comments = 2; - // By default, all project entries will be indexed on initialization. Use - // these two options to exclude some. They can still be indexed after you - // open them. + // If false, names of no linkage are not indexed in the background. They are + // indexed after the files are opened. + bool initialNoLinkage = false; + + // Use the two options to exclude files that should not be indexed in the + // background. std::vector initialBlacklist; std::vector initialWhitelist; @@ -344,10 +347,11 @@ REFLECT_STRUCT(Config::Diagnostics, blacklist, onChange, onOpen, onSave, spellChecking, whitelist) REFLECT_STRUCT(Config::Highlight, largeFileSize, lsRanges, blacklist, whitelist) REFLECT_STRUCT(Config::Index::Name, suppressUnwrittenScope); -REFLECT_STRUCT(Config::Index, blacklist, comments, initialBlacklist, - initialWhitelist, maxInitializerLines, multiVersion, - multiVersionBlacklist, multiVersionWhitelist, name, onChange, - parametersInDeclarations, threads, trackDependency, whitelist); +REFLECT_STRUCT(Config::Index, blacklist, comments, initialNoLinkage, + initialBlacklist, initialWhitelist, maxInitializerLines, + multiVersion, multiVersionBlacklist, multiVersionWhitelist, name, + onChange, parametersInDeclarations, threads, trackDependency, + whitelist); REFLECT_STRUCT(Config::Request, timeout); REFLECT_STRUCT(Config::Session, maxNum); REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); diff --git a/src/indexer.cc b/src/indexer.cc index f4e9be8b..82674998 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -62,7 +62,8 @@ struct IndexParam { VFS &vfs; ASTContext *Ctx; - IndexParam(VFS &vfs) : vfs(vfs) {} + bool no_linkage; + IndexParam(VFS &vfs, bool no_linkage) : vfs(vfs), no_linkage(no_linkage) {} void SeenFile(const FileEntry &File) { // If this is the first time we have seen the file (ignoring if we are @@ -78,9 +79,10 @@ struct IndexParam { if (std::optional content = ReadContent(path)) it->second.content = *content; - if (!vfs.Stamp(path, it->second.mtime, 1)) + if (!vfs.Stamp(path, it->second.mtime, no_linkage ? 3 : 1)) return; - it->second.db = std::make_unique(path, it->second.content); + it->second.db = + std::make_unique(path, it->second.content, no_linkage); } } @@ -693,6 +695,12 @@ class IndexDataConsumer : public index::IndexDataConsumer { bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles, ArrayRef Relations, SourceLocation Loc, ASTNodeInfo ASTNode) override { + if (!param.no_linkage) { + if (auto *ND = dyn_cast(D); ND && ND->hasLinkage()) + ; + else + return true; + } SourceManager &SM = Ctx->getSourceManager(); const LangOptions &Lang = Ctx->getLangOpts(); FileID LocFID; @@ -1166,11 +1174,12 @@ class IndexFrontendAction : public ASTFrontendAction { }; } // namespace -const int IndexFile::kMajorVersion = 20; +const int IndexFile::kMajorVersion = 21; const int IndexFile::kMinorVersion = 0; -IndexFile::IndexFile(const std::string &path, const std::string &contents) - : path(path), file_contents(contents) {} +IndexFile::IndexFile(const std::string &path, const std::string &contents, + bool no_linkage) + : path(path), no_linkage(no_linkage), file_contents(contents) {} IndexFunc &IndexFile::ToFunc(Usr usr) { auto [it, inserted] = usr2func.try_emplace(usr); @@ -1217,7 +1226,7 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, const std::string &opt_wdir, const std::string &main, const std::vector &args, const std::vector> &remapped, - bool &ok) { + bool no_linkage, bool &ok) { ok = true; auto PCH = std::make_shared(); llvm::IntrusiveRefCntPtr FS = llvm::vfs::getRealFileSystem(); @@ -1231,17 +1240,6 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, // code completion. if (g_config->index.comments > 1) CI->getLangOpts()->CommentOpts.ParseAllComments = true; - { - // FileSystemOptions& FSOpts = CI->getFileSystemOpts(); - // if (FSOpts.WorkingDir.empty()) - // FSOpts.WorkingDir = opt_wdir; - // HeaderSearchOptions &HSOpts = CI->getHeaderSearchOpts(); - // llvm::errs() << HSOpts.ResourceDir << "\n"; - // // lib/clang/7.0.0 is incorrect - // if (HSOpts.ResourceDir.compare(0, 3, "lib") == 0 && - // HSOpts.UseBuiltinIncludes) - // HSOpts.ResourceDir = g_config->clang.resourceDir; - } std::string buf = wfiles->GetContent(main); std::vector> Bufs; if (buf.size()) @@ -1260,19 +1258,22 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, if (!Clang->hasTarget()) return {}; - IndexParam param(*vfs); + IndexParam param(*vfs, no_linkage); auto DataConsumer = std::make_shared(param); index::IndexingOptions IndexOpts; IndexOpts.SystemSymbolFilter = index::IndexingOptions::SystemSymbolFilterKind::All; - IndexOpts.IndexFunctionLocals = true; - IndexOpts.IndexImplicitInstantiation = true; + if (no_linkage) { + IndexOpts.IndexFunctionLocals = true; + IndexOpts.IndexImplicitInstantiation = true; #if LLVM_VERSION_MAJOR >= 9 - IndexOpts.IndexParametersInDeclarations = - g_config->index.parametersInDeclarations; - IndexOpts.IndexTemplateParameters = true; + + IndexOpts.IndexParametersInDeclarations = + g_config->index.parametersInDeclarations; + IndexOpts.IndexTemplateParameters = true; #endif + } std::unique_ptr Action = createIndexingAction( DataConsumer, IndexOpts, std::make_unique(param)); diff --git a/src/indexer.hh b/src/indexer.hh index 62401ab3..9796ea75 100644 --- a/src/indexer.hh +++ b/src/indexer.hh @@ -304,6 +304,7 @@ struct IndexFile { // This is unfortunately time_t as used by clang::FileEntry int64_t mtime = 0; LanguageId language = LanguageId::C; + bool no_linkage; // uid2lid_and_path is used to generate lid2path, but not serialized. std::unordered_map> @@ -328,7 +329,8 @@ struct IndexFile { // File contents at the time of index. Not serialized. std::string file_contents; - IndexFile(const std::string &path, const std::string &contents); + IndexFile(const std::string &path, const std::string &contents, + bool no_linkage); IndexFunc &ToFunc(Usr usr); IndexType &ToType(Usr usr); @@ -348,7 +350,7 @@ Index(SemaManager *complete, WorkingFiles *wfiles, VFS *vfs, const std::string &opt_wdir, const std::string &file, const std::vector &args, const std::vector> &remapped, - bool &ok); + bool all_linkages, bool &ok); } // namespace idx } // namespace ccls diff --git a/src/messages/workspace.cc b/src/messages/workspace.cc index 60ff01ae..86ce0b25 100644 --- a/src/messages/workspace.cc +++ b/src/messages/workspace.cc @@ -55,7 +55,7 @@ void MessageHandler::workspace_didChangeWatchedFiles( return; IndexMode mode = - wfiles->GetFile(path) ? IndexMode::Normal : IndexMode::NonInteractive; + wfiles->GetFile(path) ? IndexMode::Normal : IndexMode::Background; switch (event.type) { case FileChangeType::Created: case FileChangeType::Changed: { diff --git a/src/pipeline.cc b/src/pipeline.cc index f2b75524..2791d1bc 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -229,18 +229,20 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, std::string path_to_index = entry.filename; std::unique_ptr prev; - bool deleted = false; + bool deleted = false, no_linkage = g_config->index.initialNoLinkage || + request.mode != IndexMode::Background; int reparse = 0; std::optional write_time = LastWriteTime(path_to_index); if (!write_time) { deleted = true; } else { - reparse = vfs->Stamp(path_to_index, *write_time, 0); + if (vfs->Stamp(path_to_index, *write_time, no_linkage ? 2 : 0)) + reparse = no_linkage ? 2 : 1; if (request.path != path_to_index) { std::optional mtime1 = LastWriteTime(request.path); if (!mtime1) deleted = true; - else if (vfs->Stamp(request.path, *mtime1, 0)) + else if (vfs->Stamp(request.path, *mtime1, no_linkage ? 2 : 0)) reparse = 2; } } @@ -293,10 +295,13 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, auto dependencies = prev->dependencies; IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); on_indexed->PushBack(std::move(update), - request.mode != IndexMode::NonInteractive); + request.mode != IndexMode::Background); { std::lock_guard lock1(vfs->mutex); - vfs->state[path_to_index].loaded++; + VFS::State &st = vfs->state[path_to_index]; + st.loaded++; + if (prev->no_linkage) + st.step = 2; } lock.unlock(); @@ -315,10 +320,12 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, continue; st.loaded++; st.timestamp = prev->mtime; + if (prev->no_linkage) + st.step = 3; } IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); on_indexed->PushBack(std::move(update), - request.mode != IndexMode::NonInteractive); + request.mode != IndexMode::Background); if (entry.id >= 0) { std::lock_guard lock2(project->mtx); project->root2folder[entry.root].path2entry_index[path] = entry.id; @@ -339,9 +346,9 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, std::vector> indexes; if (deleted) { - indexes.push_back(std::make_unique(request.path, "")); + indexes.push_back(std::make_unique(request.path, "", false)); if (request.path != path_to_index) - indexes.push_back(std::make_unique(path_to_index, "")); + indexes.push_back(std::make_unique(path_to_index, "", false)); } else { std::vector> remapped; if (g_config->index.onChange) { @@ -351,7 +358,7 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, } bool ok; indexes = idx::Index(completion, wfiles, vfs, entry.directory, - path_to_index, entry.args, remapped, ok); + path_to_index, entry.args, remapped, no_linkage, ok); if (!ok) { if (request.id.Valid()) { @@ -403,7 +410,7 @@ bool Indexer_Parse(SemaManager *completion, WorkingFiles *wfiles, } } on_indexed->PushBack(IndexUpdate::CreateDelta(prev.get(), curr.get()), - request.mode != IndexMode::NonInteractive); + request.mode != IndexMode::Background); { std::lock_guard lock1(vfs->mutex); vfs->state[path].loaded++; @@ -743,7 +750,7 @@ void Index(const std::string &path, const std::vector &args, IndexMode mode, bool must_exist, RequestId id) { pending_index_requests++; index_request->PushBack({path, args, mode, must_exist, id}, - mode != IndexMode::NonInteractive); + mode != IndexMode::Background); } void RemoveCache(const std::string &path) { diff --git a/src/pipeline.hh b/src/pipeline.hh index be881c06..2d0db15b 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -30,7 +30,7 @@ struct VFS { }; enum class IndexMode { - NonInteractive, + Background, OnChange, Normal, }; diff --git a/src/project.cc b/src/project.cc index 25bfa34c..10359515 100644 --- a/src/project.cc +++ b/src/project.cc @@ -576,7 +576,7 @@ void Project::Index(WorkingFiles *wfiles, RequestId id) { bool interactive = wfiles->GetFile(entry.filename) != nullptr; pipeline::Index(entry.filename, entry.args, interactive ? IndexMode::Normal - : IndexMode::NonInteractive, + : IndexMode::Background, false, id); } else { LOG_V(1) << "[" << i << "/" << folder.entries.size() << "]: " << reason @@ -590,7 +590,7 @@ void Project::Index(WorkingFiles *wfiles, RequestId id) { pipeline::loaded_ts = pipeline::tick; // Dummy request to indicate that project is loaded and // trigger refreshing semantic highlight for all working files. - pipeline::Index("", {}, IndexMode::NonInteractive, false); + pipeline::Index("", {}, IndexMode::Background, false); } void Project::IndexRelated(const std::string &path) { @@ -604,7 +604,7 @@ void Project::IndexRelated(const std::string &path) { std::string reason; if (sys::path::stem(entry.filename) == stem && entry.filename != path && match.Matches(entry.filename, &reason)) - pipeline::Index(entry.filename, entry.args, IndexMode::NonInteractive, + pipeline::Index(entry.filename, entry.args, IndexMode::Background, true); } break; diff --git a/src/query.cc b/src/query.cc index 6adfb424..ca2d228f 100644 --- a/src/query.cc +++ b/src/query.cc @@ -128,7 +128,7 @@ QueryType::Def Convert(const IndexType::Def &o) { IndexUpdate IndexUpdate::CreateDelta(IndexFile *previous, IndexFile *current) { IndexUpdate r; - static IndexFile empty(current->path, ""); + static IndexFile empty(current->path, "", false); if (previous) r.prev_lid2path = std::move(previous->lid2path); else diff --git a/src/serializer.cc b/src/serializer.cc index 0dec4710..a98f53cc 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -374,6 +374,7 @@ template void Reflect1(TVisitor &vis, IndexFile &v) { if (!gTestOutputMode) { REFLECT_MEMBER(mtime); REFLECT_MEMBER(language); + REFLECT_MEMBER(no_linkage); REFLECT_MEMBER(lid2path); REFLECT_MEMBER(import_file); REFLECT_MEMBER(args); @@ -482,7 +483,7 @@ Deserialize(SerializeFormat format, const std::string &path, if (major != IndexFile::kMajorVersion || minor != IndexFile::kMinorVersion) throw std::invalid_argument("Invalid version"); - file = std::make_unique(path, file_content); + file = std::make_unique(path, file_content, false); ReflectFile(reader, *file); } catch (std::invalid_argument &e) { LOG_S(INFO) << "failed to deserialize '" << path << "': " << e.what(); @@ -505,7 +506,7 @@ Deserialize(SerializeFormat format, const std::string &path, if (reader.HasParseError()) return nullptr; - file = std::make_unique(path, file_content); + file = std::make_unique(path, file_content, false); JsonReader json_reader{&reader}; try { ReflectFile(json_reader, *file); diff --git a/src/test.cc b/src/test.cc index 7faf948c..3215fc2b 100644 --- a/src/test.cc +++ b/src/test.cc @@ -327,7 +327,8 @@ bool RunIndexTests(const std::string &filter_path, bool enable_update) { for (auto &arg : flags) cargs.push_back(arg.c_str()); bool ok; - auto dbs = ccls::idx::Index(&completion, &wfiles, &vfs, "", path, cargs, {}, ok); + auto dbs = ccls::idx::Index(&completion, &wfiles, &vfs, "", path, cargs, + {}, true, ok); for (const auto &entry : all_expected_output) { const std::string &expected_path = entry.first; From 1976fec59559b7d2a88b5dcd7631e089eaa194fc Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 26 Mar 2019 18:42:48 -0700 Subject: [PATCH 2/5] Adapt clang rC357037: removal of setVirtualFileSystem --- src/indexer.cc | 7 ++++++- src/sema_manager.cc | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 82674998..c96032f0 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1251,12 +1251,17 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, 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 {}; +#if LLVM_VERSION_MAJOR >= 9 // rC357037 + Clang->createFileManager(FS); +#else + Clang->setVirtualFileSystem(FS); + Clang->createFileManager(); +#endif IndexParam param(*vfs, no_linkage); auto DataConsumer = std::make_shared(param); diff --git a/src/sema_manager.cc b/src/sema_manager.cc index d78b5e06..deb6b153 100644 --- a/src/sema_manager.cc +++ b/src/sema_manager.cc @@ -308,7 +308,6 @@ std::unique_ptr BuildCompilerInstance( auto Clang = std::make_unique(session.PCH); Clang->setInvocation(std::move(CI)); - Clang->setVirtualFileSystem(FS); Clang->createDiagnostics(&DC, false); Clang->setTarget(TargetInfo::CreateTargetInfo( Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); @@ -317,7 +316,12 @@ std::unique_ptr BuildCompilerInstance( // Construct SourceManager with UserFilesAreVolatile: true because otherwise // RequiresNullTerminator: true may cause out-of-bounds read when a file is // mmap'ed but is saved concurrently. +#if LLVM_VERSION_MAJOR >= 9 // rC357037 + Clang->createFileManager(FS); +#else + Clang->setVirtualFileSystem(FS); Clang->createFileManager(); +#endif Clang->setSourceManager(new SourceManager(Clang->getDiagnostics(), Clang->getFileManager(), true)); auto &IS = Clang->getFrontendOpts().Inputs; From 556ad0aeb50203817d0f08f9ffa52389f75435a5 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 29 Mar 2019 06:54:41 -0700 Subject: [PATCH 3/5] Add error checking of object deserialization; ignore non-object initializationOptions --- src/messages/initialize.cc | 15 +++++++++++++-- src/serializer.cc | 5 +++++ src/serializer.hh | 1 + 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index c0344a34..772b9127 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -226,8 +226,8 @@ void Reflect(JsonReader &reader, InitializeParam::Trace &value) { value = InitializeParam::Trace::Verbose; } -REFLECT_STRUCT(InitializeParam, rootUri, initializationOptions, capabilities, - trace, workspaceFolders); +// initializationOptions is deserialized separately. +REFLECT_STRUCT(InitializeParam, rootUri, capabilities, trace, workspaceFolders); struct InitializeResult { ServerCap capabilities; @@ -395,6 +395,17 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) { void MessageHandler::initialize(JsonReader &reader, ReplyOnce &reply) { InitializeParam param; Reflect(reader, param); + auto it = reader.m->FindMember("initializationOptions"); + if (it != reader.m->MemberEnd() && it->value.IsObject()) { + JsonReader m1(&it->value); + try { + Reflect(m1, param.initializationOptions); + } catch (std::invalid_argument &) { + reader.path_.push_back("initializationOptions"); + reader.path_.insert(reader.path_.end(), m1.path_.begin(), m1.path_.end()); + throw; + } + } if (!param.rootUri) { reply.Error(ErrorCode::InvalidRequest, "expected rootUri"); return; diff --git a/src/serializer.cc b/src/serializer.cc index a98f53cc..556ff242 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -408,6 +408,11 @@ void Reflect(JsonWriter &vis, SerializeFormat &v) { } } +void ReflectMemberStart(JsonReader &vis) { + if (!vis.m->IsObject()) + throw std::invalid_argument("object"); +} + static BumpPtrAllocator Alloc; static DenseSet Strings; static std::mutex AllocMutex; diff --git a/src/serializer.hh b/src/serializer.hh index de5c24ac..21e91136 100644 --- a/src/serializer.hh +++ b/src/serializer.hh @@ -379,6 +379,7 @@ template void Reflect(BinaryWriter &vis, std::vector &v) { // ReflectMember +void ReflectMemberStart(JsonReader &); template void ReflectMemberStart(T &) {} inline void ReflectMemberStart(JsonWriter &vis) { vis.StartObject(); } From 64f9dbdc7a3e52ee2116f1f65afb818f20b8fadc Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 29 Mar 2019 07:48:58 -0700 Subject: [PATCH 4/5] Set RetainRemappedFileBuffers to true Reported by David Welch in #350. This fixes double-free of llvm::MemoryBuffer when parsing fails. --- src/indexer.cc | 3 +-- src/sema_manager.cc | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index c96032f0..59135710 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1256,6 +1256,7 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); if (!Clang->hasTarget()) return {}; + Clang->getPreprocessorOpts().RetainRemappedFileBuffers = true; #if LLVM_VERSION_MAJOR >= 9 // rC357037 Clang->createFileManager(FS); #else @@ -1302,8 +1303,6 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, LOG_S(ERROR) << "failed to index " << main; return {}; } - for (auto &Buf : Bufs) - Buf.release(); std::vector> result; for (auto &it : param.UID2File) { diff --git a/src/sema_manager.cc b/src/sema_manager.cc index deb6b153..096f2c16 100644 --- a/src/sema_manager.cc +++ b/src/sema_manager.cc @@ -313,6 +313,7 @@ std::unique_ptr BuildCompilerInstance( Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); if (!Clang->hasTarget()) return nullptr; + Clang->getPreprocessorOpts().RetainRemappedFileBuffers = true; // Construct SourceManager with UserFilesAreVolatile: true because otherwise // RequiresNullTerminator: true may cause out-of-bounds read when a file is // mmap'ed but is saved concurrently. @@ -493,7 +494,6 @@ void *CompletionMain(void *manager_) { Clang->setCodeCompletionConsumer(task->Consumer.release()); if (!Parse(*Clang)) continue; - Buf.release(); task->on_complete(&Clang->getCodeCompletionConsumer()); } @@ -583,7 +583,6 @@ void *DiagnosticMain(void *manager_) { continue; if (!Parse(*Clang)) continue; - Buf.release(); auto Fill = [](const DiagBase &d, Diagnostic &ret) { ret.range = lsRange{{d.range.start.line, d.range.start.column}, From 6710dbc2e9dc4b3bff1438e5be9549d147507b5d Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 11 Apr 2019 22:26:07 -0700 Subject: [PATCH 5/5] Set RetainCommentsFromSystemHeaders to true Note with -fretain-comments-from-system-headers, the .gch of bits/stdc++.h becomes larger by 1%, but that is fine. Fix #373 --- src/indexer.cc | 4 ++-- src/sema_manager.cc | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index 59135710..066fc9f1 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1238,8 +1238,8 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, ok = false; // -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()->CommentOpts.ParseAllComments = g_config->index.comments > 1; + CI->getLangOpts()->RetainCommentsFromSystemHeaders = true; std::string buf = wfiles->GetContent(main); std::vector> Bufs; if (buf.size()) diff --git a/src/sema_manager.cc b/src/sema_manager.cc index 096f2c16..d8e7608e 100644 --- a/src/sema_manager.cc +++ b/src/sema_manager.cc @@ -363,6 +363,7 @@ void BuildPreamble(Session &session, CompilerInvocation &CI, CI.getDiagnosticOpts().IgnoreWarnings = false; CI.getFrontendOpts().SkipFunctionBodies = true; CI.getLangOpts()->CommentOpts.ParseAllComments = g_config->index.comments > 1; + CI.getLangOpts()->RetainCommentsFromSystemHeaders = true; StoreDiags DC(task.path); IntrusiveRefCntPtr DE =