17330f729Sjoerg //===--- DirectoryLookup.h - Info for searching for headers -----*- C++ -*-===// 27330f729Sjoerg // 37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information. 57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 67330f729Sjoerg // 77330f729Sjoerg //===----------------------------------------------------------------------===// 87330f729Sjoerg // 97330f729Sjoerg // This file defines the DirectoryLookup interface. 107330f729Sjoerg // 117330f729Sjoerg //===----------------------------------------------------------------------===// 127330f729Sjoerg 137330f729Sjoerg #ifndef LLVM_CLANG_LEX_DIRECTORYLOOKUP_H 147330f729Sjoerg #define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H 157330f729Sjoerg 167330f729Sjoerg #include "clang/Basic/LLVM.h" 17*e038c9c4Sjoerg #include "clang/Basic/FileManager.h" 187330f729Sjoerg #include "clang/Basic/SourceManager.h" 197330f729Sjoerg #include "clang/Lex/ModuleMap.h" 207330f729Sjoerg 217330f729Sjoerg namespace clang { 227330f729Sjoerg class HeaderMap; 237330f729Sjoerg class HeaderSearch; 247330f729Sjoerg class Module; 257330f729Sjoerg 267330f729Sjoerg /// DirectoryLookup - This class represents one entry in the search list that 277330f729Sjoerg /// specifies the search order for directories in \#include directives. It 287330f729Sjoerg /// represents either a directory, a framework, or a headermap. 297330f729Sjoerg /// 307330f729Sjoerg class DirectoryLookup { 317330f729Sjoerg public: 327330f729Sjoerg enum LookupType_t { 337330f729Sjoerg LT_NormalDir, 347330f729Sjoerg LT_Framework, 357330f729Sjoerg LT_HeaderMap 367330f729Sjoerg }; 377330f729Sjoerg private: 387330f729Sjoerg union DLU { // This union is discriminated by isHeaderMap. 397330f729Sjoerg /// Dir - This is the actual directory that we're referring to for a normal 407330f729Sjoerg /// directory or a framework. 417330f729Sjoerg DirectoryEntryRef Dir; 427330f729Sjoerg 437330f729Sjoerg /// Map - This is the HeaderMap if this is a headermap lookup. 447330f729Sjoerg /// 457330f729Sjoerg const HeaderMap *Map; 467330f729Sjoerg DLU(DirectoryEntryRef Dir)477330f729Sjoerg DLU(DirectoryEntryRef Dir) : Dir(Dir) {} DLU(const HeaderMap * Map)487330f729Sjoerg DLU(const HeaderMap *Map) : Map(Map) {} 497330f729Sjoerg } u; 507330f729Sjoerg 517330f729Sjoerg /// DirCharacteristic - The type of directory this is: this is an instance of 527330f729Sjoerg /// SrcMgr::CharacteristicKind. 537330f729Sjoerg unsigned DirCharacteristic : 2; 547330f729Sjoerg 557330f729Sjoerg /// LookupType - This indicates whether this DirectoryLookup object is a 567330f729Sjoerg /// normal directory, a framework, or a headermap. 577330f729Sjoerg unsigned LookupType : 2; 587330f729Sjoerg 597330f729Sjoerg /// Whether this is a header map used when building a framework. 607330f729Sjoerg unsigned IsIndexHeaderMap : 1; 617330f729Sjoerg 627330f729Sjoerg /// Whether we've performed an exhaustive search for module maps 637330f729Sjoerg /// within the subdirectories of this directory. 647330f729Sjoerg unsigned SearchedAllModuleMaps : 1; 657330f729Sjoerg 667330f729Sjoerg public: 677330f729Sjoerg /// This ctor *does not take ownership* of 'Dir'. DirectoryLookup(DirectoryEntryRef Dir,SrcMgr::CharacteristicKind DT,bool isFramework)687330f729Sjoerg DirectoryLookup(DirectoryEntryRef Dir, SrcMgr::CharacteristicKind DT, 697330f729Sjoerg bool isFramework) 707330f729Sjoerg : u(Dir), DirCharacteristic(DT), 717330f729Sjoerg LookupType(isFramework ? LT_Framework : LT_NormalDir), 727330f729Sjoerg IsIndexHeaderMap(false), SearchedAllModuleMaps(false) {} 737330f729Sjoerg 747330f729Sjoerg /// This ctor *does not take ownership* of 'Map'. DirectoryLookup(const HeaderMap * Map,SrcMgr::CharacteristicKind DT,bool isIndexHeaderMap)757330f729Sjoerg DirectoryLookup(const HeaderMap *Map, SrcMgr::CharacteristicKind DT, 767330f729Sjoerg bool isIndexHeaderMap) 777330f729Sjoerg : u(Map), DirCharacteristic(DT), LookupType(LT_HeaderMap), 787330f729Sjoerg IsIndexHeaderMap(isIndexHeaderMap), SearchedAllModuleMaps(false) {} 797330f729Sjoerg 807330f729Sjoerg /// getLookupType - Return the kind of directory lookup that this is: either a 817330f729Sjoerg /// normal directory, a framework path, or a HeaderMap. getLookupType()827330f729Sjoerg LookupType_t getLookupType() const { return (LookupType_t)LookupType; } 837330f729Sjoerg 847330f729Sjoerg /// getName - Return the directory or filename corresponding to this lookup 857330f729Sjoerg /// object. 867330f729Sjoerg StringRef getName() const; 877330f729Sjoerg 887330f729Sjoerg /// getDir - Return the directory that this entry refers to. 897330f729Sjoerg /// getDir()907330f729Sjoerg const DirectoryEntry *getDir() const { 917330f729Sjoerg return isNormalDir() ? &u.Dir.getDirEntry() : nullptr; 927330f729Sjoerg } 937330f729Sjoerg 947330f729Sjoerg /// getFrameworkDir - Return the directory that this framework refers to. 957330f729Sjoerg /// getFrameworkDir()967330f729Sjoerg const DirectoryEntry *getFrameworkDir() const { 977330f729Sjoerg return isFramework() ? &u.Dir.getDirEntry() : nullptr; 987330f729Sjoerg } 997330f729Sjoerg getFrameworkDirRef()1007330f729Sjoerg Optional<DirectoryEntryRef> getFrameworkDirRef() const { 1017330f729Sjoerg return isFramework() ? Optional<DirectoryEntryRef>(u.Dir) : None; 1027330f729Sjoerg } 1037330f729Sjoerg 1047330f729Sjoerg /// getHeaderMap - Return the directory that this entry refers to. 1057330f729Sjoerg /// getHeaderMap()1067330f729Sjoerg const HeaderMap *getHeaderMap() const { 1077330f729Sjoerg return isHeaderMap() ? u.Map : nullptr; 1087330f729Sjoerg } 1097330f729Sjoerg 1107330f729Sjoerg /// isNormalDir - Return true if this is a normal directory, not a header map. isNormalDir()1117330f729Sjoerg bool isNormalDir() const { return getLookupType() == LT_NormalDir; } 1127330f729Sjoerg 1137330f729Sjoerg /// isFramework - True if this is a framework directory. 1147330f729Sjoerg /// isFramework()1157330f729Sjoerg bool isFramework() const { return getLookupType() == LT_Framework; } 1167330f729Sjoerg 1177330f729Sjoerg /// isHeaderMap - Return true if this is a header map, not a normal directory. isHeaderMap()1187330f729Sjoerg bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; } 1197330f729Sjoerg 1207330f729Sjoerg /// Determine whether we have already searched this entire 1217330f729Sjoerg /// directory for module maps. haveSearchedAllModuleMaps()1227330f729Sjoerg bool haveSearchedAllModuleMaps() const { return SearchedAllModuleMaps; } 1237330f729Sjoerg 1247330f729Sjoerg /// Specify whether we have already searched all of the subdirectories 1257330f729Sjoerg /// for module maps. setSearchedAllModuleMaps(bool SAMM)1267330f729Sjoerg void setSearchedAllModuleMaps(bool SAMM) { 1277330f729Sjoerg SearchedAllModuleMaps = SAMM; 1287330f729Sjoerg } 1297330f729Sjoerg 1307330f729Sjoerg /// DirCharacteristic - The type of directory this is, one of the DirType enum 1317330f729Sjoerg /// values. getDirCharacteristic()1327330f729Sjoerg SrcMgr::CharacteristicKind getDirCharacteristic() const { 1337330f729Sjoerg return (SrcMgr::CharacteristicKind)DirCharacteristic; 1347330f729Sjoerg } 1357330f729Sjoerg 1367330f729Sjoerg /// Whether this describes a system header directory. isSystemHeaderDirectory()1377330f729Sjoerg bool isSystemHeaderDirectory() const { 1387330f729Sjoerg return getDirCharacteristic() != SrcMgr::C_User; 1397330f729Sjoerg } 1407330f729Sjoerg 1417330f729Sjoerg /// Whether this header map is building a framework or not. isIndexHeaderMap()1427330f729Sjoerg bool isIndexHeaderMap() const { 1437330f729Sjoerg return isHeaderMap() && IsIndexHeaderMap; 1447330f729Sjoerg } 1457330f729Sjoerg 1467330f729Sjoerg /// LookupFile - Lookup the specified file in this search path, returning it 1477330f729Sjoerg /// if it exists or returning null if not. 1487330f729Sjoerg /// 1497330f729Sjoerg /// \param Filename The file to look up relative to the search paths. 1507330f729Sjoerg /// 1517330f729Sjoerg /// \param HS The header search instance to search with. 1527330f729Sjoerg /// 1537330f729Sjoerg /// \param IncludeLoc the source location of the #include or #import 1547330f729Sjoerg /// directive. 1557330f729Sjoerg /// 1567330f729Sjoerg /// \param SearchPath If not NULL, will be set to the search path relative 1577330f729Sjoerg /// to which the file was found. 1587330f729Sjoerg /// 1597330f729Sjoerg /// \param RelativePath If not NULL, will be set to the path relative to 1607330f729Sjoerg /// SearchPath at which the file was found. This only differs from the 1617330f729Sjoerg /// Filename for framework includes. 1627330f729Sjoerg /// 1637330f729Sjoerg /// \param RequestingModule The module in which the lookup was performed. 1647330f729Sjoerg /// 1657330f729Sjoerg /// \param SuggestedModule If non-null, and the file found is semantically 1667330f729Sjoerg /// part of a known module, this will be set to the module that should 1677330f729Sjoerg /// be imported instead of preprocessing/parsing the file found. 1687330f729Sjoerg /// 1697330f729Sjoerg /// \param [out] InUserSpecifiedSystemFramework If the file is found, 1707330f729Sjoerg /// set to true if the file is located in a framework that has been 1717330f729Sjoerg /// user-specified to be treated as a system framework. 1727330f729Sjoerg /// 1737330f729Sjoerg /// \param [out] IsFrameworkFound For a framework directory set to true if 1747330f729Sjoerg /// specified '.framework' directory is found. 1757330f729Sjoerg /// 1767330f729Sjoerg /// \param [out] MappedName if this is a headermap which maps the filename to 1777330f729Sjoerg /// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this 1787330f729Sjoerg /// vector and point Filename to it. 1797330f729Sjoerg Optional<FileEntryRef> 1807330f729Sjoerg LookupFile(StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc, 1817330f729Sjoerg SmallVectorImpl<char> *SearchPath, 1827330f729Sjoerg SmallVectorImpl<char> *RelativePath, Module *RequestingModule, 1837330f729Sjoerg ModuleMap::KnownHeader *SuggestedModule, 1847330f729Sjoerg bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound, 1857330f729Sjoerg bool &IsInHeaderMap, SmallVectorImpl<char> &MappedName) const; 1867330f729Sjoerg 1877330f729Sjoerg private: 1887330f729Sjoerg Optional<FileEntryRef> DoFrameworkLookup( 1897330f729Sjoerg StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath, 1907330f729Sjoerg SmallVectorImpl<char> *RelativePath, Module *RequestingModule, 1917330f729Sjoerg ModuleMap::KnownHeader *SuggestedModule, 1927330f729Sjoerg bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound) const; 1937330f729Sjoerg }; 1947330f729Sjoerg 1957330f729Sjoerg } // end namespace clang 1967330f729Sjoerg 1977330f729Sjoerg #endif 198