10b57cec5SDimitry Andric //===- HeaderSearchOptions.h ------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #ifndef LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
100b57cec5SDimitry Andric #define LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
110b57cec5SDimitry Andric
120b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
130b57cec5SDimitry Andric #include "llvm/ADT/CachedHashString.h"
14a7dea167SDimitry Andric #include "llvm/ADT/Hashing.h"
150b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h"
160b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
17349cc55cSDimitry Andric #include "llvm/Support/HashBuilder.h"
180b57cec5SDimitry Andric #include <cstdint>
19349cc55cSDimitry Andric #include <map>
200b57cec5SDimitry Andric #include <string>
210b57cec5SDimitry Andric #include <vector>
220b57cec5SDimitry Andric
230b57cec5SDimitry Andric namespace clang {
240b57cec5SDimitry Andric
250b57cec5SDimitry Andric namespace frontend {
260b57cec5SDimitry Andric
270b57cec5SDimitry Andric /// IncludeDirGroup - Identifies the group an include Entry belongs to,
280b57cec5SDimitry Andric /// representing its relative positive in the search list.
290b57cec5SDimitry Andric /// \#include directives whose paths are enclosed by string quotes ("")
300b57cec5SDimitry Andric /// start searching at the Quoted group (specified by '-iquote'),
310b57cec5SDimitry Andric /// then search the Angled group, then the System group, etc.
320b57cec5SDimitry Andric enum IncludeDirGroup {
330b57cec5SDimitry Andric /// '\#include ""' paths, added by 'gcc -iquote'.
340b57cec5SDimitry Andric Quoted = 0,
350b57cec5SDimitry Andric
360b57cec5SDimitry Andric /// Paths for '\#include <>' added by '-I'.
370b57cec5SDimitry Andric Angled,
380b57cec5SDimitry Andric
390b57cec5SDimitry Andric /// Like Angled, but marks header maps used when building frameworks.
400b57cec5SDimitry Andric IndexHeaderMap,
410b57cec5SDimitry Andric
420b57cec5SDimitry Andric /// Like Angled, but marks system directories.
430b57cec5SDimitry Andric System,
440b57cec5SDimitry Andric
450b57cec5SDimitry Andric /// Like System, but headers are implicitly wrapped in extern "C".
460b57cec5SDimitry Andric ExternCSystem,
470b57cec5SDimitry Andric
480b57cec5SDimitry Andric /// Like System, but only used for C.
490b57cec5SDimitry Andric CSystem,
500b57cec5SDimitry Andric
510b57cec5SDimitry Andric /// Like System, but only used for C++.
520b57cec5SDimitry Andric CXXSystem,
530b57cec5SDimitry Andric
540b57cec5SDimitry Andric /// Like System, but only used for ObjC.
550b57cec5SDimitry Andric ObjCSystem,
560b57cec5SDimitry Andric
570b57cec5SDimitry Andric /// Like System, but only used for ObjC++.
580b57cec5SDimitry Andric ObjCXXSystem,
590b57cec5SDimitry Andric
600b57cec5SDimitry Andric /// Like System, but searched after the system directories.
610b57cec5SDimitry Andric After
620b57cec5SDimitry Andric };
630b57cec5SDimitry Andric
640b57cec5SDimitry Andric } // namespace frontend
650b57cec5SDimitry Andric
660b57cec5SDimitry Andric /// HeaderSearchOptions - Helper class for storing options related to the
670b57cec5SDimitry Andric /// initialization of the HeaderSearch object.
680b57cec5SDimitry Andric class HeaderSearchOptions {
690b57cec5SDimitry Andric public:
700b57cec5SDimitry Andric struct Entry {
710b57cec5SDimitry Andric std::string Path;
720b57cec5SDimitry Andric frontend::IncludeDirGroup Group;
735f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
740b57cec5SDimitry Andric unsigned IsFramework : 1;
750b57cec5SDimitry Andric
760b57cec5SDimitry Andric /// IgnoreSysRoot - This is false if an absolute path should be treated
770b57cec5SDimitry Andric /// relative to the sysroot, or true if it should always be the absolute
780b57cec5SDimitry Andric /// path.
795f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
800b57cec5SDimitry Andric unsigned IgnoreSysRoot : 1;
810b57cec5SDimitry Andric
EntryEntry820b57cec5SDimitry Andric Entry(StringRef path, frontend::IncludeDirGroup group, bool isFramework,
830b57cec5SDimitry Andric bool ignoreSysRoot)
840b57cec5SDimitry Andric : Path(path), Group(group), IsFramework(isFramework),
850b57cec5SDimitry Andric IgnoreSysRoot(ignoreSysRoot) {}
860b57cec5SDimitry Andric };
870b57cec5SDimitry Andric
880b57cec5SDimitry Andric struct SystemHeaderPrefix {
890b57cec5SDimitry Andric /// A prefix to be matched against paths in \#include directives.
900b57cec5SDimitry Andric std::string Prefix;
910b57cec5SDimitry Andric
920b57cec5SDimitry Andric /// True if paths beginning with this prefix should be treated as system
930b57cec5SDimitry Andric /// headers.
940b57cec5SDimitry Andric bool IsSystemHeader;
950b57cec5SDimitry Andric
SystemHeaderPrefixSystemHeaderPrefix960b57cec5SDimitry Andric SystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader)
970b57cec5SDimitry Andric : Prefix(Prefix), IsSystemHeader(IsSystemHeader) {}
980b57cec5SDimitry Andric };
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric /// If non-empty, the directory to use as a "virtual system root" for include
1010b57cec5SDimitry Andric /// paths.
1020b57cec5SDimitry Andric std::string Sysroot;
1030b57cec5SDimitry Andric
1040b57cec5SDimitry Andric /// User specified include entries.
1050b57cec5SDimitry Andric std::vector<Entry> UserEntries;
1060b57cec5SDimitry Andric
1070b57cec5SDimitry Andric /// User-specified system header prefixes.
1080b57cec5SDimitry Andric std::vector<SystemHeaderPrefix> SystemHeaderPrefixes;
1090b57cec5SDimitry Andric
1100b57cec5SDimitry Andric /// The directory which holds the compiler resource files (builtin includes,
1110b57cec5SDimitry Andric /// etc.).
1120b57cec5SDimitry Andric std::string ResourceDir;
1130b57cec5SDimitry Andric
1140b57cec5SDimitry Andric /// The directory used for the module cache.
1150b57cec5SDimitry Andric std::string ModuleCachePath;
1160b57cec5SDimitry Andric
1170b57cec5SDimitry Andric /// The directory used for a user build.
1180b57cec5SDimitry Andric std::string ModuleUserBuildPath;
1190b57cec5SDimitry Andric
1200b57cec5SDimitry Andric /// The mapping of module names to prebuilt module files.
1215ffd83dbSDimitry Andric std::map<std::string, std::string, std::less<>> PrebuiltModuleFiles;
1220b57cec5SDimitry Andric
1230b57cec5SDimitry Andric /// The directories used to load prebuilt module files.
1240b57cec5SDimitry Andric std::vector<std::string> PrebuiltModulePaths;
1250b57cec5SDimitry Andric
1260b57cec5SDimitry Andric /// The module/pch container format.
1270b57cec5SDimitry Andric std::string ModuleFormat;
1280b57cec5SDimitry Andric
1290b57cec5SDimitry Andric /// Whether we should disable the use of the hash string within the
1300b57cec5SDimitry Andric /// module cache.
1310b57cec5SDimitry Andric ///
1320b57cec5SDimitry Andric /// Note: Only used for testing!
1335f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
1340b57cec5SDimitry Andric unsigned DisableModuleHash : 1;
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andric /// Implicit module maps. This option is enabld by default when
1370b57cec5SDimitry Andric /// modules is enabled.
1385f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
1390b57cec5SDimitry Andric unsigned ImplicitModuleMaps : 1;
1400b57cec5SDimitry Andric
1410b57cec5SDimitry Andric /// Set the 'home directory' of a module map file to the current
1420b57cec5SDimitry Andric /// working directory (or the home directory of the module map file that
1430b57cec5SDimitry Andric /// contained the 'extern module' directive importing this module map file
1440b57cec5SDimitry Andric /// if any) rather than the directory containing the module map file.
1450b57cec5SDimitry Andric //
1460b57cec5SDimitry Andric /// The home directory is where we look for files named in the module map
1470b57cec5SDimitry Andric /// file.
1485f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
1490b57cec5SDimitry Andric unsigned ModuleMapFileHomeIsCwd : 1;
1500b57cec5SDimitry Andric
15181ad6265SDimitry Andric /// Set the base path of a built module file to be the current working
15281ad6265SDimitry Andric /// directory. This is useful for sharing module files across machines
15381ad6265SDimitry Andric /// that build with different paths without having to rewrite all
15481ad6265SDimitry Andric /// modulemap files to have working directory relative paths.
1555f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
15681ad6265SDimitry Andric unsigned ModuleFileHomeIsCwd : 1;
15781ad6265SDimitry Andric
158e8d8bef9SDimitry Andric /// Also search for prebuilt implicit modules in the prebuilt module cache
159e8d8bef9SDimitry Andric /// path.
1605f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
161e8d8bef9SDimitry Andric unsigned EnablePrebuiltImplicitModules : 1;
162e8d8bef9SDimitry Andric
1630b57cec5SDimitry Andric /// The interval (in seconds) between pruning operations.
1640b57cec5SDimitry Andric ///
1650b57cec5SDimitry Andric /// This operation is expensive, because it requires Clang to walk through
1660b57cec5SDimitry Andric /// the directory structure of the module cache, stat()'ing and removing
1670b57cec5SDimitry Andric /// files.
1680b57cec5SDimitry Andric ///
1690b57cec5SDimitry Andric /// The default value is large, e.g., the operation runs once a week.
1700b57cec5SDimitry Andric unsigned ModuleCachePruneInterval = 7 * 24 * 60 * 60;
1710b57cec5SDimitry Andric
1720b57cec5SDimitry Andric /// The time (in seconds) after which an unused module file will be
1730b57cec5SDimitry Andric /// considered unused and will, therefore, be pruned.
1740b57cec5SDimitry Andric ///
1750b57cec5SDimitry Andric /// When the module cache is pruned, any module file that has not been
1760b57cec5SDimitry Andric /// accessed in this many seconds will be removed. The default value is
1770b57cec5SDimitry Andric /// large, e.g., a month, to avoid forcing infrequently-used modules to be
1780b57cec5SDimitry Andric /// regenerated often.
1790b57cec5SDimitry Andric unsigned ModuleCachePruneAfter = 31 * 24 * 60 * 60;
1800b57cec5SDimitry Andric
1810b57cec5SDimitry Andric /// The time in seconds when the build session started.
1820b57cec5SDimitry Andric ///
1830b57cec5SDimitry Andric /// This time is used by other optimizations in header search and module
1840b57cec5SDimitry Andric /// loading.
1850b57cec5SDimitry Andric uint64_t BuildSessionTimestamp = 0;
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andric /// The set of macro names that should be ignored for the purposes
1880b57cec5SDimitry Andric /// of computing the module hash.
1890b57cec5SDimitry Andric llvm::SmallSetVector<llvm::CachedHashString, 16> ModulesIgnoreMacros;
1900b57cec5SDimitry Andric
1910b57cec5SDimitry Andric /// The set of user-provided virtual filesystem overlay files.
1920b57cec5SDimitry Andric std::vector<std::string> VFSOverlayFiles;
1930b57cec5SDimitry Andric
1940b57cec5SDimitry Andric /// Include the compiler builtin includes.
1955f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
1960b57cec5SDimitry Andric unsigned UseBuiltinIncludes : 1;
1970b57cec5SDimitry Andric
1980b57cec5SDimitry Andric /// Include the system standard include search directories.
1995f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
2000b57cec5SDimitry Andric unsigned UseStandardSystemIncludes : 1;
2010b57cec5SDimitry Andric
2020b57cec5SDimitry Andric /// Include the system standard C++ library include search directories.
2035f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
2040b57cec5SDimitry Andric unsigned UseStandardCXXIncludes : 1;
2050b57cec5SDimitry Andric
2060b57cec5SDimitry Andric /// Use libc++ instead of the default libstdc++.
2075f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
2080b57cec5SDimitry Andric unsigned UseLibcxx : 1;
2090b57cec5SDimitry Andric
2100b57cec5SDimitry Andric /// Whether header search information should be output as for -v.
2115f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
2120b57cec5SDimitry Andric unsigned Verbose : 1;
2130b57cec5SDimitry Andric
2140b57cec5SDimitry Andric /// If true, skip verifying input files used by modules if the
2150b57cec5SDimitry Andric /// module was already verified during this build session (see
2160b57cec5SDimitry Andric /// \c BuildSessionTimestamp).
2175f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
2180b57cec5SDimitry Andric unsigned ModulesValidateOncePerBuildSession : 1;
2190b57cec5SDimitry Andric
2200b57cec5SDimitry Andric /// Whether to validate system input files when a module is loaded.
2215f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
2220b57cec5SDimitry Andric unsigned ModulesValidateSystemHeaders : 1;
2230b57cec5SDimitry Andric
224a7dea167SDimitry Andric // Whether the content of input files should be hashed and used to
225a7dea167SDimitry Andric // validate consistency.
2265f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
227a7dea167SDimitry Andric unsigned ValidateASTInputFilesContent : 1;
228a7dea167SDimitry Andric
2295f757f3fSDimitry Andric // Whether the input files from C++20 Modules should be checked.
2305f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
2315f757f3fSDimitry Andric unsigned ForceCheckCXX20ModulesInputFiles : 1;
2325f757f3fSDimitry Andric
2330b57cec5SDimitry Andric /// Whether the module includes debug information (-gmodules).
2345f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
2350b57cec5SDimitry Andric unsigned UseDebugInfo : 1;
2360b57cec5SDimitry Andric
2375f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
2380b57cec5SDimitry Andric unsigned ModulesValidateDiagnosticOptions : 1;
2390b57cec5SDimitry Andric
2405f757f3fSDimitry Andric /// Whether to entirely skip writing diagnostic options.
2415f757f3fSDimitry Andric /// Primarily used to speed up deserialization during dependency scanning.
2425f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
2435f757f3fSDimitry Andric unsigned ModulesSkipDiagnosticOptions : 1;
2445f757f3fSDimitry Andric
2455f757f3fSDimitry Andric /// Whether to entirely skip writing header search paths.
2465f757f3fSDimitry Andric /// Primarily used to speed up deserialization during dependency scanning.
2475f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
2485f757f3fSDimitry Andric unsigned ModulesSkipHeaderSearchPaths : 1;
2495f757f3fSDimitry Andric
2505f757f3fSDimitry Andric /// Whether to entirely skip writing pragma diagnostic mappings.
2515f757f3fSDimitry Andric /// Primarily used to speed up deserialization during dependency scanning.
2525f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
2535f757f3fSDimitry Andric unsigned ModulesSkipPragmaDiagnosticMappings : 1;
2545f757f3fSDimitry Andric
2555f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
2560b57cec5SDimitry Andric unsigned ModulesHashContent : 1;
2570b57cec5SDimitry Andric
258a7dea167SDimitry Andric /// Whether we should include all things that could impact the module in the
259a7dea167SDimitry Andric /// hash.
260a7dea167SDimitry Andric ///
261a7dea167SDimitry Andric /// This includes things like the full header search path, and enabled
262a7dea167SDimitry Andric /// diagnostics.
2635f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool)
264a7dea167SDimitry Andric unsigned ModulesStrictContextHash : 1;
265a7dea167SDimitry Andric
2660b57cec5SDimitry Andric HeaderSearchOptions(StringRef _Sysroot = "/")
Sysroot(_Sysroot)2670b57cec5SDimitry Andric : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false),
2680b57cec5SDimitry Andric ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false),
26981ad6265SDimitry Andric ModuleFileHomeIsCwd(false), EnablePrebuiltImplicitModules(false),
27081ad6265SDimitry Andric UseBuiltinIncludes(true), UseStandardSystemIncludes(true),
27181ad6265SDimitry Andric UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
2720b57cec5SDimitry Andric ModulesValidateOncePerBuildSession(false),
273a7dea167SDimitry Andric ModulesValidateSystemHeaders(false),
2745f757f3fSDimitry Andric ValidateASTInputFilesContent(false),
2755f757f3fSDimitry Andric ForceCheckCXX20ModulesInputFiles(false), UseDebugInfo(false),
2765f757f3fSDimitry Andric ModulesValidateDiagnosticOptions(true),
2775f757f3fSDimitry Andric ModulesSkipDiagnosticOptions(false),
2785f757f3fSDimitry Andric ModulesSkipHeaderSearchPaths(false),
2795f757f3fSDimitry Andric ModulesSkipPragmaDiagnosticMappings(false), ModulesHashContent(false),
280a7dea167SDimitry Andric ModulesStrictContextHash(false) {}
2810b57cec5SDimitry Andric
2820b57cec5SDimitry Andric /// AddPath - Add the \p Path path to the specified \p Group list.
AddPath(StringRef Path,frontend::IncludeDirGroup Group,bool IsFramework,bool IgnoreSysRoot)2830b57cec5SDimitry Andric void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
2840b57cec5SDimitry Andric bool IsFramework, bool IgnoreSysRoot) {
2850b57cec5SDimitry Andric UserEntries.emplace_back(Path, Group, IsFramework, IgnoreSysRoot);
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric
2880b57cec5SDimitry Andric /// AddSystemHeaderPrefix - Override whether \#include directives naming a
2890b57cec5SDimitry Andric /// path starting with \p Prefix should be considered as naming a system
2900b57cec5SDimitry Andric /// header.
AddSystemHeaderPrefix(StringRef Prefix,bool IsSystemHeader)2910b57cec5SDimitry Andric void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) {
2920b57cec5SDimitry Andric SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader);
2930b57cec5SDimitry Andric }
2940b57cec5SDimitry Andric
AddVFSOverlayFile(StringRef Name)2950b57cec5SDimitry Andric void AddVFSOverlayFile(StringRef Name) {
2965ffd83dbSDimitry Andric VFSOverlayFiles.push_back(std::string(Name));
2970b57cec5SDimitry Andric }
2980b57cec5SDimitry Andric
AddPrebuiltModulePath(StringRef Name)2990b57cec5SDimitry Andric void AddPrebuiltModulePath(StringRef Name) {
3005ffd83dbSDimitry Andric PrebuiltModulePaths.push_back(std::string(Name));
3010b57cec5SDimitry Andric }
3020b57cec5SDimitry Andric };
3030b57cec5SDimitry Andric
hash_value(const HeaderSearchOptions::Entry & E)304a7dea167SDimitry Andric inline llvm::hash_code hash_value(const HeaderSearchOptions::Entry &E) {
305a7dea167SDimitry Andric return llvm::hash_combine(E.Path, E.Group, E.IsFramework, E.IgnoreSysRoot);
306a7dea167SDimitry Andric }
307a7dea167SDimitry Andric
3085f757f3fSDimitry Andric template <typename HasherT, llvm::endianness Endianness>
addHash(llvm::HashBuilder<HasherT,Endianness> & HBuilder,const HeaderSearchOptions::Entry & E)3095f757f3fSDimitry Andric inline void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
310349cc55cSDimitry Andric const HeaderSearchOptions::Entry &E) {
311349cc55cSDimitry Andric HBuilder.add(E.Path, E.Group, E.IsFramework, E.IgnoreSysRoot);
312349cc55cSDimitry Andric }
313349cc55cSDimitry Andric
314a7dea167SDimitry Andric inline llvm::hash_code
hash_value(const HeaderSearchOptions::SystemHeaderPrefix & SHP)315a7dea167SDimitry Andric hash_value(const HeaderSearchOptions::SystemHeaderPrefix &SHP) {
316a7dea167SDimitry Andric return llvm::hash_combine(SHP.Prefix, SHP.IsSystemHeader);
317a7dea167SDimitry Andric }
318a7dea167SDimitry Andric
3195f757f3fSDimitry Andric template <typename HasherT, llvm::endianness Endianness>
addHash(llvm::HashBuilder<HasherT,Endianness> & HBuilder,const HeaderSearchOptions::SystemHeaderPrefix & SHP)3205f757f3fSDimitry Andric inline void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
321349cc55cSDimitry Andric const HeaderSearchOptions::SystemHeaderPrefix &SHP) {
322349cc55cSDimitry Andric HBuilder.add(SHP.Prefix, SHP.IsSystemHeader);
323349cc55cSDimitry Andric }
324349cc55cSDimitry Andric
3250b57cec5SDimitry Andric } // namespace clang
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andric #endif // LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
328