clang 23.0.0git
ModuleDepCollector.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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#ifndef LLVM_CLANG_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H
10#define LLVM_CLANG_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H
11
12#include "clang/Basic/LLVM.h"
13#include "clang/Basic/Module.h"
22#include "llvm/ADT/DenseMap.h"
23#include "llvm/ADT/Hashing.h"
24#include "llvm/ADT/StringSet.h"
25#include "llvm/Support/raw_ostream.h"
26#include <optional>
27#include <string>
28#include <unordered_map>
29#include <variant>
30
31namespace clang {
32namespace dependencies {
33
37
38/// Attributes loaded from AST files of prebuilt modules collected prior to
39/// ModuleDepCollector creation.
40using PrebuiltModulesAttrsMap = llvm::StringMap<PrebuiltModuleASTAttrs>;
42public:
43 /// When a module is discovered to not be in stable directories, traverse &
44 /// update all modules that depend on it.
45 void
47
48 /// Read-only access to whether the module is made up of dependencies in
49 /// stable directories.
50 bool isInStableDir() const { return IsInStableDirs; }
51
52 /// Read-only access to vfs map files.
53 const llvm::StringSet<> &getVFS() const { return VFSMap; }
54
55 /// Update the VFSMap to the one discovered from serializing the AST file.
56 void setVFS(llvm::StringSet<> &&VFS) { VFSMap = std::move(VFS); }
57
58 /// Add a direct dependent module file, so it can be updated if the current
59 /// module is from stable directores.
60 void addDependent(StringRef ModuleFile) {
61 ModuleFileDependents.insert(ModuleFile);
62 }
63
64 /// Update whether the prebuilt module resolves entirely in a stable
65 /// directories.
66 void setInStableDir(bool V = false) {
67 // Cannot reset attribute once it's false.
68 if (!IsInStableDirs)
69 return;
70 IsInStableDirs = V;
71 }
72
73private:
74 llvm::StringSet<> VFSMap;
75 bool IsInStableDirs = true;
76 std::set<StringRef> ModuleFileDependents;
77};
78
79/// Collects modular and non-modular dependencies of the main file by attaching
80/// \c ModuleDepCollectorPP to the preprocessor.
82public:
84 std::unique_ptr<DependencyOutputOptions> Opts,
85 CompilerInstance &ScanInstance,
87 CompilerInvocation OriginalCI,
88 const PrebuiltModulesAttrsMap PrebuiltModulesASTMap,
89 const ArrayRef<StringRef> StableDirs);
90
91 /// Processes the accumulated dependency information and reports it to the
92 /// \c Consumer.
93 void run(DependencyConsumer &Consumer);
94
95 void attachToPreprocessor(Preprocessor &PP) override;
96 void attachToASTReader(ASTReader &R) override;
97
98 PPCallbacks *getPPCallbacks() { return CollectorPPPtr; }
99
100 /// Apply any changes implied by the discovered dependencies to the given
101 /// invocation, (e.g. disable implicit modules, add explicit module paths).
103
104private:
105 class ModuleDepCollectorPP;
106
107 /// The parent dependency scanning service.
109 /// The compiler instance for scanning the current translation unit.
110 CompilerInstance &ScanInstance;
111 /// Callbacks for computing dependency information.
112 DependencyActionController &Controller;
113 /// Mapping from prebuilt AST filepaths to their attributes referenced during
114 /// dependency collecting.
115 const PrebuiltModulesAttrsMap PrebuiltModulesASTMap;
116 /// Directory paths known to be stable through an active development and build
117 /// cycle.
118 const ArrayRef<StringRef> StableDirs;
119 /// Path to the main source file.
120 std::string MainFile;
121 /// Non-modular file dependencies. This includes the main source file and
122 /// textually included header files.
123 std::vector<std::string> FileDeps;
124 /// Direct and transitive modular dependencies of the main source file.
125 llvm::MapVector<serialization::ModuleFile *, std::unique_ptr<ModuleDeps>>
126 ModularDeps;
127 /// Secondary mapping for \c ModularDeps allowing lookup by ModuleID without
128 /// a preprocessor. Storage owned by \c ModularDeps.
129 llvm::DenseMap<ModuleID, ModuleDeps *> ModuleDepsByID;
130 /// Direct modular dependencies that have already been built.
131 llvm::MapVector<serialization::ModuleFile *, PrebuiltModuleDep>
132 DirectPrebuiltModularDeps;
133 /// Working set of direct modular dependencies.
134 llvm::SetVector<serialization::ModuleFile *> DirectModularDeps;
135 /// Working set of direct modular dependencies, as they were imported.
137 /// All direct and transitive visible modules.
138 llvm::StringSet<> VisibleModules;
139
140 /// Options that control the dependency output generation.
141 std::unique_ptr<DependencyOutputOptions> Opts;
142 /// A Clang invocation that's based on the original TU invocation and that has
143 /// been partially transformed into one that can perform explicit build of
144 /// a discovered modular dependency. Note that this still needs to be adjusted
145 /// for each individual module.
146 CowCompilerInvocation CommonInvocation;
147
148 std::optional<P1689ModuleInfo> ProvidedStdCXXModule;
149 std::vector<P1689ModuleInfo> RequiredStdCXXModules;
150
151 /// A pointer to the preprocessor callback so we can invoke it directly
152 /// if needed. The callback is created and added to a Preprocessor instance by
153 /// attachToPreprocessor and the Preprocessor instance owns it.
154 PPCallbacks *CollectorPPPtr = nullptr;
155
156 void handleImport(const Module *Imported);
157
158 /// Returns the ID or nothing if the dependency is spurious and is ignored.
159 std::optional<ModuleID> handleTopLevelModule(serialization::ModuleFile *MF);
160
161 /// Adds direct module dependencies to the ModuleDeps instance. This includes
162 /// prebuilt module and implicitly-built modules.
163 void addAllModuleDeps(serialization::ModuleFile &MF, ModuleDeps &MD);
164
165 /// Checks whether the module is known as being prebuilt.
166 bool isPrebuiltModule(const serialization::ModuleFile *MF);
167
168 /// Computes all visible modules resolved from direct imports.
169 void addVisibleModules();
170
171 /// Adds \p Path to \c FileDeps, making it absolute if necessary.
172 void addFileDep(StringRef Path);
173 /// Adds \p Path to \c MD.FileDeps, making it absolute if necessary.
174 void addFileDep(ModuleDeps &MD, StringRef Path);
175
176 /// Get a Clang invocation adjusted to build the given modular dependency.
177 /// This excludes paths that are yet-to-be-provided by the build system.
178 CowCompilerInvocation getInvocationAdjustedForModuleBuildWithoutOutputs(
179 const ModuleDeps &Deps,
180 llvm::function_ref<void(CowCompilerInvocation &)> Optimize) const;
181
182 /// Collect module map files for given modules.
183 llvm::DenseSet<const FileEntry *>
184 collectModuleMapFiles(ArrayRef<ModuleID> ClangModuleDeps) const;
185
186 /// Add module map files to the invocation, if needed.
187 void addModuleMapFiles(CompilerInvocation &CI,
188 ArrayRef<ModuleID> ClangModuleDeps) const;
189 /// Add module files (pcm) to the invocation, if needed.
190 void addModuleFiles(CompilerInvocation &CI,
191 ArrayRef<ModuleID> ClangModuleDeps) const;
192 void addModuleFiles(CowCompilerInvocation &CI,
193 ArrayRef<ModuleID> ClangModuleDeps) const;
194
195 /// Add paths that require looking up outputs to the given dependencies.
196 void addOutputPaths(CowCompilerInvocation &CI, ModuleDeps &Deps);
197
198 /// Compute the context hash for \p Deps, and create the mapping
199 /// \c ModuleDepsByID[Deps.ID] = &Deps.
200 void associateWithContextHash(const CowCompilerInvocation &CI,
201 ModuleDeps &Deps);
202};
203
204/// Resets codegen options that don't affect modules/PCH.
206 const LangOptions &LangOpts,
207 CodeGenOptions &CGOpts);
208
209/// Determine if \c Input can be resolved within a stable directory.
210///
211/// \param Directories Paths known to be in a stable location. e.g. Sysroot.
212/// \param Input Path to evaluate.
213bool isPathInStableDir(const ArrayRef<StringRef> Directories,
214 const StringRef Input);
215
216/// Determine if options collected from a module's
217/// compilation can safely be considered as stable.
218///
219/// \param Directories Paths known to be in a stable location. e.g. Sysroot.
220/// \param HSOpts Header search options derived from the compiler invocation.
221bool areOptionsInStableDir(const ArrayRef<StringRef> Directories,
222 const HeaderSearchOptions &HSOpts);
223
224} // end namespace dependencies
225} // end namespace clang
226
227#endif // LLVM_CLANG_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H
#define V(N, I)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::Module class, which describes a module in the source code.
Defines the PPCallbacks interface.
Defines the SourceManager interface.
Reads an AST files chain containing the contents of a translation unit.
Definition ASTReader.h:427
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
Helper class for holding the data necessary to invoke the compiler.
Same as CompilerInvocation, but with copy-on-write optimization.
An interface for collecting the dependencies of a compilation.
Definition Utils.h:63
HeaderSearchOptions - Helper class for storing options related to the initialization of the HeaderSea...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Describes a module or submodule.
Definition Module.h:340
This interface provides a way to observe the actions of the preprocessor as it does its thing.
Definition PPCallbacks.h:37
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Dependency scanner callbacks that are used during scanning to influence the behaviour of the scan - f...
The dependency scanning service contains shared configuration and state that is used by the individua...
void run(DependencyConsumer &Consumer)
Processes the accumulated dependency information and reports it to the Consumer.
ModuleDepCollector(DependencyScanningService &Service, std::unique_ptr< DependencyOutputOptions > Opts, CompilerInstance &ScanInstance, DependencyActionController &Controller, CompilerInvocation OriginalCI, const PrebuiltModulesAttrsMap PrebuiltModulesASTMap, const ArrayRef< StringRef > StableDirs)
void applyDiscoveredDependencies(CompilerInvocation &CI)
Apply any changes implied by the discovered dependencies to the given invocation, (e....
void attachToPreprocessor(Preprocessor &PP) override
void attachToASTReader(ASTReader &R) override
void updateDependentsNotInStableDirs(PrebuiltModulesAttrsMap &PrebuiltModulesMap)
When a module is discovered to not be in stable directories, traverse & update all modules that depen...
void setVFS(llvm::StringSet<> &&VFS)
Update the VFSMap to the one discovered from serializing the AST file.
bool isInStableDir() const
Read-only access to whether the module is made up of dependencies in stable directories.
void addDependent(StringRef ModuleFile)
Add a direct dependent module file, so it can be updated if the current module is from stable directo...
void setInStableDir(bool V=false)
Update whether the prebuilt module resolves entirely in a stable directories.
const llvm::StringSet & getVFS() const
Read-only access to vfs map files.
Information about a module that has been loaded by the ASTReader.
Definition ModuleFile.h:158
bool areOptionsInStableDir(const ArrayRef< StringRef > Directories, const HeaderSearchOptions &HSOpts)
Determine if options collected from a module's compilation can safely be considered as stable.
@ VFS
Remove unused -ivfsoverlay arguments.
@ ModuleFile
The module file (.pcm). Required.
llvm::StringMap< PrebuiltModuleASTAttrs > PrebuiltModulesAttrsMap
Attributes loaded from AST files of prebuilt modules collected prior to ModuleDepCollector creation.
bool isPathInStableDir(const ArrayRef< StringRef > Directories, const StringRef Input)
Determine if Input can be resolved within a stable directory.
void resetBenignCodeGenOptions(frontend::ActionKind ProgramAction, const LangOptions &LangOpts, CodeGenOptions &CGOpts)
Resets codegen options that don't affect modules/PCH.
The JSON file list parser is used to communicate input to InstallAPI.