Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clangd] [C++20] [Modules] Introduce initial support for C++20 Modules #66462

Merged
merged 8 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang-tools-extra/clangd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,14 @@ add_clang_library(clangDaemon
IncludeFixer.cpp
InlayHints.cpp
JSONTransport.cpp
ModulesBuilder.cpp
PathMapping.cpp
Protocol.cpp
Quality.cpp
ParsedAST.cpp
Preamble.cpp
RIFF.cpp
ScanningProjectModules.cpp
Selection.cpp
SemanticHighlighting.cpp
SemanticSelection.cpp
Expand Down Expand Up @@ -161,6 +163,7 @@ clang_target_link_libraries(clangDaemon
clangAST
clangASTMatchers
clangBasic
clangDependencyScanning
Copy link
Contributor

@nico nico Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dependency makes clangd depend (transitively) on clangCodeGen (and its dependencies, e.g. LLVM_TARGETS_TO_BUILD), which it didn't depend on previously.

This makes clangd take ~30% longer to build, increases its binary size, and it's conceptually strange that a language server contains code generation code.

Any chance we could cut the dependency on clangCodeGen again?

Copy link
Member Author

@ChuanqiXu9 ChuanqiXu9 Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like it comes from

PCHContainerOps->registerReader(
std::make_unique<ObjectFilePCHContainerReader>());

but clangd didn't touch this function. So it might be possible to split that. I file an issue to track this: #99479

clangDriver
clangFormat
clangFrontend
Expand Down
10 changes: 10 additions & 0 deletions clang-tools-extra/clangd/ClangdLSPServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "Feature.h"
#include "GlobalCompilationDatabase.h"
#include "LSPBinder.h"
#include "ModulesBuilder.h"
#include "Protocol.h"
#include "SemanticHighlighting.h"
#include "SourceCode.h"
Expand Down Expand Up @@ -51,6 +52,9 @@

namespace clang {
namespace clangd {

extern llvm::cl::opt<bool> ExperimentalModulesSupport;
kadircet marked this conversation as resolved.
Show resolved Hide resolved

namespace {
// Tracks end-to-end latency of high level lsp calls. Measurements are in
// seconds.
Expand Down Expand Up @@ -563,6 +567,12 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
Mangler.ResourceDir = *Opts.ResourceDir;
CDB.emplace(BaseCDB.get(), Params.initializationOptions.fallbackFlags,
std::move(Mangler));

if (Opts.EnableExperimentalModulesSupport) {
ModulesManager.emplace(*CDB);
Opts.ModulesManager = &*ModulesManager;
}

{
// Switch caller's context with LSPServer's background context. Since we
// rather want to propagate information from LSPServer's context into the
Expand Down
5 changes: 5 additions & 0 deletions clang-tools-extra/clangd/ClangdLSPServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ class ClangdLSPServer : private ClangdServer::Callbacks,

/// Limit the number of references returned (0 means no limit).
size_t ReferencesLimit = 0;

/// Flag to hint the experimental modules support is enabled.
bool EnableExperimentalModulesSupport = false;
};

ClangdLSPServer(Transport &Transp, const ThreadsafeFS &TFS,
Expand Down Expand Up @@ -323,6 +326,8 @@ class ClangdLSPServer : private ClangdServer::Callbacks,
std::optional<OverlayCDB> CDB;
// The ClangdServer is created by the "initialize" LSP method.
std::optional<ClangdServer> Server;
// Manages to build module files.
std::optional<ModulesBuilder> ModulesManager;
};
} // namespace clangd
} // namespace clang
Expand Down
2 changes: 2 additions & 0 deletions clang-tools-extra/clangd/ClangdServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
Callbacks *Callbacks)
: FeatureModules(Opts.FeatureModules), CDB(CDB), TFS(TFS),
DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex() : nullptr),
ModulesManager(Opts.ModulesManager),
ClangTidyProvider(Opts.ClangTidyProvider),
UseDirtyHeaders(Opts.UseDirtyHeaders),
LineFoldingOnly(Opts.LineFoldingOnly),
Expand Down Expand Up @@ -308,6 +309,7 @@ void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents,
Inputs.Index = Index;
Inputs.ClangTidyProvider = ClangTidyProvider;
Inputs.FeatureModules = FeatureModules;
Inputs.ModulesManager = ModulesManager;
bool NewFile = WorkScheduler->update(File, Inputs, WantDiags);
// If we loaded Foo.h, we want to make sure Foo.cpp is indexed.
if (NewFile && BackgroundIdx)
Expand Down
6 changes: 6 additions & 0 deletions clang-tools-extra/clangd/ClangdServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "FeatureModule.h"
#include "GlobalCompilationDatabase.h"
#include "Hover.h"
#include "ModulesBuilder.h"
#include "Protocol.h"
#include "SemanticHighlighting.h"
#include "TUScheduler.h"
Expand Down Expand Up @@ -112,6 +113,9 @@ class ClangdServer {
/// This throttler controls which preambles may be built at a given time.
clangd::PreambleThrottler *PreambleThrottler = nullptr;

/// Manages to build module files.
ModulesBuilder *ModulesManager = nullptr;

/// If true, ClangdServer builds a dynamic in-memory index for symbols in
/// opened files and uses the index to augment code completion results.
bool BuildDynamicSymbolIndex = false;
Expand Down Expand Up @@ -477,6 +481,8 @@ class ClangdServer {
std::unique_ptr<BackgroundIndex> BackgroundIdx;
// Storage for merged views of the various indexes.
std::vector<std::unique_ptr<SymbolIndex>> MergedIdx;
// Manage module files.
ModulesBuilder *ModulesManager = nullptr;

// When set, provides clang-tidy options for a specific file.
TidyProviderRef ClangTidyProvider;
Expand Down
3 changes: 3 additions & 0 deletions clang-tools-extra/clangd/Compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_COMPILER_H

#include "FeatureModule.h"
#include "ModulesBuilder.h"
#include "TidyProvider.h"
#include "index/Index.h"
#include "support/ThreadsafeFS.h"
Expand Down Expand Up @@ -60,6 +61,8 @@ struct ParseInputs {
TidyProviderRef ClangTidyProvider = {};
// Used to acquire ASTListeners when parsing files.
FeatureModuleSet *FeatureModules = nullptr;
// Used to build and manage (C++) modules.
ModulesBuilder *ModulesManager = nullptr;
};

/// Clears \p CI from options that are not supported by clangd, like codegen or
Expand Down
23 changes: 23 additions & 0 deletions clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "GlobalCompilationDatabase.h"
#include "Config.h"
#include "FS.h"
#include "ProjectModules.h"
#include "ScanningProjectModules.h"
#include "SourceCode.h"
#include "support/Logger.h"
#include "support/Path.h"
Expand Down Expand Up @@ -740,6 +742,20 @@ DirectoryBasedGlobalCompilationDatabase::getProjectInfo(PathRef File) const {
return Res->PI;
}

std::unique_ptr<ProjectModules>
DirectoryBasedGlobalCompilationDatabase::getProjectModules(PathRef File) const {
CDBLookupRequest Req;
Req.FileName = File;
Req.ShouldBroadcast = false;
Req.FreshTime = Req.FreshTimeMissing =
std::chrono::steady_clock::time_point::min();
auto Res = lookupCDB(Req);
if (!Res)
return {};

return scanningProjectModules(Res->CDB, Opts.TFS);
}

OverlayCDB::OverlayCDB(const GlobalCompilationDatabase *Base,
std::vector<std::string> FallbackFlags,
CommandMangler Mangler)
Expand Down Expand Up @@ -832,6 +848,13 @@ std::optional<ProjectInfo> DelegatingCDB::getProjectInfo(PathRef File) const {
return Base->getProjectInfo(File);
}

std::unique_ptr<ProjectModules>
DelegatingCDB::getProjectModules(PathRef File) const {
if (!Base)
return nullptr;
return Base->getProjectModules(File);
}

tooling::CompileCommand DelegatingCDB::getFallbackCommand(PathRef File) const {
if (!Base)
return GlobalCompilationDatabase::getFallbackCommand(File);
Expand Down
13 changes: 13 additions & 0 deletions clang-tools-extra/clangd/GlobalCompilationDatabase.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_GLOBALCOMPILATIONDATABASE_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_GLOBALCOMPILATIONDATABASE_H

#include "ProjectModules.h"
#include "support/Function.h"
#include "support/Path.h"
#include "support/Threading.h"
Expand Down Expand Up @@ -45,6 +46,12 @@ class GlobalCompilationDatabase {
return std::nullopt;
}

/// Get the modules in the closest project to \p File
virtual std::unique_ptr<ProjectModules>
getProjectModules(PathRef File) const {
return nullptr;
}

/// Makes a guess at how to build a file.
/// The default implementation just runs clang on the file.
/// Clangd should treat the results as unreliable.
Expand Down Expand Up @@ -76,6 +83,9 @@ class DelegatingCDB : public GlobalCompilationDatabase {

std::optional<ProjectInfo> getProjectInfo(PathRef File) const override;

std::unique_ptr<ProjectModules>
getProjectModules(PathRef File) const override;

tooling::CompileCommand getFallbackCommand(PathRef File) const override;

bool blockUntilIdle(Deadline D) const override;
Expand Down Expand Up @@ -122,6 +132,9 @@ class DirectoryBasedGlobalCompilationDatabase
/// \p File's parents.
std::optional<ProjectInfo> getProjectInfo(PathRef File) const override;

std::unique_ptr<ProjectModules>
getProjectModules(PathRef File) const override;

bool blockUntilIdle(Deadline Timeout) const override;

private:
Expand Down
Loading
Loading