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