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