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