1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
#pragma once
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
//===--- GlobalModuleIndex.h - Global Module Index --------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the GlobalModuleIndex class, which manages a global index
// containing all of the identifiers known to the various modules within a given
// subdirectory of the module cache. It is used to improve the performance of
// queries such as "do any modules know about this identifier?"
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_SERIALIZATION_GLOBALMODULEINDEX_H
#define LLVM_CLANG_SERIALIZATION_GLOBALMODULEINDEX_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include <memory>
#include <utility>
namespace llvm {
class BitstreamCursor;
class MemoryBuffer;
}
namespace clang {
class FileManager;
class IdentifierIterator;
class PCHContainerOperations;
class PCHContainerReader;
namespace serialization {
class ModuleFile;
}
/// A global index for a set of module files, providing information about
/// the identifiers within those module files.
///
/// The global index is an aid for name lookup into modules, offering a central
/// place where one can look for identifiers determine which
/// module files contain any information about that identifier. This
/// allows the client to restrict the search to only those module files known
/// to have a information about that identifier, improving performance. Moreover,
/// the global module index may know about module files that have not been
/// imported, and can be queried to determine which modules the current
/// translation could or should load to fix a problem.
class GlobalModuleIndex {
using ModuleFile = serialization::ModuleFile;
/// Buffer containing the index file, which is lazily accessed so long
/// as the global module index is live.
std::unique_ptr<llvm::MemoryBuffer> Buffer;
/// The hash table.
///
/// This pointer actually points to a IdentifierIndexTable object,
/// but that type is only accessible within the implementation of
/// GlobalModuleIndex.
void *IdentifierIndex;
/// Information about a given module file.
struct ModuleInfo {
ModuleInfo() : File(), Size(), ModTime() { }
/// The module file, once it has been resolved.
ModuleFile *File;
/// The module file name.
std::string FileName;
/// Size of the module file at the time the global index was built.
off_t Size;
/// Modification time of the module file at the time the global
/// index was built.
time_t ModTime;
/// The module IDs on which this module directly depends.
/// FIXME: We don't really need a vector here.
llvm::SmallVector<unsigned, 4> Dependencies;
};
/// A mapping from module IDs to information about each module.
///
/// This vector may have gaps, if module files have been removed or have
/// been updated since the index was built. A gap is indicated by an empty
/// file name.
llvm::SmallVector<ModuleInfo, 16> Modules;
/// Lazily-populated mapping from module files to their
/// corresponding index into the \c Modules vector.
llvm::DenseMap<ModuleFile *, unsigned> ModulesByFile;
/// The set of modules that have not yet been resolved.
///
/// The string is just the name of the module itself, which maps to the
/// module ID.
llvm::StringMap<unsigned> UnresolvedModules;
/// The number of identifier lookups we performed.
unsigned NumIdentifierLookups;
/// The number of identifier lookup hits, where we recognize the
/// identifier.
unsigned NumIdentifierLookupHits;
/// Internal constructor. Use \c readIndex() to read an index.
explicit GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer> Buffer,
llvm::BitstreamCursor Cursor);
GlobalModuleIndex(const GlobalModuleIndex &) = delete;
GlobalModuleIndex &operator=(const GlobalModuleIndex &) = delete;
public:
~GlobalModuleIndex();
/// Read a global index file for the given directory.
///
/// \param Path The path to the specific module cache where the module files
/// for the intended configuration reside.
///
/// \returns A pair containing the global module index (if it exists) and
/// the error.
static std::pair<GlobalModuleIndex *, llvm::Error>
readIndex(llvm::StringRef Path);
/// Returns an iterator for identifiers stored in the index table.
///
/// The caller accepts ownership of the returned object.
IdentifierIterator *createIdentifierIterator() const;
/// Retrieve the set of modules that have up-to-date indexes.
///
/// \param ModuleFiles Will be populated with the set of module files that
/// have been indexed.
void getKnownModules(llvm::SmallVectorImpl<ModuleFile *> &ModuleFiles);
/// Retrieve the set of module files on which the given module file
/// directly depends.
void getModuleDependencies(ModuleFile *File,
llvm::SmallVectorImpl<ModuleFile *> &Dependencies);
/// A set of module files in which we found a result.
typedef llvm::SmallPtrSet<ModuleFile *, 4> HitSet;
/// Look for all of the module files with information about the given
/// identifier, e.g., a global function, variable, or type with that name.
///
/// \param Name The identifier to look for.
///
/// \param Hits Will be populated with the set of module files that have
/// information about this name.
///
/// \returns true if the identifier is known to the index, false otherwise.
bool lookupIdentifier(llvm::StringRef Name, HitSet &Hits);
/// Note that the given module file has been loaded.
///
/// \returns false if the global module index has information about this
/// module file, and true otherwise.
bool loadedModuleFile(ModuleFile *File);
/// Print statistics to standard error.
void printStats();
/// Print debugging view to standard error.
void dump();
/// Write a global index into the given
///
/// \param FileMgr The file manager to use to load module files.
/// \param PCHContainerRdr - The PCHContainerOperations to use for loading and
/// creating modules.
/// \param Path The path to the directory containing module files, into
/// which the global index will be written.
static llvm::Error writeIndex(FileManager &FileMgr,
const PCHContainerReader &PCHContainerRdr,
llvm::StringRef Path);
};
}
#endif
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
|