clang API Documentation

HeaderSearch.cpp
Go to the documentation of this file.
00001 //===--- HeaderSearch.cpp - Resolve Header File Locations ---===//
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 implements the DirectoryLookup and HeaderSearch interfaces.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "clang/Lex/HeaderSearch.h"
00015 #include "clang/Basic/FileManager.h"
00016 #include "clang/Basic/IdentifierTable.h"
00017 #include "clang/Lex/HeaderMap.h"
00018 #include "clang/Lex/HeaderSearchOptions.h"
00019 #include "clang/Lex/LexDiagnostic.h"
00020 #include "clang/Lex/Lexer.h"
00021 #include "llvm/ADT/APInt.h"
00022 #include "llvm/ADT/Hashing.h"
00023 #include "llvm/ADT/SmallString.h"
00024 #include "llvm/Support/Capacity.h"
00025 #include "llvm/Support/FileSystem.h"
00026 #include "llvm/Support/Path.h"
00027 #include "llvm/Support/raw_ostream.h"
00028 #include <cstdio>
00029 #if defined(LLVM_ON_UNIX)
00030 #include <limits.h>
00031 #endif
00032 using namespace clang;
00033 
00034 const IdentifierInfo *
00035 HeaderFileInfo::getControllingMacro(ExternalIdentifierLookup *External) {
00036   if (ControllingMacro)
00037     return ControllingMacro;
00038 
00039   if (!ControllingMacroID || !External)
00040     return nullptr;
00041 
00042   ControllingMacro = External->GetIdentifier(ControllingMacroID);
00043   return ControllingMacro;
00044 }
00045 
00046 ExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() {}
00047 
00048 HeaderSearch::HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
00049                            SourceManager &SourceMgr, DiagnosticsEngine &Diags,
00050                            const LangOptions &LangOpts,
00051                            const TargetInfo *Target)
00052     : HSOpts(HSOpts), Diags(Diags), FileMgr(SourceMgr.getFileManager()),
00053       FrameworkMap(64), ModMap(SourceMgr, Diags, LangOpts, Target, *this) {
00054   AngledDirIdx = 0;
00055   SystemDirIdx = 0;
00056   NoCurDirSearch = false;
00057 
00058   ExternalLookup = nullptr;
00059   ExternalSource = nullptr;
00060   NumIncluded = 0;
00061   NumMultiIncludeFileOptzn = 0;
00062   NumFrameworkLookups = NumSubFrameworkLookups = 0;
00063 
00064   EnabledModules = LangOpts.Modules;
00065 }
00066 
00067 HeaderSearch::~HeaderSearch() {
00068   // Delete headermaps.
00069   for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
00070     delete HeaderMaps[i].second;
00071 }
00072 
00073 void HeaderSearch::PrintStats() {
00074   fprintf(stderr, "\n*** HeaderSearch Stats:\n");
00075   fprintf(stderr, "%d files tracked.\n", (int)FileInfo.size());
00076   unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0;
00077   for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) {
00078     NumOnceOnlyFiles += FileInfo[i].isImport;
00079     if (MaxNumIncludes < FileInfo[i].NumIncludes)
00080       MaxNumIncludes = FileInfo[i].NumIncludes;
00081     NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1;
00082   }
00083   fprintf(stderr, "  %d #import/#pragma once files.\n", NumOnceOnlyFiles);
00084   fprintf(stderr, "  %d included exactly once.\n", NumSingleIncludedFiles);
00085   fprintf(stderr, "  %d max times a file is included.\n", MaxNumIncludes);
00086 
00087   fprintf(stderr, "  %d #include/#include_next/#import.\n", NumIncluded);
00088   fprintf(stderr, "    %d #includes skipped due to"
00089           " the multi-include optimization.\n", NumMultiIncludeFileOptzn);
00090 
00091   fprintf(stderr, "%d framework lookups.\n", NumFrameworkLookups);
00092   fprintf(stderr, "%d subframework lookups.\n", NumSubFrameworkLookups);
00093 }
00094 
00095 /// CreateHeaderMap - This method returns a HeaderMap for the specified
00096 /// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
00097 const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) {
00098   // We expect the number of headermaps to be small, and almost always empty.
00099   // If it ever grows, use of a linear search should be re-evaluated.
00100   if (!HeaderMaps.empty()) {
00101     for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
00102       // Pointer equality comparison of FileEntries works because they are
00103       // already uniqued by inode.
00104       if (HeaderMaps[i].first == FE)
00105         return HeaderMaps[i].second;
00106   }
00107 
00108   if (const HeaderMap *HM = HeaderMap::Create(FE, FileMgr)) {
00109     HeaderMaps.push_back(std::make_pair(FE, HM));
00110     return HM;
00111   }
00112 
00113   return nullptr;
00114 }
00115 
00116 std::string HeaderSearch::getModuleFileName(Module *Module) {
00117   const FileEntry *ModuleMap =
00118       getModuleMap().getModuleMapFileForUniquing(Module);
00119   return getModuleFileName(Module->Name, ModuleMap->getName());
00120 }
00121 
00122 std::string HeaderSearch::getModuleFileName(StringRef ModuleName,
00123                                             StringRef ModuleMapPath) {
00124   // If we don't have a module cache path, we can't do anything.
00125   if (ModuleCachePath.empty()) 
00126     return std::string();
00127 
00128   SmallString<256> Result(ModuleCachePath);
00129   llvm::sys::fs::make_absolute(Result);
00130 
00131   if (HSOpts->DisableModuleHash) {
00132     llvm::sys::path::append(Result, ModuleName + ".pcm");
00133   } else {
00134     // Construct the name <ModuleName>-<hash of ModuleMapPath>.pcm which should
00135     // be globally unique to this particular module. To avoid false-negatives
00136     // on case-insensitive filesystems, we use lower-case, which is safe because
00137     // to cause a collision the modules must have the same name, which is an
00138     // error if they are imported in the same translation.
00139     SmallString<256> AbsModuleMapPath(ModuleMapPath);
00140     llvm::sys::fs::make_absolute(AbsModuleMapPath);
00141     llvm::APInt Code(64, llvm::hash_value(AbsModuleMapPath.str().lower()));
00142     SmallString<128> HashStr;
00143     Code.toStringUnsigned(HashStr, /*Radix*/36);
00144     llvm::sys::path::append(Result, ModuleName + "-" + HashStr.str() + ".pcm");
00145   }
00146   return Result.str().str();
00147 }
00148 
00149 Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) {
00150   // Look in the module map to determine if there is a module by this name.
00151   Module *Module = ModMap.findModule(ModuleName);
00152   if (Module || !AllowSearch)
00153     return Module;
00154   
00155   // Look through the various header search paths to load any available module
00156   // maps, searching for a module map that describes this module.
00157   for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
00158     if (SearchDirs[Idx].isFramework()) {
00159       // Search for or infer a module map for a framework.
00160       SmallString<128> FrameworkDirName;
00161       FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName();
00162       llvm::sys::path::append(FrameworkDirName, ModuleName + ".framework");
00163       if (const DirectoryEntry *FrameworkDir 
00164             = FileMgr.getDirectory(FrameworkDirName)) {
00165         bool IsSystem
00166           = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User;
00167         Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem);
00168         if (Module)
00169           break;
00170       }
00171     }
00172     
00173     // FIXME: Figure out how header maps and module maps will work together.
00174     
00175     // Only deal with normal search directories.
00176     if (!SearchDirs[Idx].isNormalDir())
00177       continue;
00178 
00179     bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
00180     // Search for a module map file in this directory.
00181     if (loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem,
00182                           /*IsFramework*/false) == LMM_NewlyLoaded) {
00183       // We just loaded a module map file; check whether the module is
00184       // available now.
00185       Module = ModMap.findModule(ModuleName);
00186       if (Module)
00187         break;
00188     }
00189               
00190     // Search for a module map in a subdirectory with the same name as the
00191     // module.
00192     SmallString<128> NestedModuleMapDirName;
00193     NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName();
00194     llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
00195     if (loadModuleMapFile(NestedModuleMapDirName, IsSystem,
00196                           /*IsFramework*/false) == LMM_NewlyLoaded){
00197       // If we just loaded a module map file, look for the module again.
00198       Module = ModMap.findModule(ModuleName);
00199       if (Module)
00200         break;
00201     }
00202 
00203     // If we've already performed the exhaustive search for module maps in this
00204     // search directory, don't do it again.
00205     if (SearchDirs[Idx].haveSearchedAllModuleMaps())
00206       continue;
00207 
00208     // Load all module maps in the immediate subdirectories of this search
00209     // directory.
00210     loadSubdirectoryModuleMaps(SearchDirs[Idx]);
00211 
00212     // Look again for the module.
00213     Module = ModMap.findModule(ModuleName);
00214     if (Module)
00215       break;
00216   }
00217 
00218   return Module;
00219 }
00220 
00221 //===----------------------------------------------------------------------===//
00222 // File lookup within a DirectoryLookup scope
00223 //===----------------------------------------------------------------------===//
00224 
00225 /// getName - Return the directory or filename corresponding to this lookup
00226 /// object.
00227 const char *DirectoryLookup::getName() const {
00228   if (isNormalDir())
00229     return getDir()->getName();
00230   if (isFramework())
00231     return getFrameworkDir()->getName();
00232   assert(isHeaderMap() && "Unknown DirectoryLookup");
00233   return getHeaderMap()->getFileName();
00234 }
00235 
00236 static const FileEntry *
00237 getFileAndSuggestModule(HeaderSearch &HS, StringRef FileName,
00238                         const DirectoryEntry *Dir, bool IsSystemHeaderDir,
00239                         ModuleMap::KnownHeader *SuggestedModule) {
00240   // If we have a module map that might map this header, load it and
00241   // check whether we'll have a suggestion for a module.
00242   HS.hasModuleMap(FileName, Dir, IsSystemHeaderDir);
00243   if (SuggestedModule) {
00244     const FileEntry *File = HS.getFileMgr().getFile(FileName,
00245                                                     /*OpenFile=*/false);
00246     if (File) {
00247       // If there is a module that corresponds to this header, suggest it.
00248       *SuggestedModule = HS.findModuleForHeader(File);
00249 
00250       // FIXME: This appears to be a no-op. We loaded the module map for this
00251       // directory at the start of this function.
00252       if (!SuggestedModule->getModule() &&
00253           HS.hasModuleMap(FileName, Dir, IsSystemHeaderDir))
00254         *SuggestedModule = HS.findModuleForHeader(File);
00255     }
00256 
00257     return File;
00258   }
00259 
00260   return HS.getFileMgr().getFile(FileName, /*openFile=*/true);
00261 }
00262 
00263 /// LookupFile - Lookup the specified file in this search path, returning it
00264 /// if it exists or returning null if not.
00265 const FileEntry *DirectoryLookup::LookupFile(
00266     StringRef &Filename,
00267     HeaderSearch &HS,
00268     SmallVectorImpl<char> *SearchPath,
00269     SmallVectorImpl<char> *RelativePath,
00270     ModuleMap::KnownHeader *SuggestedModule,
00271     bool &InUserSpecifiedSystemFramework,
00272     bool &HasBeenMapped,
00273     SmallVectorImpl<char> &MappedName) const {
00274   InUserSpecifiedSystemFramework = false;
00275   HasBeenMapped = false;
00276 
00277   SmallString<1024> TmpDir;
00278   if (isNormalDir()) {
00279     // Concatenate the requested file onto the directory.
00280     TmpDir = getDir()->getName();
00281     llvm::sys::path::append(TmpDir, Filename);
00282     if (SearchPath) {
00283       StringRef SearchPathRef(getDir()->getName());
00284       SearchPath->clear();
00285       SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
00286     }
00287     if (RelativePath) {
00288       RelativePath->clear();
00289       RelativePath->append(Filename.begin(), Filename.end());
00290     }
00291 
00292     return getFileAndSuggestModule(HS, TmpDir.str(), getDir(),
00293                                    isSystemHeaderDirectory(),
00294                                    SuggestedModule);
00295   }
00296 
00297   if (isFramework())
00298     return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
00299                              SuggestedModule, InUserSpecifiedSystemFramework);
00300 
00301   assert(isHeaderMap() && "Unknown directory lookup");
00302   const HeaderMap *HM = getHeaderMap();
00303   SmallString<1024> Path;
00304   StringRef Dest = HM->lookupFilename(Filename, Path);
00305   if (Dest.empty())
00306     return nullptr;
00307 
00308   const FileEntry *Result;
00309 
00310   // Check if the headermap maps the filename to a framework include
00311   // ("Foo.h" -> "Foo/Foo.h"), in which case continue header lookup using the
00312   // framework include.
00313   if (llvm::sys::path::is_relative(Dest)) {
00314     MappedName.clear();
00315     MappedName.append(Dest.begin(), Dest.end());
00316     Filename = StringRef(MappedName.begin(), MappedName.size());
00317     HasBeenMapped = true;
00318     Result = HM->LookupFile(Filename, HS.getFileMgr());
00319 
00320   } else {
00321     Result = HS.getFileMgr().getFile(Dest);
00322   }
00323 
00324   if (Result) {
00325     if (SearchPath) {
00326       StringRef SearchPathRef(getName());
00327       SearchPath->clear();
00328       SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
00329     }
00330     if (RelativePath) {
00331       RelativePath->clear();
00332       RelativePath->append(Filename.begin(), Filename.end());
00333     }
00334   }
00335   return Result;
00336 }
00337 
00338 /// \brief Given a framework directory, find the top-most framework directory.
00339 ///
00340 /// \param FileMgr The file manager to use for directory lookups.
00341 /// \param DirName The name of the framework directory.
00342 /// \param SubmodulePath Will be populated with the submodule path from the
00343 /// returned top-level module to the originally named framework.
00344 static const DirectoryEntry *
00345 getTopFrameworkDir(FileManager &FileMgr, StringRef DirName,
00346                    SmallVectorImpl<std::string> &SubmodulePath) {
00347   assert(llvm::sys::path::extension(DirName) == ".framework" &&
00348          "Not a framework directory");
00349 
00350   // Note: as an egregious but useful hack we use the real path here, because
00351   // frameworks moving between top-level frameworks to embedded frameworks tend
00352   // to be symlinked, and we base the logical structure of modules on the
00353   // physical layout. In particular, we need to deal with crazy includes like
00354   //
00355   //   #include <Foo/Frameworks/Bar.framework/Headers/Wibble.h>
00356   //
00357   // where 'Bar' used to be embedded in 'Foo', is now a top-level framework
00358   // which one should access with, e.g.,
00359   //
00360   //   #include <Bar/Wibble.h>
00361   //
00362   // Similar issues occur when a top-level framework has moved into an
00363   // embedded framework.
00364   const DirectoryEntry *TopFrameworkDir = FileMgr.getDirectory(DirName);
00365   DirName = FileMgr.getCanonicalName(TopFrameworkDir);
00366   do {
00367     // Get the parent directory name.
00368     DirName = llvm::sys::path::parent_path(DirName);
00369     if (DirName.empty())
00370       break;
00371 
00372     // Determine whether this directory exists.
00373     const DirectoryEntry *Dir = FileMgr.getDirectory(DirName);
00374     if (!Dir)
00375       break;
00376 
00377     // If this is a framework directory, then we're a subframework of this
00378     // framework.
00379     if (llvm::sys::path::extension(DirName) == ".framework") {
00380       SubmodulePath.push_back(llvm::sys::path::stem(DirName));
00381       TopFrameworkDir = Dir;
00382     }
00383   } while (true);
00384 
00385   return TopFrameworkDir;
00386 }
00387 
00388 /// DoFrameworkLookup - Do a lookup of the specified file in the current
00389 /// DirectoryLookup, which is a framework directory.
00390 const FileEntry *DirectoryLookup::DoFrameworkLookup(
00391     StringRef Filename,
00392     HeaderSearch &HS,
00393     SmallVectorImpl<char> *SearchPath,
00394     SmallVectorImpl<char> *RelativePath,
00395     ModuleMap::KnownHeader *SuggestedModule,
00396     bool &InUserSpecifiedSystemFramework) const
00397 {
00398   FileManager &FileMgr = HS.getFileMgr();
00399 
00400   // Framework names must have a '/' in the filename.
00401   size_t SlashPos = Filename.find('/');
00402   if (SlashPos == StringRef::npos) return nullptr;
00403 
00404   // Find out if this is the home for the specified framework, by checking
00405   // HeaderSearch.  Possible answers are yes/no and unknown.
00406   HeaderSearch::FrameworkCacheEntry &CacheEntry =
00407     HS.LookupFrameworkCache(Filename.substr(0, SlashPos));
00408 
00409   // If it is known and in some other directory, fail.
00410   if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDir())
00411     return nullptr;
00412 
00413   // Otherwise, construct the path to this framework dir.
00414 
00415   // FrameworkName = "/System/Library/Frameworks/"
00416   SmallString<1024> FrameworkName;
00417   FrameworkName += getFrameworkDir()->getName();
00418   if (FrameworkName.empty() || FrameworkName.back() != '/')
00419     FrameworkName.push_back('/');
00420 
00421   // FrameworkName = "/System/Library/Frameworks/Cocoa"
00422   StringRef ModuleName(Filename.begin(), SlashPos);
00423   FrameworkName += ModuleName;
00424 
00425   // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/"
00426   FrameworkName += ".framework/";
00427 
00428   // If the cache entry was unresolved, populate it now.
00429   if (!CacheEntry.Directory) {
00430     HS.IncrementFrameworkLookupCount();
00431 
00432     // If the framework dir doesn't exist, we fail.
00433     const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str());
00434     if (!Dir) return nullptr;
00435 
00436     // Otherwise, if it does, remember that this is the right direntry for this
00437     // framework.
00438     CacheEntry.Directory = getFrameworkDir();
00439 
00440     // If this is a user search directory, check if the framework has been
00441     // user-specified as a system framework.
00442     if (getDirCharacteristic() == SrcMgr::C_User) {
00443       SmallString<1024> SystemFrameworkMarker(FrameworkName);
00444       SystemFrameworkMarker += ".system_framework";
00445       if (llvm::sys::fs::exists(SystemFrameworkMarker.str())) {
00446         CacheEntry.IsUserSpecifiedSystemFramework = true;
00447       }
00448     }
00449   }
00450 
00451   // Set the 'user-specified system framework' flag.
00452   InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework;
00453 
00454   if (RelativePath) {
00455     RelativePath->clear();
00456     RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
00457   }
00458   
00459   // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
00460   unsigned OrigSize = FrameworkName.size();
00461 
00462   FrameworkName += "Headers/";
00463 
00464   if (SearchPath) {
00465     SearchPath->clear();
00466     // Without trailing '/'.
00467     SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
00468   }
00469 
00470   FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
00471   const FileEntry *FE = FileMgr.getFile(FrameworkName.str(),
00472                                         /*openFile=*/!SuggestedModule);
00473   if (!FE) {
00474     // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
00475     const char *Private = "Private";
00476     FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
00477                          Private+strlen(Private));
00478     if (SearchPath)
00479       SearchPath->insert(SearchPath->begin()+OrigSize, Private,
00480                          Private+strlen(Private));
00481 
00482     FE = FileMgr.getFile(FrameworkName.str(), /*openFile=*/!SuggestedModule);
00483   }
00484 
00485   // If we found the header and are allowed to suggest a module, do so now.
00486   if (FE && SuggestedModule) {
00487     // Find the framework in which this header occurs.
00488     StringRef FrameworkPath = FE->getDir()->getName();
00489     bool FoundFramework = false;
00490     do {
00491       // Determine whether this directory exists.
00492       const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkPath);
00493       if (!Dir)
00494         break;
00495 
00496       // If this is a framework directory, then we're a subframework of this
00497       // framework.
00498       if (llvm::sys::path::extension(FrameworkPath) == ".framework") {
00499         FoundFramework = true;
00500         break;
00501       }
00502 
00503       // Get the parent directory name.
00504       FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
00505       if (FrameworkPath.empty())
00506         break;
00507     } while (true);
00508 
00509     if (FoundFramework) {
00510       // Find the top-level framework based on this framework.
00511       SmallVector<std::string, 4> SubmodulePath;
00512       const DirectoryEntry *TopFrameworkDir
00513         = ::getTopFrameworkDir(FileMgr, FrameworkPath, SubmodulePath);
00514 
00515       // Determine the name of the top-level framework.
00516       StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName());
00517 
00518       // Load this framework module. If that succeeds, find the suggested module
00519       // for this header, if any.
00520       bool IsSystem = getDirCharacteristic() != SrcMgr::C_User;
00521       if (HS.loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystem)) {
00522         *SuggestedModule = HS.findModuleForHeader(FE);
00523       }
00524     } else {
00525       *SuggestedModule = HS.findModuleForHeader(FE);
00526     }
00527   }
00528   return FE;
00529 }
00530 
00531 void HeaderSearch::setTarget(const TargetInfo &Target) {
00532   ModMap.setTarget(Target);
00533 }
00534 
00535 
00536 //===----------------------------------------------------------------------===//
00537 // Header File Location.
00538 //===----------------------------------------------------------------------===//
00539 
00540 /// \brief Return true with a diagnostic if the file that MSVC would have found
00541 /// fails to match the one that Clang would have found with MSVC header search
00542 /// disabled.
00543 static bool checkMSVCHeaderSearch(DiagnosticsEngine &Diags,
00544                                   const FileEntry *MSFE, const FileEntry *FE,
00545                                   SourceLocation IncludeLoc) {
00546   if (MSFE && FE != MSFE) {
00547     Diags.Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->getName();
00548     return true;
00549   }
00550   return false;
00551 }
00552 
00553 static const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
00554   assert(!Str.empty());
00555   char *CopyStr = Alloc.Allocate<char>(Str.size()+1);
00556   std::copy(Str.begin(), Str.end(), CopyStr);
00557   CopyStr[Str.size()] = '\0';
00558   return CopyStr;
00559 }
00560 
00561 /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
00562 /// return null on failure.  isAngled indicates whether the file reference is
00563 /// for system \#include's or not (i.e. using <> instead of ""). Includers, if
00564 /// non-empty, indicates where the \#including file(s) are, in case a relative
00565 /// search is needed. Microsoft mode will pass all \#including files.
00566 const FileEntry *HeaderSearch::LookupFile(
00567     StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
00568     const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir,
00569     ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
00570     SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
00571     ModuleMap::KnownHeader *SuggestedModule, bool SkipCache) {
00572   if (!HSOpts->ModuleMapFiles.empty()) {
00573     // Preload all explicitly specified module map files. This enables modules
00574     // map files lying in a directory structure separate from the header files
00575     // that they describe. These cannot be loaded lazily upon encountering a
00576     // header file, as there is no other known mapping from a header file to its
00577     // module map file.
00578     for (const auto &Filename : HSOpts->ModuleMapFiles)
00579       if (const FileEntry *File = FileMgr.getFile(Filename))
00580         loadModuleMapFile(File, /*IsSystem=*/false);
00581     HSOpts->ModuleMapFiles.clear();
00582   }
00583 
00584   if (SuggestedModule)
00585     *SuggestedModule = ModuleMap::KnownHeader();
00586     
00587   // If 'Filename' is absolute, check to see if it exists and no searching.
00588   if (llvm::sys::path::is_absolute(Filename)) {
00589     CurDir = nullptr;
00590 
00591     // If this was an #include_next "/absolute/file", fail.
00592     if (FromDir) return nullptr;
00593 
00594     if (SearchPath)
00595       SearchPath->clear();
00596     if (RelativePath) {
00597       RelativePath->clear();
00598       RelativePath->append(Filename.begin(), Filename.end());
00599     }
00600     // Otherwise, just return the file.
00601     return FileMgr.getFile(Filename, /*openFile=*/true);
00602   }
00603 
00604   // This is the header that MSVC's header search would have found.
00605   const FileEntry *MSFE = nullptr;
00606   ModuleMap::KnownHeader MSSuggestedModule;
00607 
00608   // Unless disabled, check to see if the file is in the #includer's
00609   // directory.  This cannot be based on CurDir, because each includer could be
00610   // a #include of a subdirectory (#include "foo/bar.h") and a subsequent
00611   // include of "baz.h" should resolve to "whatever/foo/baz.h".
00612   // This search is not done for <> headers.
00613   if (!Includers.empty() && !isAngled && !NoCurDirSearch) {
00614     SmallString<1024> TmpDir;
00615     bool First = true;
00616     for (const auto &IncluderAndDir : Includers) {
00617       const FileEntry *Includer = IncluderAndDir.first;
00618 
00619       // Concatenate the requested file onto the directory.
00620       // FIXME: Portability.  Filename concatenation should be in sys::Path.
00621       TmpDir = IncluderAndDir.second->getName();
00622       TmpDir.push_back('/');
00623       TmpDir.append(Filename.begin(), Filename.end());
00624 
00625       // FIXME: We don't cache the result of getFileInfo across the call to
00626       // getFileAndSuggestModule, because it's a reference to an element of
00627       // a container that could be reallocated across this call.
00628       bool IncluderIsSystemHeader =
00629           getFileInfo(Includer).DirInfo != SrcMgr::C_User;
00630       if (const FileEntry *FE = getFileAndSuggestModule(
00631               *this, TmpDir.str(), IncluderAndDir.second,
00632               IncluderIsSystemHeader, SuggestedModule)) {
00633         // Leave CurDir unset.
00634         // This file is a system header or C++ unfriendly if the old file is.
00635         //
00636         // Note that we only use one of FromHFI/ToHFI at once, due to potential
00637         // reallocation of the underlying vector potentially making the first
00638         // reference binding dangling.
00639         HeaderFileInfo &FromHFI = getFileInfo(Includer);
00640         unsigned DirInfo = FromHFI.DirInfo;
00641         bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader;
00642         StringRef Framework = FromHFI.Framework;
00643 
00644         HeaderFileInfo &ToHFI = getFileInfo(FE);
00645         ToHFI.DirInfo = DirInfo;
00646         ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader;
00647         ToHFI.Framework = Framework;
00648 
00649         if (SearchPath) {
00650           StringRef SearchPathRef(IncluderAndDir.second->getName());
00651           SearchPath->clear();
00652           SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
00653         }
00654         if (RelativePath) {
00655           RelativePath->clear();
00656           RelativePath->append(Filename.begin(), Filename.end());
00657         }
00658         if (First)
00659           return FE;
00660 
00661         // Otherwise, we found the path via MSVC header search rules.  If
00662         // -Wmsvc-include is enabled, we have to keep searching to see if we
00663         // would've found this header in -I or -isystem directories.
00664         if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
00665           return FE;
00666         } else {
00667           MSFE = FE;
00668           if (SuggestedModule) {
00669             MSSuggestedModule = *SuggestedModule;
00670             *SuggestedModule = ModuleMap::KnownHeader();
00671           }
00672           break;
00673         }
00674       }
00675       First = false;
00676     }
00677   }
00678 
00679   CurDir = nullptr;
00680 
00681   // If this is a system #include, ignore the user #include locs.
00682   unsigned i = isAngled ? AngledDirIdx : 0;
00683 
00684   // If this is a #include_next request, start searching after the directory the
00685   // file was found in.
00686   if (FromDir)
00687     i = FromDir-&SearchDirs[0];
00688 
00689   // Cache all of the lookups performed by this method.  Many headers are
00690   // multiply included, and the "pragma once" optimization prevents them from
00691   // being relex/pp'd, but they would still have to search through a
00692   // (potentially huge) series of SearchDirs to find it.
00693   LookupFileCacheInfo &CacheLookup =
00694     LookupFileCache.GetOrCreateValue(Filename).getValue();
00695 
00696   // If the entry has been previously looked up, the first value will be
00697   // non-zero.  If the value is equal to i (the start point of our search), then
00698   // this is a matching hit.
00699   if (!SkipCache && CacheLookup.StartIdx == i+1) {
00700     // Skip querying potentially lots of directories for this lookup.
00701     i = CacheLookup.HitIdx;
00702     if (CacheLookup.MappedName)
00703       Filename = CacheLookup.MappedName;
00704   } else {
00705     // Otherwise, this is the first query, or the previous query didn't match
00706     // our search start.  We will fill in our found location below, so prime the
00707     // start point value.
00708     CacheLookup.reset(/*StartIdx=*/i+1);
00709   }
00710 
00711   SmallString<64> MappedName;
00712 
00713   // Check each directory in sequence to see if it contains this file.
00714   for (; i != SearchDirs.size(); ++i) {
00715     bool InUserSpecifiedSystemFramework = false;
00716     bool HasBeenMapped = false;
00717     const FileEntry *FE =
00718       SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath,
00719                                SuggestedModule, InUserSpecifiedSystemFramework,
00720                                HasBeenMapped, MappedName);
00721     if (HasBeenMapped) {
00722       CacheLookup.MappedName =
00723           copyString(Filename, LookupFileCache.getAllocator());
00724     }
00725     if (!FE) continue;
00726 
00727     CurDir = &SearchDirs[i];
00728 
00729     // This file is a system header or C++ unfriendly if the dir is.
00730     HeaderFileInfo &HFI = getFileInfo(FE);
00731     HFI.DirInfo = CurDir->getDirCharacteristic();
00732 
00733     // If the directory characteristic is User but this framework was
00734     // user-specified to be treated as a system framework, promote the
00735     // characteristic.
00736     if (HFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework)
00737       HFI.DirInfo = SrcMgr::C_System;
00738 
00739     // If the filename matches a known system header prefix, override
00740     // whether the file is a system header.
00741     for (unsigned j = SystemHeaderPrefixes.size(); j; --j) {
00742       if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) {
00743         HFI.DirInfo = SystemHeaderPrefixes[j-1].second ? SrcMgr::C_System
00744                                                        : SrcMgr::C_User;
00745         break;
00746       }
00747     }
00748 
00749     // If this file is found in a header map and uses the framework style of
00750     // includes, then this header is part of a framework we're building.
00751     if (CurDir->isIndexHeaderMap()) {
00752       size_t SlashPos = Filename.find('/');
00753       if (SlashPos != StringRef::npos) {
00754         HFI.IndexHeaderMapHeader = 1;
00755         HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(), 
00756                                                          SlashPos));
00757       }
00758     }
00759 
00760     if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) {
00761       if (SuggestedModule)
00762         *SuggestedModule = MSSuggestedModule;
00763       return MSFE;
00764     }
00765 
00766     // Remember this location for the next lookup we do.
00767     CacheLookup.HitIdx = i;
00768     return FE;
00769   }
00770 
00771   // If we are including a file with a quoted include "foo.h" from inside
00772   // a header in a framework that is currently being built, and we couldn't
00773   // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where
00774   // "Foo" is the name of the framework in which the including header was found.
00775   if (!Includers.empty() && !isAngled &&
00776       Filename.find('/') == StringRef::npos) {
00777     HeaderFileInfo &IncludingHFI = getFileInfo(Includers.front().first);
00778     if (IncludingHFI.IndexHeaderMapHeader) {
00779       SmallString<128> ScratchFilename;
00780       ScratchFilename += IncludingHFI.Framework;
00781       ScratchFilename += '/';
00782       ScratchFilename += Filename;
00783 
00784       const FileEntry *FE = LookupFile(
00785           ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, CurDir,
00786           Includers.front(), SearchPath, RelativePath, SuggestedModule);
00787 
00788       if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) {
00789         if (SuggestedModule)
00790           *SuggestedModule = MSSuggestedModule;
00791         return MSFE;
00792       }
00793 
00794       LookupFileCacheInfo &CacheLookup 
00795         = LookupFileCache.GetOrCreateValue(Filename).getValue();
00796       CacheLookup.HitIdx
00797         = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().HitIdx;
00798       // FIXME: SuggestedModule.
00799       return FE;
00800     }
00801   }
00802 
00803   if (checkMSVCHeaderSearch(Diags, MSFE, nullptr, IncludeLoc)) {
00804     if (SuggestedModule)
00805       *SuggestedModule = MSSuggestedModule;
00806     return MSFE;
00807   }
00808 
00809   // Otherwise, didn't find it. Remember we didn't find this.
00810   CacheLookup.HitIdx = SearchDirs.size();
00811   return nullptr;
00812 }
00813 
00814 /// LookupSubframeworkHeader - Look up a subframework for the specified
00815 /// \#include file.  For example, if \#include'ing <HIToolbox/HIToolbox.h> from
00816 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
00817 /// is a subframework within Carbon.framework.  If so, return the FileEntry
00818 /// for the designated file, otherwise return null.
00819 const FileEntry *HeaderSearch::
00820 LookupSubframeworkHeader(StringRef Filename,
00821                          const FileEntry *ContextFileEnt,
00822                          SmallVectorImpl<char> *SearchPath,
00823                          SmallVectorImpl<char> *RelativePath,
00824                          ModuleMap::KnownHeader *SuggestedModule) {
00825   assert(ContextFileEnt && "No context file?");
00826 
00827   // Framework names must have a '/' in the filename.  Find it.
00828   // FIXME: Should we permit '\' on Windows?
00829   size_t SlashPos = Filename.find('/');
00830   if (SlashPos == StringRef::npos) return nullptr;
00831 
00832   // Look up the base framework name of the ContextFileEnt.
00833   const char *ContextName = ContextFileEnt->getName();
00834 
00835   // If the context info wasn't a framework, couldn't be a subframework.
00836   const unsigned DotFrameworkLen = 10;
00837   const char *FrameworkPos = strstr(ContextName, ".framework");
00838   if (FrameworkPos == nullptr ||
00839       (FrameworkPos[DotFrameworkLen] != '/' && 
00840        FrameworkPos[DotFrameworkLen] != '\\'))
00841     return nullptr;
00842 
00843   SmallString<1024> FrameworkName(ContextName, FrameworkPos+DotFrameworkLen+1);
00844 
00845   // Append Frameworks/HIToolbox.framework/
00846   FrameworkName += "Frameworks/";
00847   FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
00848   FrameworkName += ".framework/";
00849 
00850   llvm::StringMapEntry<FrameworkCacheEntry> &CacheLookup =
00851     FrameworkMap.GetOrCreateValue(Filename.substr(0, SlashPos));
00852 
00853   // Some other location?
00854   if (CacheLookup.getValue().Directory &&
00855       CacheLookup.getKeyLength() == FrameworkName.size() &&
00856       memcmp(CacheLookup.getKeyData(), &FrameworkName[0],
00857              CacheLookup.getKeyLength()) != 0)
00858     return nullptr;
00859 
00860   // Cache subframework.
00861   if (!CacheLookup.getValue().Directory) {
00862     ++NumSubFrameworkLookups;
00863 
00864     // If the framework dir doesn't exist, we fail.
00865     const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str());
00866     if (!Dir) return nullptr;
00867 
00868     // Otherwise, if it does, remember that this is the right direntry for this
00869     // framework.
00870     CacheLookup.getValue().Directory = Dir;
00871   }
00872 
00873   const FileEntry *FE = nullptr;
00874 
00875   if (RelativePath) {
00876     RelativePath->clear();
00877     RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
00878   }
00879 
00880   // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h"
00881   SmallString<1024> HeadersFilename(FrameworkName);
00882   HeadersFilename += "Headers/";
00883   if (SearchPath) {
00884     SearchPath->clear();
00885     // Without trailing '/'.
00886     SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
00887   }
00888 
00889   HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
00890   if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) {
00891 
00892     // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
00893     HeadersFilename = FrameworkName;
00894     HeadersFilename += "PrivateHeaders/";
00895     if (SearchPath) {
00896       SearchPath->clear();
00897       // Without trailing '/'.
00898       SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
00899     }
00900 
00901     HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
00902     if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true)))
00903       return nullptr;
00904   }
00905 
00906   // This file is a system header or C++ unfriendly if the old file is.
00907   //
00908   // Note that the temporary 'DirInfo' is required here, as either call to
00909   // getFileInfo could resize the vector and we don't want to rely on order
00910   // of evaluation.
00911   unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo;
00912   getFileInfo(FE).DirInfo = DirInfo;
00913 
00914   // If we're supposed to suggest a module, look for one now.
00915   if (SuggestedModule) {
00916     // Find the top-level framework based on this framework.
00917     FrameworkName.pop_back(); // remove the trailing '/'
00918     SmallVector<std::string, 4> SubmodulePath;
00919     const DirectoryEntry *TopFrameworkDir
00920       = ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath);
00921     
00922     // Determine the name of the top-level framework.
00923     StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName());
00924 
00925     // Load this framework module. If that succeeds, find the suggested module
00926     // for this header, if any.
00927     bool IsSystem = false;
00928     if (loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystem)) {
00929       *SuggestedModule = findModuleForHeader(FE);
00930     }
00931   }
00932 
00933   return FE;
00934 }
00935 
00936 //===----------------------------------------------------------------------===//
00937 // File Info Management.
00938 //===----------------------------------------------------------------------===//
00939 
00940 /// \brief Merge the header file info provided by \p OtherHFI into the current
00941 /// header file info (\p HFI)
00942 static void mergeHeaderFileInfo(HeaderFileInfo &HFI, 
00943                                 const HeaderFileInfo &OtherHFI) {
00944   HFI.isImport |= OtherHFI.isImport;
00945   HFI.isPragmaOnce |= OtherHFI.isPragmaOnce;
00946   HFI.isModuleHeader |= OtherHFI.isModuleHeader;
00947   HFI.NumIncludes += OtherHFI.NumIncludes;
00948   
00949   if (!HFI.ControllingMacro && !HFI.ControllingMacroID) {
00950     HFI.ControllingMacro = OtherHFI.ControllingMacro;
00951     HFI.ControllingMacroID = OtherHFI.ControllingMacroID;
00952   }
00953   
00954   if (OtherHFI.External) {
00955     HFI.DirInfo = OtherHFI.DirInfo;
00956     HFI.External = OtherHFI.External;
00957     HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader;
00958   }
00959 
00960   if (HFI.Framework.empty())
00961     HFI.Framework = OtherHFI.Framework;
00962   
00963   HFI.Resolved = true;
00964 }
00965                                 
00966 /// getFileInfo - Return the HeaderFileInfo structure for the specified
00967 /// FileEntry.
00968 HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) {
00969   if (FE->getUID() >= FileInfo.size())
00970     FileInfo.resize(FE->getUID()+1);
00971   
00972   HeaderFileInfo &HFI = FileInfo[FE->getUID()];
00973   if (ExternalSource && !HFI.Resolved)
00974     mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE));
00975   HFI.IsValid = 1;
00976   return HFI;
00977 }
00978 
00979 bool HeaderSearch::tryGetFileInfo(const FileEntry *FE, HeaderFileInfo &Result) const {
00980   if (FE->getUID() >= FileInfo.size())
00981     return false;
00982   const HeaderFileInfo &HFI = FileInfo[FE->getUID()];
00983   if (HFI.IsValid) {
00984     Result = HFI;
00985     return true;
00986   }
00987   return false;
00988 }
00989 
00990 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) {
00991   // Check if we've ever seen this file as a header.
00992   if (File->getUID() >= FileInfo.size())
00993     return false;
00994 
00995   // Resolve header file info from the external source, if needed.
00996   HeaderFileInfo &HFI = FileInfo[File->getUID()];
00997   if (ExternalSource && !HFI.Resolved)
00998     mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(File));
00999 
01000   return HFI.isPragmaOnce || HFI.isImport ||
01001       HFI.ControllingMacro || HFI.ControllingMacroID;
01002 }
01003 
01004 void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE,
01005                                         ModuleMap::ModuleHeaderRole Role,
01006                                         bool isCompilingModuleHeader) {
01007   if (FE->getUID() >= FileInfo.size())
01008     FileInfo.resize(FE->getUID()+1);
01009 
01010   HeaderFileInfo &HFI = FileInfo[FE->getUID()];
01011   HFI.isModuleHeader = true;
01012   HFI.isCompilingModuleHeader = isCompilingModuleHeader;
01013   HFI.setHeaderRole(Role);
01014 }
01015 
01016 bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){
01017   ++NumIncluded; // Count # of attempted #includes.
01018 
01019   // Get information about this file.
01020   HeaderFileInfo &FileInfo = getFileInfo(File);
01021 
01022   // If this is a #import directive, check that we have not already imported
01023   // this header.
01024   if (isImport) {
01025     // If this has already been imported, don't import it again.
01026     FileInfo.isImport = true;
01027 
01028     // Has this already been #import'ed or #include'd?
01029     if (FileInfo.NumIncludes) return false;
01030   } else {
01031     // Otherwise, if this is a #include of a file that was previously #import'd
01032     // or if this is the second #include of a #pragma once file, ignore it.
01033     if (FileInfo.isImport)
01034       return false;
01035   }
01036 
01037   // Next, check to see if the file is wrapped with #ifndef guards.  If so, and
01038   // if the macro that guards it is defined, we know the #include has no effect.
01039   if (const IdentifierInfo *ControllingMacro
01040       = FileInfo.getControllingMacro(ExternalLookup))
01041     if (ControllingMacro->hasMacroDefinition()) {
01042       ++NumMultiIncludeFileOptzn;
01043       return false;
01044     }
01045 
01046   // Increment the number of times this file has been included.
01047   ++FileInfo.NumIncludes;
01048 
01049   return true;
01050 }
01051 
01052 size_t HeaderSearch::getTotalMemory() const {
01053   return SearchDirs.capacity()
01054     + llvm::capacity_in_bytes(FileInfo)
01055     + llvm::capacity_in_bytes(HeaderMaps)
01056     + LookupFileCache.getAllocator().getTotalMemory()
01057     + FrameworkMap.getAllocator().getTotalMemory();
01058 }
01059 
01060 StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
01061   return FrameworkNames.GetOrCreateValue(Framework).getKey();
01062 }
01063 
01064 bool HeaderSearch::hasModuleMap(StringRef FileName, 
01065                                 const DirectoryEntry *Root,
01066                                 bool IsSystem) {
01067   if (!enabledModules())
01068     return false;
01069 
01070   SmallVector<const DirectoryEntry *, 2> FixUpDirectories;
01071   
01072   StringRef DirName = FileName;
01073   do {
01074     // Get the parent directory name.
01075     DirName = llvm::sys::path::parent_path(DirName);
01076     if (DirName.empty())
01077       return false;
01078 
01079     // Determine whether this directory exists.
01080     const DirectoryEntry *Dir = FileMgr.getDirectory(DirName);
01081     if (!Dir)
01082       return false;
01083 
01084     // Try to load the module map file in this directory.
01085     switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/false)) {
01086     case LMM_NewlyLoaded:
01087     case LMM_AlreadyLoaded:
01088       // Success. All of the directories we stepped through inherit this module
01089       // map file.
01090       for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
01091         DirectoryHasModuleMap[FixUpDirectories[I]] = true;
01092       return true;
01093 
01094     case LMM_NoDirectory:
01095     case LMM_InvalidModuleMap:
01096       break;
01097     }
01098 
01099     // If we hit the top of our search, we're done.
01100     if (Dir == Root)
01101       return false;
01102         
01103     // Keep track of all of the directories we checked, so we can mark them as
01104     // having module maps if we eventually do find a module map.
01105     FixUpDirectories.push_back(Dir);
01106   } while (true);
01107 }
01108 
01109 ModuleMap::KnownHeader
01110 HeaderSearch::findModuleForHeader(const FileEntry *File) const {
01111   if (ExternalSource) {
01112     // Make sure the external source has handled header info about this file,
01113     // which includes whether the file is part of a module.
01114     (void)getFileInfo(File);
01115   }
01116   return ModMap.findModuleForHeader(File);
01117 }
01118 
01119 static const FileEntry *getPrivateModuleMap(StringRef ModuleMapPath,
01120                                             const DirectoryEntry *Directory,
01121                                             FileManager &FileMgr) {
01122   StringRef Filename = llvm::sys::path::filename(ModuleMapPath);
01123   SmallString<128>  PrivateFilename(Directory->getName());
01124   if (Filename == "module.map")
01125     llvm::sys::path::append(PrivateFilename, "module_private.map");
01126   else if (Filename == "module.modulemap")
01127     llvm::sys::path::append(PrivateFilename, "module.private.modulemap");
01128   else
01129     return nullptr;
01130   return FileMgr.getFile(PrivateFilename);
01131 }
01132 
01133 bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) {
01134   switch (loadModuleMapFileImpl(File, IsSystem)) {
01135   case LMM_AlreadyLoaded:
01136   case LMM_NewlyLoaded:
01137     return false;
01138   case LMM_NoDirectory:
01139   case LMM_InvalidModuleMap:
01140     return true;
01141   }
01142   llvm_unreachable("Unknown load module map result");
01143 }
01144 
01145 HeaderSearch::LoadModuleMapResult
01146 HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem) {
01147   assert(File && "expected FileEntry");
01148 
01149   // Check whether we've already loaded this module map, and mark it as being
01150   // loaded in case we recursively try to load it from itself.
01151   auto AddResult = LoadedModuleMaps.insert(std::make_pair(File, true));
01152   if (!AddResult.second)
01153     return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
01154 
01155   if (ModMap.parseModuleMapFile(File, IsSystem)) {
01156     LoadedModuleMaps[File] = false;
01157     return LMM_InvalidModuleMap;
01158   }
01159 
01160   // Try to load a corresponding private module map.
01161   if (const FileEntry *PMMFile =
01162           getPrivateModuleMap(File->getName(), File->getDir(), FileMgr)) {
01163     if (ModMap.parseModuleMapFile(PMMFile, IsSystem)) {
01164       LoadedModuleMaps[File] = false;
01165       return LMM_InvalidModuleMap;
01166     }
01167   }
01168 
01169   // This directory has a module map.
01170   return LMM_NewlyLoaded;
01171 }
01172 
01173 const FileEntry *
01174 HeaderSearch::lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework) {
01175   // For frameworks, the preferred spelling is Modules/module.modulemap, but
01176   // module.map at the framework root is also accepted.
01177   SmallString<128> ModuleMapFileName(Dir->getName());
01178   if (IsFramework)
01179     llvm::sys::path::append(ModuleMapFileName, "Modules");
01180   llvm::sys::path::append(ModuleMapFileName, "module.modulemap");
01181   if (const FileEntry *F = FileMgr.getFile(ModuleMapFileName))
01182     return F;
01183 
01184   // Continue to allow module.map
01185   ModuleMapFileName = Dir->getName();
01186   llvm::sys::path::append(ModuleMapFileName, "module.map");
01187   return FileMgr.getFile(ModuleMapFileName);
01188 }
01189 
01190 Module *HeaderSearch::loadFrameworkModule(StringRef Name,
01191                                           const DirectoryEntry *Dir,
01192                                           bool IsSystem) {
01193   if (Module *Module = ModMap.findModule(Name))
01194     return Module;
01195   
01196   // Try to load a module map file.
01197   switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) {
01198   case LMM_InvalidModuleMap:
01199     break;
01200     
01201   case LMM_AlreadyLoaded:
01202   case LMM_NoDirectory:
01203     return nullptr;
01204 
01205   case LMM_NewlyLoaded:
01206     return ModMap.findModule(Name);
01207   }
01208 
01209 
01210   // Try to infer a module map from the framework directory.
01211   return ModMap.inferFrameworkModule(Name, Dir, IsSystem, /*Parent=*/nullptr);
01212 }
01213 
01214 
01215 HeaderSearch::LoadModuleMapResult 
01216 HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem,
01217                                 bool IsFramework) {
01218   if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName))
01219     return loadModuleMapFile(Dir, IsSystem, IsFramework);
01220   
01221   return LMM_NoDirectory;
01222 }
01223 
01224 HeaderSearch::LoadModuleMapResult 
01225 HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem,
01226                                 bool IsFramework) {
01227   auto KnownDir = DirectoryHasModuleMap.find(Dir);
01228   if (KnownDir != DirectoryHasModuleMap.end())
01229     return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
01230 
01231   if (const FileEntry *ModuleMapFile = lookupModuleMapFile(Dir, IsFramework)) {
01232     LoadModuleMapResult Result = loadModuleMapFileImpl(ModuleMapFile, IsSystem);
01233     // Add Dir explicitly in case ModuleMapFile is in a subdirectory.
01234     // E.g. Foo.framework/Modules/module.modulemap
01235     //      ^Dir                  ^ModuleMapFile
01236     if (Result == LMM_NewlyLoaded)
01237       DirectoryHasModuleMap[Dir] = true;
01238     else if (Result == LMM_InvalidModuleMap)
01239       DirectoryHasModuleMap[Dir] = false;
01240     return Result;
01241   }
01242   return LMM_InvalidModuleMap;
01243 }
01244 
01245 void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
01246   Modules.clear();
01247   
01248   // Load module maps for each of the header search directories.
01249   for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
01250     bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
01251     if (SearchDirs[Idx].isFramework()) {
01252       std::error_code EC;
01253       SmallString<128> DirNative;
01254       llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(),
01255                               DirNative);
01256       
01257       // Search each of the ".framework" directories to load them as modules.
01258       for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd;
01259            Dir != DirEnd && !EC; Dir.increment(EC)) {
01260         if (llvm::sys::path::extension(Dir->path()) != ".framework")
01261           continue;
01262         
01263         const DirectoryEntry *FrameworkDir = FileMgr.getDirectory(Dir->path());
01264         if (!FrameworkDir)
01265           continue;
01266         
01267         // Load this framework module.
01268         loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir,
01269                             IsSystem);
01270       }
01271       continue;
01272     }
01273     
01274     // FIXME: Deal with header maps.
01275     if (SearchDirs[Idx].isHeaderMap())
01276       continue;
01277     
01278     // Try to load a module map file for the search directory.
01279     loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem, /*IsFramework*/false);
01280     
01281     // Try to load module map files for immediate subdirectories of this search
01282     // directory.
01283     loadSubdirectoryModuleMaps(SearchDirs[Idx]);
01284   }
01285   
01286   // Populate the list of modules.
01287   for (ModuleMap::module_iterator M = ModMap.module_begin(), 
01288                                MEnd = ModMap.module_end();
01289        M != MEnd; ++M) {
01290     Modules.push_back(M->getValue());
01291   }
01292 }
01293 
01294 void HeaderSearch::loadTopLevelSystemModules() {
01295   // Load module maps for each of the header search directories.
01296   for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
01297     // We only care about normal header directories.
01298     if (!SearchDirs[Idx].isNormalDir()) {
01299       continue;
01300     }
01301 
01302     // Try to load a module map file for the search directory.
01303     loadModuleMapFile(SearchDirs[Idx].getDir(),
01304                       SearchDirs[Idx].isSystemHeaderDirectory(),
01305                       SearchDirs[Idx].isFramework());
01306   }
01307 }
01308 
01309 void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
01310   if (SearchDir.haveSearchedAllModuleMaps())
01311     return;
01312 
01313   std::error_code EC;
01314   SmallString<128> DirNative;
01315   llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative);
01316   for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd;
01317        Dir != DirEnd && !EC; Dir.increment(EC)) {
01318     loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(),
01319                       SearchDir.isFramework());
01320   }
01321 
01322   SearchDir.setSearchedAllModuleMaps(true);
01323 }