22#include "clang/Tooling/ArgumentsAdjusters.h"
23#include "clang/Tooling/Execution.h"
24#include "clang/Tooling/Tooling.h"
25#include "llvm/Support/CommandLine.h"
26#include "llvm/Support/Signals.h"
33static llvm::cl::opt<IndexFileFormat>
34 Format(
"format", llvm::cl::desc(
"Format of the index to be written"),
36 "human-readable YAML format"),
38 "binary RIFF format")),
41static llvm::cl::list<std::string> QueryDriverGlobs{
44 "Comma separated list of globs for white-listing gcc-compatible "
45 "drivers that are safe to execute. Drivers matching any of these globs "
46 "will be used to extract system includes. e.g. "
47 "/usr/bin/**/clang-*,/path/to/repo/**/g++-*"),
48 llvm::cl::CommaSeparated,
51class IndexActionFactory :
public tooling::FrontendActionFactory {
53 IndexActionFactory(IndexFileIn &Result) : Result(Result) {}
55 std::unique_ptr<FrontendAction> create()
override {
56 SymbolCollector::Options Opts;
57 Opts.CountReferences =
true;
58 Opts.FileFilter = [&](
const SourceManager &SM, FileID FID) {
59 const auto F = SM.getFileEntryRefForID(FID);
65 std::lock_guard<std::mutex> Lock(FilesMu);
66 return Files.insert(*AbsPath).second;
72 std::lock_guard<std::mutex> Lock(SymbolsMu);
73 for (
const auto &Sym : S) {
74 if (
const auto *Existing = Symbols.find(Sym.ID))
81 std::lock_guard<std::mutex> Lock(RefsMu);
82 for (
const auto &Sym : S) {
84 for (
const auto &Ref : Sym.second)
85 Refs.insert(Sym.first, Ref);
89 std::lock_guard<std::mutex> Lock(RelsMu);
90 for (
const auto &R : S) {
97 bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
99 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
102 return tooling::FrontendActionFactory::runInvocation(
103 std::move(Invocation), Files, std::move(PCHContainerOps),
DiagConsumer);
108 ~IndexActionFactory() {
109 Result.Symbols = std::move(Symbols).build();
110 Result.Refs = std::move(Refs).build();
111 Result.Relations = std::move(Relations).build();
117 llvm::StringSet<> Files;
118 std::mutex SymbolsMu;
119 SymbolSlab::Builder Symbols;
121 RefSlab::Builder Refs;
123 RelationSlab::Builder Relations;
130int main(
int argc,
const char **argv) {
131 llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
133 const char *Overview = R
"(
134 Creates an index of symbol information etc in a whole project.
136 Example usage for a project using CMake compile commands:
138 $ clangd-indexer --executor=all-TUs compile_commands.json > clangd.dex
140 Example usage for file sequence index without flags:
142 $ clangd-indexer File1.cpp File2.cpp ... FileN.cpp > clangd.dex
144 Note: only symbols from header files will be indexed.
147 auto Executor = clang::tooling::createExecutorFromCommandLineArgs(
148 argc, argv, llvm::cl::getGeneralCategory(), Overview);
151 llvm::errs() << llvm::toString(Executor.takeError()) <<
"\n";
157 auto Mangler = std::make_shared<clang::clangd::CommandMangler>(
160 static_cast<llvm::ArrayRef<std::string>
>(
161 clang::clangd::QueryDriverGlobs));
162 auto Err = Executor->get()->execute(
163 std::make_unique<clang::clangd::IndexActionFactory>(Data),
164 clang::tooling::ArgumentsAdjuster(
165 [Mangler = std::move(Mangler)](
const std::vector<std::string> &
Args,
166 llvm::StringRef File) {
167 clang::tooling::CompileCommand Cmd;
168 Cmd.CommandLine =
Args;
169 Mangler->operator()(Cmd, File);
170 return Cmd.CommandLine;
178 Out.Format = clang::clangd::Format;
CompiledFragmentImpl & Out
int main(int argc, const char **argv)
DiagnosticConsumer DiagConsumer
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(SymbolSlab)> SymbolsCallback, std::function< void(RefSlab)> RefsCallback, std::function< void(RelationSlab)> RelationsCallback, std::function< void(IncludeGraph)> IncludeGraphCallback)
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()