diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -165,6 +165,8 @@ bool FoldingRanges = false; FeatureModuleSet *FeatureModules = nullptr; + /// If true, use the dirty buffer contents when building Preambles. + bool UseDirtyHeaders = false; explicit operator TUScheduler::Options() const; }; @@ -394,6 +396,9 @@ private: FeatureModuleSet *FeatureModules; const GlobalCompilationDatabase &CDB; + const ThreadsafeFS &getHeaderFS() const { + return UseDirtyHeaders ? *DirtyFS : TFS; + } const ThreadsafeFS &TFS; Path ResourceDir; @@ -413,6 +418,8 @@ // When set, provides clang-tidy options for a specific file. TidyProviderRef ClangTidyProvider; + bool UseDirtyHeaders = false; + // GUARDED_BY(CachedCompletionFuzzyFindRequestMutex) llvm::StringMap> CachedCompletionFuzzyFindRequestByFile; diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -156,7 +156,7 @@ : FeatureModules(Opts.FeatureModules), CDB(CDB), TFS(TFS), DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex() : nullptr), ClangTidyProvider(Opts.ClangTidyProvider), - WorkspaceRoot(Opts.WorkspaceRoot), + UseDirtyHeaders(Opts.UseDirtyHeaders), WorkspaceRoot(Opts.WorkspaceRoot), Transient(Opts.ImplicitCancellation ? TUScheduler::InvalidateOnUpdate : TUScheduler::NoInvalidation), DirtyFS(std::make_unique(TFS, DraftMgr)) { @@ -228,7 +228,7 @@ // Compile command is set asynchronously during update, as it can be slow. ParseInputs Inputs; - Inputs.TFS = &TFS; + Inputs.TFS = &getHeaderFS(); Inputs.Contents = std::string(Contents); Inputs.Version = std::move(ActualVersion); Inputs.ForceRebuild = ForceRebuild; @@ -368,7 +368,7 @@ SpecFuzzyFind->CachedReq = CachedCompletionFuzzyFindRequestByFile[File]; } } - ParseInputs ParseInput{IP->Command, &TFS, IP->Contents.str()}; + ParseInputs ParseInput{IP->Command, &getHeaderFS(), IP->Contents.str()}; // FIXME: Add traling new line if there is none at eof, workaround a crash, // see https://github.com/clangd/clangd/issues/332 if (!IP->Contents.endswith("\n")) @@ -420,7 +420,7 @@ if (!PreambleData) return CB(error("Failed to parse includes")); - ParseInputs ParseInput{IP->Command, &TFS, IP->Contents.str()}; + ParseInputs ParseInput{IP->Command, &getHeaderFS(), IP->Contents.str()}; // FIXME: Add traling new line if there is none at eof, workaround a crash, // see https://github.com/clangd/clangd/issues/332 if (!IP->Contents.endswith("\n")) diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -492,6 +492,12 @@ init(true), }; +opt UseDirtyHeaders{"use-dirty-headers", cat(Misc), + desc("Use files open in the editor when parsing " + "headers instead of reading from the disk"), + Hidden, + init(ClangdServer::Options().UseDirtyHeaders)}; + #if defined(__GLIBC__) && CLANGD_MALLOC_TRIM opt EnableMallocTrim{ "malloc-trim", @@ -928,6 +934,7 @@ ClangTidyOptProvider = combine(std::move(Providers)); Opts.ClangTidyProvider = ClangTidyOptProvider; } + Opts.UseDirtyHeaders = UseDirtyHeaders; Opts.QueryDriverGlobs = std::move(QueryDriverGlobs); Opts.TweakFilter = [&](const Tweak &T) { if (T.hidden() && !HiddenFeatures)