clang API Documentation

HeaderSearch.h
Go to the documentation of this file.
00001 //===--- HeaderSearch.h - Resolve Header File Locations ---------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the HeaderSearch interface.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_LEX_HEADERSEARCH_H
00015 #define LLVM_CLANG_LEX_HEADERSEARCH_H
00016 
00017 #include "clang/Lex/DirectoryLookup.h"
00018 #include "clang/Lex/ModuleMap.h"
00019 #include "llvm/ADT/ArrayRef.h"
00020 #include "llvm/ADT/IntrusiveRefCntPtr.h"
00021 #include "llvm/ADT/StringMap.h"
00022 #include "llvm/ADT/StringSet.h"
00023 #include "llvm/Support/Allocator.h"
00024 #include <memory>
00025 #include <vector>
00026 
00027 namespace clang {
00028   
00029 class DiagnosticsEngine;  
00030 class ExternalIdentifierLookup;
00031 class FileEntry;
00032 class FileManager;
00033 class HeaderSearchOptions;
00034 class IdentifierInfo;
00035 
00036 /// \brief The preprocessor keeps track of this information for each
00037 /// file that is \#included.
00038 struct HeaderFileInfo {
00039   /// \brief True if this is a \#import'd or \#pragma once file.
00040   unsigned isImport : 1;
00041 
00042   /// \brief True if this is a \#pragma once file.
00043   unsigned isPragmaOnce : 1;
00044 
00045   /// DirInfo - Keep track of whether this is a system header, and if so,
00046   /// whether it is C++ clean or not.  This can be set by the include paths or
00047   /// by \#pragma gcc system_header.  This is an instance of
00048   /// SrcMgr::CharacteristicKind.
00049   unsigned DirInfo : 2;
00050 
00051   /// \brief Whether this header file info was supplied by an external source.
00052   unsigned External : 1;
00053 
00054   /// \brief Whether this header is part of a module.
00055   unsigned isModuleHeader : 1;
00056 
00057   /// \brief Whether this header is part of the module that we are building.
00058   unsigned isCompilingModuleHeader : 1;
00059 
00060   /// \brief Whether this header is part of the module that we are building.
00061   /// This is an instance of ModuleMap::ModuleHeaderRole.
00062   unsigned HeaderRole : 2;
00063   
00064   /// \brief Whether this structure is considered to already have been
00065   /// "resolved", meaning that it was loaded from the external source.
00066   unsigned Resolved : 1;
00067   
00068   /// \brief Whether this is a header inside a framework that is currently
00069   /// being built. 
00070   ///
00071   /// When a framework is being built, the headers have not yet been placed
00072   /// into the appropriate framework subdirectories, and therefore are
00073   /// provided via a header map. This bit indicates when this is one of
00074   /// those framework headers.
00075   unsigned IndexHeaderMapHeader : 1;
00076 
00077   /// \brief Whether this file had been looked up as a header.
00078   unsigned IsValid : 1;
00079   
00080   /// \brief The number of times the file has been included already.
00081   unsigned short NumIncludes;
00082 
00083   /// \brief The ID number of the controlling macro.
00084   ///
00085   /// This ID number will be non-zero when there is a controlling
00086   /// macro whose IdentifierInfo may not yet have been loaded from
00087   /// external storage.
00088   unsigned ControllingMacroID;
00089 
00090   /// If this file has a \#ifndef XXX (or equivalent) guard that
00091   /// protects the entire contents of the file, this is the identifier
00092   /// for the macro that controls whether or not it has any effect.
00093   ///
00094   /// Note: Most clients should use getControllingMacro() to access
00095   /// the controlling macro of this header, since
00096   /// getControllingMacro() is able to load a controlling macro from
00097   /// external storage.
00098   const IdentifierInfo *ControllingMacro;
00099 
00100   /// \brief If this header came from a framework include, this is the name
00101   /// of the framework.
00102   StringRef Framework;
00103   
00104   HeaderFileInfo()
00105     : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), 
00106       External(false), isModuleHeader(false), isCompilingModuleHeader(false),
00107       HeaderRole(ModuleMap::NormalHeader),
00108       Resolved(false), IndexHeaderMapHeader(false), IsValid(0),
00109       NumIncludes(0), ControllingMacroID(0), ControllingMacro(nullptr)  {}
00110 
00111   /// \brief Retrieve the controlling macro for this header file, if
00112   /// any.
00113   const IdentifierInfo *getControllingMacro(ExternalIdentifierLookup *External);
00114   
00115   /// \brief Determine whether this is a non-default header file info, e.g.,
00116   /// it corresponds to an actual header we've included or tried to include.
00117   bool isNonDefault() const {
00118     return isImport || isPragmaOnce || NumIncludes || ControllingMacro || 
00119       ControllingMacroID;
00120   }
00121 
00122   /// \brief Get the HeaderRole properly typed.
00123   ModuleMap::ModuleHeaderRole getHeaderRole() const {
00124     return static_cast<ModuleMap::ModuleHeaderRole>(HeaderRole);
00125   }
00126 
00127   /// \brief Set the HeaderRole properly typed.
00128   void setHeaderRole(ModuleMap::ModuleHeaderRole Role) {
00129     HeaderRole = Role;
00130   }
00131 };
00132 
00133 /// \brief An external source of header file information, which may supply
00134 /// information about header files already included.
00135 class ExternalHeaderFileInfoSource {
00136 public:
00137   virtual ~ExternalHeaderFileInfoSource();
00138   
00139   /// \brief Retrieve the header file information for the given file entry.
00140   ///
00141   /// \returns Header file information for the given file entry, with the
00142   /// \c External bit set. If the file entry is not known, return a 
00143   /// default-constructed \c HeaderFileInfo.
00144   virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0;
00145 };
00146   
00147 /// \brief Encapsulates the information needed to find the file referenced
00148 /// by a \#include or \#include_next, (sub-)framework lookup, etc.
00149 class HeaderSearch {
00150   /// This structure is used to record entries in our framework cache.
00151   struct FrameworkCacheEntry {
00152     /// The directory entry which should be used for the cached framework.
00153     const DirectoryEntry *Directory;
00154 
00155     /// Whether this framework has been "user-specified" to be treated as if it
00156     /// were a system framework (even if it was found outside a system framework
00157     /// directory).
00158     bool IsUserSpecifiedSystemFramework;
00159   };
00160 
00161   /// \brief Header-search options used to initialize this header search.
00162   IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
00163 
00164   DiagnosticsEngine &Diags;
00165   FileManager &FileMgr;
00166   /// \#include search path information.  Requests for \#include "x" search the
00167   /// directory of the \#including file first, then each directory in SearchDirs
00168   /// consecutively. Requests for <x> search the current dir first, then each
00169   /// directory in SearchDirs, starting at AngledDirIdx, consecutively.  If
00170   /// NoCurDirSearch is true, then the check for the file in the current
00171   /// directory is suppressed.
00172   std::vector<DirectoryLookup> SearchDirs;
00173   unsigned AngledDirIdx;
00174   unsigned SystemDirIdx;
00175   bool NoCurDirSearch;
00176 
00177   /// \brief \#include prefixes for which the 'system header' property is
00178   /// overridden.
00179   ///
00180   /// For a \#include "x" or \#include <x> directive, the last string in this
00181   /// list which is a prefix of 'x' determines whether the file is treated as
00182   /// a system header.
00183   std::vector<std::pair<std::string, bool> > SystemHeaderPrefixes;
00184 
00185   /// \brief The path to the module cache.
00186   std::string ModuleCachePath;
00187   
00188   /// \brief All of the preprocessor-specific data about files that are
00189   /// included, indexed by the FileEntry's UID.
00190   std::vector<HeaderFileInfo> FileInfo;
00191 
00192   /// Keeps track of each lookup performed by LookupFile.
00193   struct LookupFileCacheInfo {
00194     /// Starting index in SearchDirs that the cached search was performed from.
00195     /// If there is a hit and this value doesn't match the current query, the
00196     /// cache has to be ignored.
00197     unsigned StartIdx;
00198     /// The entry in SearchDirs that satisfied the query.
00199     unsigned HitIdx;
00200     /// This is non-null if the original filename was mapped to a framework
00201     /// include via a headermap.
00202     const char *MappedName;
00203 
00204     /// Default constructor -- Initialize all members with zero.
00205     LookupFileCacheInfo(): StartIdx(0), HitIdx(0), MappedName(nullptr) {}
00206 
00207     void reset(unsigned StartIdx) {
00208       this->StartIdx = StartIdx;
00209       this->MappedName = nullptr;
00210     }
00211   };
00212   llvm::StringMap<LookupFileCacheInfo, llvm::BumpPtrAllocator> LookupFileCache;
00213 
00214   /// \brief Collection mapping a framework or subframework
00215   /// name like "Carbon" to the Carbon.framework directory.
00216   llvm::StringMap<FrameworkCacheEntry, llvm::BumpPtrAllocator> FrameworkMap;
00217 
00218   /// IncludeAliases - maps include file names (including the quotes or
00219   /// angle brackets) to other include file names.  This is used to support the
00220   /// include_alias pragma for Microsoft compatibility.
00221   typedef llvm::StringMap<std::string, llvm::BumpPtrAllocator>
00222     IncludeAliasMap;
00223   std::unique_ptr<IncludeAliasMap> IncludeAliases;
00224 
00225   /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
00226   /// headermaps.  This vector owns the headermap.
00227   std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
00228 
00229   /// \brief The mapping between modules and headers.
00230   mutable ModuleMap ModMap;
00231   
00232   /// \brief Describes whether a given directory has a module map in it.
00233   llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap;
00234 
00235   /// \brief Set of module map files we've already loaded, and a flag indicating
00236   /// whether they were valid or not.
00237   llvm::DenseMap<const FileEntry *, bool> LoadedModuleMaps;
00238 
00239   /// \brief Uniqued set of framework names, which is used to track which 
00240   /// headers were included as framework headers.
00241   llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
00242   
00243   /// \brief Entity used to resolve the identifier IDs of controlling
00244   /// macros into IdentifierInfo pointers, as needed.
00245   ExternalIdentifierLookup *ExternalLookup;
00246 
00247   /// \brief Entity used to look up stored header file information.
00248   ExternalHeaderFileInfoSource *ExternalSource;
00249   
00250   // Various statistics we track for performance analysis.
00251   unsigned NumIncluded;
00252   unsigned NumMultiIncludeFileOptzn;
00253   unsigned NumFrameworkLookups, NumSubFrameworkLookups;
00254 
00255   bool EnabledModules;
00256 
00257   // HeaderSearch doesn't support default or copy construction.
00258   HeaderSearch(const HeaderSearch&) LLVM_DELETED_FUNCTION;
00259   void operator=(const HeaderSearch&) LLVM_DELETED_FUNCTION;
00260 
00261   friend class DirectoryLookup;
00262   
00263 public:
00264   HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
00265                SourceManager &SourceMgr, DiagnosticsEngine &Diags,
00266                const LangOptions &LangOpts, const TargetInfo *Target);
00267   ~HeaderSearch();
00268 
00269   /// \brief Retrieve the header-search options with which this header search
00270   /// was initialized.
00271   HeaderSearchOptions &getHeaderSearchOpts() const { return *HSOpts; }
00272   
00273   FileManager &getFileMgr() const { return FileMgr; }
00274 
00275   /// \brief Interface for setting the file search paths.
00276   void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
00277                       unsigned angledDirIdx, unsigned systemDirIdx,
00278                       bool noCurDirSearch) {
00279     assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
00280         "Directory indicies are unordered");
00281     SearchDirs = dirs;
00282     AngledDirIdx = angledDirIdx;
00283     SystemDirIdx = systemDirIdx;
00284     NoCurDirSearch = noCurDirSearch;
00285     //LookupFileCache.clear();
00286   }
00287 
00288   /// \brief Add an additional search path.
00289   void AddSearchPath(const DirectoryLookup &dir, bool isAngled) {
00290     unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
00291     SearchDirs.insert(SearchDirs.begin() + idx, dir);
00292     if (!isAngled)
00293       AngledDirIdx++;
00294     SystemDirIdx++;
00295   }
00296 
00297   /// \brief Set the list of system header prefixes.
00298   void SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string, bool> > P) {
00299     SystemHeaderPrefixes.assign(P.begin(), P.end());
00300   }
00301 
00302   /// \brief Checks whether the map exists or not.
00303   bool HasIncludeAliasMap() const { return (bool)IncludeAliases; }
00304 
00305   /// \brief Map the source include name to the dest include name.
00306   ///
00307   /// The Source should include the angle brackets or quotes, the dest 
00308   /// should not.  This allows for distinction between <> and "" headers.
00309   void AddIncludeAlias(StringRef Source, StringRef Dest) {
00310     if (!IncludeAliases)
00311       IncludeAliases.reset(new IncludeAliasMap);
00312     (*IncludeAliases)[Source] = Dest;
00313   }
00314 
00315   /// MapHeaderToIncludeAlias - Maps one header file name to a different header
00316   /// file name, for use with the include_alias pragma.  Note that the source
00317   /// file name should include the angle brackets or quotes.  Returns StringRef
00318   /// as null if the header cannot be mapped.
00319   StringRef MapHeaderToIncludeAlias(StringRef Source) {
00320     assert(IncludeAliases && "Trying to map headers when there's no map");
00321 
00322     // Do any filename replacements before anything else
00323     IncludeAliasMap::const_iterator Iter = IncludeAliases->find(Source);
00324     if (Iter != IncludeAliases->end())
00325       return Iter->second;
00326     return StringRef();
00327   }
00328 
00329   /// \brief Set the path to the module cache.
00330   void setModuleCachePath(StringRef CachePath) {
00331     ModuleCachePath = CachePath;
00332   }
00333   
00334   /// \brief Retrieve the path to the module cache.
00335   StringRef getModuleCachePath() const { return ModuleCachePath; }
00336 
00337   /// \brief Consider modules when including files from this directory.
00338   void setDirectoryHasModuleMap(const DirectoryEntry* Dir) {
00339     DirectoryHasModuleMap[Dir] = true;
00340   }
00341   
00342   /// \brief Forget everything we know about headers so far.
00343   void ClearFileInfo() {
00344     FileInfo.clear();
00345   }
00346 
00347   void SetExternalLookup(ExternalIdentifierLookup *EIL) {
00348     ExternalLookup = EIL;
00349   }
00350 
00351   ExternalIdentifierLookup *getExternalLookup() const {
00352     return ExternalLookup;
00353   }
00354   
00355   /// \brief Set the external source of header information.
00356   void SetExternalSource(ExternalHeaderFileInfoSource *ES) {
00357     ExternalSource = ES;
00358   }
00359   
00360   /// \brief Set the target information for the header search, if not
00361   /// already known.
00362   void setTarget(const TargetInfo &Target);
00363   
00364   /// \brief Given a "foo" or <foo> reference, look up the indicated file,
00365   /// return null on failure.
00366   ///
00367   /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
00368   /// the file was found in, or null if not applicable.
00369   ///
00370   /// \param IncludeLoc Used for diagnostics if valid.
00371   ///
00372   /// \param isAngled indicates whether the file reference is a <> reference.
00373   ///
00374   /// \param CurDir If non-null, the file was found in the specified directory
00375   /// search location.  This is used to implement \#include_next.
00376   ///
00377   /// \param Includers Indicates where the \#including file(s) are, in case
00378   /// relative searches are needed. In reverse order of inclusion.
00379   ///
00380   /// \param SearchPath If non-null, will be set to the search path relative
00381   /// to which the file was found. If the include path is absolute, SearchPath
00382   /// will be set to an empty string.
00383   ///
00384   /// \param RelativePath If non-null, will be set to the path relative to
00385   /// SearchPath at which the file was found. This only differs from the
00386   /// Filename for framework includes.
00387   ///
00388   /// \param SuggestedModule If non-null, and the file found is semantically
00389   /// part of a known module, this will be set to the module that should
00390   /// be imported instead of preprocessing/parsing the file found.
00391   const FileEntry *LookupFile(
00392       StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
00393       const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir,
00394       ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
00395       SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
00396       ModuleMap::KnownHeader *SuggestedModule, bool SkipCache = false);
00397 
00398   /// \brief Look up a subframework for the specified \#include file.
00399   ///
00400   /// For example, if \#include'ing <HIToolbox/HIToolbox.h> from
00401   /// within ".../Carbon.framework/Headers/Carbon.h", check to see if
00402   /// HIToolbox is a subframework within Carbon.framework.  If so, return
00403   /// the FileEntry for the designated file, otherwise return null.
00404   const FileEntry *LookupSubframeworkHeader(
00405       StringRef Filename,
00406       const FileEntry *RelativeFileEnt,
00407       SmallVectorImpl<char> *SearchPath,
00408       SmallVectorImpl<char> *RelativePath,
00409       ModuleMap::KnownHeader *SuggestedModule);
00410 
00411   /// \brief Look up the specified framework name in our framework cache.
00412   /// \returns The DirectoryEntry it is in if we know, null otherwise.
00413   FrameworkCacheEntry &LookupFrameworkCache(StringRef FWName) {
00414     return FrameworkMap.GetOrCreateValue(FWName).getValue();
00415   }
00416 
00417   /// \brief Mark the specified file as a target of of a \#include,
00418   /// \#include_next, or \#import directive.
00419   ///
00420   /// \return false if \#including the file will have no effect or true
00421   /// if we should include it.
00422   bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport);
00423 
00424 
00425   /// \brief Return whether the specified file is a normal header,
00426   /// a system header, or a C++ friendly system header.
00427   SrcMgr::CharacteristicKind getFileDirFlavor(const FileEntry *File) {
00428     return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo;
00429   }
00430 
00431   /// \brief Mark the specified file as a "once only" file, e.g. due to
00432   /// \#pragma once.
00433   void MarkFileIncludeOnce(const FileEntry *File) {
00434     HeaderFileInfo &FI = getFileInfo(File);
00435     FI.isImport = true;
00436     FI.isPragmaOnce = true;
00437   }
00438 
00439   /// \brief Mark the specified file as a system header, e.g. due to
00440   /// \#pragma GCC system_header.
00441   void MarkFileSystemHeader(const FileEntry *File) {
00442     getFileInfo(File).DirInfo = SrcMgr::C_System;
00443   }
00444 
00445   /// \brief Mark the specified file as part of a module.
00446   void MarkFileModuleHeader(const FileEntry *File,
00447                             ModuleMap::ModuleHeaderRole Role,
00448                             bool IsCompiledModuleHeader);
00449 
00450   /// \brief Increment the count for the number of times the specified
00451   /// FileEntry has been entered.
00452   void IncrementIncludeCount(const FileEntry *File) {
00453     ++getFileInfo(File).NumIncludes;
00454   }
00455 
00456   /// \brief Mark the specified file as having a controlling macro.
00457   ///
00458   /// This is used by the multiple-include optimization to eliminate
00459   /// no-op \#includes.
00460   void SetFileControllingMacro(const FileEntry *File,
00461                                const IdentifierInfo *ControllingMacro) {
00462     getFileInfo(File).ControllingMacro = ControllingMacro;
00463   }
00464 
00465   /// \brief Return true if this is the first time encountering this header.
00466   bool FirstTimeLexingFile(const FileEntry *File) {
00467     return getFileInfo(File).NumIncludes == 1;
00468   }
00469 
00470   /// \brief Determine whether this file is intended to be safe from
00471   /// multiple inclusions, e.g., it has \#pragma once or a controlling
00472   /// macro.
00473   ///
00474   /// This routine does not consider the effect of \#import
00475   bool isFileMultipleIncludeGuarded(const FileEntry *File);
00476 
00477   /// CreateHeaderMap - This method returns a HeaderMap for the specified
00478   /// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
00479   const HeaderMap *CreateHeaderMap(const FileEntry *FE);
00480 
00481   /// Returns true if modules are enabled.
00482   bool enabledModules() const { return EnabledModules; }
00483 
00484   /// \brief Retrieve the name of the module file that should be used to 
00485   /// load the given module.
00486   ///
00487   /// \param Module The module whose module file name will be returned.
00488   ///
00489   /// \returns The name of the module file that corresponds to this module,
00490   /// or an empty string if this module does not correspond to any module file.
00491   std::string getModuleFileName(Module *Module);
00492 
00493   /// \brief Retrieve the name of the module file that should be used to 
00494   /// load a module with the given name.
00495   ///
00496   /// \param ModuleName The module whose module file name will be returned.
00497   ///
00498   /// \param ModuleMapPath A path that when combined with \c ModuleName
00499   /// uniquely identifies this module. See Module::ModuleMap.
00500   ///
00501   /// \returns The name of the module file that corresponds to this module,
00502   /// or an empty string if this module does not correspond to any module file.
00503   std::string getModuleFileName(StringRef ModuleName, StringRef ModuleMapPath);
00504 
00505   /// \brief Lookup a module Search for a module with the given name.
00506   ///
00507   /// \param ModuleName The name of the module we're looking for.
00508   ///
00509   /// \param AllowSearch Whether we are allowed to search in the various
00510   /// search directories to produce a module definition. If not, this lookup
00511   /// will only return an already-known module.
00512   ///
00513   /// \returns The module with the given name.
00514   Module *lookupModule(StringRef ModuleName, bool AllowSearch = true);
00515 
00516   /// \brief Try to find a module map file in the given directory, returning
00517   /// \c nullptr if none is found.
00518   const FileEntry *lookupModuleMapFile(const DirectoryEntry *Dir,
00519                                        bool IsFramework);
00520   
00521   void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
00522 
00523   /// \brief Determine whether there is a module map that may map the header
00524   /// with the given file name to a (sub)module.
00525   /// Always returns false if modules are disabled.
00526   ///
00527   /// \param Filename The name of the file.
00528   ///
00529   /// \param Root The "root" directory, at which we should stop looking for
00530   /// module maps.
00531   ///
00532   /// \param IsSystem Whether the directories we're looking at are system
00533   /// header directories.
00534   bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root,
00535                     bool IsSystem);
00536   
00537   /// \brief Retrieve the module that corresponds to the given file, if any.
00538   ///
00539   /// \param File The header that we wish to map to a module.
00540   ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File) const;
00541   
00542   /// \brief Read the contents of the given module map file.
00543   ///
00544   /// \param File The module map file.
00545   /// \param IsSystem Whether this file is in a system header directory.
00546   ///
00547   /// \returns true if an error occurred, false otherwise.
00548   bool loadModuleMapFile(const FileEntry *File, bool IsSystem);
00549 
00550   /// \brief Collect the set of all known, top-level modules.
00551   ///
00552   /// \param Modules Will be filled with the set of known, top-level modules.
00553   void collectAllModules(SmallVectorImpl<Module *> &Modules);
00554 
00555   /// \brief Load all known, top-level system modules.
00556   void loadTopLevelSystemModules();
00557 
00558 private:
00559   /// \brief Retrieve a module with the given name, which may be part of the
00560   /// given framework.
00561   ///
00562   /// \param Name The name of the module to retrieve.
00563   ///
00564   /// \param Dir The framework directory (e.g., ModuleName.framework).
00565   ///
00566   /// \param IsSystem Whether the framework directory is part of the system
00567   /// frameworks.
00568   ///
00569   /// \returns The module, if found; otherwise, null.
00570   Module *loadFrameworkModule(StringRef Name, 
00571                               const DirectoryEntry *Dir,
00572                               bool IsSystem);
00573 
00574   /// \brief Load all of the module maps within the immediate subdirectories
00575   /// of the given search directory.
00576   void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir);
00577 
00578   /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
00579   const HeaderFileInfo &getFileInfo(const FileEntry *FE) const {
00580     return const_cast<HeaderSearch*>(this)->getFileInfo(FE);
00581   }
00582 
00583 public:
00584   /// \brief Retrieve the module map.
00585   ModuleMap &getModuleMap() { return ModMap; }
00586   
00587   unsigned header_file_size() const { return FileInfo.size(); }
00588 
00589   /// \brief Get a \c HeaderFileInfo structure for the specified \c FileEntry,
00590   /// if one exists.
00591   bool tryGetFileInfo(const FileEntry *FE, HeaderFileInfo &Result) const;
00592 
00593   // Used by external tools
00594   typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
00595   search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
00596   search_dir_iterator search_dir_end() const { return SearchDirs.end(); }
00597   unsigned search_dir_size() const { return SearchDirs.size(); }
00598 
00599   search_dir_iterator quoted_dir_begin() const {
00600     return SearchDirs.begin();
00601   }
00602   search_dir_iterator quoted_dir_end() const {
00603     return SearchDirs.begin() + AngledDirIdx;
00604   }
00605 
00606   search_dir_iterator angled_dir_begin() const {
00607     return SearchDirs.begin() + AngledDirIdx;
00608   }
00609   search_dir_iterator angled_dir_end() const {
00610     return SearchDirs.begin() + SystemDirIdx;
00611   }
00612 
00613   search_dir_iterator system_dir_begin() const {
00614     return SearchDirs.begin() + SystemDirIdx;
00615   }
00616   search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
00617 
00618   /// \brief Retrieve a uniqued framework name.
00619   StringRef getUniqueFrameworkName(StringRef Framework);
00620   
00621   void PrintStats();
00622   
00623   size_t getTotalMemory() const;
00624 
00625   static std::string NormalizeDashIncludePath(StringRef File,
00626                                               FileManager &FileMgr);
00627 
00628 private:
00629   /// \brief Describes what happened when we tried to load a module map file.
00630   enum LoadModuleMapResult {
00631     /// \brief The module map file had already been loaded.
00632     LMM_AlreadyLoaded,
00633     /// \brief The module map file was loaded by this invocation.
00634     LMM_NewlyLoaded,
00635     /// \brief There is was directory with the given name.
00636     LMM_NoDirectory,
00637     /// \brief There was either no module map file or the module map file was
00638     /// invalid.
00639     LMM_InvalidModuleMap
00640   };
00641 
00642   LoadModuleMapResult loadModuleMapFileImpl(const FileEntry *File,
00643                                             bool IsSystem);
00644 
00645   /// \brief Try to load the module map file in the given directory.
00646   ///
00647   /// \param DirName The name of the directory where we will look for a module
00648   /// map file.
00649   /// \param IsSystem Whether this is a system header directory.
00650   /// \param IsFramework Whether this is a framework directory.
00651   ///
00652   /// \returns The result of attempting to load the module map file from the
00653   /// named directory.
00654   LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem,
00655                                         bool IsFramework);
00656 
00657   /// \brief Try to load the module map file in the given directory.
00658   ///
00659   /// \param Dir The directory where we will look for a module map file.
00660   /// \param IsSystem Whether this is a system header directory.
00661   /// \param IsFramework Whether this is a framework directory.
00662   ///
00663   /// \returns The result of attempting to load the module map file from the
00664   /// named directory.
00665   LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir,
00666                                         bool IsSystem, bool IsFramework);
00667 
00668   /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
00669   HeaderFileInfo &getFileInfo(const FileEntry *FE);
00670 };
00671 
00672 }  // end namespace clang
00673 
00674 #endif