clang-tools  9.0.0
IndexerMain.cpp
Go to the documentation of this file.
1 //===--- IndexerMain.cpp -----------------------------------------*- C++-*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // clangd-indexer is a tool to gather index data (symbols, xrefs) from source.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "index/IndexAction.h"
14 #include "index/Merge.h"
15 #include "index/Ref.h"
16 #include "index/Serialization.h"
17 #include "index/Symbol.h"
18 #include "index/SymbolCollector.h"
19 #include "clang/Tooling/ArgumentsAdjusters.h"
20 #include "clang/Tooling/CommonOptionsParser.h"
21 #include "clang/Tooling/Execution.h"
22 #include "clang/Tooling/Tooling.h"
23 #include "llvm/Support/CommandLine.h"
24 #include "llvm/Support/Signals.h"
25 
26 namespace clang {
27 namespace clangd {
28 namespace {
29 
30 static llvm::cl::opt<IndexFileFormat>
31  Format("format", llvm::cl::desc("Format of the index to be written"),
32  llvm::cl::values(clEnumValN(IndexFileFormat::YAML, "yaml",
33  "human-readable YAML format"),
34  clEnumValN(IndexFileFormat::RIFF, "binary",
35  "binary RIFF format")),
36  llvm::cl::init(IndexFileFormat::RIFF));
37 
38 class IndexActionFactory : public tooling::FrontendActionFactory {
39 public:
40  IndexActionFactory(IndexFileIn &Result) : Result(Result) {}
41 
42  clang::FrontendAction *create() override {
43  SymbolCollector::Options Opts;
44  Opts.CountReferences = true;
46  Opts,
47  [&](SymbolSlab S) {
48  // Merge as we go.
49  std::lock_guard<std::mutex> Lock(SymbolsMu);
50  for (const auto &Sym : S) {
51  if (const auto *Existing = Symbols.find(Sym.ID))
52  Symbols.insert(mergeSymbol(*Existing, Sym));
53  else
54  Symbols.insert(Sym);
55  }
56  },
57  [&](RefSlab S) {
58  std::lock_guard<std::mutex> Lock(SymbolsMu);
59  for (const auto &Sym : S) {
60  // Deduplication happens during insertion.
61  for (const auto &Ref : Sym.second)
62  Refs.insert(Sym.first, Ref);
63  }
64  },
65  [&](RelationSlab S) {
66  std::lock_guard<std::mutex> Lock(SymbolsMu);
67  for (const auto &R : S) {
68  Relations.insert(R);
69  }
70  },
71  /*IncludeGraphCallback=*/nullptr)
72  .release();
73  }
74 
75  // Awkward: we write the result in the destructor, because the executor
76  // takes ownership so it's the easiest way to get our data back out.
77  ~IndexActionFactory() {
78  Result.Symbols = std::move(Symbols).build();
79  Result.Refs = std::move(Refs).build();
80  Result.Relations = std::move(Relations).build();
81  }
82 
83 private:
84  IndexFileIn &Result;
85  std::mutex SymbolsMu;
89 };
90 
91 } // namespace
92 } // namespace clangd
93 } // namespace clang
94 
95 int main(int argc, const char **argv) {
96  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
97 
98  const char *Overview = R"(
99  Creates an index of symbol information etc in a whole project.
100 
101  Example usage for a project using CMake compile commands:
102 
103  $ clangd-indexer --executor=all-TUs compile_commands.json > clangd.dex
104 
105  Example usage for file sequence index without flags:
106 
107  $ clangd-indexer File1.cpp File2.cpp ... FileN.cpp > clangd.dex
108 
109  Note: only symbols from header files will be indexed.
110  )";
111 
112  auto Executor = clang::tooling::createExecutorFromCommandLineArgs(
113  argc, argv, llvm::cl::GeneralCategory, Overview);
114 
115  if (!Executor) {
116  llvm::errs() << llvm::toString(Executor.takeError()) << "\n";
117  return 1;
118  }
119 
120  // Collect symbols found in each translation unit, merging as we go.
122  auto Err = Executor->get()->execute(
123  llvm::make_unique<clang::clangd::IndexActionFactory>(Data),
124  clang::tooling::getStripPluginsAdjuster());
125  if (Err) {
126  llvm::errs() << llvm::toString(std::move(Err)) << "\n";
127  }
128 
129  // Emit collected data.
130  clang::clangd::IndexFileOut Out(Data);
131  Out.Format = clang::clangd::Format;
132  llvm::outs() << Out;
133  return 0;
134 }
int main(int argc, const char **argv)
Definition: IndexerMain.cpp:95
static llvm::StringRef toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K)
Symbol mergeSymbol(const Symbol &L, const Symbol &R)
Definition: Merge.cpp:165
RelationSlab Relations
SymbolSlab Symbols
CodeCompletionBuilder Builder
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
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)
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
Definition: Rename.cpp:36
RefSlab Refs