Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:56

0001 //===- HeaderSearch.h - Resolve Header File Locations -----------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the HeaderSearch interface.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_CLANG_LEX_HEADERSEARCH_H
0014 #define LLVM_CLANG_LEX_HEADERSEARCH_H
0015 
0016 #include "clang/Basic/SourceLocation.h"
0017 #include "clang/Basic/SourceManager.h"
0018 #include "clang/Lex/DirectoryLookup.h"
0019 #include "clang/Lex/ExternalPreprocessorSource.h"
0020 #include "clang/Lex/HeaderMap.h"
0021 #include "clang/Lex/ModuleMap.h"
0022 #include "llvm/ADT/ArrayRef.h"
0023 #include "llvm/ADT/DenseMap.h"
0024 #include "llvm/ADT/SmallString.h"
0025 #include "llvm/ADT/StringMap.h"
0026 #include "llvm/ADT/StringRef.h"
0027 #include "llvm/ADT/StringSet.h"
0028 #include "llvm/Support/Allocator.h"
0029 #include <cassert>
0030 #include <cstddef>
0031 #include <memory>
0032 #include <string>
0033 #include <utility>
0034 #include <vector>
0035 
0036 namespace llvm {
0037 
0038 class Triple;
0039 
0040 } // namespace llvm
0041 
0042 namespace clang {
0043 
0044 class DiagnosticsEngine;
0045 class DirectoryEntry;
0046 class ExternalPreprocessorSource;
0047 class FileEntry;
0048 class FileManager;
0049 class HeaderSearch;
0050 class HeaderSearchOptions;
0051 class IdentifierInfo;
0052 class LangOptions;
0053 class Module;
0054 class Preprocessor;
0055 class TargetInfo;
0056 
0057 /// The preprocessor keeps track of this information for each
0058 /// file that is \#included.
0059 struct HeaderFileInfo {
0060   // TODO: Whether the file was included is not a property of the file itself.
0061   // It's a preprocessor state, move it there.
0062   /// True if this file has been included (or imported) **locally**.
0063   LLVM_PREFERRED_TYPE(bool)
0064   unsigned IsLocallyIncluded : 1;
0065 
0066   // TODO: Whether the file was imported is not a property of the file itself.
0067   // It's a preprocessor state, move it there.
0068   /// True if this is a \#import'd file.
0069   LLVM_PREFERRED_TYPE(bool)
0070   unsigned isImport : 1;
0071 
0072   /// True if this is a \#pragma once file.
0073   LLVM_PREFERRED_TYPE(bool)
0074   unsigned isPragmaOnce : 1;
0075 
0076   /// Keep track of whether this is a system header, and if so,
0077   /// whether it is C++ clean or not.  This can be set by the include paths or
0078   /// by \#pragma gcc system_header.  This is an instance of
0079   /// SrcMgr::CharacteristicKind.
0080   LLVM_PREFERRED_TYPE(SrcMgr::CharacteristicKind)
0081   unsigned DirInfo : 3;
0082 
0083   /// Whether this header file info was supplied by an external source,
0084   /// and has not changed since.
0085   LLVM_PREFERRED_TYPE(bool)
0086   unsigned External : 1;
0087 
0088   /// Whether this header is part of and built with a module.  i.e. it is listed
0089   /// in a module map, and is not `excluded` or `textual`. (same meaning as
0090   /// `ModuleMap::isModular()`).
0091   LLVM_PREFERRED_TYPE(bool)
0092   unsigned isModuleHeader : 1;
0093 
0094   /// Whether this header is a `textual header` in a module. If a header is
0095   /// textual in one module and normal in another module, this bit will not be
0096   /// set, only `isModuleHeader`.
0097   LLVM_PREFERRED_TYPE(bool)
0098   unsigned isTextualModuleHeader : 1;
0099 
0100   /// Whether this header is part of the module that we are building, even if it
0101   /// doesn't build with the module. i.e. this will include `excluded` and
0102   /// `textual` headers as well as normal headers.
0103   LLVM_PREFERRED_TYPE(bool)
0104   unsigned isCompilingModuleHeader : 1;
0105 
0106   /// Whether this structure is considered to already have been
0107   /// "resolved", meaning that it was loaded from the external source.
0108   LLVM_PREFERRED_TYPE(bool)
0109   unsigned Resolved : 1;
0110 
0111   /// Whether this file has been looked up as a header.
0112   LLVM_PREFERRED_TYPE(bool)
0113   unsigned IsValid : 1;
0114 
0115   /// If this file has a \#ifndef XXX (or equivalent) guard that
0116   /// protects the entire contents of the file, this is the identifier
0117   /// for the macro that controls whether or not it has any effect.
0118   ///
0119   /// Note: Most clients should use getControllingMacro() to access
0120   /// the controlling macro of this header, since
0121   /// getControllingMacro() is able to load a controlling macro from
0122   /// external storage.
0123   LazyIdentifierInfoPtr LazyControllingMacro;
0124 
0125   HeaderFileInfo()
0126       : IsLocallyIncluded(false), isImport(false), isPragmaOnce(false),
0127         DirInfo(SrcMgr::C_User), External(false), isModuleHeader(false),
0128         isTextualModuleHeader(false), isCompilingModuleHeader(false),
0129         Resolved(false), IsValid(false) {}
0130 
0131   /// Retrieve the controlling macro for this header file, if
0132   /// any.
0133   const IdentifierInfo *
0134   getControllingMacro(ExternalPreprocessorSource *External);
0135 
0136   /// Update the module membership bits based on the header role.
0137   ///
0138   /// isModuleHeader will potentially be set, but not cleared.
0139   /// isTextualModuleHeader will be set or cleared based on the role update.
0140   void mergeModuleMembership(ModuleMap::ModuleHeaderRole Role);
0141 };
0142 
0143 static_assert(sizeof(HeaderFileInfo) <= 16);
0144 
0145 /// An external source of header file information, which may supply
0146 /// information about header files already included.
0147 class ExternalHeaderFileInfoSource {
0148 public:
0149   virtual ~ExternalHeaderFileInfoSource();
0150 
0151   /// Retrieve the header file information for the given file entry.
0152   ///
0153   /// \returns Header file information for the given file entry, with the
0154   /// \c External bit set. If the file entry is not known, return a
0155   /// default-constructed \c HeaderFileInfo.
0156   virtual HeaderFileInfo GetHeaderFileInfo(FileEntryRef FE) = 0;
0157 };
0158 
0159 /// This structure is used to record entries in our framework cache.
0160 struct FrameworkCacheEntry {
0161   /// The directory entry which should be used for the cached framework.
0162   OptionalDirectoryEntryRef Directory;
0163 
0164   /// Whether this framework has been "user-specified" to be treated as if it
0165   /// were a system framework (even if it was found outside a system framework
0166   /// directory).
0167   bool IsUserSpecifiedSystemFramework;
0168 };
0169 
0170 namespace detail {
0171 template <bool Const, typename T>
0172 using Qualified = std::conditional_t<Const, const T, T>;
0173 
0174 /// Forward iterator over the search directories of \c HeaderSearch.
0175 template <bool IsConst>
0176 struct SearchDirIteratorImpl
0177     : llvm::iterator_facade_base<SearchDirIteratorImpl<IsConst>,
0178                                  std::forward_iterator_tag,
0179                                  Qualified<IsConst, DirectoryLookup>> {
0180   /// Const -> non-const iterator conversion.
0181   template <typename Enable = std::enable_if<IsConst, bool>>
0182   SearchDirIteratorImpl(const SearchDirIteratorImpl<false> &Other)
0183       : HS(Other.HS), Idx(Other.Idx) {}
0184 
0185   SearchDirIteratorImpl(const SearchDirIteratorImpl &) = default;
0186 
0187   SearchDirIteratorImpl &operator=(const SearchDirIteratorImpl &) = default;
0188 
0189   bool operator==(const SearchDirIteratorImpl &RHS) const {
0190     return HS == RHS.HS && Idx == RHS.Idx;
0191   }
0192 
0193   SearchDirIteratorImpl &operator++() {
0194     assert(*this && "Invalid iterator.");
0195     ++Idx;
0196     return *this;
0197   }
0198 
0199   Qualified<IsConst, DirectoryLookup> &operator*() const {
0200     assert(*this && "Invalid iterator.");
0201     return HS->SearchDirs[Idx];
0202   }
0203 
0204   /// Creates an invalid iterator.
0205   SearchDirIteratorImpl(std::nullptr_t) : HS(nullptr), Idx(0) {}
0206 
0207   /// Checks whether the iterator is valid.
0208   explicit operator bool() const { return HS != nullptr; }
0209 
0210 private:
0211   /// The parent \c HeaderSearch. This is \c nullptr for invalid iterator.
0212   Qualified<IsConst, HeaderSearch> *HS;
0213 
0214   /// The index of the current element.
0215   size_t Idx;
0216 
0217   /// The constructor that creates a valid iterator.
0218   SearchDirIteratorImpl(Qualified<IsConst, HeaderSearch> &HS, size_t Idx)
0219       : HS(&HS), Idx(Idx) {}
0220 
0221   /// Only HeaderSearch is allowed to instantiate valid iterators.
0222   friend HeaderSearch;
0223 
0224   /// Enables const -> non-const conversion.
0225   friend SearchDirIteratorImpl<!IsConst>;
0226 };
0227 } // namespace detail
0228 
0229 using ConstSearchDirIterator = detail::SearchDirIteratorImpl<true>;
0230 using SearchDirIterator = detail::SearchDirIteratorImpl<false>;
0231 
0232 using ConstSearchDirRange = llvm::iterator_range<ConstSearchDirIterator>;
0233 using SearchDirRange = llvm::iterator_range<SearchDirIterator>;
0234 
0235 /// Encapsulates the information needed to find the file referenced
0236 /// by a \#include or \#include_next, (sub-)framework lookup, etc.
0237 class HeaderSearch {
0238   friend class DirectoryLookup;
0239 
0240   friend ConstSearchDirIterator;
0241   friend SearchDirIterator;
0242 
0243   /// Header-search options used to initialize this header search.
0244   std::shared_ptr<HeaderSearchOptions> HSOpts;
0245 
0246   /// Mapping from SearchDir to HeaderSearchOptions::UserEntries indices.
0247   llvm::DenseMap<unsigned, unsigned> SearchDirToHSEntry;
0248 
0249   DiagnosticsEngine &Diags;
0250   FileManager &FileMgr;
0251 
0252   /// \#include search path information.  Requests for \#include "x" search the
0253   /// directory of the \#including file first, then each directory in SearchDirs
0254   /// consecutively. Requests for <x> search the current dir first, then each
0255   /// directory in SearchDirs, starting at AngledDirIdx, consecutively.
0256   std::vector<DirectoryLookup> SearchDirs;
0257   /// Whether the DirectoryLookup at the corresponding index in SearchDirs has
0258   /// been successfully used to lookup a file.
0259   std::vector<bool> SearchDirsUsage;
0260   unsigned AngledDirIdx = 0;
0261   unsigned SystemDirIdx = 0;
0262 
0263   /// Maps HeaderMap keys to SearchDir indices. When HeaderMaps are used
0264   /// heavily, SearchDirs can start with thousands of HeaderMaps, so this Index
0265   /// lets us avoid scanning them all to find a match.
0266   llvm::StringMap<unsigned, llvm::BumpPtrAllocator> SearchDirHeaderMapIndex;
0267 
0268   /// The index of the first SearchDir that isn't a header map.
0269   unsigned FirstNonHeaderMapSearchDirIdx = 0;
0270 
0271   /// \#include prefixes for which the 'system header' property is
0272   /// overridden.
0273   ///
0274   /// For a \#include "x" or \#include \<x> directive, the last string in this
0275   /// list which is a prefix of 'x' determines whether the file is treated as
0276   /// a system header.
0277   std::vector<std::pair<std::string, bool>> SystemHeaderPrefixes;
0278 
0279   /// The hash used for module cache paths.
0280   std::string ModuleHash;
0281 
0282   /// The path to the module cache.
0283   std::string ModuleCachePath;
0284 
0285   /// All of the preprocessor-specific data about files that are
0286   /// included, indexed by the FileEntry's UID.
0287   mutable std::vector<HeaderFileInfo> FileInfo;
0288 
0289   /// Keeps track of each lookup performed by LookupFile.
0290   struct LookupFileCacheInfo {
0291     // The requesting module for the lookup we cached.
0292     const Module *RequestingModule = nullptr;
0293 
0294     /// Starting search directory iterator that the cached search was performed
0295     /// from. If there is a hit and this value doesn't match the current query,
0296     /// the cache has to be ignored.
0297     ConstSearchDirIterator StartIt = nullptr;
0298 
0299     /// The search directory iterator that satisfied the query.
0300     ConstSearchDirIterator HitIt = nullptr;
0301 
0302     /// This is non-null if the original filename was mapped to a framework
0303     /// include via a headermap.
0304     const char *MappedName = nullptr;
0305 
0306     /// Default constructor -- Initialize all members with zero.
0307     LookupFileCacheInfo() = default;
0308 
0309     void reset(const Module *NewRequestingModule,
0310                ConstSearchDirIterator NewStartIt) {
0311       RequestingModule = NewRequestingModule;
0312       StartIt = NewStartIt;
0313       MappedName = nullptr;
0314     }
0315   };
0316   llvm::StringMap<LookupFileCacheInfo, llvm::BumpPtrAllocator> LookupFileCache;
0317 
0318   /// Collection mapping a framework or subframework
0319   /// name like "Carbon" to the Carbon.framework directory.
0320   llvm::StringMap<FrameworkCacheEntry, llvm::BumpPtrAllocator> FrameworkMap;
0321 
0322   /// Maps include file names (including the quotes or
0323   /// angle brackets) to other include file names.  This is used to support the
0324   /// include_alias pragma for Microsoft compatibility.
0325   using IncludeAliasMap =
0326       llvm::StringMap<std::string, llvm::BumpPtrAllocator>;
0327   std::unique_ptr<IncludeAliasMap> IncludeAliases;
0328 
0329   /// This is a mapping from FileEntry -> HeaderMap, uniquing headermaps.
0330   std::vector<std::pair<FileEntryRef, std::unique_ptr<HeaderMap>>> HeaderMaps;
0331 
0332   /// The mapping between modules and headers.
0333   mutable ModuleMap ModMap;
0334 
0335   /// Describes whether a given directory has a module map in it.
0336   llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap;
0337 
0338   /// Set of module map files we've already loaded, and a flag indicating
0339   /// whether they were valid or not.
0340   llvm::DenseMap<const FileEntry *, bool> LoadedModuleMaps;
0341 
0342   // A map of discovered headers with their associated include file name.
0343   llvm::DenseMap<const FileEntry *, llvm::SmallString<64>> IncludeNames;
0344 
0345   /// Uniqued set of framework names, which is used to track which
0346   /// headers were included as framework headers.
0347   llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
0348 
0349   /// Entity used to resolve the identifier IDs of controlling
0350   /// macros into IdentifierInfo pointers, and keep the identifire up to date,
0351   /// as needed.
0352   ExternalPreprocessorSource *ExternalLookup = nullptr;
0353 
0354   /// Entity used to look up stored header file information.
0355   ExternalHeaderFileInfoSource *ExternalSource = nullptr;
0356 
0357   /// Scan all of the header maps at the beginning of SearchDirs and
0358   /// map their keys to the SearchDir index of their header map.
0359   void indexInitialHeaderMaps();
0360 
0361 public:
0362   HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts,
0363                SourceManager &SourceMgr, DiagnosticsEngine &Diags,
0364                const LangOptions &LangOpts, const TargetInfo *Target);
0365   HeaderSearch(const HeaderSearch &) = delete;
0366   HeaderSearch &operator=(const HeaderSearch &) = delete;
0367 
0368   /// Retrieve the header-search options with which this header search
0369   /// was initialized.
0370   HeaderSearchOptions &getHeaderSearchOpts() const { return *HSOpts; }
0371 
0372   FileManager &getFileMgr() const { return FileMgr; }
0373 
0374   DiagnosticsEngine &getDiags() const { return Diags; }
0375 
0376   /// Interface for setting the file search paths.
0377   void SetSearchPaths(std::vector<DirectoryLookup> dirs, unsigned angledDirIdx,
0378                       unsigned systemDirIdx,
0379                       llvm::DenseMap<unsigned, unsigned> searchDirToHSEntry);
0380 
0381   /// Add an additional search path.
0382   void AddSearchPath(const DirectoryLookup &dir, bool isAngled);
0383 
0384   /// Add an additional system search path.
0385   void AddSystemSearchPath(const DirectoryLookup &dir) {
0386     SearchDirs.push_back(dir);
0387     SearchDirsUsage.push_back(false);
0388   }
0389 
0390   /// Set the list of system header prefixes.
0391   void SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string, bool>> P) {
0392     SystemHeaderPrefixes.assign(P.begin(), P.end());
0393   }
0394 
0395   /// Checks whether the map exists or not.
0396   bool HasIncludeAliasMap() const { return (bool)IncludeAliases; }
0397 
0398   /// Map the source include name to the dest include name.
0399   ///
0400   /// The Source should include the angle brackets or quotes, the dest
0401   /// should not.  This allows for distinction between <> and "" headers.
0402   void AddIncludeAlias(StringRef Source, StringRef Dest) {
0403     if (!IncludeAliases)
0404       IncludeAliases.reset(new IncludeAliasMap);
0405     (*IncludeAliases)[Source] = std::string(Dest);
0406   }
0407 
0408   /// Maps one header file name to a different header
0409   /// file name, for use with the include_alias pragma.  Note that the source
0410   /// file name should include the angle brackets or quotes.  Returns StringRef
0411   /// as null if the header cannot be mapped.
0412   StringRef MapHeaderToIncludeAlias(StringRef Source) {
0413     assert(IncludeAliases && "Trying to map headers when there's no map");
0414 
0415     // Do any filename replacements before anything else
0416     IncludeAliasMap::const_iterator Iter = IncludeAliases->find(Source);
0417     if (Iter != IncludeAliases->end())
0418       return Iter->second;
0419     return {};
0420   }
0421 
0422   /// Set the hash to use for module cache paths.
0423   void setModuleHash(StringRef Hash) { ModuleHash = std::string(Hash); }
0424 
0425   /// Set the path to the module cache.
0426   void setModuleCachePath(StringRef CachePath) {
0427     ModuleCachePath = std::string(CachePath);
0428   }
0429 
0430   /// Retrieve the module hash.
0431   StringRef getModuleHash() const { return ModuleHash; }
0432 
0433   /// Retrieve the path to the module cache.
0434   StringRef getModuleCachePath() const { return ModuleCachePath; }
0435 
0436   /// Consider modules when including files from this directory.
0437   void setDirectoryHasModuleMap(const DirectoryEntry* Dir) {
0438     DirectoryHasModuleMap[Dir] = true;
0439   }
0440 
0441   /// Forget everything we know about headers so far.
0442   void ClearFileInfo() {
0443     FileInfo.clear();
0444   }
0445 
0446   void SetExternalLookup(ExternalPreprocessorSource *EPS) {
0447     ExternalLookup = EPS;
0448   }
0449 
0450   ExternalPreprocessorSource *getExternalLookup() const {
0451     return ExternalLookup;
0452   }
0453 
0454   /// Set the external source of header information.
0455   void SetExternalSource(ExternalHeaderFileInfoSource *ES) {
0456     ExternalSource = ES;
0457   }
0458 
0459   /// Set the target information for the header search, if not
0460   /// already known.
0461   void setTarget(const TargetInfo &Target);
0462 
0463   /// Given a "foo" or \<foo> reference, look up the indicated file,
0464   /// return null on failure.
0465   ///
0466   /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
0467   /// the file was found in, or null if not applicable.
0468   ///
0469   /// \param IncludeLoc Used for diagnostics if valid.
0470   ///
0471   /// \param isAngled indicates whether the file reference is a <> reference.
0472   ///
0473   /// \param CurDir If non-null, the file was found in the specified directory
0474   /// search location.  This is used to implement \#include_next.
0475   ///
0476   /// \param Includers Indicates where the \#including file(s) are, in case
0477   /// relative searches are needed. In reverse order of inclusion.
0478   ///
0479   /// \param SearchPath If non-null, will be set to the search path relative
0480   /// to which the file was found. If the include path is absolute, SearchPath
0481   /// will be set to an empty string.
0482   ///
0483   /// \param RelativePath If non-null, will be set to the path relative to
0484   /// SearchPath at which the file was found. This only differs from the
0485   /// Filename for framework includes.
0486   ///
0487   /// \param SuggestedModule If non-null, and the file found is semantically
0488   /// part of a known module, this will be set to the module that should
0489   /// be imported instead of preprocessing/parsing the file found.
0490   ///
0491   /// \param IsMapped If non-null, and the search involved header maps, set to
0492   /// true.
0493   ///
0494   /// \param IsFrameworkFound If non-null, will be set to true if a framework is
0495   /// found in any of searched SearchDirs. Will be set to false if a framework
0496   /// is found only through header maps. Doesn't guarantee the requested file is
0497   /// found.
0498   OptionalFileEntryRef LookupFile(
0499       StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
0500       ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDir,
0501       ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
0502       SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
0503       Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
0504       bool *IsMapped, bool *IsFrameworkFound, bool SkipCache = false,
0505       bool BuildSystemModule = false, bool OpenFile = true,
0506       bool CacheFailures = true);
0507 
0508   /// Look up a subframework for the specified \#include file.
0509   ///
0510   /// For example, if \#include'ing <HIToolbox/HIToolbox.h> from
0511   /// within ".../Carbon.framework/Headers/Carbon.h", check to see if
0512   /// HIToolbox is a subframework within Carbon.framework.  If so, return
0513   /// the FileEntry for the designated file, otherwise return null.
0514   OptionalFileEntryRef LookupSubframeworkHeader(
0515       StringRef Filename, FileEntryRef ContextFileEnt,
0516       SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
0517       Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule);
0518 
0519   /// Look up the specified framework name in our framework cache.
0520   /// \returns The DirectoryEntry it is in if we know, null otherwise.
0521   FrameworkCacheEntry &LookupFrameworkCache(StringRef FWName) {
0522     return FrameworkMap[FWName];
0523   }
0524 
0525   /// Mark the specified file as a target of a \#include,
0526   /// \#include_next, or \#import directive.
0527   ///
0528   /// \return false if \#including the file will have no effect or true
0529   /// if we should include it.
0530   ///
0531   /// \param M The module to which `File` belongs (this should usually be the
0532   /// SuggestedModule returned by LookupFile/LookupSubframeworkHeader)
0533   bool ShouldEnterIncludeFile(Preprocessor &PP, FileEntryRef File,
0534                               bool isImport, bool ModulesEnabled, Module *M,
0535                               bool &IsFirstIncludeOfFile);
0536 
0537   /// Return whether the specified file is a normal header,
0538   /// a system header, or a C++ friendly system header.
0539   SrcMgr::CharacteristicKind getFileDirFlavor(FileEntryRef File) {
0540     if (const HeaderFileInfo *HFI = getExistingFileInfo(File))
0541       return (SrcMgr::CharacteristicKind)HFI->DirInfo;
0542     return (SrcMgr::CharacteristicKind)HeaderFileInfo().DirInfo;
0543   }
0544 
0545   /// Mark the specified file as a "once only" file due to
0546   /// \#pragma once.
0547   void MarkFileIncludeOnce(FileEntryRef File) {
0548     getFileInfo(File).isPragmaOnce = true;
0549   }
0550 
0551   /// Mark the specified file as a system header, e.g. due to
0552   /// \#pragma GCC system_header.
0553   void MarkFileSystemHeader(FileEntryRef File) {
0554     getFileInfo(File).DirInfo = SrcMgr::C_System;
0555   }
0556 
0557   /// Mark the specified file as part of a module.
0558   void MarkFileModuleHeader(FileEntryRef FE, ModuleMap::ModuleHeaderRole Role,
0559                             bool isCompilingModuleHeader);
0560 
0561   /// Mark the specified file as having a controlling macro.
0562   ///
0563   /// This is used by the multiple-include optimization to eliminate
0564   /// no-op \#includes.
0565   void SetFileControllingMacro(FileEntryRef File,
0566                                const IdentifierInfo *ControllingMacro) {
0567     getFileInfo(File).LazyControllingMacro = ControllingMacro;
0568   }
0569 
0570   /// Determine whether this file is intended to be safe from
0571   /// multiple inclusions, e.g., it has \#pragma once or a controlling
0572   /// macro.
0573   ///
0574   /// This routine does not consider the effect of \#import
0575   bool isFileMultipleIncludeGuarded(FileEntryRef File) const;
0576 
0577   /// Determine whether the given file is known to have ever been \#imported.
0578   bool hasFileBeenImported(FileEntryRef File) const {
0579     const HeaderFileInfo *FI = getExistingFileInfo(File);
0580     return FI && FI->isImport;
0581   }
0582 
0583   /// Determine which HeaderSearchOptions::UserEntries have been successfully
0584   /// used so far and mark their index with 'true' in the resulting bit vector.
0585   /// Note: implicit module maps don't contribute to entry usage.
0586   std::vector<bool> computeUserEntryUsage() const;
0587 
0588   /// Collect which HeaderSearchOptions::VFSOverlayFiles have been meaningfully
0589   /// used so far and mark their index with 'true' in the resulting bit vector.
0590   ///
0591   /// Note: this ignores VFSs that redirect non-affecting files such as unused
0592   /// modulemaps.
0593   std::vector<bool> collectVFSUsageAndClear() const;
0594 
0595   /// This method returns a HeaderMap for the specified
0596   /// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
0597   const HeaderMap *CreateHeaderMap(FileEntryRef FE);
0598 
0599   /// Get filenames for all registered header maps.
0600   void getHeaderMapFileNames(SmallVectorImpl<std::string> &Names) const;
0601 
0602   /// Retrieve the name of the cached module file that should be used
0603   /// to load the given module.
0604   ///
0605   /// \param Module The module whose module file name will be returned.
0606   ///
0607   /// \returns The name of the module file that corresponds to this module,
0608   /// or an empty string if this module does not correspond to any module file.
0609   std::string getCachedModuleFileName(Module *Module);
0610 
0611   /// Retrieve the name of the prebuilt module file that should be used
0612   /// to load a module with the given name.
0613   ///
0614   /// \param ModuleName The module whose module file name will be returned.
0615   ///
0616   /// \param FileMapOnly If true, then only look in the explicit module name
0617   //  to file name map and skip the directory search.
0618   ///
0619   /// \returns The name of the module file that corresponds to this module,
0620   /// or an empty string if this module does not correspond to any module file.
0621   std::string getPrebuiltModuleFileName(StringRef ModuleName,
0622                                         bool FileMapOnly = false);
0623 
0624   /// Retrieve the name of the prebuilt module file that should be used
0625   /// to load the given module.
0626   ///
0627   /// \param Module The module whose module file name will be returned.
0628   ///
0629   /// \returns The name of the module file that corresponds to this module,
0630   /// or an empty string if this module does not correspond to any module file.
0631   std::string getPrebuiltImplicitModuleFileName(Module *Module);
0632 
0633   /// Retrieve the name of the (to-be-)cached module file that should
0634   /// be used to load a module with the given name.
0635   ///
0636   /// \param ModuleName The module whose module file name will be returned.
0637   ///
0638   /// \param ModuleMapPath A path that when combined with \c ModuleName
0639   /// uniquely identifies this module. See Module::ModuleMap.
0640   ///
0641   /// \returns The name of the module file that corresponds to this module,
0642   /// or an empty string if this module does not correspond to any module file.
0643   std::string getCachedModuleFileName(StringRef ModuleName,
0644                                       StringRef ModuleMapPath);
0645 
0646   /// Lookup a module Search for a module with the given name.
0647   ///
0648   /// \param ModuleName The name of the module we're looking for.
0649   ///
0650   /// \param ImportLoc Location of the module include/import.
0651   ///
0652   /// \param AllowSearch Whether we are allowed to search in the various
0653   /// search directories to produce a module definition. If not, this lookup
0654   /// will only return an already-known module.
0655   ///
0656   /// \param AllowExtraModuleMapSearch Whether we allow to search modulemaps
0657   /// in subdirectories.
0658   ///
0659   /// \returns The module with the given name.
0660   Module *lookupModule(StringRef ModuleName,
0661                        SourceLocation ImportLoc = SourceLocation(),
0662                        bool AllowSearch = true,
0663                        bool AllowExtraModuleMapSearch = false);
0664 
0665   /// Try to find a module map file in the given directory, returning
0666   /// \c nullopt if none is found.
0667   OptionalFileEntryRef lookupModuleMapFile(DirectoryEntryRef Dir,
0668                                            bool IsFramework);
0669 
0670   /// Determine whether there is a module map that may map the header
0671   /// with the given file name to a (sub)module.
0672   /// Always returns false if modules are disabled.
0673   ///
0674   /// \param Filename The name of the file.
0675   ///
0676   /// \param Root The "root" directory, at which we should stop looking for
0677   /// module maps.
0678   ///
0679   /// \param IsSystem Whether the directories we're looking at are system
0680   /// header directories.
0681   bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root,
0682                     bool IsSystem);
0683 
0684   /// Retrieve the module that corresponds to the given file, if any.
0685   ///
0686   /// \param File The header that we wish to map to a module.
0687   /// \param AllowTextual Whether we want to find textual headers too.
0688   ModuleMap::KnownHeader findModuleForHeader(FileEntryRef File,
0689                                              bool AllowTextual = false,
0690                                              bool AllowExcluded = false) const;
0691 
0692   /// Retrieve all the modules corresponding to the given file.
0693   ///
0694   /// \ref findModuleForHeader should typically be used instead of this.
0695   ArrayRef<ModuleMap::KnownHeader>
0696   findAllModulesForHeader(FileEntryRef File) const;
0697 
0698   /// Like \ref findAllModulesForHeader, but do not attempt to infer module
0699   /// ownership from umbrella headers if we've not already done so.
0700   ArrayRef<ModuleMap::KnownHeader>
0701   findResolvedModulesForHeader(FileEntryRef File) const;
0702 
0703   /// Read the contents of the given module map file.
0704   ///
0705   /// \param File The module map file.
0706   /// \param IsSystem Whether this file is in a system header directory.
0707   /// \param ID If the module map file is already mapped (perhaps as part of
0708   ///        processing a preprocessed module), the ID of the file.
0709   /// \param Offset [inout] An offset within ID to start parsing. On exit,
0710   ///        filled by the end of the parsed contents (either EOF or the
0711   ///        location of an end-of-module-map pragma).
0712   /// \param OriginalModuleMapFile The original path to the module map file,
0713   ///        used to resolve paths within the module (this is required when
0714   ///        building the module from preprocessed source).
0715   /// \returns true if an error occurred, false otherwise.
0716   bool loadModuleMapFile(FileEntryRef File, bool IsSystem, FileID ID = FileID(),
0717                          unsigned *Offset = nullptr,
0718                          StringRef OriginalModuleMapFile = StringRef());
0719 
0720   /// Collect the set of all known, top-level modules.
0721   ///
0722   /// \param Modules Will be filled with the set of known, top-level modules.
0723   void collectAllModules(SmallVectorImpl<Module *> &Modules);
0724 
0725   /// Load all known, top-level system modules.
0726   void loadTopLevelSystemModules();
0727 
0728 private:
0729   /// Lookup a module with the given module name and search-name.
0730   ///
0731   /// \param ModuleName The name of the module we're looking for.
0732   ///
0733   /// \param SearchName The "search-name" to derive filesystem paths from
0734   /// when looking for the module map; this is usually equal to ModuleName,
0735   /// but for compatibility with some buggy frameworks, additional attempts
0736   /// may be made to find the module under a related-but-different search-name.
0737   ///
0738   /// \param ImportLoc Location of the module include/import.
0739   ///
0740   /// \param AllowExtraModuleMapSearch Whether we allow to search modulemaps
0741   /// in subdirectories.
0742   ///
0743   /// \returns The module named ModuleName.
0744   Module *lookupModule(StringRef ModuleName, StringRef SearchName,
0745                        SourceLocation ImportLoc,
0746                        bool AllowExtraModuleMapSearch = false);
0747 
0748   /// Retrieve the name of the (to-be-)cached module file that should
0749   /// be used to load a module with the given name.
0750   ///
0751   /// \param ModuleName The module whose module file name will be returned.
0752   ///
0753   /// \param ModuleMapPath A path that when combined with \c ModuleName
0754   /// uniquely identifies this module. See Module::ModuleMap.
0755   ///
0756   /// \param CachePath A path to the module cache.
0757   ///
0758   /// \returns The name of the module file that corresponds to this module,
0759   /// or an empty string if this module does not correspond to any module file.
0760   std::string getCachedModuleFileNameImpl(StringRef ModuleName,
0761                                           StringRef ModuleMapPath,
0762                                           StringRef CachePath);
0763 
0764   /// Retrieve a module with the given name, which may be part of the
0765   /// given framework.
0766   ///
0767   /// \param Name The name of the module to retrieve.
0768   ///
0769   /// \param Dir The framework directory (e.g., ModuleName.framework).
0770   ///
0771   /// \param IsSystem Whether the framework directory is part of the system
0772   /// frameworks.
0773   ///
0774   /// \returns The module, if found; otherwise, null.
0775   Module *loadFrameworkModule(StringRef Name, DirectoryEntryRef Dir,
0776                               bool IsSystem);
0777 
0778   /// Load all of the module maps within the immediate subdirectories
0779   /// of the given search directory.
0780   void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir);
0781 
0782   /// Find and suggest a usable module for the given file.
0783   ///
0784   /// \return \c true if the file can be used, \c false if we are not permitted to
0785   ///         find this file due to requirements from \p RequestingModule.
0786   bool findUsableModuleForHeader(FileEntryRef File, const DirectoryEntry *Root,
0787                                  Module *RequestingModule,
0788                                  ModuleMap::KnownHeader *SuggestedModule,
0789                                  bool IsSystemHeaderDir);
0790 
0791   /// Find and suggest a usable module for the given file, which is part of
0792   /// the specified framework.
0793   ///
0794   /// \return \c true if the file can be used, \c false if we are not permitted to
0795   ///         find this file due to requirements from \p RequestingModule.
0796   bool findUsableModuleForFrameworkHeader(
0797       FileEntryRef File, StringRef FrameworkName, Module *RequestingModule,
0798       ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework);
0799 
0800   /// Look up the file with the specified name and determine its owning
0801   /// module.
0802   OptionalFileEntryRef
0803   getFileAndSuggestModule(StringRef FileName, SourceLocation IncludeLoc,
0804                           const DirectoryEntry *Dir, bool IsSystemHeaderDir,
0805                           Module *RequestingModule,
0806                           ModuleMap::KnownHeader *SuggestedModule,
0807                           bool OpenFile = true, bool CacheFailures = true);
0808 
0809   /// Cache the result of a successful lookup at the given include location
0810   /// using the search path at \c HitIt.
0811   void cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
0812                           ConstSearchDirIterator HitIt,
0813                           SourceLocation IncludeLoc);
0814 
0815   /// Note that a lookup at the given include location was successful using the
0816   /// search path at index `HitIdx`.
0817   void noteLookupUsage(unsigned HitIdx, SourceLocation IncludeLoc);
0818 
0819 public:
0820   /// Retrieve the module map.
0821   ModuleMap &getModuleMap() { return ModMap; }
0822 
0823   /// Retrieve the module map.
0824   const ModuleMap &getModuleMap() const { return ModMap; }
0825 
0826   unsigned header_file_size() const { return FileInfo.size(); }
0827 
0828   /// Return the HeaderFileInfo structure for the specified FileEntry, in
0829   /// preparation for updating it in some way.
0830   HeaderFileInfo &getFileInfo(FileEntryRef FE);
0831 
0832   /// Return the HeaderFileInfo structure for the specified FileEntry, if it has
0833   /// ever been filled in (either locally or externally).
0834   const HeaderFileInfo *getExistingFileInfo(FileEntryRef FE) const;
0835 
0836   /// Return the headerFileInfo structure for the specified FileEntry, if it has
0837   /// ever been filled in locally.
0838   const HeaderFileInfo *getExistingLocalFileInfo(FileEntryRef FE) const;
0839 
0840   SearchDirIterator search_dir_begin() { return {*this, 0}; }
0841   SearchDirIterator search_dir_end() { return {*this, SearchDirs.size()}; }
0842   SearchDirRange search_dir_range() {
0843     return {search_dir_begin(), search_dir_end()};
0844   }
0845 
0846   ConstSearchDirIterator search_dir_begin() const { return quoted_dir_begin(); }
0847   ConstSearchDirIterator search_dir_nth(size_t n) const {
0848     assert(n < SearchDirs.size());
0849     return {*this, n};
0850   }
0851   ConstSearchDirIterator search_dir_end() const { return system_dir_end(); }
0852   ConstSearchDirRange search_dir_range() const {
0853     return {search_dir_begin(), search_dir_end()};
0854   }
0855 
0856   unsigned search_dir_size() const { return SearchDirs.size(); }
0857 
0858   ConstSearchDirIterator quoted_dir_begin() const { return {*this, 0}; }
0859   ConstSearchDirIterator quoted_dir_end() const { return angled_dir_begin(); }
0860 
0861   ConstSearchDirIterator angled_dir_begin() const {
0862     return {*this, AngledDirIdx};
0863   }
0864   ConstSearchDirIterator angled_dir_end() const { return system_dir_begin(); }
0865 
0866   ConstSearchDirIterator system_dir_begin() const {
0867     return {*this, SystemDirIdx};
0868   }
0869   ConstSearchDirIterator system_dir_end() const {
0870     return {*this, SearchDirs.size()};
0871   }
0872 
0873   /// Get the index of the given search directory.
0874   unsigned searchDirIdx(const DirectoryLookup &DL) const;
0875 
0876   /// Retrieve a uniqued framework name.
0877   StringRef getUniqueFrameworkName(StringRef Framework);
0878 
0879   /// Retrieve the include name for the header.
0880   ///
0881   /// \param File The entry for a given header.
0882   /// \returns The name of how the file was included when the header's location
0883   /// was resolved.
0884   StringRef getIncludeNameForHeader(const FileEntry *File) const;
0885 
0886   /// Suggest a path by which the specified file could be found, for use in
0887   /// diagnostics to suggest a #include. Returned path will only contain forward
0888   /// slashes as separators. MainFile is the absolute path of the file that we
0889   /// are generating the diagnostics for. It will try to shorten the path using
0890   /// MainFile location, if none of the include search directories were prefix
0891   /// of File.
0892   ///
0893   /// \param IsAngled If non-null, filled in to indicate whether the suggested
0894   ///        path should be referenced as <Header.h> instead of "Header.h".
0895   std::string suggestPathToFileForDiagnostics(FileEntryRef File,
0896                                               llvm::StringRef MainFile,
0897                                               bool *IsAngled = nullptr) const;
0898 
0899   /// Suggest a path by which the specified file could be found, for use in
0900   /// diagnostics to suggest a #include. Returned path will only contain forward
0901   /// slashes as separators. MainFile is the absolute path of the file that we
0902   /// are generating the diagnostics for. It will try to shorten the path using
0903   /// MainFile location, if none of the include search directories were prefix
0904   /// of File.
0905   ///
0906   /// \param WorkingDir If non-empty, this will be prepended to search directory
0907   /// paths that are relative.
0908   std::string suggestPathToFileForDiagnostics(llvm::StringRef File,
0909                                               llvm::StringRef WorkingDir,
0910                                               llvm::StringRef MainFile,
0911                                               bool *IsAngled = nullptr) const;
0912 
0913   void PrintStats();
0914 
0915   size_t getTotalMemory() const;
0916 
0917 private:
0918   /// Describes what happened when we tried to load a module map file.
0919   enum LoadModuleMapResult {
0920     /// The module map file had already been loaded.
0921     LMM_AlreadyLoaded,
0922 
0923     /// The module map file was loaded by this invocation.
0924     LMM_NewlyLoaded,
0925 
0926     /// There is was directory with the given name.
0927     LMM_NoDirectory,
0928 
0929     /// There was either no module map file or the module map file was
0930     /// invalid.
0931     LMM_InvalidModuleMap
0932   };
0933 
0934   LoadModuleMapResult loadModuleMapFileImpl(FileEntryRef File, bool IsSystem,
0935                                             DirectoryEntryRef Dir,
0936                                             FileID ID = FileID(),
0937                                             unsigned *Offset = nullptr);
0938 
0939   /// Try to load the module map file in the given directory.
0940   ///
0941   /// \param DirName The name of the directory where we will look for a module
0942   /// map file.
0943   /// \param IsSystem Whether this is a system header directory.
0944   /// \param IsFramework Whether this is a framework directory.
0945   ///
0946   /// \returns The result of attempting to load the module map file from the
0947   /// named directory.
0948   LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem,
0949                                         bool IsFramework);
0950 
0951   /// Try to load the module map file in the given directory.
0952   ///
0953   /// \param Dir The directory where we will look for a module map file.
0954   /// \param IsSystem Whether this is a system header directory.
0955   /// \param IsFramework Whether this is a framework directory.
0956   ///
0957   /// \returns The result of attempting to load the module map file from the
0958   /// named directory.
0959   LoadModuleMapResult loadModuleMapFile(DirectoryEntryRef Dir, bool IsSystem,
0960                                         bool IsFramework);
0961 };
0962 
0963 /// Apply the header search options to get given HeaderSearch object.
0964 void ApplyHeaderSearchOptions(HeaderSearch &HS,
0965                               const HeaderSearchOptions &HSOpts,
0966                               const LangOptions &Lang,
0967                               const llvm::Triple &triple);
0968 
0969 } // namespace clang
0970 
0971 #endif // LLVM_CLANG_LEX_HEADERSEARCH_H