| 1 | //===--- DirectoryLookup.h - Info for searching for headers -----*- 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 | // This file defines the DirectoryLookup interface. |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
| 13 | #ifndef LLVM_CLANG_LEX_DIRECTORYLOOKUP_H |
| 14 | #define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H |
| 15 | |
| 16 | #include "clang/Basic/LLVM.h" |
| 17 | #include "clang/Basic/SourceManager.h" |
| 18 | #include "clang/Lex/ModuleMap.h" |
| 19 | |
| 20 | namespace clang { |
| 21 | class HeaderMap; |
| 22 | class DirectoryEntry; |
| 23 | class FileEntry; |
| 24 | class HeaderSearch; |
| 25 | class Module; |
| 26 | |
| 27 | /// DirectoryLookup - This class represents one entry in the search list that |
| 28 | /// specifies the search order for directories in \#include directives. It |
| 29 | /// represents either a directory, a framework, or a headermap. |
| 30 | /// |
| 31 | class DirectoryLookup { |
| 32 | public: |
| 33 | enum LookupType_t { |
| 34 | LT_NormalDir, |
| 35 | LT_Framework, |
| 36 | LT_HeaderMap |
| 37 | }; |
| 38 | private: |
| 39 | union { // This union is discriminated by isHeaderMap. |
| 40 | /// Dir - This is the actual directory that we're referring to for a normal |
| 41 | /// directory or a framework. |
| 42 | const DirectoryEntry *Dir; |
| 43 | |
| 44 | /// Map - This is the HeaderMap if this is a headermap lookup. |
| 45 | /// |
| 46 | const HeaderMap *Map; |
| 47 | } u; |
| 48 | |
| 49 | /// DirCharacteristic - The type of directory this is: this is an instance of |
| 50 | /// SrcMgr::CharacteristicKind. |
| 51 | unsigned DirCharacteristic : 2; |
| 52 | |
| 53 | /// LookupType - This indicates whether this DirectoryLookup object is a |
| 54 | /// normal directory, a framework, or a headermap. |
| 55 | unsigned LookupType : 2; |
| 56 | |
| 57 | /// Whether this is a header map used when building a framework. |
| 58 | unsigned IsIndexHeaderMap : 1; |
| 59 | |
| 60 | /// Whether we've performed an exhaustive search for module maps |
| 61 | /// within the subdirectories of this directory. |
| 62 | unsigned SearchedAllModuleMaps : 1; |
| 63 | |
| 64 | public: |
| 65 | /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of |
| 66 | /// 'dir'. |
| 67 | DirectoryLookup(const DirectoryEntry *dir, SrcMgr::CharacteristicKind DT, |
| 68 | bool isFramework) |
| 69 | : DirCharacteristic(DT), |
| 70 | LookupType(isFramework ? LT_Framework : LT_NormalDir), |
| 71 | IsIndexHeaderMap(false), SearchedAllModuleMaps(false) { |
| 72 | u.Dir = dir; |
| 73 | } |
| 74 | |
| 75 | /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of |
| 76 | /// 'map'. |
| 77 | DirectoryLookup(const HeaderMap *map, SrcMgr::CharacteristicKind DT, |
| 78 | bool isIndexHeaderMap) |
| 79 | : DirCharacteristic(DT), LookupType(LT_HeaderMap), |
| 80 | IsIndexHeaderMap(isIndexHeaderMap), SearchedAllModuleMaps(false) { |
| 81 | u.Map = map; |
| 82 | } |
| 83 | |
| 84 | /// getLookupType - Return the kind of directory lookup that this is: either a |
| 85 | /// normal directory, a framework path, or a HeaderMap. |
| 86 | LookupType_t getLookupType() const { return (LookupType_t)LookupType; } |
| 87 | |
| 88 | /// getName - Return the directory or filename corresponding to this lookup |
| 89 | /// object. |
| 90 | StringRef getName() const; |
| 91 | |
| 92 | /// getDir - Return the directory that this entry refers to. |
| 93 | /// |
| 94 | const DirectoryEntry *getDir() const { |
| 95 | return isNormalDir() ? u.Dir : nullptr; |
| 96 | } |
| 97 | |
| 98 | /// getFrameworkDir - Return the directory that this framework refers to. |
| 99 | /// |
| 100 | const DirectoryEntry *getFrameworkDir() const { |
| 101 | return isFramework() ? u.Dir : nullptr; |
| 102 | } |
| 103 | |
| 104 | /// getHeaderMap - Return the directory that this entry refers to. |
| 105 | /// |
| 106 | const HeaderMap *getHeaderMap() const { |
| 107 | return isHeaderMap() ? u.Map : nullptr; |
| 108 | } |
| 109 | |
| 110 | /// isNormalDir - Return true if this is a normal directory, not a header map. |
| 111 | bool isNormalDir() const { return getLookupType() == LT_NormalDir; } |
| 112 | |
| 113 | /// isFramework - True if this is a framework directory. |
| 114 | /// |
| 115 | bool isFramework() const { return getLookupType() == LT_Framework; } |
| 116 | |
| 117 | /// isHeaderMap - Return true if this is a header map, not a normal directory. |
| 118 | bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; } |
| 119 | |
| 120 | /// Determine whether we have already searched this entire |
| 121 | /// directory for module maps. |
| 122 | bool haveSearchedAllModuleMaps() const { return SearchedAllModuleMaps; } |
| 123 | |
| 124 | /// Specify whether we have already searched all of the subdirectories |
| 125 | /// for module maps. |
| 126 | void setSearchedAllModuleMaps(bool SAMM) { |
| 127 | SearchedAllModuleMaps = SAMM; |
| 128 | } |
| 129 | |
| 130 | /// DirCharacteristic - The type of directory this is, one of the DirType enum |
| 131 | /// values. |
| 132 | SrcMgr::CharacteristicKind getDirCharacteristic() const { |
| 133 | return (SrcMgr::CharacteristicKind)DirCharacteristic; |
| 134 | } |
| 135 | |
| 136 | /// Whether this describes a system header directory. |
| 137 | bool isSystemHeaderDirectory() const { |
| 138 | return getDirCharacteristic() != SrcMgr::C_User; |
| 139 | } |
| 140 | |
| 141 | /// Whether this header map is building a framework or not. |
| 142 | bool isIndexHeaderMap() const { |
| 143 | return isHeaderMap() && IsIndexHeaderMap; |
| 144 | } |
| 145 | |
| 146 | /// LookupFile - Lookup the specified file in this search path, returning it |
| 147 | /// if it exists or returning null if not. |
| 148 | /// |
| 149 | /// \param Filename The file to look up relative to the search paths. |
| 150 | /// |
| 151 | /// \param HS The header search instance to search with. |
| 152 | /// |
| 153 | /// \param IncludeLoc the source location of the #include or #import |
| 154 | /// directive. |
| 155 | /// |
| 156 | /// \param SearchPath If not NULL, will be set to the search path relative |
| 157 | /// to which the file was found. |
| 158 | /// |
| 159 | /// \param RelativePath If not NULL, will be set to the path relative to |
| 160 | /// SearchPath at which the file was found. This only differs from the |
| 161 | /// Filename for framework includes. |
| 162 | /// |
| 163 | /// \param RequestingModule The module in which the lookup was performed. |
| 164 | /// |
| 165 | /// \param SuggestedModule If non-null, and the file found is semantically |
| 166 | /// part of a known module, this will be set to the module that should |
| 167 | /// be imported instead of preprocessing/parsing the file found. |
| 168 | /// |
| 169 | /// \param [out] InUserSpecifiedSystemFramework If the file is found, |
| 170 | /// set to true if the file is located in a framework that has been |
| 171 | /// user-specified to be treated as a system framework. |
| 172 | /// |
| 173 | /// \param [out] IsFrameworkFound For a framework directory set to true if |
| 174 | /// specified '.framework' directory is found. |
| 175 | /// |
| 176 | /// \param [out] MappedName if this is a headermap which maps the filename to |
| 177 | /// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this |
| 178 | /// vector and point Filename to it. |
| 179 | const FileEntry *LookupFile(StringRef &Filename, HeaderSearch &HS, |
| 180 | SourceLocation IncludeLoc, |
| 181 | SmallVectorImpl<char> *SearchPath, |
| 182 | SmallVectorImpl<char> *RelativePath, |
| 183 | Module *RequestingModule, |
| 184 | ModuleMap::KnownHeader *SuggestedModule, |
| 185 | bool &InUserSpecifiedSystemFramework, |
| 186 | bool &IsFrameworkFound, |
| 187 | bool &HasBeenMapped, |
| 188 | SmallVectorImpl<char> &MappedName) const; |
| 189 | |
| 190 | private: |
| 191 | const FileEntry *DoFrameworkLookup( |
| 192 | StringRef Filename, HeaderSearch &HS, |
| 193 | SmallVectorImpl<char> *SearchPath, |
| 194 | SmallVectorImpl<char> *RelativePath, |
| 195 | Module *RequestingModule, |
| 196 | ModuleMap::KnownHeader *SuggestedModule, |
| 197 | bool &InUserSpecifiedSystemFramework, |
| 198 | bool &IsFrameworkFound) const; |
| 199 | |
| 200 | }; |
| 201 | |
| 202 | } // end namespace clang |
| 203 | |
| 204 | #endif |
| 205 |