DaanDeMeyer updated this revision to Diff 305396.
DaanDeMeyer added a comment.
Fixed formatting
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D91509/new/
https://reviews.llvm.org/D91509
Files:
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/ClangdServer.h
clang-tools-extra/clangd/Config.h
clang-tools-extra/clangd/ConfigCompile.cpp
clang-tools-extra/clangd/ConfigFragment.h
clang-tools-extra/clangd/ConfigYAML.cpp
clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
clang-tools-extra/clangd/GlobalCompilationDatabase.h
clang-tools-extra/clangd/QueryDriverDatabase.cpp
clang-tools-extra/clangd/TUScheduler.cpp
clang-tools-extra/clangd/TUScheduler.h
Index: clang-tools-extra/clangd/TUScheduler.h
===================================================================
--- clang-tools-extra/clangd/TUScheduler.h
+++ clang-tools-extra/clangd/TUScheduler.h
@@ -231,6 +231,8 @@
/// Returns true if the file was not previously tracked.
bool update(PathRef File, ParseInputs Inputs, WantDiagnostics WD);
+ bool hasFile(PathRef File);
+
/// Remove \p File from the list of tracked files and schedule removal of its
/// resources. Pending diagnostics for closed files may not be delivered, even
/// if requested with WantDiags::Auto or WantDiags::Yes.
Index: clang-tools-extra/clangd/TUScheduler.cpp
===================================================================
--- clang-tools-extra/clangd/TUScheduler.cpp
+++ clang-tools-extra/clangd/TUScheduler.cpp
@@ -1289,6 +1289,8 @@
return NewFile;
}
+bool TUScheduler::hasFile(PathRef File) { return Files[File] == nullptr; }
+
void TUScheduler::remove(PathRef File) {
bool Removed = Files.erase(File);
if (!Removed)
Index: clang-tools-extra/clangd/QueryDriverDatabase.cpp
===================================================================
--- clang-tools-extra/clangd/QueryDriverDatabase.cpp
+++ clang-tools-extra/clangd/QueryDriverDatabase.cpp
@@ -277,6 +277,10 @@
return addSystemIncludes(*Cmd, SystemIncludes);
}
+ tooling::CompilationDatabase *lookupCDB(PathRef File) const override {
+ return Base->lookupCDB(File);
+ }
+
llvm::Optional<ProjectInfo> getProjectInfo(PathRef File) const override {
return Base->getProjectInfo(File);
}
Index: clang-tools-extra/clangd/GlobalCompilationDatabase.h
===================================================================
--- clang-tools-extra/clangd/GlobalCompilationDatabase.h
+++ clang-tools-extra/clangd/GlobalCompilationDatabase.h
@@ -40,6 +40,8 @@
virtual llvm::Optional<tooling::CompileCommand>
getCompileCommand(PathRef File) const = 0;
+ virtual tooling::CompilationDatabase *lookupCDB(PathRef File) const = 0;
+
/// Finds the closest project to \p File.
virtual llvm::Optional<ProjectInfo> getProjectInfo(PathRef File) const {
return llvm::None;
@@ -76,6 +78,8 @@
llvm::Optional<tooling::CompileCommand>
getCompileCommand(PathRef File) const override;
+ virtual tooling::CompilationDatabase *lookupCDB(PathRef File) const override;
+
/// Returns the path to first directory containing a compilation database in
/// \p File's parents.
llvm::Optional<ProjectInfo> getProjectInfo(PathRef File) const override;
@@ -132,6 +136,9 @@
llvm::Optional<tooling::CompileCommand>
getCompileCommand(PathRef File) const override;
+
+ tooling::CompilationDatabase *lookupCDB(PathRef File) const override;
+
tooling::CompileCommand getFallbackCommand(PathRef File) const override;
/// Project info is gathered purely from the inner compilation database to
/// ensure consistency.
Index: clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
===================================================================
--- clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -68,6 +68,20 @@
llvm::Optional<tooling::CompileCommand>
DirectoryBasedGlobalCompilationDatabase::getCompileCommand(PathRef File) const {
+ auto *CDB = lookupCDB(File);
+ if (!CDB) {
+ return llvm::None;
+ }
+
+ auto Candidates = CDB->getCompileCommands(File);
+ if (!Candidates.empty())
+ return std::move(Candidates.front());
+
+ return None;
+}
+
+tooling::CompilationDatabase *
+DirectoryBasedGlobalCompilationDatabase::lookupCDB(PathRef File) const {
CDBLookupRequest Req;
Req.FileName = File;
Req.ShouldBroadcast = true;
@@ -75,14 +89,10 @@
auto Res = lookupCDB(Req);
if (!Res) {
log("Failed to find compilation database for {0}", File);
- return llvm::None;
+ return nullptr;
}
- auto Candidates = Res->CDB->getCompileCommands(File);
- if (!Candidates.empty())
- return std::move(Candidates.front());
-
- return None;
+ return Res->CDB;
}
// For platforms where paths are case-insensitive (but case-preserving),
@@ -270,6 +280,10 @@
return Cmd;
}
+tooling::CompilationDatabase *OverlayCDB::lookupCDB(PathRef File) const {
+ return Base ? Base->lookupCDB(File) : nullptr;
+}
+
tooling::CompileCommand OverlayCDB::getFallbackCommand(PathRef File) const {
auto Cmd = Base ? Base->getFallbackCommand(File)
: GlobalCompilationDatabase::getFallbackCommand(File);
Index: clang-tools-extra/clangd/ConfigYAML.cpp
===================================================================
--- clang-tools-extra/clangd/ConfigYAML.cpp
+++ clang-tools-extra/clangd/ConfigYAML.cpp
@@ -40,6 +40,7 @@
Dict.handle("CompileFlags", [&](Node &N) { parse(F.CompileFlags, N); });
Dict.handle("Index", [&](Node &N) { parse(F.Index, N); });
Dict.handle("Style", [&](Node &N) { parse(F.Style, N); });
+ Dict.handle("AST", [&](Node &N) { parse(F.AST, N); });
Dict.parse(N);
return !(N.failed() || HadError);
}
@@ -89,6 +90,12 @@
Dict.parse(N);
}
+ void parse(Fragment::ASTBlock &F, Node &N) {
+ DictParser Dict("AST", this);
+ Dict.handle("Build", [&](Node &N) { F.Build = scalarValue(N, "Build"); });
+ Dict.parse(N);
+ }
+
// Helper for parsing mapping nodes (dictionaries).
// We don't use YamlIO as we want to control over unknown keys.
class DictParser {
Index: clang-tools-extra/clangd/ConfigFragment.h
===================================================================
--- clang-tools-extra/clangd/ConfigFragment.h
+++ clang-tools-extra/clangd/ConfigFragment.h
@@ -174,6 +174,16 @@
std::vector<Located<std::string>> FullyQualifiedNamespaces;
};
StyleBlock Style;
+
+ struct ASTBlock {
+ /// Controls whether clangd prebuilds the AST for the current file. When
+ /// opening a file for the first time. clangd iterates over all the files in
+ /// its compilation database and prebuilds the AST for those that have this
+ /// option set to "PreBuild". Legal values are "PreBuild" or "OnDemand".
+ /// Default is "OnDemand".
+ llvm::Optional<Located<std::string>> Build;
+ };
+ ASTBlock AST;
};
} // namespace config
Index: clang-tools-extra/clangd/ConfigCompile.cpp
===================================================================
--- clang-tools-extra/clangd/ConfigCompile.cpp
+++ clang-tools-extra/clangd/ConfigCompile.cpp
@@ -157,6 +157,7 @@
compile(std::move(F.If));
compile(std::move(F.CompileFlags));
compile(std::move(F.Index));
+ compile(std::move(F.AST));
}
void compile(Fragment::IfBlock &&F) {
@@ -264,6 +265,18 @@
}
}
+ void compile(Fragment::ASTBlock &&F) {
+ if (F.Build) {
+ if (auto Val = compileEnum<Config::ASTPolicy>("Build", **F.Build)
+ .map("OnDemand", Config::ASTPolicy::OnDemand)
+ .map("PreBuild", Config::ASTPolicy::PreBuild)
+ .value()) {
+ Out.Apply.push_back(
+ [Val](const Params &, Config &C) { C.AST.Build = *Val; });
+ }
+ }
+ }
+
constexpr static llvm::SourceMgr::DiagKind Error = llvm::SourceMgr::DK_Error;
constexpr static llvm::SourceMgr::DiagKind Warning =
llvm::SourceMgr::DK_Warning;
Index: clang-tools-extra/clangd/Config.h
===================================================================
--- clang-tools-extra/clangd/Config.h
+++ clang-tools-extra/clangd/Config.h
@@ -70,6 +70,13 @@
// ::). All nested namespaces are affected as well.
std::vector<std::string> FullyQualifiedNamespaces;
} Style;
+
+ enum class ASTPolicy { PreBuild, OnDemand };
+ /// Controls AST prebuild behavior.
+ struct {
+ /// Whether this AST should be prebuild.
+ ASTPolicy Build = ASTPolicy::OnDemand;
+ } AST;
};
} // namespace clangd
Index: clang-tools-extra/clangd/ClangdServer.h
===================================================================
--- clang-tools-extra/clangd/ClangdServer.h
+++ clang-tools-extra/clangd/ClangdServer.h
@@ -357,6 +357,7 @@
Context createProcessingContext(PathRef) const;
config::Provider *ConfigProvider = nullptr;
+ const GlobalCompilationDatabase &CDB;
const ThreadsafeFS &TFS;
Path ResourceDir;
Index: clang-tools-extra/clangd/ClangdServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdServer.cpp
+++ clang-tools-extra/clangd/ClangdServer.cpp
@@ -172,7 +172,7 @@
ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
const ThreadsafeFS &TFS, const Options &Opts,
Callbacks *Callbacks)
- : ConfigProvider(Opts.ConfigProvider), TFS(TFS),
+ : ConfigProvider(Opts.ConfigProvider), CDB(CDB), TFS(TFS),
DynamicIdx(Opts.BuildDynamicSymbolIndex
? new FileIndex(Opts.HeavyweightDynamicSymbolIndex,
Opts.CollectMainFileRefs)
@@ -257,7 +257,7 @@
Inputs.Contents = std::string(Contents);
Inputs.Version = Version.str();
Inputs.ForceRebuild = ForceRebuild;
- Inputs.Opts = std::move(Opts);
+ Inputs.Opts = Opts;
Inputs.Index = Index;
Inputs.Opts.BuildRecoveryAST = BuildRecoveryAST;
Inputs.Opts.PreserveRecoveryASTType = PreserveRecoveryASTType;
@@ -265,6 +265,23 @@
// If we loaded Foo.h, we want to make sure Foo.cpp is indexed.
if (NewFile && BackgroundIdx)
BackgroundIdx->boostRelated(File);
+
+ if (NewFile) {
+ if (auto *InternalCDB = CDB.lookupCDB(File)) {
+ for (const auto &CDBFile : InternalCDB->getAllFiles()) {
+ if (CDBFile != File && !WorkScheduler.hasFile(File)) {
+ WithContext WithContext(createProcessingContext(CDBFile));
+ if (Config::current().AST.Build == Config::ASTPolicy::PreBuild) {
+ auto Buffer = llvm::MemoryBuffer::getFile(File);
+ Inputs.Contents = std::string(Buffer->get()->getBuffer());
+ WorkScheduler.update(CDBFile, Inputs, WantDiagnostics::No);
+ if (BackgroundIdx)
+ BackgroundIdx->boostRelated(CDBFile);
+ }
+ }
+ }
+ }
+ }
}
void ClangdServer::removeDocument(PathRef File) { WorkScheduler.remove(File); }
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits