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