18 #include "clang/Index/IndexingAction.h" 19 #include "clang/Lex/MacroInfo.h" 20 #include "clang/Lex/Preprocessor.h" 21 #include "llvm/ADT/DenseMap.h" 22 #include "llvm/ADT/DenseSet.h" 23 #include "llvm/ADT/STLExtras.h" 24 #include "llvm/ADT/StringRef.h" 30 static std::pair<SymbolSlab, RefSlab>
32 llvm::ArrayRef<Decl *> DeclsToIndex,
bool IsIndexMainAST) {
43 index::IndexingOptions IndexOpts;
45 IndexOpts.SystemSymbolFilter =
46 index::IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly;
47 IndexOpts.IndexFunctionLocals =
false;
52 IndexOpts.IndexMacrosInPreprocessor =
true;
58 index::indexTopLevelDecls(AST, *PP, DeclsToIndex, Collector, IndexOpts);
60 const auto &SM = AST.getSourceManager();
61 const auto *MainFileEntry = SM.getFileEntryForID(SM.getMainFileID());
62 std::string
FileName = MainFileEntry ? MainFileEntry->getName() :
"";
66 vlog(
"index AST for {0} (main={1}): \n" 67 " symbol slab: {2} symbols, {3} bytes\n" 68 " ref slab: {4} symbols, {5} refs, {6} bytes",
69 FileName, IsIndexMainAST, Syms.size(), Syms.bytes(), Refs.size(),
70 Refs.numRefs(), Refs.bytes());
71 return {std::move(Syms), std::move(Refs)};
81 std::shared_ptr<Preprocessor> PP) {
82 std::vector<Decl *> DeclsToIndex(
83 AST.getTranslationUnitDecl()->decls().begin(),
84 AST.getTranslationUnitDecl()->decls().end());
91 std::unique_ptr<RefSlab> Refs) {
92 std::lock_guard<std::mutex> Lock(Mutex);
94 FileToSymbols.erase(Path);
96 FileToSymbols[
Path] = std::move(Symbols);
98 FileToRefs.erase(Path);
100 FileToRefs[
Path] = std::move(Refs);
103 std::unique_ptr<SymbolIndex>
105 std::vector<std::shared_ptr<SymbolSlab>> SymbolSlabs;
106 std::vector<std::shared_ptr<RefSlab>> RefSlabs;
108 std::lock_guard<std::mutex> Lock(Mutex);
109 for (
const auto &FileAndSymbols : FileToSymbols)
110 SymbolSlabs.push_back(FileAndSymbols.second);
111 for (
const auto &FileAndRefs : FileToRefs)
112 RefSlabs.push_back(FileAndRefs.second);
114 std::vector<const Symbol *> AllSymbols;
115 std::vector<Symbol> SymsStorage;
116 switch (DuplicateHandle) {
118 llvm::DenseMap<SymbolID, Symbol> Merged;
119 for (
const auto &Slab : SymbolSlabs) {
120 for (
const auto &Sym : *Slab) {
121 auto I = Merged.try_emplace(Sym.ID, Sym);
123 I.first->second =
mergeSymbol(I.first->second, Sym);
126 SymsStorage.reserve(Merged.size());
127 for (
auto &Sym : Merged) {
128 SymsStorage.push_back(std::move(Sym.second));
129 AllSymbols.push_back(&SymsStorage.back());
135 llvm::DenseSet<SymbolID> AddedSymbols;
136 for (
const auto &Slab : SymbolSlabs)
137 for (
const auto &Sym : *Slab)
138 if (AddedSymbols.insert(Sym.ID).second)
139 AllSymbols.push_back(&Sym);
144 std::vector<Ref> RefsStorage;
145 llvm::DenseMap<SymbolID, llvm::ArrayRef<Ref>> AllRefs;
147 llvm::DenseMap<SymbolID, llvm::SmallVector<Ref, 4>> MergedRefs;
149 for (
const auto &
RefSlab : RefSlabs)
150 for (
const auto &Sym : *
RefSlab) {
151 MergedRefs[Sym.first].append(Sym.second.begin(), Sym.second.end());
152 Count += Sym.second.size();
154 RefsStorage.reserve(Count);
155 AllRefs.reserve(MergedRefs.size());
156 for (
auto &Sym : MergedRefs) {
157 auto &SymRefs = Sym.second;
160 llvm::copy(SymRefs, back_inserter(RefsStorage));
163 llvm::ArrayRef<Ref>(&RefsStorage[RefsStorage.size() - SymRefs.size()],
169 RefsStorage.size() *
sizeof(
Ref) + SymsStorage.size() *
sizeof(
Symbol);
170 for (
const auto &Slab : SymbolSlabs)
171 StorageSize += Slab->bytes();
172 for (
const auto &
RefSlab : RefSlabs)
178 return llvm::make_unique<MemIndex>(
179 llvm::make_pointee_range(AllSymbols), std::move(AllRefs),
180 std::make_tuple(std::move(SymbolSlabs), std::move(RefSlabs),
181 std::move(RefsStorage), std::move(SymsStorage)),
184 return llvm::make_unique<dex::Dex>(
185 llvm::make_pointee_range(AllSymbols), std::move(AllRefs),
186 std::make_tuple(std::move(SymbolSlabs), std::move(RefSlabs),
187 std::move(RefsStorage), std::move(SymsStorage)),
190 llvm_unreachable(
"Unknown clangd::IndexType");
194 :
MergedIndex(&MainFileIndex, &PreambleIndex), UseDex(UseDex),
199 std::shared_ptr<Preprocessor> PP) {
201 PreambleSymbols.
update(Path,
202 llvm::make_unique<SymbolSlab>(std::move(Symbols)),
203 llvm::make_unique<RefSlab>());
212 Path, llvm::make_unique<SymbolSlab>(std::move(
Contents.first)),
213 llvm::make_unique<RefSlab>(std::move(
Contents.second)));
bool CollectMacro
Collect macros.
SymbolSlab indexHeaderSymbols(ASTContext &AST, std::shared_ptr< Preprocessor > PP)
Idex declarations from AST and macros from PP that are declared in included headers.
Some operations such as code completion produce a set of candidates.
This defines Dex - a symbol index implementation based on query iterators over symbol tokens...
IndexType
Select between in-memory index implementations, which have tradeoffs.
Collect declarations (symbols) from an AST.
llvm::StringRef PathRef
A typedef to represent a ref to file path.
ArrayRef< Decl * > getLocalTopLevelDecls()
This function returns top-level decls present in the main file of the AST.
void vlog(const char *Fmt, Ts &&... Vals)
void updateMain(PathRef Path, ParsedAST &AST)
Update symbols and references from main file Path with indexMainDecls.
ASTContext & getASTContext()
Note that the returned ast will not contain decls from the preamble that were not deserialized during...
static llvm::cl::opt< bool > UseDex("use-dex-index", llvm::cl::desc("Use experimental Dex dynamic index."), llvm::cl::init(false), llvm::cl::Hidden)
DuplicateHandling
How to handle duplicated symbols across multiple files.
void updatePreamble(PathRef Path, ASTContext &AST, std::shared_ptr< Preprocessor > PP)
Update preamble symbols of file Path with all declarations in AST and macros in PP.
MemIndex is a naive in-memory index suitable for a small set of symbols.
std::shared_ptr< Preprocessor > getPreprocessorPtr()
std::pair< SymbolSlab, RefSlab > indexMainDecls(ParsedAST &AST)
Retrieves symbols and refs of local top level decls in AST (i.e.
std::string Path
A typedef to represent a file path.
std::unique_ptr< SymbolIndex > buildIndex(IndexType, DuplicateHandling DuplicateHandle=DuplicateHandling::PickOne)
Symbol mergeSymbol(const Symbol &L, const Symbol &R)
Stores and provides access to parsed AST.
FileIndex(bool UseDex=true)
static std::pair< SymbolSlab, RefSlab > indexSymbols(ASTContext &AST, std::shared_ptr< Preprocessor > PP, llvm::ArrayRef< Decl *> DeclsToIndex, bool IsIndexMainAST)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
void update(PathRef Path, std::unique_ptr< SymbolSlab > Slab, std::unique_ptr< RefSlab > Refs)
Updates all symbols and refs in a file.
void setPreprocessor(std::shared_ptr< Preprocessor > PP) override
void reset(std::unique_ptr< SymbolIndex >)
RefKind RefFilter
The symbol ref kinds that will be collected.