10b57cec5SDimitry Andric //===--- DirectoryLookup.h - Info for searching for headers -----*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines the DirectoryLookup interface. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_CLANG_LEX_DIRECTORYLOOKUP_H 140b57cec5SDimitry Andric #define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "clang/Basic/LLVM.h" 175ffd83dbSDimitry Andric #include "clang/Basic/FileManager.h" 180b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h" 190b57cec5SDimitry Andric #include "clang/Lex/ModuleMap.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace clang { 220b57cec5SDimitry Andric class HeaderMap; 230b57cec5SDimitry Andric class HeaderSearch; 240b57cec5SDimitry Andric class Module; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric /// DirectoryLookup - This class represents one entry in the search list that 270b57cec5SDimitry Andric /// specifies the search order for directories in \#include directives. It 280b57cec5SDimitry Andric /// represents either a directory, a framework, or a headermap. 290b57cec5SDimitry Andric /// 300b57cec5SDimitry Andric class DirectoryLookup { 310b57cec5SDimitry Andric public: 320b57cec5SDimitry Andric enum LookupType_t { 330b57cec5SDimitry Andric LT_NormalDir, 340b57cec5SDimitry Andric LT_Framework, 350b57cec5SDimitry Andric LT_HeaderMap 360b57cec5SDimitry Andric }; 370b57cec5SDimitry Andric private: 38a7dea167SDimitry Andric union DLU { // This union is discriminated by isHeaderMap. 390b57cec5SDimitry Andric /// Dir - This is the actual directory that we're referring to for a normal 400b57cec5SDimitry Andric /// directory or a framework. 41a7dea167SDimitry Andric DirectoryEntryRef Dir; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric /// Map - This is the HeaderMap if this is a headermap lookup. 440b57cec5SDimitry Andric /// 450b57cec5SDimitry Andric const HeaderMap *Map; 46a7dea167SDimitry Andric DLU(DirectoryEntryRef Dir)47a7dea167SDimitry Andric DLU(DirectoryEntryRef Dir) : Dir(Dir) {} DLU(const HeaderMap * Map)48a7dea167SDimitry Andric DLU(const HeaderMap *Map) : Map(Map) {} 490b57cec5SDimitry Andric } u; 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric /// DirCharacteristic - The type of directory this is: this is an instance of 520b57cec5SDimitry Andric /// SrcMgr::CharacteristicKind. 535f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(SrcMgr::CharacteristicKind) 54bdd1243dSDimitry Andric unsigned DirCharacteristic : 3; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric /// LookupType - This indicates whether this DirectoryLookup object is a 570b57cec5SDimitry Andric /// normal directory, a framework, or a headermap. 585f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(LookupType_t) 590b57cec5SDimitry Andric unsigned LookupType : 2; 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric /// Whether this is a header map used when building a framework. 625f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool) 630b57cec5SDimitry Andric unsigned IsIndexHeaderMap : 1; 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric /// Whether we've performed an exhaustive search for module maps 660b57cec5SDimitry Andric /// within the subdirectories of this directory. 675f757f3fSDimitry Andric LLVM_PREFERRED_TYPE(bool) 680b57cec5SDimitry Andric unsigned SearchedAllModuleMaps : 1; 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric public: 71a7dea167SDimitry Andric /// This ctor *does not take ownership* of 'Dir'. DirectoryLookup(DirectoryEntryRef Dir,SrcMgr::CharacteristicKind DT,bool isFramework)72a7dea167SDimitry Andric DirectoryLookup(DirectoryEntryRef Dir, SrcMgr::CharacteristicKind DT, 730b57cec5SDimitry Andric bool isFramework) 74a7dea167SDimitry Andric : u(Dir), DirCharacteristic(DT), 750b57cec5SDimitry Andric LookupType(isFramework ? LT_Framework : LT_NormalDir), 76a7dea167SDimitry Andric IsIndexHeaderMap(false), SearchedAllModuleMaps(false) {} 770b57cec5SDimitry Andric 78a7dea167SDimitry Andric /// This ctor *does not take ownership* of 'Map'. DirectoryLookup(const HeaderMap * Map,SrcMgr::CharacteristicKind DT,bool isIndexHeaderMap)79a7dea167SDimitry Andric DirectoryLookup(const HeaderMap *Map, SrcMgr::CharacteristicKind DT, 800b57cec5SDimitry Andric bool isIndexHeaderMap) 81a7dea167SDimitry Andric : u(Map), DirCharacteristic(DT), LookupType(LT_HeaderMap), 82a7dea167SDimitry Andric IsIndexHeaderMap(isIndexHeaderMap), SearchedAllModuleMaps(false) {} 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric /// getLookupType - Return the kind of directory lookup that this is: either a 850b57cec5SDimitry Andric /// normal directory, a framework path, or a HeaderMap. getLookupType()860b57cec5SDimitry Andric LookupType_t getLookupType() const { return (LookupType_t)LookupType; } 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric /// getName - Return the directory or filename corresponding to this lookup 890b57cec5SDimitry Andric /// object. 900b57cec5SDimitry Andric StringRef getName() const; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric /// getDir - Return the directory that this entry refers to. 930b57cec5SDimitry Andric /// getDir()940b57cec5SDimitry Andric const DirectoryEntry *getDir() const { 95a7dea167SDimitry Andric return isNormalDir() ? &u.Dir.getDirEntry() : nullptr; 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric getDirRef()98bdd1243dSDimitry Andric OptionalDirectoryEntryRef getDirRef() const { 99bdd1243dSDimitry Andric return isNormalDir() ? OptionalDirectoryEntryRef(u.Dir) : std::nullopt; 10081ad6265SDimitry Andric } 10181ad6265SDimitry Andric 1020b57cec5SDimitry Andric /// getFrameworkDir - Return the directory that this framework refers to. 1030b57cec5SDimitry Andric /// getFrameworkDir()1040b57cec5SDimitry Andric const DirectoryEntry *getFrameworkDir() const { 105a7dea167SDimitry Andric return isFramework() ? &u.Dir.getDirEntry() : nullptr; 106a7dea167SDimitry Andric } 107a7dea167SDimitry Andric getFrameworkDirRef()108bdd1243dSDimitry Andric OptionalDirectoryEntryRef getFrameworkDirRef() const { 109bdd1243dSDimitry Andric return isFramework() ? OptionalDirectoryEntryRef(u.Dir) : std::nullopt; 1100b57cec5SDimitry Andric } 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric /// getHeaderMap - Return the directory that this entry refers to. 1130b57cec5SDimitry Andric /// getHeaderMap()1140b57cec5SDimitry Andric const HeaderMap *getHeaderMap() const { 1150b57cec5SDimitry Andric return isHeaderMap() ? u.Map : nullptr; 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric /// isNormalDir - Return true if this is a normal directory, not a header map. isNormalDir()1190b57cec5SDimitry Andric bool isNormalDir() const { return getLookupType() == LT_NormalDir; } 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric /// isFramework - True if this is a framework directory. 1220b57cec5SDimitry Andric /// isFramework()1230b57cec5SDimitry Andric bool isFramework() const { return getLookupType() == LT_Framework; } 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric /// isHeaderMap - Return true if this is a header map, not a normal directory. isHeaderMap()1260b57cec5SDimitry Andric bool isHeaderMap() const { return getLookupType() == LT_HeaderMap; } 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric /// Determine whether we have already searched this entire 1290b57cec5SDimitry Andric /// directory for module maps. haveSearchedAllModuleMaps()1300b57cec5SDimitry Andric bool haveSearchedAllModuleMaps() const { return SearchedAllModuleMaps; } 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric /// Specify whether we have already searched all of the subdirectories 1330b57cec5SDimitry Andric /// for module maps. setSearchedAllModuleMaps(bool SAMM)1340b57cec5SDimitry Andric void setSearchedAllModuleMaps(bool SAMM) { 1350b57cec5SDimitry Andric SearchedAllModuleMaps = SAMM; 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric /// DirCharacteristic - The type of directory this is, one of the DirType enum 1390b57cec5SDimitry Andric /// values. getDirCharacteristic()1400b57cec5SDimitry Andric SrcMgr::CharacteristicKind getDirCharacteristic() const { 1410b57cec5SDimitry Andric return (SrcMgr::CharacteristicKind)DirCharacteristic; 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric /// Whether this describes a system header directory. isSystemHeaderDirectory()1450b57cec5SDimitry Andric bool isSystemHeaderDirectory() const { 1460b57cec5SDimitry Andric return getDirCharacteristic() != SrcMgr::C_User; 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric /// Whether this header map is building a framework or not. isIndexHeaderMap()1500b57cec5SDimitry Andric bool isIndexHeaderMap() const { 1510b57cec5SDimitry Andric return isHeaderMap() && IsIndexHeaderMap; 1520b57cec5SDimitry Andric } 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric /// LookupFile - Lookup the specified file in this search path, returning it 1550b57cec5SDimitry Andric /// if it exists or returning null if not. 1560b57cec5SDimitry Andric /// 1570b57cec5SDimitry Andric /// \param Filename The file to look up relative to the search paths. 1580b57cec5SDimitry Andric /// 1590b57cec5SDimitry Andric /// \param HS The header search instance to search with. 1600b57cec5SDimitry Andric /// 1610b57cec5SDimitry Andric /// \param IncludeLoc the source location of the #include or #import 1620b57cec5SDimitry Andric /// directive. 1630b57cec5SDimitry Andric /// 1640b57cec5SDimitry Andric /// \param SearchPath If not NULL, will be set to the search path relative 1650b57cec5SDimitry Andric /// to which the file was found. 1660b57cec5SDimitry Andric /// 1670b57cec5SDimitry Andric /// \param RelativePath If not NULL, will be set to the path relative to 1680b57cec5SDimitry Andric /// SearchPath at which the file was found. This only differs from the 1690b57cec5SDimitry Andric /// Filename for framework includes. 1700b57cec5SDimitry Andric /// 1710b57cec5SDimitry Andric /// \param RequestingModule The module in which the lookup was performed. 1720b57cec5SDimitry Andric /// 1730b57cec5SDimitry Andric /// \param SuggestedModule If non-null, and the file found is semantically 1740b57cec5SDimitry Andric /// part of a known module, this will be set to the module that should 1750b57cec5SDimitry Andric /// be imported instead of preprocessing/parsing the file found. 1760b57cec5SDimitry Andric /// 1770b57cec5SDimitry Andric /// \param [out] InUserSpecifiedSystemFramework If the file is found, 1780b57cec5SDimitry Andric /// set to true if the file is located in a framework that has been 1790b57cec5SDimitry Andric /// user-specified to be treated as a system framework. 1800b57cec5SDimitry Andric /// 1810b57cec5SDimitry Andric /// \param [out] IsFrameworkFound For a framework directory set to true if 1820b57cec5SDimitry Andric /// specified '.framework' directory is found. 1830b57cec5SDimitry Andric /// 1840b57cec5SDimitry Andric /// \param [out] MappedName if this is a headermap which maps the filename to 1850b57cec5SDimitry Andric /// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this 1860b57cec5SDimitry Andric /// vector and point Filename to it. 187bdd1243dSDimitry Andric OptionalFileEntryRef 188a7dea167SDimitry Andric LookupFile(StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc, 1890b57cec5SDimitry Andric SmallVectorImpl<char> *SearchPath, 190a7dea167SDimitry Andric SmallVectorImpl<char> *RelativePath, Module *RequestingModule, 1910b57cec5SDimitry Andric ModuleMap::KnownHeader *SuggestedModule, 192a7dea167SDimitry Andric bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound, 193bdd1243dSDimitry Andric bool &IsInHeaderMap, SmallVectorImpl<char> &MappedName, 194bdd1243dSDimitry Andric bool OpenFile = true) const; 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric private: 197bdd1243dSDimitry Andric OptionalFileEntryRef DoFrameworkLookup( 198a7dea167SDimitry Andric StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath, 199a7dea167SDimitry Andric SmallVectorImpl<char> *RelativePath, Module *RequestingModule, 2000b57cec5SDimitry Andric ModuleMap::KnownHeader *SuggestedModule, 201a7dea167SDimitry Andric bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound) const; 2020b57cec5SDimitry Andric }; 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric } // end namespace clang 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric #endif 207