clang API Documentation
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 }