26#include "clang/Tooling/ArgumentsAdjusters.h"
27#include "clang/Tooling/Execution.h"
28#include "clang/Tooling/Tooling.h"
29#include "llvm/Support/CommandLine.h"
30#include "llvm/Support/Path.h"
31#include "llvm/Support/Signals.h"
40static llvm::cl::opt<IndexFileFormat>
41 Format(
"format", llvm::cl::desc(
"Format of the index to be written"),
43 "human-readable YAML format"),
45 "binary RIFF format")),
48static llvm::cl::list<std::string> QueryDriverGlobs{
51 "Comma separated list of globs for white-listing gcc-compatible "
52 "drivers that are safe to execute. Drivers matching any of these globs "
53 "will be used to extract system includes. e.g. "
54 "/usr/bin/**/clang-*,/path/to/repo/**/g++-*"),
55 llvm::cl::CommaSeparated,
58static llvm::cl::opt<bool> EnableConfig{
64class IndexActionFactory :
public tooling::FrontendActionFactory {
66 IndexActionFactory(IndexFileIn &Result) : Result(Result) {}
68 std::unique_ptr<FrontendAction> create()
override {
69 SymbolCollector::Options Opts;
70 Opts.CountReferences =
true;
71 Opts.FileFilter = [&](
const SourceManager &SM, FileID FID) {
72 const auto F = SM.getFileEntryRefForID(FID);
78 std::lock_guard<std::mutex> Lock(FilesMu);
79 return Files.insert(*AbsPath).second;
84 std::lock_guard<std::mutex> Lock(SymbolsMu);
85 for (
const auto &Sym : *Result.Symbols) {
86 if (
const auto *Existing = Symbols.find(Sym.ID))
93 std::lock_guard<std::mutex> Lock(RefsMu);
94 for (
const auto &Sym : *Result.Refs) {
96 for (
const auto &Ref : Sym.second)
97 Refs.insert(Sym.first, Ref);
101 std::lock_guard<std::mutex> Lock(RelsMu);
102 for (
const auto &R : *Result.Relations) {
110 bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
112 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
113 DiagnosticConsumer *DiagConsumer)
override {
115 return tooling::FrontendActionFactory::runInvocation(
116 std::move(Invocation), Files, std::move(PCHContainerOps), DiagConsumer);
121 ~IndexActionFactory() {
122 Result.Symbols = std::move(Symbols).build();
123 Result.Refs = std::move(Refs).build();
124 Result.Relations = std::move(Relations).build();
130 llvm::StringSet<> Files;
131 std::mutex SymbolsMu;
132 SymbolSlab::Builder Symbols;
134 RefSlab::Builder Refs;
136 RelationSlab::Builder Relations;
143int main(
int argc,
const char **argv) {
144 llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
146 const char *Overview = R
"(
147 Creates an index of symbol information etc in a whole project.
149 Example usage for a project using CMake compile commands:
151 $ clangd-indexer --executor=all-TUs compile_commands.json > clangd.dex
153 Example usage for file sequence index without flags:
155 $ clangd-indexer File1.cpp File2.cpp ... FileN.cpp > clangd.dex
157 Note: only symbols from header files will be indexed.
160 auto Executor = clang::tooling::createExecutorFromCommandLineArgs(
161 argc, argv, llvm::cl::getGeneralCategory(), Overview);
164 llvm::errs() << llvm::toString(Executor.takeError()) <<
"\n";
169 std::vector<std::unique_ptr<clang::clangd::config::Provider>> ProviderStack;
170 if (clang::clangd::EnableConfig)
173 auto ConfigProvider =
175 auto ContextProvider =
177 ConfigProvider.get(),
nullptr);
181 auto Mangler = std::make_shared<clang::clangd::CommandMangler>(
184 static_cast<llvm::ArrayRef<std::string>
>(
185 clang::clangd::QueryDriverGlobs));
186 auto Err = Executor->get()->execute(
187 std::make_unique<clang::clangd::IndexActionFactory>(Data),
188 clang::tooling::ArgumentsAdjuster(
189 [Mangler = std::move(Mangler),
190 ContextProvider = std::move(ContextProvider)](
191 const std::vector<std::string> &Args, llvm::StringRef File) {
203 std::optional<clang::clangd::WithContext> WithCfg;
204 if (llvm::sys::path::is_absolute(File)) {
205 WithCfg.emplace(ContextProvider(File));
208 clang::tooling::CompileCommand Cmd;
209 Cmd.CommandLine = Args;
210 Mangler->operator()(Cmd, File);
211 return Cmd.CommandLine;
219 Out.
Format = clang::clangd::Format;
int main(int argc, const char **argv)
static std::function< Context(PathRef)> createConfiguredContextProvider(const config::Provider *Provider, ClangdServer::Callbacks *)
Creates a context provider that loads and installs config.
static const char *const EnableConfigFlagDesc
Help text for the –enable-config flag, shared by clangd tools that expose createDefaultProviders() on...
static std::vector< std::unique_ptr< Provider > > createDefaultProviders(const ThreadsafeFS &)
Returns providers for the configuration files that clangd tools read by default: project config (ance...
static std::unique_ptr< Provider > combine(std::vector< std::unique_ptr< Provider > >)
A provider that includes fragments from all the supplied providers.
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
SystemIncludeExtractorFn getSystemIncludeExtractor(llvm::ArrayRef< std::string > QueryDriverGlobs)
Symbol mergeSymbol(const Symbol &L, const Symbol &R)
std::optional< std::string > getCanonicalPath(const FileEntryRef F, FileManager &FileMgr)
Get the canonical path of F.
std::unique_ptr< FrontendAction > createStaticIndexingAction(SymbolCollector::Options Opts, std::function< void(IndexFileIn)> IndexContentsCallback)
void disableUnsupportedOptions(CompilerInvocation &CI)
Clears CI from options that are not supported by clangd, like codegen or plugins.
void elog(const char *Fmt, Ts &&... Vals)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static CommandMangler detect()