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 : 2; 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 94 /// getFrameworkDir - Return the directory that this framework refers to. 95 /// getFrameworkDir()96 const DirectoryEntry *getFrameworkDir() const { 97 return isFramework() ? &u.Dir.getDirEntry() : nullptr; 98 } 99 getFrameworkDirRef()100 Optional<DirectoryEntryRef> getFrameworkDirRef() const { 101 return isFramework() ? Optional<DirectoryEntryRef>(u.Dir) : None; 102 } 103 104 /// getHeaderMap - Return the directory that this entry refers to. 105 /// getHeaderMap()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. isNormalDir()111 bool isNormalDir() const { return getLookupType() == LT_NormalDir; } 112 113 /// isFramework - True if this is a framework directory. 114 /// isFramework()115 bool isFramework() const { return getLookupType() == LT_Framework; } 116 117 /// isHeaderMap - Return true if this is a header map, not a normal directory. isHeaderMap()118 bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; } 119 120 /// Determine whether we have already searched this entire 121 /// directory for module maps. haveSearchedAllModuleMaps()122 bool haveSearchedAllModuleMaps() const { return SearchedAllModuleMaps; } 123 124 /// Specify whether we have already searched all of the subdirectories 125 /// for module maps. setSearchedAllModuleMaps(bool SAMM)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. getDirCharacteristic()132 SrcMgr::CharacteristicKind getDirCharacteristic() const { 133 return (SrcMgr::CharacteristicKind)DirCharacteristic; 134 } 135 136 /// Whether this describes a system header directory. isSystemHeaderDirectory()137 bool isSystemHeaderDirectory() const { 138 return getDirCharacteristic() != SrcMgr::C_User; 139 } 140 141 /// Whether this header map is building a framework or not. isIndexHeaderMap()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 Optional<FileEntryRef> 180 LookupFile(StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc, 181 SmallVectorImpl<char> *SearchPath, 182 SmallVectorImpl<char> *RelativePath, Module *RequestingModule, 183 ModuleMap::KnownHeader *SuggestedModule, 184 bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound, 185 bool &IsInHeaderMap, SmallVectorImpl<char> &MappedName) const; 186 187 private: 188 Optional<FileEntryRef> DoFrameworkLookup( 189 StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath, 190 SmallVectorImpl<char> *RelativePath, Module *RequestingModule, 191 ModuleMap::KnownHeader *SuggestedModule, 192 bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound) const; 193 }; 194 195 } // end namespace clang 196 197 #endif 198