clang-tools 10.0.0

FileIndex.h
Go to the documentation of this file.
1 //===--- FileIndex.h - Index for files. ---------------------------- 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 // FileIndex implements SymbolIndex for symbols from a set of files. Symbols are
10 // maintained at source-file granularity (e.g. with ASTs), and files can be
11 // updated dynamically.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_FILEINDEX_H
16 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_FILEINDEX_H
17
18 #include "Index.h"
19 #include "MemIndex.h"
20 #include "Merge.h"
21 #include "Path.h"
22 #include "index/CanonicalIncludes.h"
23 #include "index/Symbol.h"
24 #include "clang/Lex/Preprocessor.h"
25 #include <memory>
26
27 namespace clang {
28 class ASTContext;
29 namespace clangd {
30 class ParsedAST;
31
32 /// Select between in-memory index implementations, which have tradeoffs.
33 enum class IndexType {
34 // MemIndex is trivially cheap to build, but has poor query performance.
35 Light,
36 // Dex is relatively expensive to build and uses more memory, but is fast.
37 Heavy,
38 };
39
40 /// How to handle duplicated symbols across multiple files.
41 enum class DuplicateHandling {
42 // Pick a random symbol. Less accurate but faster.
43 PickOne,
44 // Merge symbols. More accurate but slower.
45 Merge,
46 };
47
48 /// A container of Symbols from several source files. It can be updated
49 /// at source-file granularity, replacing all symbols from one file with a new
50 /// set.
51 ///
52 /// This implements a snapshot semantics for symbols in a file. Each update to a
53 /// file will create a new snapshot for all symbols in the file. Snapshots are
54 /// managed with shared pointers that are shared between this class and the
55 /// users. For each file, this class only stores a pointer pointing to the
56 /// newest snapshot, and an outdated snapshot is deleted by the last owner of
57 /// the snapshot, either this class or the symbol index.
58 ///
59 /// The snapshot semantics keeps critical sections minimal since we only need
60 /// locking when we swap or obtain references to snapshots.
61 class FileSymbols {
62 public:
63 /// Updates all symbols and refs in a file.
64 /// If either is nullptr, corresponding data for \p Path will be removed.
65 /// If CountReferences is true, \p Refs will be used for counting References
66 /// during merging.
67 void update(PathRef Path, std::unique_ptr<SymbolSlab> Slab,
68 std::unique_ptr<RefSlab> Refs,
69 std::unique_ptr<RelationSlab> Relations, bool CountReferences);
70
71 /// The index keeps the symbols alive.
72 /// Will count Symbol::References based on number of references in the main
73 /// files, while building the index with DuplicateHandling::Merge option.
74 std::unique_ptr<SymbolIndex>
75 buildIndex(IndexType,
76 DuplicateHandling DuplicateHandle = DuplicateHandling::PickOne);
77
78 private:
79 struct RefSlabAndCountReferences {
80 std::shared_ptr<RefSlab> Slab;
81 bool CountReferences = false;
82 };
83 mutable std::mutex Mutex;
84
85 /// Stores the latest symbol snapshots for all active files.
86 llvm::StringMap<std::shared_ptr<SymbolSlab>> FileToSymbols;
87 /// Stores the latest ref snapshots for all active files.
88 llvm::StringMap<RefSlabAndCountReferences> FileToRefs;
89 /// Stores the latest relation snapshots for all active files.
90 llvm::StringMap<std::shared_ptr<RelationSlab>> FileToRelations;
91 };
92
93 /// This manages symbols from files and an in-memory index on all symbols.
94 /// FIXME: Expose an interface to remove files that are closed.
95 class FileIndex : public MergedIndex {
96 public:
97 FileIndex(bool UseDex = true);
98
99 /// Update preamble symbols of file \p Path with all declarations in \p AST
100 /// and macros in \p PP.
101 void updatePreamble(PathRef Path, ASTContext &AST,
102 std::shared_ptr<Preprocessor> PP,
103 const CanonicalIncludes &Includes);
104
105 /// Update symbols and references from main file \p Path with
106 /// `indexMainDecls`.
107 void updateMain(PathRef Path, ParsedAST &AST);
108
109 private:
110 bool UseDex; // FIXME: this should be always on.
111
112 // Contains information from each file's preamble only.
113 // These are large, but update fairly infrequently (preambles are stable).
114 // Missing information:
115 // - symbol refs (these are always "from the main file")
116 // - definition locations in the main file
117 //
118 // FIXME: Because the preambles for different TUs have large overlap and
119 // FileIndex doesn't deduplicate, this uses lots of extra RAM.
120 // The biggest obstacle in fixing this: the obvious approach of partitioning
121 // by declaring file (rather than main file) fails if headers provide
122 // different symbols based on preprocessor state.
123 FileSymbols PreambleSymbols;
124 SwapIndex PreambleIndex;
125
126 // Contains information from each file's main AST.
127 // These are updated frequently (on file change), but are relatively small.
128 // Mostly contains:
129 // - refs to symbols declared in the preamble and referenced from main
130 // - symbols declared both in the main file and the preamble
131 // (Note that symbols *only* in the main file are not indexed).
132 FileSymbols MainFileSymbols;
133 SwapIndex MainFileIndex;
134 };
135
136 using SlabTuple = std::tuple<SymbolSlab, RefSlab, RelationSlab>;
137
138 /// Retrieves symbols and refs of local top level decls in \p AST (i.e.
139 /// `AST.getLocalTopLevelDecls()`).
140 /// Exposed to assist in unit tests.
141 SlabTuple indexMainDecls(ParsedAST &AST);
142
143 /// Index declarations from \p AST and macros from \p PP that are declared in
144 /// included headers.
145 SlabTuple indexHeaderSymbols(ASTContext &AST, std::shared_ptr<Preprocessor> PP,
146 const CanonicalIncludes &Includes);
147
148 } // namespace clangd
149 } // namespace clang
150
151 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_FILEINDEX_H
clang::clangd::SlabTuple
std::tuple< SymbolSlab, RefSlab, RelationSlab > SlabTuple
Definition: FileIndex.h:136
Index.h
Symbol.h
clang::clangd::IndexType
IndexType
Select between in-memory index implementations, which have tradeoffs.
Definition: FileIndex.h:33
clang::clangd::FileSymbols
A container of Symbols from several source files.
Definition: FileIndex.h:61
clang::clangd::IndexType::Light
clang::clangd::FileIndex
This manages symbols from files and an in-memory index on all symbols.
Definition: FileIndex.h:95
clang::clangd::indexMainDecls
SlabTuple indexMainDecls(ParsedAST &AST)
Retrieves symbols and refs of local top level decls in AST (i.e.
Definition: FileIndex.cpp:86
clang::clangd::DuplicateHandling::Merge
MemIndex.h
clang::clangd::PathRef
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:23
CanonicalIncludes.h
clang::clangd::DuplicateHandling
DuplicateHandling
How to handle duplicated symbols across multiple files.
Definition: FileIndex.h:41
clang::clangd::CanonicalIncludes
Maps a definition location onto an #include file, based on a set of filename rules.
Definition: CanonicalIncludes.h:36
clang::clangd::SymbolOrigin::AST
clang::clangd::Path
std::string Path
A typedef to represent a file path.
Definition: Path.h:20
clang::clangd::ParsedAST
Stores and provides access to parsed AST.
Definition: ParsedAST.h:46
clang::clangd::SwapIndex
Definition: Index.h:128
clang::clangd::DuplicateHandling::PickOne
Merge.h
clang::clangd::IndexType::Heavy
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::tidy::bugprone::PP
static Preprocessor * PP
Definition: BadSignalToKillThreadCheck.cpp:28
Path.h
Refs
RefSlab Refs
Definition: SymbolCollectorTests.cpp:296
clang::clangd::MergedIndex
Definition: Merge.h:30
clang::clangd::indexHeaderSymbols
SlabTuple indexHeaderSymbols(ASTContext &AST, std::shared_ptr< Preprocessor > PP, const CanonicalIncludes &Includes)
Index declarations from AST and macros from PP that are declared in included headers.
Definition: FileIndex.cpp:93