1 //===- HeaderSearch.h - Resolve Header File Locations -----------*- 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 HeaderSearch interface.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_LEX_HEADERSEARCH_H
14 #define LLVM_CLANG_LEX_HEADERSEARCH_H
15 
16 #include "clang/Basic/SourceLocation.h"
17 #include "clang/Basic/SourceManager.h"
18 #include "clang/Lex/DirectoryLookup.h"
19 #include "clang/Lex/HeaderMap.h"
20 #include "clang/Lex/ModuleMap.h"
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/DenseMap.h"
23 #include "llvm/ADT/SmallString.h"
24 #include "llvm/ADT/StringMap.h"
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/ADT/StringSet.h"
27 #include "llvm/Support/Allocator.h"
28 #include <cassert>
29 #include <cstddef>
30 #include <memory>
31 #include <string>
32 #include <utility>
33 #include <vector>
34 
35 namespace llvm {
36 
37 class Triple;
38 
39 } // namespace llvm
40 
41 namespace clang {
42 
43 class DiagnosticsEngine;
44 class DirectoryEntry;
45 class ExternalPreprocessorSource;
46 class FileEntry;
47 class FileManager;
48 class HeaderSearch;
49 class HeaderSearchOptions;
50 class IdentifierInfo;
51 class LangOptions;
52 class Module;
53 class Preprocessor;
54 class TargetInfo;
55 
56 /// The preprocessor keeps track of this information for each
57 /// file that is \#included.
58 struct HeaderFileInfo {
59   // TODO: Whether the file was imported is not a property of the file itself.
60   // It's a preprocessor state, move it there.
61   /// True if this is a \#import'd file.
62   LLVM_PREFERRED_TYPE(bool)
63   unsigned isImport : 1;
64 
65   /// True if this is a \#pragma once file.
66   LLVM_PREFERRED_TYPE(bool)
67   unsigned isPragmaOnce : 1;
68 
69   /// Keep track of whether this is a system header, and if so,
70   /// whether it is C++ clean or not.  This can be set by the include paths or
71   /// by \#pragma gcc system_header.  This is an instance of
72   /// SrcMgr::CharacteristicKind.
73   LLVM_PREFERRED_TYPE(SrcMgr::CharacteristicKind)
74   unsigned DirInfo : 3;
75 
76   /// Whether this header file info was supplied by an external source,
77   /// and has not changed since.
78   LLVM_PREFERRED_TYPE(bool)
79   unsigned External : 1;
80 
81   /// Whether this header is part of a module.
82   LLVM_PREFERRED_TYPE(bool)
83   unsigned isModuleHeader : 1;
84 
85   /// Whether this header is part of the module that we are building.
86   LLVM_PREFERRED_TYPE(bool)
87   unsigned isCompilingModuleHeader : 1;
88 
89   /// Whether this structure is considered to already have been
90   /// "resolved", meaning that it was loaded from the external source.
91   LLVM_PREFERRED_TYPE(bool)
92   unsigned Resolved : 1;
93 
94   /// Whether this is a header inside a framework that is currently
95   /// being built.
96   ///
97   /// When a framework is being built, the headers have not yet been placed
98   /// into the appropriate framework subdirectories, and therefore are
99   /// provided via a header map. This bit indicates when this is one of
100   /// those framework headers.
101   LLVM_PREFERRED_TYPE(bool)
102   unsigned IndexHeaderMapHeader : 1;
103 
104   /// Whether this file has been looked up as a header.
105   LLVM_PREFERRED_TYPE(bool)
106   unsigned IsValid : 1;
107 
108   /// The ID number of the controlling macro.
109   ///
110   /// This ID number will be non-zero when there is a controlling
111   /// macro whose IdentifierInfo may not yet have been loaded from
112   /// external storage.
113   unsigned ControllingMacroID = 0;
114 
115   /// If this file has a \#ifndef XXX (or equivalent) guard that
116   /// protects the entire contents of the file, this is the identifier
117   /// for the macro that controls whether or not it has any effect.
118   ///
119   /// Note: Most clients should use getControllingMacro() to access
120   /// the controlling macro of this header, since
121   /// getControllingMacro() is able to load a controlling macro from
122   /// external storage.
123   const IdentifierInfo *ControllingMacro = nullptr;
124 
125   /// If this header came from a framework include, this is the name
126   /// of the framework.
127   StringRef Framework;
128 
HeaderFileInfoHeaderFileInfo129   HeaderFileInfo()
130       : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
131         External(false), isModuleHeader(false), isCompilingModuleHeader(false),
132         Resolved(false), IndexHeaderMapHeader(false), IsValid(false)  {}
133 
134   /// Retrieve the controlling macro for this header file, if
135   /// any.
136   const IdentifierInfo *
137   getControllingMacro(ExternalPreprocessorSource *External);
138 };
139 
140 /// An external source of header file information, which may supply
141 /// information about header files already included.
142 class ExternalHeaderFileInfoSource {
143 public:
144   virtual ~ExternalHeaderFileInfoSource();
145 
146   /// Retrieve the header file information for the given file entry.
147   ///
148   /// \returns Header file information for the given file entry, with the
149   /// \c External bit set. If the file entry is not known, return a
150   /// default-constructed \c HeaderFileInfo.
151   virtual HeaderFileInfo GetHeaderFileInfo(FileEntryRef FE) = 0;
152 };
153 
154 /// This structure is used to record entries in our framework cache.
155 struct FrameworkCacheEntry {
156   /// The directory entry which should be used for the cached framework.
157   OptionalDirectoryEntryRef Directory;
158 
159   /// Whether this framework has been "user-specified" to be treated as if it
160   /// were a system framework (even if it was found outside a system framework
161   /// directory).
162   bool IsUserSpecifiedSystemFramework;
163 };
164 
165 namespace detail {
166 template <bool Const, typename T>
167 using Qualified = std::conditional_t<Const, const T, T>;
168 
169 /// Forward iterator over the search directories of \c HeaderSearch.
170 template <bool IsConst>
171 struct SearchDirIteratorImpl
172     : llvm::iterator_facade_base<SearchDirIteratorImpl<IsConst>,
173                                  std::forward_iterator_tag,
174                                  Qualified<IsConst, DirectoryLookup>> {
175   /// Const -> non-const iterator conversion.
176   template <typename Enable = std::enable_if<IsConst, bool>>
SearchDirIteratorImplSearchDirIteratorImpl177   SearchDirIteratorImpl(const SearchDirIteratorImpl<false> &Other)
178       : HS(Other.HS), Idx(Other.Idx) {}
179 
180   SearchDirIteratorImpl(const SearchDirIteratorImpl &) = default;
181 
182   SearchDirIteratorImpl &operator=(const SearchDirIteratorImpl &) = default;
183 
184   bool operator==(const SearchDirIteratorImpl &RHS) const {
185     return HS == RHS.HS && Idx == RHS.Idx;
186   }
187 
188   SearchDirIteratorImpl &operator++() {
189     assert(*this && "Invalid iterator.");
190     ++Idx;
191     return *this;
192   }
193 
194   Qualified<IsConst, DirectoryLookup> &operator*() const {
195     assert(*this && "Invalid iterator.");
196     return HS->SearchDirs[Idx];
197   }
198 
199   /// Creates an invalid iterator.
SearchDirIteratorImplSearchDirIteratorImpl200   SearchDirIteratorImpl(std::nullptr_t) : HS(nullptr), Idx(0) {}
201 
202   /// Checks whether the iterator is valid.
203   explicit operator bool() const { return HS != nullptr; }
204 
205 private:
206   /// The parent \c HeaderSearch. This is \c nullptr for invalid iterator.
207   Qualified<IsConst, HeaderSearch> *HS;
208 
209   /// The index of the current element.
210   size_t Idx;
211 
212   /// The constructor that creates a valid iterator.
SearchDirIteratorImplSearchDirIteratorImpl213   SearchDirIteratorImpl(Qualified<IsConst, HeaderSearch> &HS, size_t Idx)
214       : HS(&HS), Idx(Idx) {}
215 
216   /// Only HeaderSearch is allowed to instantiate valid iterators.
217   friend HeaderSearch;
218 
219   /// Enables const -> non-const conversion.
220   friend SearchDirIteratorImpl<!IsConst>;
221 };
222 } // namespace detail
223 
224 using ConstSearchDirIterator = detail::SearchDirIteratorImpl<true>;
225 using SearchDirIterator = detail::SearchDirIteratorImpl<false>;
226 
227 using ConstSearchDirRange = llvm::iterator_range<ConstSearchDirIterator>;
228 using SearchDirRange = llvm::iterator_range<SearchDirIterator>;
229 
230 /// Encapsulates the information needed to find the file referenced
231 /// by a \#include or \#include_next, (sub-)framework lookup, etc.
232 class HeaderSearch {
233   friend class DirectoryLookup;
234 
235   friend ConstSearchDirIterator;
236   friend SearchDirIterator;
237 
238   /// Header-search options used to initialize this header search.
239   std::shared_ptr<HeaderSearchOptions> HSOpts;
240 
241   /// Mapping from SearchDir to HeaderSearchOptions::UserEntries indices.
242   llvm::DenseMap<unsigned, unsigned> SearchDirToHSEntry;
243 
244   DiagnosticsEngine &Diags;
245   FileManager &FileMgr;
246 
247   /// \#include search path information.  Requests for \#include "x" search the
248   /// directory of the \#including file first, then each directory in SearchDirs
249   /// consecutively. Requests for <x> search the current dir first, then each
250   /// directory in SearchDirs, starting at AngledDirIdx, consecutively.
251   std::vector<DirectoryLookup> SearchDirs;
252   /// Whether the DirectoryLookup at the corresponding index in SearchDirs has
253   /// been successfully used to lookup a file.
254   std::vector<bool> SearchDirsUsage;
255   unsigned AngledDirIdx = 0;
256   unsigned SystemDirIdx = 0;
257 
258   /// Maps HeaderMap keys to SearchDir indices. When HeaderMaps are used
259   /// heavily, SearchDirs can start with thousands of HeaderMaps, so this Index
260   /// lets us avoid scanning them all to find a match.
261   llvm::StringMap<unsigned, llvm::BumpPtrAllocator> SearchDirHeaderMapIndex;
262 
263   /// The index of the first SearchDir that isn't a header map.
264   unsigned FirstNonHeaderMapSearchDirIdx = 0;
265 
266   /// \#include prefixes for which the 'system header' property is
267   /// overridden.
268   ///
269   /// For a \#include "x" or \#include \<x> directive, the last string in this
270   /// list which is a prefix of 'x' determines whether the file is treated as
271   /// a system header.
272   std::vector<std::pair<std::string, bool>> SystemHeaderPrefixes;
273 
274   /// The hash used for module cache paths.
275   std::string ModuleHash;
276 
277   /// The path to the module cache.
278   std::string ModuleCachePath;
279 
280   /// All of the preprocessor-specific data about files that are
281   /// included, indexed by the FileEntry's UID.
282   mutable std::vector<HeaderFileInfo> FileInfo;
283 
284   /// Keeps track of each lookup performed by LookupFile.
285   struct LookupFileCacheInfo {
286     // The requesting module for the lookup we cached.
287     const Module *RequestingModule = nullptr;
288 
289     /// Starting search directory iterator that the cached search was performed
290     /// from. If there is a hit and this value doesn't match the current query,
291     /// the cache has to be ignored.
292     ConstSearchDirIterator StartIt = nullptr;
293 
294     /// The search directory iterator that satisfied the query.
295     ConstSearchDirIterator HitIt = nullptr;
296 
297     /// This is non-null if the original filename was mapped to a framework
298     /// include via a headermap.
299     const char *MappedName = nullptr;
300 
301     /// Default constructor -- Initialize all members with zero.
302     LookupFileCacheInfo() = default;
303 
resetLookupFileCacheInfo304     void reset(const Module *NewRequestingModule,
305                ConstSearchDirIterator NewStartIt) {
306       RequestingModule = NewRequestingModule;
307       StartIt = NewStartIt;
308       MappedName = nullptr;
309     }
310   };
311   llvm::StringMap<LookupFileCacheInfo, llvm::BumpPtrAllocator> LookupFileCache;
312 
313   /// Collection mapping a framework or subframework
314   /// name like "Carbon" to the Carbon.framework directory.
315   llvm::StringMap<FrameworkCacheEntry, llvm::BumpPtrAllocator> FrameworkMap;
316 
317   /// Maps include file names (including the quotes or
318   /// angle brackets) to other include file names.  This is used to support the
319   /// include_alias pragma for Microsoft compatibility.
320   using IncludeAliasMap =
321       llvm::StringMap<std::string, llvm::BumpPtrAllocator>;
322   std::unique_ptr<IncludeAliasMap> IncludeAliases;
323 
324   /// This is a mapping from FileEntry -> HeaderMap, uniquing headermaps.
325   std::vector<std::pair<FileEntryRef, std::unique_ptr<HeaderMap>>> HeaderMaps;
326 
327   /// The mapping between modules and headers.
328   mutable ModuleMap ModMap;
329 
330   /// Describes whether a given directory has a module map in it.
331   llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap;
332 
333   /// Set of module map files we've already loaded, and a flag indicating
334   /// whether they were valid or not.
335   llvm::DenseMap<const FileEntry *, bool> LoadedModuleMaps;
336 
337   // A map of discovered headers with their associated include file name.
338   llvm::DenseMap<const FileEntry *, llvm::SmallString<64>> IncludeNames;
339 
340   /// Uniqued set of framework names, which is used to track which
341   /// headers were included as framework headers.
342   llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
343 
344   /// Entity used to resolve the identifier IDs of controlling
345   /// macros into IdentifierInfo pointers, and keep the identifire up to date,
346   /// as needed.
347   ExternalPreprocessorSource *ExternalLookup = nullptr;
348 
349   /// Entity used to look up stored header file information.
350   ExternalHeaderFileInfoSource *ExternalSource = nullptr;
351 
352   /// Scan all of the header maps at the beginning of SearchDirs and
353   /// map their keys to the SearchDir index of their header map.
354   void indexInitialHeaderMaps();
355 
356 public:
357   HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts,
358                SourceManager &SourceMgr, DiagnosticsEngine &Diags,
359                const LangOptions &LangOpts, const TargetInfo *Target);
360   HeaderSearch(const HeaderSearch &) = delete;
361   HeaderSearch &operator=(const HeaderSearch &) = delete;
362 
363   /// Retrieve the header-search options with which this header search
364   /// was initialized.
getHeaderSearchOpts()365   HeaderSearchOptions &getHeaderSearchOpts() const { return *HSOpts; }
366 
getFileMgr()367   FileManager &getFileMgr() const { return FileMgr; }
368 
getDiags()369   DiagnosticsEngine &getDiags() const { return Diags; }
370 
371   /// Interface for setting the file search paths.
372   void SetSearchPaths(std::vector<DirectoryLookup> dirs, unsigned angledDirIdx,
373                       unsigned systemDirIdx,
374                       llvm::DenseMap<unsigned, unsigned> searchDirToHSEntry);
375 
376   /// Add an additional search path.
377   void AddSearchPath(const DirectoryLookup &dir, bool isAngled);
378 
379   /// Add an additional system search path.
AddSystemSearchPath(const DirectoryLookup & dir)380   void AddSystemSearchPath(const DirectoryLookup &dir) {
381     SearchDirs.push_back(dir);
382     SearchDirsUsage.push_back(false);
383   }
384 
385   /// Set the list of system header prefixes.
SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string,bool>> P)386   void SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string, bool>> P) {
387     SystemHeaderPrefixes.assign(P.begin(), P.end());
388   }
389 
390   /// Checks whether the map exists or not.
HasIncludeAliasMap()391   bool HasIncludeAliasMap() const { return (bool)IncludeAliases; }
392 
393   /// Map the source include name to the dest include name.
394   ///
395   /// The Source should include the angle brackets or quotes, the dest
396   /// should not.  This allows for distinction between <> and "" headers.
AddIncludeAlias(StringRef Source,StringRef Dest)397   void AddIncludeAlias(StringRef Source, StringRef Dest) {
398     if (!IncludeAliases)
399       IncludeAliases.reset(new IncludeAliasMap);
400     (*IncludeAliases)[Source] = std::string(Dest);
401   }
402 
403   /// Maps one header file name to a different header
404   /// file name, for use with the include_alias pragma.  Note that the source
405   /// file name should include the angle brackets or quotes.  Returns StringRef
406   /// as null if the header cannot be mapped.
MapHeaderToIncludeAlias(StringRef Source)407   StringRef MapHeaderToIncludeAlias(StringRef Source) {
408     assert(IncludeAliases && "Trying to map headers when there's no map");
409 
410     // Do any filename replacements before anything else
411     IncludeAliasMap::const_iterator Iter = IncludeAliases->find(Source);
412     if (Iter != IncludeAliases->end())
413       return Iter->second;
414     return {};
415   }
416 
417   /// Set the hash to use for module cache paths.
setModuleHash(StringRef Hash)418   void setModuleHash(StringRef Hash) { ModuleHash = std::string(Hash); }
419 
420   /// Set the path to the module cache.
setModuleCachePath(StringRef CachePath)421   void setModuleCachePath(StringRef CachePath) {
422     ModuleCachePath = std::string(CachePath);
423   }
424 
425   /// Retrieve the module hash.
getModuleHash()426   StringRef getModuleHash() const { return ModuleHash; }
427 
428   /// Retrieve the path to the module cache.
getModuleCachePath()429   StringRef getModuleCachePath() const { return ModuleCachePath; }
430 
431   /// Consider modules when including files from this directory.
setDirectoryHasModuleMap(const DirectoryEntry * Dir)432   void setDirectoryHasModuleMap(const DirectoryEntry* Dir) {
433     DirectoryHasModuleMap[Dir] = true;
434   }
435 
436   /// Forget everything we know about headers so far.
ClearFileInfo()437   void ClearFileInfo() {
438     FileInfo.clear();
439   }
440 
SetExternalLookup(ExternalPreprocessorSource * EPS)441   void SetExternalLookup(ExternalPreprocessorSource *EPS) {
442     ExternalLookup = EPS;
443   }
444 
getExternalLookup()445   ExternalPreprocessorSource *getExternalLookup() const {
446     return ExternalLookup;
447   }
448 
449   /// Set the external source of header information.
SetExternalSource(ExternalHeaderFileInfoSource * ES)450   void SetExternalSource(ExternalHeaderFileInfoSource *ES) {
451     ExternalSource = ES;
452   }
453 
454   /// Set the target information for the header search, if not
455   /// already known.
456   void setTarget(const TargetInfo &Target);
457 
458   /// Given a "foo" or \<foo> reference, look up the indicated file,
459   /// return null on failure.
460   ///
461   /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
462   /// the file was found in, or null if not applicable.
463   ///
464   /// \param IncludeLoc Used for diagnostics if valid.
465   ///
466   /// \param isAngled indicates whether the file reference is a <> reference.
467   ///
468   /// \param CurDir If non-null, the file was found in the specified directory
469   /// search location.  This is used to implement \#include_next.
470   ///
471   /// \param Includers Indicates where the \#including file(s) are, in case
472   /// relative searches are needed. In reverse order of inclusion.
473   ///
474   /// \param SearchPath If non-null, will be set to the search path relative
475   /// to which the file was found. If the include path is absolute, SearchPath
476   /// will be set to an empty string.
477   ///
478   /// \param RelativePath If non-null, will be set to the path relative to
479   /// SearchPath at which the file was found. This only differs from the
480   /// Filename for framework includes.
481   ///
482   /// \param SuggestedModule If non-null, and the file found is semantically
483   /// part of a known module, this will be set to the module that should
484   /// be imported instead of preprocessing/parsing the file found.
485   ///
486   /// \param IsMapped If non-null, and the search involved header maps, set to
487   /// true.
488   ///
489   /// \param IsFrameworkFound If non-null, will be set to true if a framework is
490   /// found in any of searched SearchDirs. Will be set to false if a framework
491   /// is found only through header maps. Doesn't guarantee the requested file is
492   /// found.
493   OptionalFileEntryRef LookupFile(
494       StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
495       ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDir,
496       ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
497       SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
498       Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
499       bool *IsMapped, bool *IsFrameworkFound, bool SkipCache = false,
500       bool BuildSystemModule = false, bool OpenFile = true,
501       bool CacheFailures = true);
502 
503   /// Look up a subframework for the specified \#include file.
504   ///
505   /// For example, if \#include'ing <HIToolbox/HIToolbox.h> from
506   /// within ".../Carbon.framework/Headers/Carbon.h", check to see if
507   /// HIToolbox is a subframework within Carbon.framework.  If so, return
508   /// the FileEntry for the designated file, otherwise return null.
509   OptionalFileEntryRef LookupSubframeworkHeader(
510       StringRef Filename, FileEntryRef ContextFileEnt,
511       SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
512       Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule);
513 
514   /// Look up the specified framework name in our framework cache.
515   /// \returns The DirectoryEntry it is in if we know, null otherwise.
LookupFrameworkCache(StringRef FWName)516   FrameworkCacheEntry &LookupFrameworkCache(StringRef FWName) {
517     return FrameworkMap[FWName];
518   }
519 
520   /// Mark the specified file as a target of a \#include,
521   /// \#include_next, or \#import directive.
522   ///
523   /// \return false if \#including the file will have no effect or true
524   /// if we should include it.
525   bool ShouldEnterIncludeFile(Preprocessor &PP, FileEntryRef File,
526                               bool isImport, bool ModulesEnabled, Module *M,
527                               bool &IsFirstIncludeOfFile);
528 
529   /// Return whether the specified file is a normal header,
530   /// a system header, or a C++ friendly system header.
getFileDirFlavor(FileEntryRef File)531   SrcMgr::CharacteristicKind getFileDirFlavor(FileEntryRef File) {
532     return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo;
533   }
534 
535   /// Mark the specified file as a "once only" file due to
536   /// \#pragma once.
MarkFileIncludeOnce(FileEntryRef File)537   void MarkFileIncludeOnce(FileEntryRef File) {
538     HeaderFileInfo &FI = getFileInfo(File);
539     FI.isPragmaOnce = true;
540   }
541 
542   /// Mark the specified file as a system header, e.g. due to
543   /// \#pragma GCC system_header.
MarkFileSystemHeader(FileEntryRef File)544   void MarkFileSystemHeader(FileEntryRef File) {
545     getFileInfo(File).DirInfo = SrcMgr::C_System;
546   }
547 
548   /// Mark the specified file as part of a module.
549   void MarkFileModuleHeader(FileEntryRef FE, ModuleMap::ModuleHeaderRole Role,
550                             bool isCompilingModuleHeader);
551 
552   /// Mark the specified file as having a controlling macro.
553   ///
554   /// This is used by the multiple-include optimization to eliminate
555   /// no-op \#includes.
SetFileControllingMacro(FileEntryRef File,const IdentifierInfo * ControllingMacro)556   void SetFileControllingMacro(FileEntryRef File,
557                                const IdentifierInfo *ControllingMacro) {
558     getFileInfo(File).ControllingMacro = ControllingMacro;
559   }
560 
561   /// Determine whether this file is intended to be safe from
562   /// multiple inclusions, e.g., it has \#pragma once or a controlling
563   /// macro.
564   ///
565   /// This routine does not consider the effect of \#import
566   bool isFileMultipleIncludeGuarded(FileEntryRef File) const;
567 
568   /// Determine whether the given file is known to have ever been \#imported.
hasFileBeenImported(FileEntryRef File)569   bool hasFileBeenImported(FileEntryRef File) const {
570     const HeaderFileInfo *FI = getExistingFileInfo(File);
571     return FI && FI->isImport;
572   }
573 
574   /// Determine which HeaderSearchOptions::UserEntries have been successfully
575   /// used so far and mark their index with 'true' in the resulting bit vector.
576   /// Note: implicit module maps don't contribute to entry usage.
577   std::vector<bool> computeUserEntryUsage() const;
578 
579   /// This method returns a HeaderMap for the specified
580   /// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
581   const HeaderMap *CreateHeaderMap(FileEntryRef FE);
582 
583   /// Get filenames for all registered header maps.
584   void getHeaderMapFileNames(SmallVectorImpl<std::string> &Names) const;
585 
586   /// Retrieve the name of the cached module file that should be used
587   /// to load the given module.
588   ///
589   /// \param Module The module whose module file name will be returned.
590   ///
591   /// \returns The name of the module file that corresponds to this module,
592   /// or an empty string if this module does not correspond to any module file.
593   std::string getCachedModuleFileName(Module *Module);
594 
595   /// Retrieve the name of the prebuilt module file that should be used
596   /// to load a module with the given name.
597   ///
598   /// \param ModuleName The module whose module file name will be returned.
599   ///
600   /// \param FileMapOnly If true, then only look in the explicit module name
601   //  to file name map and skip the directory search.
602   ///
603   /// \returns The name of the module file that corresponds to this module,
604   /// or an empty string if this module does not correspond to any module file.
605   std::string getPrebuiltModuleFileName(StringRef ModuleName,
606                                         bool FileMapOnly = false);
607 
608   /// Retrieve the name of the prebuilt module file that should be used
609   /// to load the given module.
610   ///
611   /// \param Module The module whose module file name will be returned.
612   ///
613   /// \returns The name of the module file that corresponds to this module,
614   /// or an empty string if this module does not correspond to any module file.
615   std::string getPrebuiltImplicitModuleFileName(Module *Module);
616 
617   /// Retrieve the name of the (to-be-)cached module file that should
618   /// be used to load a module with the given name.
619   ///
620   /// \param ModuleName The module whose module file name will be returned.
621   ///
622   /// \param ModuleMapPath A path that when combined with \c ModuleName
623   /// uniquely identifies this module. See Module::ModuleMap.
624   ///
625   /// \returns The name of the module file that corresponds to this module,
626   /// or an empty string if this module does not correspond to any module file.
627   std::string getCachedModuleFileName(StringRef ModuleName,
628                                       StringRef ModuleMapPath);
629 
630   /// Lookup a module Search for a module with the given name.
631   ///
632   /// \param ModuleName The name of the module we're looking for.
633   ///
634   /// \param ImportLoc Location of the module include/import.
635   ///
636   /// \param AllowSearch Whether we are allowed to search in the various
637   /// search directories to produce a module definition. If not, this lookup
638   /// will only return an already-known module.
639   ///
640   /// \param AllowExtraModuleMapSearch Whether we allow to search modulemaps
641   /// in subdirectories.
642   ///
643   /// \returns The module with the given name.
644   Module *lookupModule(StringRef ModuleName,
645                        SourceLocation ImportLoc = SourceLocation(),
646                        bool AllowSearch = true,
647                        bool AllowExtraModuleMapSearch = false);
648 
649   /// Try to find a module map file in the given directory, returning
650   /// \c nullopt if none is found.
651   OptionalFileEntryRef lookupModuleMapFile(DirectoryEntryRef Dir,
652                                            bool IsFramework);
653 
654   /// Determine whether there is a module map that may map the header
655   /// with the given file name to a (sub)module.
656   /// Always returns false if modules are disabled.
657   ///
658   /// \param Filename The name of the file.
659   ///
660   /// \param Root The "root" directory, at which we should stop looking for
661   /// module maps.
662   ///
663   /// \param IsSystem Whether the directories we're looking at are system
664   /// header directories.
665   bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root,
666                     bool IsSystem);
667 
668   /// Retrieve the module that corresponds to the given file, if any.
669   ///
670   /// \param File The header that we wish to map to a module.
671   /// \param AllowTextual Whether we want to find textual headers too.
672   ModuleMap::KnownHeader findModuleForHeader(FileEntryRef File,
673                                              bool AllowTextual = false,
674                                              bool AllowExcluded = false) const;
675 
676   /// Retrieve all the modules corresponding to the given file.
677   ///
678   /// \ref findModuleForHeader should typically be used instead of this.
679   ArrayRef<ModuleMap::KnownHeader>
680   findAllModulesForHeader(FileEntryRef File) const;
681 
682   /// Like \ref findAllModulesForHeader, but do not attempt to infer module
683   /// ownership from umbrella headers if we've not already done so.
684   ArrayRef<ModuleMap::KnownHeader>
685   findResolvedModulesForHeader(FileEntryRef File) const;
686 
687   /// Read the contents of the given module map file.
688   ///
689   /// \param File The module map file.
690   /// \param IsSystem Whether this file is in a system header directory.
691   /// \param ID If the module map file is already mapped (perhaps as part of
692   ///        processing a preprocessed module), the ID of the file.
693   /// \param Offset [inout] An offset within ID to start parsing. On exit,
694   ///        filled by the end of the parsed contents (either EOF or the
695   ///        location of an end-of-module-map pragma).
696   /// \param OriginalModuleMapFile The original path to the module map file,
697   ///        used to resolve paths within the module (this is required when
698   ///        building the module from preprocessed source).
699   /// \returns true if an error occurred, false otherwise.
700   bool loadModuleMapFile(FileEntryRef File, bool IsSystem, FileID ID = FileID(),
701                          unsigned *Offset = nullptr,
702                          StringRef OriginalModuleMapFile = StringRef());
703 
704   /// Collect the set of all known, top-level modules.
705   ///
706   /// \param Modules Will be filled with the set of known, top-level modules.
707   void collectAllModules(SmallVectorImpl<Module *> &Modules);
708 
709   /// Load all known, top-level system modules.
710   void loadTopLevelSystemModules();
711 
712 private:
713   /// Lookup a module with the given module name and search-name.
714   ///
715   /// \param ModuleName The name of the module we're looking for.
716   ///
717   /// \param SearchName The "search-name" to derive filesystem paths from
718   /// when looking for the module map; this is usually equal to ModuleName,
719   /// but for compatibility with some buggy frameworks, additional attempts
720   /// may be made to find the module under a related-but-different search-name.
721   ///
722   /// \param ImportLoc Location of the module include/import.
723   ///
724   /// \param AllowExtraModuleMapSearch Whether we allow to search modulemaps
725   /// in subdirectories.
726   ///
727   /// \returns The module named ModuleName.
728   Module *lookupModule(StringRef ModuleName, StringRef SearchName,
729                        SourceLocation ImportLoc,
730                        bool AllowExtraModuleMapSearch = false);
731 
732   /// Retrieve the name of the (to-be-)cached module file that should
733   /// be used to load a module with the given name.
734   ///
735   /// \param ModuleName The module whose module file name will be returned.
736   ///
737   /// \param ModuleMapPath A path that when combined with \c ModuleName
738   /// uniquely identifies this module. See Module::ModuleMap.
739   ///
740   /// \param CachePath A path to the module cache.
741   ///
742   /// \returns The name of the module file that corresponds to this module,
743   /// or an empty string if this module does not correspond to any module file.
744   std::string getCachedModuleFileNameImpl(StringRef ModuleName,
745                                           StringRef ModuleMapPath,
746                                           StringRef CachePath);
747 
748   /// Retrieve a module with the given name, which may be part of the
749   /// given framework.
750   ///
751   /// \param Name The name of the module to retrieve.
752   ///
753   /// \param Dir The framework directory (e.g., ModuleName.framework).
754   ///
755   /// \param IsSystem Whether the framework directory is part of the system
756   /// frameworks.
757   ///
758   /// \returns The module, if found; otherwise, null.
759   Module *loadFrameworkModule(StringRef Name, DirectoryEntryRef Dir,
760                               bool IsSystem);
761 
762   /// Load all of the module maps within the immediate subdirectories
763   /// of the given search directory.
764   void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir);
765 
766   /// Find and suggest a usable module for the given file.
767   ///
768   /// \return \c true if the file can be used, \c false if we are not permitted to
769   ///         find this file due to requirements from \p RequestingModule.
770   bool findUsableModuleForHeader(FileEntryRef File, const DirectoryEntry *Root,
771                                  Module *RequestingModule,
772                                  ModuleMap::KnownHeader *SuggestedModule,
773                                  bool IsSystemHeaderDir);
774 
775   /// Find and suggest a usable module for the given file, which is part of
776   /// the specified framework.
777   ///
778   /// \return \c true if the file can be used, \c false if we are not permitted to
779   ///         find this file due to requirements from \p RequestingModule.
780   bool findUsableModuleForFrameworkHeader(
781       FileEntryRef File, StringRef FrameworkName, Module *RequestingModule,
782       ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework);
783 
784   /// Look up the file with the specified name and determine its owning
785   /// module.
786   OptionalFileEntryRef
787   getFileAndSuggestModule(StringRef FileName, SourceLocation IncludeLoc,
788                           const DirectoryEntry *Dir, bool IsSystemHeaderDir,
789                           Module *RequestingModule,
790                           ModuleMap::KnownHeader *SuggestedModule,
791                           bool OpenFile = true, bool CacheFailures = true);
792 
793   /// Cache the result of a successful lookup at the given include location
794   /// using the search path at \c HitIt.
795   void cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
796                           ConstSearchDirIterator HitIt,
797                           SourceLocation IncludeLoc);
798 
799   /// Note that a lookup at the given include location was successful using the
800   /// search path at index `HitIdx`.
801   void noteLookupUsage(unsigned HitIdx, SourceLocation IncludeLoc);
802 
803 public:
804   /// Retrieve the module map.
getModuleMap()805   ModuleMap &getModuleMap() { return ModMap; }
806 
807   /// Retrieve the module map.
getModuleMap()808   const ModuleMap &getModuleMap() const { return ModMap; }
809 
header_file_size()810   unsigned header_file_size() const { return FileInfo.size(); }
811 
812   /// Return the HeaderFileInfo structure for the specified FileEntry,
813   /// in preparation for updating it in some way.
814   HeaderFileInfo &getFileInfo(FileEntryRef FE);
815 
816   /// Return the HeaderFileInfo structure for the specified FileEntry,
817   /// if it has ever been filled in.
818   /// \param WantExternal Whether the caller wants purely-external header file
819   ///        info (where \p External is true).
820   const HeaderFileInfo *getExistingFileInfo(FileEntryRef FE,
821                                             bool WantExternal = true) const;
822 
search_dir_begin()823   SearchDirIterator search_dir_begin() { return {*this, 0}; }
search_dir_end()824   SearchDirIterator search_dir_end() { return {*this, SearchDirs.size()}; }
search_dir_range()825   SearchDirRange search_dir_range() {
826     return {search_dir_begin(), search_dir_end()};
827   }
828 
search_dir_begin()829   ConstSearchDirIterator search_dir_begin() const { return quoted_dir_begin(); }
search_dir_nth(size_t n)830   ConstSearchDirIterator search_dir_nth(size_t n) const {
831     assert(n < SearchDirs.size());
832     return {*this, n};
833   }
search_dir_end()834   ConstSearchDirIterator search_dir_end() const { return system_dir_end(); }
search_dir_range()835   ConstSearchDirRange search_dir_range() const {
836     return {search_dir_begin(), search_dir_end()};
837   }
838 
search_dir_size()839   unsigned search_dir_size() const { return SearchDirs.size(); }
840 
quoted_dir_begin()841   ConstSearchDirIterator quoted_dir_begin() const { return {*this, 0}; }
quoted_dir_end()842   ConstSearchDirIterator quoted_dir_end() const { return angled_dir_begin(); }
843 
angled_dir_begin()844   ConstSearchDirIterator angled_dir_begin() const {
845     return {*this, AngledDirIdx};
846   }
angled_dir_end()847   ConstSearchDirIterator angled_dir_end() const { return system_dir_begin(); }
848 
system_dir_begin()849   ConstSearchDirIterator system_dir_begin() const {
850     return {*this, SystemDirIdx};
851   }
system_dir_end()852   ConstSearchDirIterator system_dir_end() const {
853     return {*this, SearchDirs.size()};
854   }
855 
856   /// Get the index of the given search directory.
857   unsigned searchDirIdx(const DirectoryLookup &DL) const;
858 
859   /// Retrieve a uniqued framework name.
860   StringRef getUniqueFrameworkName(StringRef Framework);
861 
862   /// Retrieve the include name for the header.
863   ///
864   /// \param File The entry for a given header.
865   /// \returns The name of how the file was included when the header's location
866   /// was resolved.
867   StringRef getIncludeNameForHeader(const FileEntry *File) const;
868 
869   /// Suggest a path by which the specified file could be found, for use in
870   /// diagnostics to suggest a #include. Returned path will only contain forward
871   /// slashes as separators. MainFile is the absolute path of the file that we
872   /// are generating the diagnostics for. It will try to shorten the path using
873   /// MainFile location, if none of the include search directories were prefix
874   /// of File.
875   ///
876   /// \param IsAngled If non-null, filled in to indicate whether the suggested
877   ///        path should be referenced as <Header.h> instead of "Header.h".
878   std::string suggestPathToFileForDiagnostics(FileEntryRef File,
879                                               llvm::StringRef MainFile,
880                                               bool *IsAngled = nullptr) const;
881 
882   /// Suggest a path by which the specified file could be found, for use in
883   /// diagnostics to suggest a #include. Returned path will only contain forward
884   /// slashes as separators. MainFile is the absolute path of the file that we
885   /// are generating the diagnostics for. It will try to shorten the path using
886   /// MainFile location, if none of the include search directories were prefix
887   /// of File.
888   ///
889   /// \param WorkingDir If non-empty, this will be prepended to search directory
890   /// paths that are relative.
891   std::string suggestPathToFileForDiagnostics(llvm::StringRef File,
892                                               llvm::StringRef WorkingDir,
893                                               llvm::StringRef MainFile,
894                                               bool *IsAngled = nullptr) const;
895 
896   void PrintStats();
897 
898   size_t getTotalMemory() const;
899 
900 private:
901   /// Describes what happened when we tried to load a module map file.
902   enum LoadModuleMapResult {
903     /// The module map file had already been loaded.
904     LMM_AlreadyLoaded,
905 
906     /// The module map file was loaded by this invocation.
907     LMM_NewlyLoaded,
908 
909     /// There is was directory with the given name.
910     LMM_NoDirectory,
911 
912     /// There was either no module map file or the module map file was
913     /// invalid.
914     LMM_InvalidModuleMap
915   };
916 
917   LoadModuleMapResult loadModuleMapFileImpl(FileEntryRef File, bool IsSystem,
918                                             DirectoryEntryRef Dir,
919                                             FileID ID = FileID(),
920                                             unsigned *Offset = nullptr);
921 
922   /// Try to load the module map file in the given directory.
923   ///
924   /// \param DirName The name of the directory where we will look for a module
925   /// map file.
926   /// \param IsSystem Whether this is a system header directory.
927   /// \param IsFramework Whether this is a framework directory.
928   ///
929   /// \returns The result of attempting to load the module map file from the
930   /// named directory.
931   LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem,
932                                         bool IsFramework);
933 
934   /// Try to load the module map file in the given directory.
935   ///
936   /// \param Dir The directory where we will look for a module map file.
937   /// \param IsSystem Whether this is a system header directory.
938   /// \param IsFramework Whether this is a framework directory.
939   ///
940   /// \returns The result of attempting to load the module map file from the
941   /// named directory.
942   LoadModuleMapResult loadModuleMapFile(DirectoryEntryRef Dir, bool IsSystem,
943                                         bool IsFramework);
944 };
945 
946 /// Apply the header search options to get given HeaderSearch object.
947 void ApplyHeaderSearchOptions(HeaderSearch &HS,
948                               const HeaderSearchOptions &HSOpts,
949                               const LangOptions &Lang,
950                               const llvm::Triple &triple);
951 
952 } // namespace clang
953 
954 #endif // LLVM_CLANG_LEX_HEADERSEARCH_H
955