1 //===- HeaderSearchOptions.h ------------------------------------*- 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 #ifndef LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
10 #define LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
11 
12 #include "clang/Basic/LLVM.h"
13 #include "llvm/ADT/CachedHashString.h"
14 #include "llvm/ADT/Hashing.h"
15 #include "llvm/ADT/SetVector.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/Support/HashBuilder.h"
18 #include <cstdint>
19 #include <map>
20 #include <string>
21 #include <vector>
22 
23 namespace clang {
24 
25 namespace frontend {
26 
27 /// IncludeDirGroup - Identifies the group an include Entry belongs to,
28 /// representing its relative positive in the search list.
29 /// \#include directives whose paths are enclosed by string quotes ("")
30 /// start searching at the Quoted group (specified by '-iquote'),
31 /// then search the Angled group, then the System group, etc.
32 enum IncludeDirGroup {
33   /// '\#include ""' paths, added by 'gcc -iquote'.
34   Quoted = 0,
35 
36   /// Paths for '\#include <>' added by '-I'.
37   Angled,
38 
39   /// Like Angled, but marks header maps used when building frameworks.
40   IndexHeaderMap,
41 
42   /// Like Angled, but marks system directories.
43   System,
44 
45   /// Like System, but headers are implicitly wrapped in extern "C".
46   ExternCSystem,
47 
48   /// Like System, but only used for C.
49   CSystem,
50 
51   /// Like System, but only used for C++.
52   CXXSystem,
53 
54   /// Like System, but only used for ObjC.
55   ObjCSystem,
56 
57   /// Like System, but only used for ObjC++.
58   ObjCXXSystem,
59 
60   /// Like System, but searched after the system directories.
61   After
62 };
63 
64 } // namespace frontend
65 
66 /// HeaderSearchOptions - Helper class for storing options related to the
67 /// initialization of the HeaderSearch object.
68 class HeaderSearchOptions {
69 public:
70   struct Entry {
71     std::string Path;
72     frontend::IncludeDirGroup Group;
73     LLVM_PREFERRED_TYPE(bool)
74     unsigned IsFramework : 1;
75 
76     /// IgnoreSysRoot - This is false if an absolute path should be treated
77     /// relative to the sysroot, or true if it should always be the absolute
78     /// path.
79     LLVM_PREFERRED_TYPE(bool)
80     unsigned IgnoreSysRoot : 1;
81 
82     Entry(StringRef path, frontend::IncludeDirGroup group, bool isFramework,
83           bool ignoreSysRoot)
84         : Path(path), Group(group), IsFramework(isFramework),
85           IgnoreSysRoot(ignoreSysRoot) {}
86   };
87 
88   struct SystemHeaderPrefix {
89     /// A prefix to be matched against paths in \#include directives.
90     std::string Prefix;
91 
92     /// True if paths beginning with this prefix should be treated as system
93     /// headers.
94     bool IsSystemHeader;
95 
96     SystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader)
97         : Prefix(Prefix), IsSystemHeader(IsSystemHeader) {}
98   };
99 
100   /// If non-empty, the directory to use as a "virtual system root" for include
101   /// paths.
102   std::string Sysroot;
103 
104   /// User specified include entries.
105   std::vector<Entry> UserEntries;
106 
107   /// User-specified system header prefixes.
108   std::vector<SystemHeaderPrefix> SystemHeaderPrefixes;
109 
110   /// The directory which holds the compiler resource files (builtin includes,
111   /// etc.).
112   std::string ResourceDir;
113 
114   /// The directory used for the module cache.
115   std::string ModuleCachePath;
116 
117   /// The directory used for a user build.
118   std::string ModuleUserBuildPath;
119 
120   /// The mapping of module names to prebuilt module files.
121   std::map<std::string, std::string, std::less<>> PrebuiltModuleFiles;
122 
123   /// The directories used to load prebuilt module files.
124   std::vector<std::string> PrebuiltModulePaths;
125 
126   /// The module/pch container format.
127   std::string ModuleFormat;
128 
129   /// Whether we should disable the use of the hash string within the
130   /// module cache.
131   ///
132   /// Note: Only used for testing!
133   LLVM_PREFERRED_TYPE(bool)
134   unsigned DisableModuleHash : 1;
135 
136   /// Implicit module maps.  This option is enabld by default when
137   /// modules is enabled.
138   LLVM_PREFERRED_TYPE(bool)
139   unsigned ImplicitModuleMaps : 1;
140 
141   /// Set the 'home directory' of a module map file to the current
142   /// working directory (or the home directory of the module map file that
143   /// contained the 'extern module' directive importing this module map file
144   /// if any) rather than the directory containing the module map file.
145   //
146   /// The home directory is where we look for files named in the module map
147   /// file.
148   LLVM_PREFERRED_TYPE(bool)
149   unsigned ModuleMapFileHomeIsCwd : 1;
150 
151   /// Set the base path of a built module file to be the current working
152   /// directory. This is useful for sharing module files across machines
153   /// that build with different paths without having to rewrite all
154   /// modulemap files to have working directory relative paths.
155   LLVM_PREFERRED_TYPE(bool)
156   unsigned ModuleFileHomeIsCwd : 1;
157 
158   /// Also search for prebuilt implicit modules in the prebuilt module cache
159   /// path.
160   LLVM_PREFERRED_TYPE(bool)
161   unsigned EnablePrebuiltImplicitModules : 1;
162 
163   /// The interval (in seconds) between pruning operations.
164   ///
165   /// This operation is expensive, because it requires Clang to walk through
166   /// the directory structure of the module cache, stat()'ing and removing
167   /// files.
168   ///
169   /// The default value is large, e.g., the operation runs once a week.
170   unsigned ModuleCachePruneInterval = 7 * 24 * 60 * 60;
171 
172   /// The time (in seconds) after which an unused module file will be
173   /// considered unused and will, therefore, be pruned.
174   ///
175   /// When the module cache is pruned, any module file that has not been
176   /// accessed in this many seconds will be removed. The default value is
177   /// large, e.g., a month, to avoid forcing infrequently-used modules to be
178   /// regenerated often.
179   unsigned ModuleCachePruneAfter = 31 * 24 * 60 * 60;
180 
181   /// The time in seconds when the build session started.
182   ///
183   /// This time is used by other optimizations in header search and module
184   /// loading.
185   uint64_t BuildSessionTimestamp = 0;
186 
187   /// The set of macro names that should be ignored for the purposes
188   /// of computing the module hash.
189   llvm::SmallSetVector<llvm::CachedHashString, 16> ModulesIgnoreMacros;
190 
191   /// The set of user-provided virtual filesystem overlay files.
192   std::vector<std::string> VFSOverlayFiles;
193 
194   /// Include the compiler builtin includes.
195   LLVM_PREFERRED_TYPE(bool)
196   unsigned UseBuiltinIncludes : 1;
197 
198   /// Include the system standard include search directories.
199   LLVM_PREFERRED_TYPE(bool)
200   unsigned UseStandardSystemIncludes : 1;
201 
202   /// Include the system standard C++ library include search directories.
203   LLVM_PREFERRED_TYPE(bool)
204   unsigned UseStandardCXXIncludes : 1;
205 
206   /// Use libc++ instead of the default libstdc++.
207   LLVM_PREFERRED_TYPE(bool)
208   unsigned UseLibcxx : 1;
209 
210   /// Whether header search information should be output as for -v.
211   LLVM_PREFERRED_TYPE(bool)
212   unsigned Verbose : 1;
213 
214   /// If true, skip verifying input files used by modules if the
215   /// module was already verified during this build session (see
216   /// \c BuildSessionTimestamp).
217   LLVM_PREFERRED_TYPE(bool)
218   unsigned ModulesValidateOncePerBuildSession : 1;
219 
220   /// Whether to validate system input files when a module is loaded.
221   LLVM_PREFERRED_TYPE(bool)
222   unsigned ModulesValidateSystemHeaders : 1;
223 
224   // Whether the content of input files should be hashed and used to
225   // validate consistency.
226   LLVM_PREFERRED_TYPE(bool)
227   unsigned ValidateASTInputFilesContent : 1;
228 
229   // Whether the input files from C++20 Modules should be checked.
230   LLVM_PREFERRED_TYPE(bool)
231   unsigned ForceCheckCXX20ModulesInputFiles : 1;
232 
233   /// Whether the module includes debug information (-gmodules).
234   LLVM_PREFERRED_TYPE(bool)
235   unsigned UseDebugInfo : 1;
236 
237   LLVM_PREFERRED_TYPE(bool)
238   unsigned ModulesValidateDiagnosticOptions : 1;
239 
240   /// Whether to entirely skip writing diagnostic options.
241   /// Primarily used to speed up deserialization during dependency scanning.
242   LLVM_PREFERRED_TYPE(bool)
243   unsigned ModulesSkipDiagnosticOptions : 1;
244 
245   /// Whether to entirely skip writing header search paths.
246   /// Primarily used to speed up deserialization during dependency scanning.
247   LLVM_PREFERRED_TYPE(bool)
248   unsigned ModulesSkipHeaderSearchPaths : 1;
249 
250   /// Whether to entirely skip writing pragma diagnostic mappings.
251   /// Primarily used to speed up deserialization during dependency scanning.
252   LLVM_PREFERRED_TYPE(bool)
253   unsigned ModulesSkipPragmaDiagnosticMappings : 1;
254 
255   LLVM_PREFERRED_TYPE(bool)
256   unsigned ModulesHashContent : 1;
257 
258   /// Whether we should include all things that could impact the module in the
259   /// hash.
260   ///
261   /// This includes things like the full header search path, and enabled
262   /// diagnostics.
263   LLVM_PREFERRED_TYPE(bool)
264   unsigned ModulesStrictContextHash : 1;
265 
266   HeaderSearchOptions(StringRef _Sysroot = "/")
267       : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false),
268         ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false),
269         ModuleFileHomeIsCwd(false), EnablePrebuiltImplicitModules(false),
270         UseBuiltinIncludes(true), UseStandardSystemIncludes(true),
271         UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
272         ModulesValidateOncePerBuildSession(false),
273         ModulesValidateSystemHeaders(false),
274         ValidateASTInputFilesContent(false),
275         ForceCheckCXX20ModulesInputFiles(false), UseDebugInfo(false),
276         ModulesValidateDiagnosticOptions(true),
277         ModulesSkipDiagnosticOptions(false),
278         ModulesSkipHeaderSearchPaths(false),
279         ModulesSkipPragmaDiagnosticMappings(false), ModulesHashContent(false),
280         ModulesStrictContextHash(false) {}
281 
282   /// AddPath - Add the \p Path path to the specified \p Group list.
283   void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
284                bool IsFramework, bool IgnoreSysRoot) {
285     UserEntries.emplace_back(Path, Group, IsFramework, IgnoreSysRoot);
286   }
287 
288   /// AddSystemHeaderPrefix - Override whether \#include directives naming a
289   /// path starting with \p Prefix should be considered as naming a system
290   /// header.
291   void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) {
292     SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader);
293   }
294 
295   void AddVFSOverlayFile(StringRef Name) {
296     VFSOverlayFiles.push_back(std::string(Name));
297   }
298 
299   void AddPrebuiltModulePath(StringRef Name) {
300     PrebuiltModulePaths.push_back(std::string(Name));
301   }
302 };
303 
304 inline llvm::hash_code hash_value(const HeaderSearchOptions::Entry &E) {
305   return llvm::hash_combine(E.Path, E.Group, E.IsFramework, E.IgnoreSysRoot);
306 }
307 
308 template <typename HasherT, llvm::endianness Endianness>
309 inline void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
310                     const HeaderSearchOptions::Entry &E) {
311   HBuilder.add(E.Path, E.Group, E.IsFramework, E.IgnoreSysRoot);
312 }
313 
314 inline llvm::hash_code
315 hash_value(const HeaderSearchOptions::SystemHeaderPrefix &SHP) {
316   return llvm::hash_combine(SHP.Prefix, SHP.IsSystemHeader);
317 }
318 
319 template <typename HasherT, llvm::endianness Endianness>
320 inline void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
321                     const HeaderSearchOptions::SystemHeaderPrefix &SHP) {
322   HBuilder.add(SHP.Prefix, SHP.IsSystemHeader);
323 }
324 
325 } // namespace clang
326 
327 #endif // LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
328