1 //===--- HeaderSearch.cpp - Resolve Header File Locations ---===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the DirectoryLookup and HeaderSearch interfaces. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Lex/HeaderSearch.h" 15 #include "clang/Basic/FileManager.h" 16 #include "clang/Basic/IdentifierTable.h" 17 #include "clang/Lex/HeaderMap.h" 18 #include "clang/Lex/HeaderSearchOptions.h" 19 #include "clang/Lex/LexDiagnostic.h" 20 #include "clang/Lex/Lexer.h" 21 #include "llvm/ADT/SmallString.h" 22 #include "llvm/Support/Capacity.h" 23 #include "llvm/Support/FileSystem.h" 24 #include "llvm/Support/Path.h" 25 #include "llvm/Support/raw_ostream.h" 26 #include <cstdio> 27 #if defined(LLVM_ON_UNIX) 28 #include <limits.h> 29 #endif 30 using namespace clang; 31 32 const IdentifierInfo * 33 HeaderFileInfo::getControllingMacro(ExternalIdentifierLookup *External) { 34 if (ControllingMacro) 35 return ControllingMacro; 36 37 if (!ControllingMacroID || !External) 38 return 0; 39 40 ControllingMacro = External->GetIdentifier(ControllingMacroID); 41 return ControllingMacro; 42 } 43 44 ExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() {} 45 46 HeaderSearch::HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts, 47 SourceManager &SourceMgr, DiagnosticsEngine &Diags, 48 const LangOptions &LangOpts, 49 const TargetInfo *Target) 50 : HSOpts(HSOpts), Diags(Diags), FileMgr(SourceMgr.getFileManager()), 51 FrameworkMap(64), ModMap(SourceMgr, Diags, LangOpts, Target, *this) { 52 AngledDirIdx = 0; 53 SystemDirIdx = 0; 54 NoCurDirSearch = false; 55 56 ExternalLookup = 0; 57 ExternalSource = 0; 58 NumIncluded = 0; 59 NumMultiIncludeFileOptzn = 0; 60 NumFrameworkLookups = NumSubFrameworkLookups = 0; 61 62 EnabledModules = LangOpts.Modules; 63 } 64 65 HeaderSearch::~HeaderSearch() { 66 // Delete headermaps. 67 for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i) 68 delete HeaderMaps[i].second; 69 } 70 71 void HeaderSearch::PrintStats() { 72 fprintf(stderr, "\n*** HeaderSearch Stats:\n"); 73 fprintf(stderr, "%d files tracked.\n", (int)FileInfo.size()); 74 unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0; 75 for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) { 76 NumOnceOnlyFiles += FileInfo[i].isImport; 77 if (MaxNumIncludes < FileInfo[i].NumIncludes) 78 MaxNumIncludes = FileInfo[i].NumIncludes; 79 NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1; 80 } 81 fprintf(stderr, " %d #import/#pragma once files.\n", NumOnceOnlyFiles); 82 fprintf(stderr, " %d included exactly once.\n", NumSingleIncludedFiles); 83 fprintf(stderr, " %d max times a file is included.\n", MaxNumIncludes); 84 85 fprintf(stderr, " %d #include/#include_next/#import.\n", NumIncluded); 86 fprintf(stderr, " %d #includes skipped due to" 87 " the multi-include optimization.\n", NumMultiIncludeFileOptzn); 88 89 fprintf(stderr, "%d framework lookups.\n", NumFrameworkLookups); 90 fprintf(stderr, "%d subframework lookups.\n", NumSubFrameworkLookups); 91 } 92 93 /// CreateHeaderMap - This method returns a HeaderMap for the specified 94 /// FileEntry, uniquing them through the 'HeaderMaps' datastructure. 95 const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) { 96 // We expect the number of headermaps to be small, and almost always empty. 97 // If it ever grows, use of a linear search should be re-evaluated. 98 if (!HeaderMaps.empty()) { 99 for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i) 100 // Pointer equality comparison of FileEntries works because they are 101 // already uniqued by inode. 102 if (HeaderMaps[i].first == FE) 103 return HeaderMaps[i].second; 104 } 105 106 if (const HeaderMap *HM = HeaderMap::Create(FE, FileMgr)) { 107 HeaderMaps.push_back(std::make_pair(FE, HM)); 108 return HM; 109 } 110 111 return 0; 112 } 113 114 std::string HeaderSearch::getModuleFileName(Module *Module) { 115 // If we don't have a module cache path, we can't do anything. 116 if (ModuleCachePath.empty()) 117 return std::string(); 118 119 120 SmallString<256> Result(ModuleCachePath); 121 llvm::sys::path::append(Result, Module->getTopLevelModule()->Name + ".pcm"); 122 return Result.str().str(); 123 } 124 125 std::string HeaderSearch::getModuleFileName(StringRef ModuleName) { 126 // If we don't have a module cache path, we can't do anything. 127 if (ModuleCachePath.empty()) 128 return std::string(); 129 130 131 SmallString<256> Result(ModuleCachePath); 132 llvm::sys::path::append(Result, ModuleName + ".pcm"); 133 return Result.str().str(); 134 } 135 136 Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) { 137 // Look in the module map to determine if there is a module by this name. 138 Module *Module = ModMap.findModule(ModuleName); 139 if (Module || !AllowSearch) 140 return Module; 141 142 // Look through the various header search paths to load any available module 143 // maps, searching for a module map that describes this module. 144 for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 145 if (SearchDirs[Idx].isFramework()) { 146 // Search for or infer a module map for a framework. 147 SmallString<128> FrameworkDirName; 148 FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName(); 149 llvm::sys::path::append(FrameworkDirName, ModuleName + ".framework"); 150 if (const DirectoryEntry *FrameworkDir 151 = FileMgr.getDirectory(FrameworkDirName)) { 152 bool IsSystem 153 = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User; 154 Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem); 155 if (Module) 156 break; 157 } 158 } 159 160 // FIXME: Figure out how header maps and module maps will work together. 161 162 // Only deal with normal search directories. 163 if (!SearchDirs[Idx].isNormalDir()) 164 continue; 165 166 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory(); 167 // Search for a module map file in this directory. 168 if (loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem, 169 /*IsFramework*/false) == LMM_NewlyLoaded) { 170 // We just loaded a module map file; check whether the module is 171 // available now. 172 Module = ModMap.findModule(ModuleName); 173 if (Module) 174 break; 175 } 176 177 // Search for a module map in a subdirectory with the same name as the 178 // module. 179 SmallString<128> NestedModuleMapDirName; 180 NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName(); 181 llvm::sys::path::append(NestedModuleMapDirName, ModuleName); 182 if (loadModuleMapFile(NestedModuleMapDirName, IsSystem, 183 /*IsFramework*/false) == LMM_NewlyLoaded){ 184 // If we just loaded a module map file, look for the module again. 185 Module = ModMap.findModule(ModuleName); 186 if (Module) 187 break; 188 } 189 190 // If we've already performed the exhaustive search for module maps in this 191 // search directory, don't do it again. 192 if (SearchDirs[Idx].haveSearchedAllModuleMaps()) 193 continue; 194 195 // Load all module maps in the immediate subdirectories of this search 196 // directory. 197 loadSubdirectoryModuleMaps(SearchDirs[Idx]); 198 199 // Look again for the module. 200 Module = ModMap.findModule(ModuleName); 201 if (Module) 202 break; 203 } 204 205 return Module; 206 } 207 208 //===----------------------------------------------------------------------===// 209 // File lookup within a DirectoryLookup scope 210 //===----------------------------------------------------------------------===// 211 212 /// getName - Return the directory or filename corresponding to this lookup 213 /// object. 214 const char *DirectoryLookup::getName() const { 215 if (isNormalDir()) 216 return getDir()->getName(); 217 if (isFramework()) 218 return getFrameworkDir()->getName(); 219 assert(isHeaderMap() && "Unknown DirectoryLookup"); 220 return getHeaderMap()->getFileName(); 221 } 222 223 static const FileEntry * 224 getFileAndSuggestModule(HeaderSearch &HS, StringRef FileName, 225 const DirectoryEntry *Dir, bool IsSystemHeaderDir, 226 ModuleMap::KnownHeader *SuggestedModule) { 227 // If we have a module map that might map this header, load it and 228 // check whether we'll have a suggestion for a module. 229 HS.hasModuleMap(FileName, Dir, IsSystemHeaderDir); 230 if (SuggestedModule) { 231 const FileEntry *File = HS.getFileMgr().getFile(FileName, 232 /*OpenFile=*/false); 233 if (File) { 234 // If there is a module that corresponds to this header, suggest it. 235 *SuggestedModule = HS.findModuleForHeader(File); 236 237 // FIXME: This appears to be a no-op. We loaded the module map for this 238 // directory at the start of this function. 239 if (!SuggestedModule->getModule() && 240 HS.hasModuleMap(FileName, Dir, IsSystemHeaderDir)) 241 *SuggestedModule = HS.findModuleForHeader(File); 242 } 243 244 return File; 245 } 246 247 return HS.getFileMgr().getFile(FileName, /*openFile=*/true); 248 } 249 250 /// LookupFile - Lookup the specified file in this search path, returning it 251 /// if it exists or returning null if not. 252 const FileEntry *DirectoryLookup::LookupFile( 253 StringRef &Filename, 254 HeaderSearch &HS, 255 SmallVectorImpl<char> *SearchPath, 256 SmallVectorImpl<char> *RelativePath, 257 ModuleMap::KnownHeader *SuggestedModule, 258 bool &InUserSpecifiedSystemFramework, 259 bool &HasBeenMapped, 260 SmallVectorImpl<char> &MappedName) const { 261 InUserSpecifiedSystemFramework = false; 262 HasBeenMapped = false; 263 264 SmallString<1024> TmpDir; 265 if (isNormalDir()) { 266 // Concatenate the requested file onto the directory. 267 TmpDir = getDir()->getName(); 268 llvm::sys::path::append(TmpDir, Filename); 269 if (SearchPath != NULL) { 270 StringRef SearchPathRef(getDir()->getName()); 271 SearchPath->clear(); 272 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 273 } 274 if (RelativePath != NULL) { 275 RelativePath->clear(); 276 RelativePath->append(Filename.begin(), Filename.end()); 277 } 278 279 return getFileAndSuggestModule(HS, TmpDir.str(), getDir(), 280 isSystemHeaderDirectory(), 281 SuggestedModule); 282 } 283 284 if (isFramework()) 285 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath, 286 SuggestedModule, InUserSpecifiedSystemFramework); 287 288 assert(isHeaderMap() && "Unknown directory lookup"); 289 const HeaderMap *HM = getHeaderMap(); 290 SmallString<1024> Path; 291 StringRef Dest = HM->lookupFilename(Filename, Path); 292 if (Dest.empty()) 293 return 0; 294 295 const FileEntry *Result; 296 297 // Check if the headermap maps the filename to a framework include 298 // ("Foo.h" -> "Foo/Foo.h"), in which case continue header lookup using the 299 // framework include. 300 if (llvm::sys::path::is_relative(Dest)) { 301 MappedName.clear(); 302 MappedName.append(Dest.begin(), Dest.end()); 303 Filename = StringRef(MappedName.begin(), MappedName.size()); 304 HasBeenMapped = true; 305 Result = HM->LookupFile(Filename, HS.getFileMgr()); 306 307 } else { 308 Result = HS.getFileMgr().getFile(Dest); 309 } 310 311 if (Result) { 312 if (SearchPath != NULL) { 313 StringRef SearchPathRef(getName()); 314 SearchPath->clear(); 315 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 316 } 317 if (RelativePath != NULL) { 318 RelativePath->clear(); 319 RelativePath->append(Filename.begin(), Filename.end()); 320 } 321 } 322 return Result; 323 } 324 325 /// \brief Given a framework directory, find the top-most framework directory. 326 /// 327 /// \param FileMgr The file manager to use for directory lookups. 328 /// \param DirName The name of the framework directory. 329 /// \param SubmodulePath Will be populated with the submodule path from the 330 /// returned top-level module to the originally named framework. 331 static const DirectoryEntry * 332 getTopFrameworkDir(FileManager &FileMgr, StringRef DirName, 333 SmallVectorImpl<std::string> &SubmodulePath) { 334 assert(llvm::sys::path::extension(DirName) == ".framework" && 335 "Not a framework directory"); 336 337 // Note: as an egregious but useful hack we use the real path here, because 338 // frameworks moving between top-level frameworks to embedded frameworks tend 339 // to be symlinked, and we base the logical structure of modules on the 340 // physical layout. In particular, we need to deal with crazy includes like 341 // 342 // #include <Foo/Frameworks/Bar.framework/Headers/Wibble.h> 343 // 344 // where 'Bar' used to be embedded in 'Foo', is now a top-level framework 345 // which one should access with, e.g., 346 // 347 // #include <Bar/Wibble.h> 348 // 349 // Similar issues occur when a top-level framework has moved into an 350 // embedded framework. 351 const DirectoryEntry *TopFrameworkDir = FileMgr.getDirectory(DirName); 352 DirName = FileMgr.getCanonicalName(TopFrameworkDir); 353 do { 354 // Get the parent directory name. 355 DirName = llvm::sys::path::parent_path(DirName); 356 if (DirName.empty()) 357 break; 358 359 // Determine whether this directory exists. 360 const DirectoryEntry *Dir = FileMgr.getDirectory(DirName); 361 if (!Dir) 362 break; 363 364 // If this is a framework directory, then we're a subframework of this 365 // framework. 366 if (llvm::sys::path::extension(DirName) == ".framework") { 367 SubmodulePath.push_back(llvm::sys::path::stem(DirName)); 368 TopFrameworkDir = Dir; 369 } 370 } while (true); 371 372 return TopFrameworkDir; 373 } 374 375 /// DoFrameworkLookup - Do a lookup of the specified file in the current 376 /// DirectoryLookup, which is a framework directory. 377 const FileEntry *DirectoryLookup::DoFrameworkLookup( 378 StringRef Filename, 379 HeaderSearch &HS, 380 SmallVectorImpl<char> *SearchPath, 381 SmallVectorImpl<char> *RelativePath, 382 ModuleMap::KnownHeader *SuggestedModule, 383 bool &InUserSpecifiedSystemFramework) const 384 { 385 FileManager &FileMgr = HS.getFileMgr(); 386 387 // Framework names must have a '/' in the filename. 388 size_t SlashPos = Filename.find('/'); 389 if (SlashPos == StringRef::npos) return 0; 390 391 // Find out if this is the home for the specified framework, by checking 392 // HeaderSearch. Possible answers are yes/no and unknown. 393 HeaderSearch::FrameworkCacheEntry &CacheEntry = 394 HS.LookupFrameworkCache(Filename.substr(0, SlashPos)); 395 396 // If it is known and in some other directory, fail. 397 if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDir()) 398 return 0; 399 400 // Otherwise, construct the path to this framework dir. 401 402 // FrameworkName = "/System/Library/Frameworks/" 403 SmallString<1024> FrameworkName; 404 FrameworkName += getFrameworkDir()->getName(); 405 if (FrameworkName.empty() || FrameworkName.back() != '/') 406 FrameworkName.push_back('/'); 407 408 // FrameworkName = "/System/Library/Frameworks/Cocoa" 409 StringRef ModuleName(Filename.begin(), SlashPos); 410 FrameworkName += ModuleName; 411 412 // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/" 413 FrameworkName += ".framework/"; 414 415 // If the cache entry was unresolved, populate it now. 416 if (CacheEntry.Directory == 0) { 417 HS.IncrementFrameworkLookupCount(); 418 419 // If the framework dir doesn't exist, we fail. 420 const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); 421 if (Dir == 0) return 0; 422 423 // Otherwise, if it does, remember that this is the right direntry for this 424 // framework. 425 CacheEntry.Directory = getFrameworkDir(); 426 427 // If this is a user search directory, check if the framework has been 428 // user-specified as a system framework. 429 if (getDirCharacteristic() == SrcMgr::C_User) { 430 SmallString<1024> SystemFrameworkMarker(FrameworkName); 431 SystemFrameworkMarker += ".system_framework"; 432 if (llvm::sys::fs::exists(SystemFrameworkMarker.str())) { 433 CacheEntry.IsUserSpecifiedSystemFramework = true; 434 } 435 } 436 } 437 438 // Set the 'user-specified system framework' flag. 439 InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework; 440 441 if (RelativePath != NULL) { 442 RelativePath->clear(); 443 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 444 } 445 446 // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h" 447 unsigned OrigSize = FrameworkName.size(); 448 449 FrameworkName += "Headers/"; 450 451 if (SearchPath != NULL) { 452 SearchPath->clear(); 453 // Without trailing '/'. 454 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1); 455 } 456 457 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end()); 458 const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), 459 /*openFile=*/!SuggestedModule); 460 if (!FE) { 461 // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h" 462 const char *Private = "Private"; 463 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private, 464 Private+strlen(Private)); 465 if (SearchPath != NULL) 466 SearchPath->insert(SearchPath->begin()+OrigSize, Private, 467 Private+strlen(Private)); 468 469 FE = FileMgr.getFile(FrameworkName.str(), /*openFile=*/!SuggestedModule); 470 } 471 472 // If we found the header and are allowed to suggest a module, do so now. 473 if (FE && SuggestedModule) { 474 // Find the framework in which this header occurs. 475 StringRef FrameworkPath = FE->getName(); 476 bool FoundFramework = false; 477 do { 478 // Get the parent directory name. 479 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath); 480 if (FrameworkPath.empty()) 481 break; 482 483 // Determine whether this directory exists. 484 const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkPath); 485 if (!Dir) 486 break; 487 488 // If this is a framework directory, then we're a subframework of this 489 // framework. 490 if (llvm::sys::path::extension(FrameworkPath) == ".framework") { 491 FoundFramework = true; 492 break; 493 } 494 } while (true); 495 496 if (FoundFramework) { 497 // Find the top-level framework based on this framework. 498 SmallVector<std::string, 4> SubmodulePath; 499 const DirectoryEntry *TopFrameworkDir 500 = ::getTopFrameworkDir(FileMgr, FrameworkPath, SubmodulePath); 501 502 // Determine the name of the top-level framework. 503 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName()); 504 505 // Load this framework module. If that succeeds, find the suggested module 506 // for this header, if any. 507 bool IsSystem = getDirCharacteristic() != SrcMgr::C_User; 508 if (HS.loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystem)) { 509 *SuggestedModule = HS.findModuleForHeader(FE); 510 } 511 } else { 512 *SuggestedModule = HS.findModuleForHeader(FE); 513 } 514 } 515 return FE; 516 } 517 518 void HeaderSearch::setTarget(const TargetInfo &Target) { 519 ModMap.setTarget(Target); 520 } 521 522 523 //===----------------------------------------------------------------------===// 524 // Header File Location. 525 //===----------------------------------------------------------------------===// 526 527 /// \brief Return true with a diagnostic if the file that MSVC would have found 528 /// fails to match the one that Clang would have found with MSVC header search 529 /// disabled. 530 static bool checkMSVCHeaderSearch(DiagnosticsEngine &Diags, 531 const FileEntry *MSFE, const FileEntry *FE, 532 SourceLocation IncludeLoc) { 533 if (MSFE && FE != MSFE) { 534 Diags.Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->getName(); 535 return true; 536 } 537 return false; 538 } 539 540 static const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) { 541 assert(!Str.empty()); 542 char *CopyStr = Alloc.Allocate<char>(Str.size()+1); 543 std::copy(Str.begin(), Str.end(), CopyStr); 544 CopyStr[Str.size()] = '\0'; 545 return CopyStr; 546 } 547 548 /// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file, 549 /// return null on failure. isAngled indicates whether the file reference is 550 /// for system \#include's or not (i.e. using <> instead of ""). Includers, if 551 /// non-empty, indicates where the \#including file(s) are, in case a relative 552 /// search is needed. Microsoft mode will pass all \#including files. 553 const FileEntry *HeaderSearch::LookupFile( 554 StringRef Filename, SourceLocation IncludeLoc, bool isAngled, 555 const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, 556 ArrayRef<const FileEntry *> Includers, SmallVectorImpl<char> *SearchPath, 557 SmallVectorImpl<char> *RelativePath, 558 ModuleMap::KnownHeader *SuggestedModule, bool SkipCache) { 559 if (!HSOpts->ModuleMapFiles.empty()) { 560 // Preload all explicitly specified module map files. This enables modules 561 // map files lying in a directory structure separate from the header files 562 // that they describe. These cannot be loaded lazily upon encountering a 563 // header file, as there is no other known mapping from a header file to its 564 // module map file. 565 for (llvm::SetVector<std::string>::iterator 566 I = HSOpts->ModuleMapFiles.begin(), 567 E = HSOpts->ModuleMapFiles.end(); 568 I != E; ++I) { 569 const FileEntry *File = FileMgr.getFile(*I); 570 if (!File) 571 continue; 572 loadModuleMapFile(File, /*IsSystem=*/false); 573 } 574 HSOpts->ModuleMapFiles.clear(); 575 } 576 577 if (SuggestedModule) 578 *SuggestedModule = ModuleMap::KnownHeader(); 579 580 // If 'Filename' is absolute, check to see if it exists and no searching. 581 if (llvm::sys::path::is_absolute(Filename)) { 582 CurDir = 0; 583 584 // If this was an #include_next "/absolute/file", fail. 585 if (FromDir) return 0; 586 587 if (SearchPath != NULL) 588 SearchPath->clear(); 589 if (RelativePath != NULL) { 590 RelativePath->clear(); 591 RelativePath->append(Filename.begin(), Filename.end()); 592 } 593 // Otherwise, just return the file. 594 return FileMgr.getFile(Filename, /*openFile=*/true); 595 } 596 597 // This is the header that MSVC's header search would have found. 598 const FileEntry *MSFE = 0; 599 ModuleMap::KnownHeader MSSuggestedModule; 600 601 // Unless disabled, check to see if the file is in the #includer's 602 // directory. This cannot be based on CurDir, because each includer could be 603 // a #include of a subdirectory (#include "foo/bar.h") and a subsequent 604 // include of "baz.h" should resolve to "whatever/foo/baz.h". 605 // This search is not done for <> headers. 606 if (!Includers.empty() && !isAngled && !NoCurDirSearch) { 607 SmallString<1024> TmpDir; 608 for (ArrayRef<const FileEntry *>::iterator I = Includers.begin(), 609 E = Includers.end(); 610 I != E; ++I) { 611 const FileEntry *Includer = *I; 612 // Concatenate the requested file onto the directory. 613 // FIXME: Portability. Filename concatenation should be in sys::Path. 614 TmpDir = Includer->getDir()->getName(); 615 TmpDir.push_back('/'); 616 TmpDir.append(Filename.begin(), Filename.end()); 617 618 // FIXME: We don't cache the result of getFileInfo across the call to 619 // getFileAndSuggestModule, because it's a reference to an element of 620 // a container that could be reallocated across this call. 621 bool IncluderIsSystemHeader = 622 getFileInfo(Includer).DirInfo != SrcMgr::C_User; 623 if (const FileEntry *FE = 624 getFileAndSuggestModule(*this, TmpDir.str(), Includer->getDir(), 625 IncluderIsSystemHeader, 626 SuggestedModule)) { 627 // Leave CurDir unset. 628 // This file is a system header or C++ unfriendly if the old file is. 629 // 630 // Note that we only use one of FromHFI/ToHFI at once, due to potential 631 // reallocation of the underlying vector potentially making the first 632 // reference binding dangling. 633 HeaderFileInfo &FromHFI = getFileInfo(Includer); 634 unsigned DirInfo = FromHFI.DirInfo; 635 bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader; 636 StringRef Framework = FromHFI.Framework; 637 638 HeaderFileInfo &ToHFI = getFileInfo(FE); 639 ToHFI.DirInfo = DirInfo; 640 ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader; 641 ToHFI.Framework = Framework; 642 643 if (SearchPath != NULL) { 644 StringRef SearchPathRef(Includer->getDir()->getName()); 645 SearchPath->clear(); 646 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 647 } 648 if (RelativePath != NULL) { 649 RelativePath->clear(); 650 RelativePath->append(Filename.begin(), Filename.end()); 651 } 652 if (I == Includers.begin()) 653 return FE; 654 655 // Otherwise, we found the path via MSVC header search rules. If 656 // -Wmsvc-include is enabled, we have to keep searching to see if we 657 // would've found this header in -I or -isystem directories. 658 if (Diags.getDiagnosticLevel(diag::ext_pp_include_search_ms, 659 IncludeLoc) == 660 DiagnosticsEngine::Ignored) { 661 return FE; 662 } else { 663 MSFE = FE; 664 if (SuggestedModule) { 665 MSSuggestedModule = *SuggestedModule; 666 *SuggestedModule = ModuleMap::KnownHeader(); 667 } 668 break; 669 } 670 } 671 } 672 } 673 674 CurDir = 0; 675 676 // If this is a system #include, ignore the user #include locs. 677 unsigned i = isAngled ? AngledDirIdx : 0; 678 679 // If this is a #include_next request, start searching after the directory the 680 // file was found in. 681 if (FromDir) 682 i = FromDir-&SearchDirs[0]; 683 684 // Cache all of the lookups performed by this method. Many headers are 685 // multiply included, and the "pragma once" optimization prevents them from 686 // being relex/pp'd, but they would still have to search through a 687 // (potentially huge) series of SearchDirs to find it. 688 LookupFileCacheInfo &CacheLookup = 689 LookupFileCache.GetOrCreateValue(Filename).getValue(); 690 691 // If the entry has been previously looked up, the first value will be 692 // non-zero. If the value is equal to i (the start point of our search), then 693 // this is a matching hit. 694 if (!SkipCache && CacheLookup.StartIdx == i+1) { 695 // Skip querying potentially lots of directories for this lookup. 696 i = CacheLookup.HitIdx; 697 if (CacheLookup.MappedName) 698 Filename = CacheLookup.MappedName; 699 } else { 700 // Otherwise, this is the first query, or the previous query didn't match 701 // our search start. We will fill in our found location below, so prime the 702 // start point value. 703 CacheLookup.reset(/*StartIdx=*/i+1); 704 } 705 706 SmallString<64> MappedName; 707 708 // Check each directory in sequence to see if it contains this file. 709 for (; i != SearchDirs.size(); ++i) { 710 bool InUserSpecifiedSystemFramework = false; 711 bool HasBeenMapped = false; 712 const FileEntry *FE = 713 SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath, 714 SuggestedModule, InUserSpecifiedSystemFramework, 715 HasBeenMapped, MappedName); 716 if (HasBeenMapped) { 717 CacheLookup.MappedName = 718 copyString(Filename, LookupFileCache.getAllocator()); 719 } 720 if (!FE) continue; 721 722 CurDir = &SearchDirs[i]; 723 724 // This file is a system header or C++ unfriendly if the dir is. 725 HeaderFileInfo &HFI = getFileInfo(FE); 726 HFI.DirInfo = CurDir->getDirCharacteristic(); 727 728 // If the directory characteristic is User but this framework was 729 // user-specified to be treated as a system framework, promote the 730 // characteristic. 731 if (HFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework) 732 HFI.DirInfo = SrcMgr::C_System; 733 734 // If the filename matches a known system header prefix, override 735 // whether the file is a system header. 736 for (unsigned j = SystemHeaderPrefixes.size(); j; --j) { 737 if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) { 738 HFI.DirInfo = SystemHeaderPrefixes[j-1].second ? SrcMgr::C_System 739 : SrcMgr::C_User; 740 break; 741 } 742 } 743 744 // If this file is found in a header map and uses the framework style of 745 // includes, then this header is part of a framework we're building. 746 if (CurDir->isIndexHeaderMap()) { 747 size_t SlashPos = Filename.find('/'); 748 if (SlashPos != StringRef::npos) { 749 HFI.IndexHeaderMapHeader = 1; 750 HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(), 751 SlashPos)); 752 } 753 } 754 755 if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) { 756 if (SuggestedModule) 757 *SuggestedModule = MSSuggestedModule; 758 return MSFE; 759 } 760 761 // Remember this location for the next lookup we do. 762 CacheLookup.HitIdx = i; 763 return FE; 764 } 765 766 // If we are including a file with a quoted include "foo.h" from inside 767 // a header in a framework that is currently being built, and we couldn't 768 // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where 769 // "Foo" is the name of the framework in which the including header was found. 770 if (!Includers.empty() && !isAngled && 771 Filename.find('/') == StringRef::npos) { 772 HeaderFileInfo &IncludingHFI = getFileInfo(Includers.front()); 773 if (IncludingHFI.IndexHeaderMapHeader) { 774 SmallString<128> ScratchFilename; 775 ScratchFilename += IncludingHFI.Framework; 776 ScratchFilename += '/'; 777 ScratchFilename += Filename; 778 779 const FileEntry *FE = LookupFile( 780 ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, CurDir, 781 Includers.front(), SearchPath, RelativePath, SuggestedModule); 782 783 if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) { 784 if (SuggestedModule) 785 *SuggestedModule = MSSuggestedModule; 786 return MSFE; 787 } 788 789 LookupFileCacheInfo &CacheLookup 790 = LookupFileCache.GetOrCreateValue(Filename).getValue(); 791 CacheLookup.HitIdx 792 = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().HitIdx; 793 // FIXME: SuggestedModule. 794 return FE; 795 } 796 } 797 798 if (checkMSVCHeaderSearch(Diags, MSFE, 0, IncludeLoc)) { 799 if (SuggestedModule) 800 *SuggestedModule = MSSuggestedModule; 801 return MSFE; 802 } 803 804 // Otherwise, didn't find it. Remember we didn't find this. 805 CacheLookup.HitIdx = SearchDirs.size(); 806 return 0; 807 } 808 809 /// LookupSubframeworkHeader - Look up a subframework for the specified 810 /// \#include file. For example, if \#include'ing <HIToolbox/HIToolbox.h> from 811 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox 812 /// is a subframework within Carbon.framework. If so, return the FileEntry 813 /// for the designated file, otherwise return null. 814 const FileEntry *HeaderSearch:: 815 LookupSubframeworkHeader(StringRef Filename, 816 const FileEntry *ContextFileEnt, 817 SmallVectorImpl<char> *SearchPath, 818 SmallVectorImpl<char> *RelativePath, 819 ModuleMap::KnownHeader *SuggestedModule) { 820 assert(ContextFileEnt && "No context file?"); 821 822 // Framework names must have a '/' in the filename. Find it. 823 // FIXME: Should we permit '\' on Windows? 824 size_t SlashPos = Filename.find('/'); 825 if (SlashPos == StringRef::npos) return 0; 826 827 // Look up the base framework name of the ContextFileEnt. 828 const char *ContextName = ContextFileEnt->getName(); 829 830 // If the context info wasn't a framework, couldn't be a subframework. 831 const unsigned DotFrameworkLen = 10; 832 const char *FrameworkPos = strstr(ContextName, ".framework"); 833 if (FrameworkPos == 0 || 834 (FrameworkPos[DotFrameworkLen] != '/' && 835 FrameworkPos[DotFrameworkLen] != '\\')) 836 return 0; 837 838 SmallString<1024> FrameworkName(ContextName, FrameworkPos+DotFrameworkLen+1); 839 840 // Append Frameworks/HIToolbox.framework/ 841 FrameworkName += "Frameworks/"; 842 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos); 843 FrameworkName += ".framework/"; 844 845 llvm::StringMapEntry<FrameworkCacheEntry> &CacheLookup = 846 FrameworkMap.GetOrCreateValue(Filename.substr(0, SlashPos)); 847 848 // Some other location? 849 if (CacheLookup.getValue().Directory && 850 CacheLookup.getKeyLength() == FrameworkName.size() && 851 memcmp(CacheLookup.getKeyData(), &FrameworkName[0], 852 CacheLookup.getKeyLength()) != 0) 853 return 0; 854 855 // Cache subframework. 856 if (CacheLookup.getValue().Directory == 0) { 857 ++NumSubFrameworkLookups; 858 859 // If the framework dir doesn't exist, we fail. 860 const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); 861 if (Dir == 0) return 0; 862 863 // Otherwise, if it does, remember that this is the right direntry for this 864 // framework. 865 CacheLookup.getValue().Directory = Dir; 866 } 867 868 const FileEntry *FE = 0; 869 870 if (RelativePath != NULL) { 871 RelativePath->clear(); 872 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 873 } 874 875 // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h" 876 SmallString<1024> HeadersFilename(FrameworkName); 877 HeadersFilename += "Headers/"; 878 if (SearchPath != NULL) { 879 SearchPath->clear(); 880 // Without trailing '/'. 881 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 882 } 883 884 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 885 if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) { 886 887 // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h" 888 HeadersFilename = FrameworkName; 889 HeadersFilename += "PrivateHeaders/"; 890 if (SearchPath != NULL) { 891 SearchPath->clear(); 892 // Without trailing '/'. 893 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 894 } 895 896 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 897 if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) 898 return 0; 899 } 900 901 // This file is a system header or C++ unfriendly if the old file is. 902 // 903 // Note that the temporary 'DirInfo' is required here, as either call to 904 // getFileInfo could resize the vector and we don't want to rely on order 905 // of evaluation. 906 unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo; 907 getFileInfo(FE).DirInfo = DirInfo; 908 909 // If we're supposed to suggest a module, look for one now. 910 if (SuggestedModule) { 911 // Find the top-level framework based on this framework. 912 FrameworkName.pop_back(); // remove the trailing '/' 913 SmallVector<std::string, 4> SubmodulePath; 914 const DirectoryEntry *TopFrameworkDir 915 = ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath); 916 917 // Determine the name of the top-level framework. 918 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName()); 919 920 // Load this framework module. If that succeeds, find the suggested module 921 // for this header, if any. 922 bool IsSystem = false; 923 if (loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystem)) { 924 *SuggestedModule = findModuleForHeader(FE); 925 } 926 } 927 928 return FE; 929 } 930 931 /// \brief Helper static function to normalize a path for injection into 932 /// a synthetic header. 933 /*static*/ std::string 934 HeaderSearch::NormalizeDashIncludePath(StringRef File, FileManager &FileMgr) { 935 // Implicit include paths should be resolved relative to the current 936 // working directory first, and then use the regular header search 937 // mechanism. The proper way to handle this is to have the 938 // predefines buffer located at the current working directory, but 939 // it has no file entry. For now, workaround this by using an 940 // absolute path if we find the file here, and otherwise letting 941 // header search handle it. 942 SmallString<128> Path(File); 943 llvm::sys::fs::make_absolute(Path); 944 bool exists; 945 if (llvm::sys::fs::exists(Path.str(), exists) || !exists) 946 Path = File; 947 else if (exists) 948 FileMgr.getFile(File); 949 950 return Lexer::Stringify(Path.str()); 951 } 952 953 //===----------------------------------------------------------------------===// 954 // File Info Management. 955 //===----------------------------------------------------------------------===// 956 957 /// \brief Merge the header file info provided by \p OtherHFI into the current 958 /// header file info (\p HFI) 959 static void mergeHeaderFileInfo(HeaderFileInfo &HFI, 960 const HeaderFileInfo &OtherHFI) { 961 HFI.isImport |= OtherHFI.isImport; 962 HFI.isPragmaOnce |= OtherHFI.isPragmaOnce; 963 HFI.isModuleHeader |= OtherHFI.isModuleHeader; 964 HFI.NumIncludes += OtherHFI.NumIncludes; 965 966 if (!HFI.ControllingMacro && !HFI.ControllingMacroID) { 967 HFI.ControllingMacro = OtherHFI.ControllingMacro; 968 HFI.ControllingMacroID = OtherHFI.ControllingMacroID; 969 } 970 971 if (OtherHFI.External) { 972 HFI.DirInfo = OtherHFI.DirInfo; 973 HFI.External = OtherHFI.External; 974 HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader; 975 } 976 977 if (HFI.Framework.empty()) 978 HFI.Framework = OtherHFI.Framework; 979 980 HFI.Resolved = true; 981 } 982 983 /// getFileInfo - Return the HeaderFileInfo structure for the specified 984 /// FileEntry. 985 HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) { 986 if (FE->getUID() >= FileInfo.size()) 987 FileInfo.resize(FE->getUID()+1); 988 989 HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 990 if (ExternalSource && !HFI.Resolved) 991 mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE)); 992 HFI.IsValid = 1; 993 return HFI; 994 } 995 996 bool HeaderSearch::tryGetFileInfo(const FileEntry *FE, HeaderFileInfo &Result) const { 997 if (FE->getUID() >= FileInfo.size()) 998 return false; 999 const HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 1000 if (HFI.IsValid) { 1001 Result = HFI; 1002 return true; 1003 } 1004 return false; 1005 } 1006 1007 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) { 1008 // Check if we've ever seen this file as a header. 1009 if (File->getUID() >= FileInfo.size()) 1010 return false; 1011 1012 // Resolve header file info from the external source, if needed. 1013 HeaderFileInfo &HFI = FileInfo[File->getUID()]; 1014 if (ExternalSource && !HFI.Resolved) 1015 mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(File)); 1016 1017 return HFI.isPragmaOnce || HFI.isImport || 1018 HFI.ControllingMacro || HFI.ControllingMacroID; 1019 } 1020 1021 void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE, 1022 ModuleMap::ModuleHeaderRole Role, 1023 bool isCompilingModuleHeader) { 1024 if (FE->getUID() >= FileInfo.size()) 1025 FileInfo.resize(FE->getUID()+1); 1026 1027 HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 1028 HFI.isModuleHeader = true; 1029 HFI.isCompilingModuleHeader = isCompilingModuleHeader; 1030 HFI.setHeaderRole(Role); 1031 } 1032 1033 bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){ 1034 ++NumIncluded; // Count # of attempted #includes. 1035 1036 // Get information about this file. 1037 HeaderFileInfo &FileInfo = getFileInfo(File); 1038 1039 // If this is a #import directive, check that we have not already imported 1040 // this header. 1041 if (isImport) { 1042 // If this has already been imported, don't import it again. 1043 FileInfo.isImport = true; 1044 1045 // Has this already been #import'ed or #include'd? 1046 if (FileInfo.NumIncludes) return false; 1047 } else { 1048 // Otherwise, if this is a #include of a file that was previously #import'd 1049 // or if this is the second #include of a #pragma once file, ignore it. 1050 if (FileInfo.isImport) 1051 return false; 1052 } 1053 1054 // Next, check to see if the file is wrapped with #ifndef guards. If so, and 1055 // if the macro that guards it is defined, we know the #include has no effect. 1056 if (const IdentifierInfo *ControllingMacro 1057 = FileInfo.getControllingMacro(ExternalLookup)) 1058 if (ControllingMacro->hasMacroDefinition()) { 1059 ++NumMultiIncludeFileOptzn; 1060 return false; 1061 } 1062 1063 // Increment the number of times this file has been included. 1064 ++FileInfo.NumIncludes; 1065 1066 return true; 1067 } 1068 1069 size_t HeaderSearch::getTotalMemory() const { 1070 return SearchDirs.capacity() 1071 + llvm::capacity_in_bytes(FileInfo) 1072 + llvm::capacity_in_bytes(HeaderMaps) 1073 + LookupFileCache.getAllocator().getTotalMemory() 1074 + FrameworkMap.getAllocator().getTotalMemory(); 1075 } 1076 1077 StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { 1078 return FrameworkNames.GetOrCreateValue(Framework).getKey(); 1079 } 1080 1081 bool HeaderSearch::hasModuleMap(StringRef FileName, 1082 const DirectoryEntry *Root, 1083 bool IsSystem) { 1084 if (!enabledModules()) 1085 return false; 1086 1087 SmallVector<const DirectoryEntry *, 2> FixUpDirectories; 1088 1089 StringRef DirName = FileName; 1090 do { 1091 // Get the parent directory name. 1092 DirName = llvm::sys::path::parent_path(DirName); 1093 if (DirName.empty()) 1094 return false; 1095 1096 // Determine whether this directory exists. 1097 const DirectoryEntry *Dir = FileMgr.getDirectory(DirName); 1098 if (!Dir) 1099 return false; 1100 1101 // Try to load the module map file in this directory. 1102 switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/false)) { 1103 case LMM_NewlyLoaded: 1104 case LMM_AlreadyLoaded: 1105 // Success. All of the directories we stepped through inherit this module 1106 // map file. 1107 for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I) 1108 DirectoryHasModuleMap[FixUpDirectories[I]] = true; 1109 return true; 1110 1111 case LMM_NoDirectory: 1112 case LMM_InvalidModuleMap: 1113 break; 1114 } 1115 1116 // If we hit the top of our search, we're done. 1117 if (Dir == Root) 1118 return false; 1119 1120 // Keep track of all of the directories we checked, so we can mark them as 1121 // having module maps if we eventually do find a module map. 1122 FixUpDirectories.push_back(Dir); 1123 } while (true); 1124 } 1125 1126 ModuleMap::KnownHeader 1127 HeaderSearch::findModuleForHeader(const FileEntry *File) const { 1128 if (ExternalSource) { 1129 // Make sure the external source has handled header info about this file, 1130 // which includes whether the file is part of a module. 1131 (void)getFileInfo(File); 1132 } 1133 return ModMap.findModuleForHeader(File); 1134 } 1135 1136 static const FileEntry *getPrivateModuleMap(StringRef ModuleMapPath, 1137 const DirectoryEntry *Directory, 1138 FileManager &FileMgr) { 1139 StringRef Filename = llvm::sys::path::filename(ModuleMapPath); 1140 SmallString<128> PrivateFilename(Directory->getName()); 1141 if (Filename == "module.map") 1142 llvm::sys::path::append(PrivateFilename, "module_private.map"); 1143 else if (Filename == "module.modulemap") 1144 llvm::sys::path::append(PrivateFilename, "module.private.modulemap"); 1145 else 1146 return nullptr; 1147 return FileMgr.getFile(PrivateFilename); 1148 } 1149 1150 bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) { 1151 switch (loadModuleMapFileImpl(File, IsSystem)) { 1152 case LMM_AlreadyLoaded: 1153 case LMM_NewlyLoaded: 1154 return false; 1155 case LMM_NoDirectory: 1156 case LMM_InvalidModuleMap: 1157 return true; 1158 } 1159 llvm_unreachable("Unknown load module map result"); 1160 } 1161 1162 HeaderSearch::LoadModuleMapResult 1163 HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem) { 1164 assert(File && "expected FileEntry"); 1165 1166 const DirectoryEntry *Dir = File->getDir(); 1167 auto KnownDir = DirectoryHasModuleMap.find(Dir); 1168 if (KnownDir != DirectoryHasModuleMap.end()) 1169 return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap; 1170 1171 if (ModMap.parseModuleMapFile(File, IsSystem)) { 1172 DirectoryHasModuleMap[Dir] = false; 1173 return LMM_InvalidModuleMap; 1174 } 1175 1176 // Try to load a corresponding private module map. 1177 if (const FileEntry *PMMFile = 1178 getPrivateModuleMap(File->getName(), Dir, FileMgr)) { 1179 if (ModMap.parseModuleMapFile(PMMFile, IsSystem)) { 1180 DirectoryHasModuleMap[Dir] = false; 1181 return LMM_InvalidModuleMap; 1182 } 1183 } 1184 1185 // This directory has a module map. 1186 DirectoryHasModuleMap[Dir] = true; 1187 return LMM_NewlyLoaded; 1188 } 1189 1190 const FileEntry * 1191 HeaderSearch::lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework) { 1192 // For frameworks, the preferred spelling is Modules/module.modulemap, but 1193 // module.map at the framework root is also accepted. 1194 SmallString<128> ModuleMapFileName(Dir->getName()); 1195 if (IsFramework) 1196 llvm::sys::path::append(ModuleMapFileName, "Modules"); 1197 llvm::sys::path::append(ModuleMapFileName, "module.modulemap"); 1198 if (const FileEntry *F = FileMgr.getFile(ModuleMapFileName)) 1199 return F; 1200 1201 // Continue to allow module.map 1202 ModuleMapFileName = Dir->getName(); 1203 llvm::sys::path::append(ModuleMapFileName, "module.map"); 1204 return FileMgr.getFile(ModuleMapFileName); 1205 } 1206 1207 Module *HeaderSearch::loadFrameworkModule(StringRef Name, 1208 const DirectoryEntry *Dir, 1209 bool IsSystem) { 1210 if (Module *Module = ModMap.findModule(Name)) 1211 return Module; 1212 1213 // Try to load a module map file. 1214 switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) { 1215 case LMM_InvalidModuleMap: 1216 break; 1217 1218 case LMM_AlreadyLoaded: 1219 case LMM_NoDirectory: 1220 return 0; 1221 1222 case LMM_NewlyLoaded: 1223 return ModMap.findModule(Name); 1224 } 1225 1226 1227 // Try to infer a module map from the framework directory. 1228 return ModMap.inferFrameworkModule(Name, Dir, IsSystem, /*Parent=*/0); 1229 } 1230 1231 1232 HeaderSearch::LoadModuleMapResult 1233 HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem, 1234 bool IsFramework) { 1235 if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName)) 1236 return loadModuleMapFile(Dir, IsSystem, IsFramework); 1237 1238 return LMM_NoDirectory; 1239 } 1240 1241 HeaderSearch::LoadModuleMapResult 1242 HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem, 1243 bool IsFramework) { 1244 auto KnownDir = DirectoryHasModuleMap.find(Dir); 1245 if (KnownDir != DirectoryHasModuleMap.end()) 1246 return KnownDir->second? LMM_AlreadyLoaded : LMM_InvalidModuleMap; 1247 1248 if (const FileEntry *ModuleMapFile = lookupModuleMapFile(Dir, IsFramework)) { 1249 LoadModuleMapResult Result = loadModuleMapFileImpl(ModuleMapFile, IsSystem); 1250 // Add Dir explicitly in case ModuleMapFile is in a subdirectory. 1251 // E.g. Foo.framework/Modules/module.modulemap 1252 // ^Dir ^ModuleMapFile 1253 if (Result == LMM_NewlyLoaded) 1254 DirectoryHasModuleMap[Dir] = true; 1255 return Result; 1256 } 1257 return LMM_InvalidModuleMap; 1258 } 1259 1260 void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) { 1261 Modules.clear(); 1262 1263 // Load module maps for each of the header search directories. 1264 for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 1265 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory(); 1266 if (SearchDirs[Idx].isFramework()) { 1267 llvm::error_code EC; 1268 SmallString<128> DirNative; 1269 llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(), 1270 DirNative); 1271 1272 // Search each of the ".framework" directories to load them as modules. 1273 for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; 1274 Dir != DirEnd && !EC; Dir.increment(EC)) { 1275 if (llvm::sys::path::extension(Dir->path()) != ".framework") 1276 continue; 1277 1278 const DirectoryEntry *FrameworkDir = FileMgr.getDirectory(Dir->path()); 1279 if (!FrameworkDir) 1280 continue; 1281 1282 // Load this framework module. 1283 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir, 1284 IsSystem); 1285 } 1286 continue; 1287 } 1288 1289 // FIXME: Deal with header maps. 1290 if (SearchDirs[Idx].isHeaderMap()) 1291 continue; 1292 1293 // Try to load a module map file for the search directory. 1294 loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem, /*IsFramework*/false); 1295 1296 // Try to load module map files for immediate subdirectories of this search 1297 // directory. 1298 loadSubdirectoryModuleMaps(SearchDirs[Idx]); 1299 } 1300 1301 // Populate the list of modules. 1302 for (ModuleMap::module_iterator M = ModMap.module_begin(), 1303 MEnd = ModMap.module_end(); 1304 M != MEnd; ++M) { 1305 Modules.push_back(M->getValue()); 1306 } 1307 } 1308 1309 void HeaderSearch::loadTopLevelSystemModules() { 1310 // Load module maps for each of the header search directories. 1311 for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 1312 // We only care about normal header directories. 1313 if (!SearchDirs[Idx].isNormalDir()) { 1314 continue; 1315 } 1316 1317 // Try to load a module map file for the search directory. 1318 loadModuleMapFile(SearchDirs[Idx].getDir(), 1319 SearchDirs[Idx].isSystemHeaderDirectory(), 1320 SearchDirs[Idx].isFramework()); 1321 } 1322 } 1323 1324 void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) { 1325 if (SearchDir.haveSearchedAllModuleMaps()) 1326 return; 1327 1328 llvm::error_code EC; 1329 SmallString<128> DirNative; 1330 llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative); 1331 for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; 1332 Dir != DirEnd && !EC; Dir.increment(EC)) { 1333 loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(), 1334 SearchDir.isFramework()); 1335 } 1336 1337 SearchDir.setSearchedAllModuleMaps(true); 1338 } 1339