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     unsigned IsFramework : 1;
74 
75     /// IgnoreSysRoot - This is false if an absolute path should be treated
76     /// relative to the sysroot, or true if it should always be the absolute
77     /// path.
78     unsigned IgnoreSysRoot : 1;
79 
80     Entry(StringRef path, frontend::IncludeDirGroup group, bool isFramework,
81           bool ignoreSysRoot)
82         : Path(path), Group(group), IsFramework(isFramework),
83           IgnoreSysRoot(ignoreSysRoot) {}
84   };
85 
86   struct SystemHeaderPrefix {
87     /// A prefix to be matched against paths in \#include directives.
88     std::string Prefix;
89 
90     /// True if paths beginning with this prefix should be treated as system
91     /// headers.
92     bool IsSystemHeader;
93 
94     SystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader)
95         : Prefix(Prefix), IsSystemHeader(IsSystemHeader) {}
96   };
97 
98   /// If non-empty, the directory to use as a "virtual system root" for include
99   /// paths.
100   std::string Sysroot;
101 
102   /// User specified include entries.
103   std::vector<Entry> UserEntries;
104 
105   /// User-specified system header prefixes.
106   std::vector<SystemHeaderPrefix> SystemHeaderPrefixes;
107 
108   /// The directory which holds the compiler resource files (builtin includes,
109   /// etc.).
110   std::string ResourceDir;
111 
112   /// The directory used for the module cache.
113   std::string ModuleCachePath;
114 
115   /// The directory used for a user build.
116   std::string ModuleUserBuildPath;
117 
118   /// The mapping of module names to prebuilt module files.
119   std::map<std::string, std::string, std::less<>> PrebuiltModuleFiles;
120 
121   /// The directories used to load prebuilt module files.
122   std::vector<std::string> PrebuiltModulePaths;
123 
124   /// The module/pch container format.
125   std::string ModuleFormat;
126 
127   /// Whether we should disable the use of the hash string within the
128   /// module cache.
129   ///
130   /// Note: Only used for testing!
131   unsigned DisableModuleHash : 1;
132 
133   /// Implicit module maps.  This option is enabld by default when
134   /// modules is enabled.
135   unsigned ImplicitModuleMaps : 1;
136 
137   /// Set the 'home directory' of a module map file to the current
138   /// working directory (or the home directory of the module map file that
139   /// contained the 'extern module' directive importing this module map file
140   /// if any) rather than the directory containing the module map file.
141   //
142   /// The home directory is where we look for files named in the module map
143   /// file.
144   unsigned ModuleMapFileHomeIsCwd : 1;
145 
146   /// Set the base path of a built module file to be the current working
147   /// directory. This is useful for sharing module files across machines
148   /// that build with different paths without having to rewrite all
149   /// modulemap files to have working directory relative paths.
150   unsigned ModuleFileHomeIsCwd : 1;
151 
152   /// Also search for prebuilt implicit modules in the prebuilt module cache
153   /// path.
154   unsigned EnablePrebuiltImplicitModules : 1;
155 
156   /// The interval (in seconds) between pruning operations.
157   ///
158   /// This operation is expensive, because it requires Clang to walk through
159   /// the directory structure of the module cache, stat()'ing and removing
160   /// files.
161   ///
162   /// The default value is large, e.g., the operation runs once a week.
163   unsigned ModuleCachePruneInterval = 7 * 24 * 60 * 60;
164 
165   /// The time (in seconds) after which an unused module file will be
166   /// considered unused and will, therefore, be pruned.
167   ///
168   /// When the module cache is pruned, any module file that has not been
169   /// accessed in this many seconds will be removed. The default value is
170   /// large, e.g., a month, to avoid forcing infrequently-used modules to be
171   /// regenerated often.
172   unsigned ModuleCachePruneAfter = 31 * 24 * 60 * 60;
173 
174   /// The time in seconds when the build session started.
175   ///
176   /// This time is used by other optimizations in header search and module
177   /// loading.
178   uint64_t BuildSessionTimestamp = 0;
179 
180   /// The set of macro names that should be ignored for the purposes
181   /// of computing the module hash.
182   llvm::SmallSetVector<llvm::CachedHashString, 16> ModulesIgnoreMacros;
183 
184   /// The set of user-provided virtual filesystem overlay files.
185   std::vector<std::string> VFSOverlayFiles;
186 
187   /// Include the compiler builtin includes.
188   unsigned UseBuiltinIncludes : 1;
189 
190   /// Include the system standard include search directories.
191   unsigned UseStandardSystemIncludes : 1;
192 
193   /// Include the system standard C++ library include search directories.
194   unsigned UseStandardCXXIncludes : 1;
195 
196   /// Use libc++ instead of the default libstdc++.
197   unsigned UseLibcxx : 1;
198 
199   /// Whether header search information should be output as for -v.
200   unsigned Verbose : 1;
201 
202   /// If true, skip verifying input files used by modules if the
203   /// module was already verified during this build session (see
204   /// \c BuildSessionTimestamp).
205   unsigned ModulesValidateOncePerBuildSession : 1;
206 
207   /// Whether to validate system input files when a module is loaded.
208   unsigned ModulesValidateSystemHeaders : 1;
209 
210   // Whether the content of input files should be hashed and used to
211   // validate consistency.
212   unsigned ValidateASTInputFilesContent : 1;
213 
214   /// Whether the module includes debug information (-gmodules).
215   unsigned UseDebugInfo : 1;
216 
217   unsigned ModulesValidateDiagnosticOptions : 1;
218 
219   unsigned ModulesHashContent : 1;
220 
221   /// Whether we should include all things that could impact the module in the
222   /// hash.
223   ///
224   /// This includes things like the full header search path, and enabled
225   /// diagnostics.
226   unsigned ModulesStrictContextHash : 1;
227 
228   HeaderSearchOptions(StringRef _Sysroot = "/")
229       : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false),
230         ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false),
231         ModuleFileHomeIsCwd(false), EnablePrebuiltImplicitModules(false),
232         UseBuiltinIncludes(true), UseStandardSystemIncludes(true),
233         UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
234         ModulesValidateOncePerBuildSession(false),
235         ModulesValidateSystemHeaders(false),
236         ValidateASTInputFilesContent(false), UseDebugInfo(false),
237         ModulesValidateDiagnosticOptions(true), ModulesHashContent(false),
238         ModulesStrictContextHash(false) {}
239 
240   /// AddPath - Add the \p Path path to the specified \p Group list.
241   void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
242                bool IsFramework, bool IgnoreSysRoot) {
243     UserEntries.emplace_back(Path, Group, IsFramework, IgnoreSysRoot);
244   }
245 
246   /// AddSystemHeaderPrefix - Override whether \#include directives naming a
247   /// path starting with \p Prefix should be considered as naming a system
248   /// header.
249   void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) {
250     SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader);
251   }
252 
253   void AddVFSOverlayFile(StringRef Name) {
254     VFSOverlayFiles.push_back(std::string(Name));
255   }
256 
257   void AddPrebuiltModulePath(StringRef Name) {
258     PrebuiltModulePaths.push_back(std::string(Name));
259   }
260 };
261 
262 inline llvm::hash_code hash_value(const HeaderSearchOptions::Entry &E) {
263   return llvm::hash_combine(E.Path, E.Group, E.IsFramework, E.IgnoreSysRoot);
264 }
265 
266 template <typename HasherT, llvm::support::endianness Endianness>
267 inline void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
268                     const HeaderSearchOptions::Entry &E) {
269   HBuilder.add(E.Path, E.Group, E.IsFramework, E.IgnoreSysRoot);
270 }
271 
272 inline llvm::hash_code
273 hash_value(const HeaderSearchOptions::SystemHeaderPrefix &SHP) {
274   return llvm::hash_combine(SHP.Prefix, SHP.IsSystemHeader);
275 }
276 
277 template <typename HasherT, llvm::support::endianness Endianness>
278 inline void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
279                     const HeaderSearchOptions::SystemHeaderPrefix &SHP) {
280   HBuilder.add(SHP.Prefix, SHP.IsSystemHeader);
281 }
282 
283 } // namespace clang
284 
285 #endif // LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
286