clang-tools  10.0.0git
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  std::unique_ptr<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  }
73 
74  // Awkward: we write the result in the destructor, because the executor
75  // takes ownership so it's the easiest way to get our data back out.
76  ~IndexActionFactory() {
77  Result.Symbols = std::move(Symbols).build();
78  Result.Refs = std::move(Refs).build();
79  Result.Relations = std::move(Relations).build();
80  }
81 
82 private:
83  IndexFileIn &Result;
84  std::mutex SymbolsMu;
87  RelationSlab::Builder Relations;
88 };
89 
90 } // namespace
91 } // namespace clangd
92 } // namespace clang
93 
94 int main(int argc, const char **argv) {
95  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
96 
97  const char *Overview = R"(
98  Creates an index of symbol information etc in a whole project.
99 
100  Example usage for a project using CMake compile commands:
101 
102  $ clangd-indexer --executor=all-TUs compile_commands.json > clangd.dex
103 
104  Example usage for file sequence index without flags:
105 
106  $ clangd-indexer File1.cpp File2.cpp ... FileN.cpp > clangd.dex
107 
108  Note: only symbols from header files will be indexed.
109  )";
110 
111  auto Executor = clang::tooling::createExecutorFromCommandLineArgs(
112  argc, argv, llvm::cl::GeneralCategory, Overview);
113 
114  if (!Executor) {
115  llvm::errs() << llvm::toString(Executor.takeError()) << "\n";
116  return 1;
117  }
118 
119  // Collect symbols found in each translation unit, merging as we go.
121  auto Err = Executor->get()->execute(
122  std::make_unique<clang::clangd::IndexActionFactory>(Data),
123  clang::tooling::getStripPluginsAdjuster());
124  if (Err) {
125  llvm::errs() << llvm::toString(std::move(Err)) << "\n";
126  }
127 
128  // Emit collected data.
129  clang::clangd::IndexFileOut Out(Data);
130  Out.Format = clang::clangd::Format;
131  llvm::outs() << Out;
132  return 0;
133 }
int main(int argc, const char **argv)
Definition: IndexerMain.cpp:94
static llvm::StringRef toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K)
Symbol mergeSymbol(const Symbol &L, const Symbol &R)
Definition: Merge.cpp:172
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)
RefSlab Refs