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