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