15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- HeaderSearch.cpp - Resolve Header File Locations ---===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file implements the DirectoryLookup and HeaderSearch interfaces. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Lex/HeaderSearch.h" 15822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner#include "clang/Lex/HeaderMap.h" 16cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth#include "clang/Lex/Lexer.h" 17a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Basic/Diagnostic.h" 18c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#include "clang/Basic/FileManager.h" 19c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#include "clang/Basic/IdentifierTable.h" 2032bef4edba854303800b3b01cb49a282e5da4f69Michael J. Spencer#include "llvm/Support/FileSystem.h" 2103013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Path.h" 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/SmallString.h" 23eabea45e23abc07e917f0d4bce15054ce75623efTed Kremenek#include "llvm/Support/Capacity.h" 243daed52a57d03765223021f5f921bdc280c8f3ccChris Lattner#include <cstdio> 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 278c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorconst IdentifierInfo * 288c5a760b82e73ed90b560090772db97e2ae27b09Douglas GregorHeaderFileInfo::getControllingMacro(ExternalIdentifierLookup *External) { 298c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor if (ControllingMacro) 308c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor return ControllingMacro; 318c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 328c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor if (!ControllingMacroID || !External) 338c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor return 0; 348c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 358c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor ControllingMacro = External->GetIdentifier(ControllingMacroID); 368c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor return ControllingMacro; 378c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor} 388c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 39cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas GregorExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() {} 40cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 4151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas GregorHeaderSearch::HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags, 42dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor const LangOptions &LangOpts, 43dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor const TargetInfo *Target) 44a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor : FileMgr(FM), Diags(Diags), FrameworkMap(64), 45dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor ModMap(FileMgr, *Diags.getClient(), LangOpts, Target) 468e23806863721495f9e1f84aed614f7afba774a3Douglas Gregor{ 4774a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber AngledDirIdx = 0; 485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SystemDirIdx = 0; 495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NoCurDirSearch = false; 501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 518c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor ExternalLookup = 0; 52cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor ExternalSource = 0; 535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumIncluded = 0; 545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumMultiIncludeFileOptzn = 0; 555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumFrameworkLookups = NumSubFrameworkLookups = 0; 565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 58822da61b74ce14e89b3fa8774db18c833aa5748bChris LattnerHeaderSearch::~HeaderSearch() { 59822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner // Delete headermaps. 60822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i) 61822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner delete HeaderMaps[i].second; 62822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner} 631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid HeaderSearch::PrintStats() { 655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "\n*** HeaderSearch Stats:\n"); 665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "%d files tracked.\n", (int)FileInfo.size()); 675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0; 685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) { 695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumOnceOnlyFiles += FileInfo[i].isImport; 705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (MaxNumIncludes < FileInfo[i].NumIncludes) 715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer MaxNumIncludes = FileInfo[i].NumIncludes; 725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1; 735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d #import/#pragma once files.\n", NumOnceOnlyFiles); 755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d included exactly once.\n", NumSingleIncludedFiles); 765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d max times a file is included.\n", MaxNumIncludes); 771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d #include/#include_next/#import.\n", NumIncluded); 795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d #includes skipped due to" 805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer " the multi-include optimization.\n", NumMultiIncludeFileOptzn); 811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "%d framework lookups.\n", NumFrameworkLookups); 835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "%d subframework lookups.\n", NumSubFrameworkLookups); 845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 86822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner/// CreateHeaderMap - This method returns a HeaderMap for the specified 87bed28ac1d1463adca3ecf24fca5c30646fa9dbb2Sylvestre Ledru/// FileEntry, uniquing them through the 'HeaderMaps' datastructure. 881bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattnerconst HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) { 89822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner // We expect the number of headermaps to be small, and almost always empty. 90df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // If it ever grows, use of a linear search should be re-evaluated. 91822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner if (!HeaderMaps.empty()) { 92822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i) 93df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // Pointer equality comparison of FileEntries works because they are 94df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // already uniqued by inode. 951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (HeaderMaps[i].first == FE) 96822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner return HeaderMaps[i].second; 97822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner } 981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9939b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner if (const HeaderMap *HM = HeaderMap::Create(FE, FileMgr)) { 100822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner HeaderMaps.push_back(std::make_pair(FE, HM)); 101822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner return HM; 102822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner } 1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 104822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner return 0; 105822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner} 106822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner 107e434ec71fccfe078906403affd641f709702d598Douglas Gregorstd::string HeaderSearch::getModuleFileName(Module *Module) { 1089a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor // If we don't have a module cache path, we can't do anything. 109e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (ModuleCachePath.empty()) 110e434ec71fccfe078906403affd641f709702d598Douglas Gregor return std::string(); 111e434ec71fccfe078906403affd641f709702d598Douglas Gregor 112e434ec71fccfe078906403affd641f709702d598Douglas Gregor 113f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<256> Result(ModuleCachePath); 114e434ec71fccfe078906403affd641f709702d598Douglas Gregor llvm::sys::path::append(Result, Module->getTopLevelModule()->Name + ".pcm"); 115e434ec71fccfe078906403affd641f709702d598Douglas Gregor return Result.str().str(); 116e434ec71fccfe078906403affd641f709702d598Douglas Gregor} 117e434ec71fccfe078906403affd641f709702d598Douglas Gregor 118e434ec71fccfe078906403affd641f709702d598Douglas Gregorstd::string HeaderSearch::getModuleFileName(StringRef ModuleName) { 119e434ec71fccfe078906403affd641f709702d598Douglas Gregor // If we don't have a module cache path, we can't do anything. 120e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (ModuleCachePath.empty()) 121e434ec71fccfe078906403affd641f709702d598Douglas Gregor return std::string(); 1226e975c4517958bcc11c834336d340797356058dbDouglas Gregor 123e434ec71fccfe078906403affd641f709702d598Douglas Gregor 124f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<256> Result(ModuleCachePath); 125e434ec71fccfe078906403affd641f709702d598Douglas Gregor llvm::sys::path::append(Result, ModuleName + ".pcm"); 126e434ec71fccfe078906403affd641f709702d598Douglas Gregor return Result.str().str(); 127e434ec71fccfe078906403affd641f709702d598Douglas Gregor} 128e434ec71fccfe078906403affd641f709702d598Douglas Gregor 129e434ec71fccfe078906403affd641f709702d598Douglas GregorModule *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) { 130cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // Look in the module map to determine if there is a module by this name. 131e434ec71fccfe078906403affd641f709702d598Douglas Gregor Module *Module = ModMap.findModule(ModuleName); 132e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (Module || !AllowSearch) 133e434ec71fccfe078906403affd641f709702d598Douglas Gregor return Module; 134e434ec71fccfe078906403affd641f709702d598Douglas Gregor 135e434ec71fccfe078906403affd641f709702d598Douglas Gregor // Look through the various header search paths to load any avai;able module 136e434ec71fccfe078906403affd641f709702d598Douglas Gregor // maps, searching for a module map that describes this module. 137e434ec71fccfe078906403affd641f709702d598Douglas Gregor for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 138e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (SearchDirs[Idx].isFramework()) { 139e434ec71fccfe078906403affd641f709702d598Douglas Gregor // Search for or infer a module map for a framework. 140f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> FrameworkDirName; 141e434ec71fccfe078906403affd641f709702d598Douglas Gregor FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName(); 142e434ec71fccfe078906403affd641f709702d598Douglas Gregor llvm::sys::path::append(FrameworkDirName, ModuleName + ".framework"); 143e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (const DirectoryEntry *FrameworkDir 144e434ec71fccfe078906403affd641f709702d598Douglas Gregor = FileMgr.getDirectory(FrameworkDirName)) { 145e434ec71fccfe078906403affd641f709702d598Douglas Gregor bool IsSystem 146e434ec71fccfe078906403affd641f709702d598Douglas Gregor = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User; 147e434ec71fccfe078906403affd641f709702d598Douglas Gregor Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem); 148cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (Module) 149cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor break; 150cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 151e434ec71fccfe078906403affd641f709702d598Douglas Gregor } 152e434ec71fccfe078906403affd641f709702d598Douglas Gregor 153e434ec71fccfe078906403affd641f709702d598Douglas Gregor // FIXME: Figure out how header maps and module maps will work together. 154e434ec71fccfe078906403affd641f709702d598Douglas Gregor 155e434ec71fccfe078906403affd641f709702d598Douglas Gregor // Only deal with normal search directories. 156e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (!SearchDirs[Idx].isNormalDir()) 157e434ec71fccfe078906403affd641f709702d598Douglas Gregor continue; 158e434ec71fccfe078906403affd641f709702d598Douglas Gregor 159e434ec71fccfe078906403affd641f709702d598Douglas Gregor // Search for a module map file in this directory. 160e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (loadModuleMapFile(SearchDirs[Idx].getDir()) == LMM_NewlyLoaded) { 161e434ec71fccfe078906403affd641f709702d598Douglas Gregor // We just loaded a module map file; check whether the module is 162e434ec71fccfe078906403affd641f709702d598Douglas Gregor // available now. 163e434ec71fccfe078906403affd641f709702d598Douglas Gregor Module = ModMap.findModule(ModuleName); 164e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (Module) 165e434ec71fccfe078906403affd641f709702d598Douglas Gregor break; 166e434ec71fccfe078906403affd641f709702d598Douglas Gregor } 167e434ec71fccfe078906403affd641f709702d598Douglas Gregor 168e434ec71fccfe078906403affd641f709702d598Douglas Gregor // Search for a module map in a subdirectory with the same name as the 169e434ec71fccfe078906403affd641f709702d598Douglas Gregor // module. 170f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> NestedModuleMapDirName; 171e434ec71fccfe078906403affd641f709702d598Douglas Gregor NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName(); 172e434ec71fccfe078906403affd641f709702d598Douglas Gregor llvm::sys::path::append(NestedModuleMapDirName, ModuleName); 173e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (loadModuleMapFile(NestedModuleMapDirName) == LMM_NewlyLoaded) { 174e434ec71fccfe078906403affd641f709702d598Douglas Gregor // If we just loaded a module map file, look for the module again. 175e434ec71fccfe078906403affd641f709702d598Douglas Gregor Module = ModMap.findModule(ModuleName); 176e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (Module) 177e434ec71fccfe078906403affd641f709702d598Douglas Gregor break; 178cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 179cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 180e434ec71fccfe078906403affd641f709702d598Douglas Gregor 181e434ec71fccfe078906403affd641f709702d598Douglas Gregor return Module; 1829a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor} 1839a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor 184df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner//===----------------------------------------------------------------------===// 185df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner// File lookup within a DirectoryLookup scope 186df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner//===----------------------------------------------------------------------===// 187df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 1883af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner/// getName - Return the directory or filename corresponding to this lookup 1893af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner/// object. 1903af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattnerconst char *DirectoryLookup::getName() const { 1913af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner if (isNormalDir()) 1923af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner return getDir()->getName(); 1933af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner if (isFramework()) 1943af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner return getFrameworkDir()->getName(); 1953af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner assert(isHeaderMap() && "Unknown DirectoryLookup"); 1963af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner return getHeaderMap()->getFileName(); 1973af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner} 1983af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner 1993af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner 200df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner/// LookupFile - Lookup the specified file in this search path, returning it 201df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner/// if it exists or returning null if not. 202b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruthconst FileEntry *DirectoryLookup::LookupFile( 2035f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Filename, 2047412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek HeaderSearch &HS, 2055f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *SearchPath, 206fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SmallVectorImpl<char> *RelativePath, 20785ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar Module **SuggestedModule, 20885ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar bool &InUserSpecifiedSystemFramework) const { 20985ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar InUserSpecifiedSystemFramework = false; 21085ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar 211f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<1024> TmpDir; 212afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner if (isNormalDir()) { 213afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Concatenate the requested file onto the directory. 214a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman TmpDir = getDir()->getName(); 215a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman llvm::sys::path::append(TmpDir, Filename); 2167412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 2175f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef SearchPathRef(getDir()->getName()); 2187412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 2197412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 2207412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 2217412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 2227412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 2237412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin(), Filename.end()); 2247412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 225a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 226a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // If we have a module map that might map this header, load it and 227a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // check whether we'll have a suggestion for a module. 228a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (SuggestedModule && HS.hasModuleMap(TmpDir, getDir())) { 229a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor const FileEntry *File = HS.getFileMgr().getFile(TmpDir.str(), 230a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /*openFile=*/false); 231a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!File) 232a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return File; 233a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 234a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // If there is a module that corresponds to this header, 235a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // suggest it. 2365e3f9223db88227d6d21679c613b139d8160186dDouglas Gregor *SuggestedModule = HS.findModuleForHeader(File); 237a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return File; 238a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 239a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 2403cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis return HS.getFileMgr().getFile(TmpDir.str(), /*openFile=*/true); 241afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner } 2421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 243afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner if (isFramework()) 244fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath, 24585ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar SuggestedModule, InUserSpecifiedSystemFramework); 2461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 247b09e71fd52d0e7fdf3e88b1df72ea0cee5d9b37bChris Lattner assert(isHeaderMap() && "Unknown directory lookup"); 2487412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek const FileEntry * const Result = getHeaderMap()->LookupFile( 2497412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek Filename, HS.getFileMgr()); 2507412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (Result) { 2517412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 2525f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef SearchPathRef(getName()); 2537412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 2547412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 2557412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 2567412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 2577412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 2587412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin(), Filename.end()); 2597412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 2607412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 2617412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek return Result; 262df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner} 263df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 264df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 265afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner/// DoFrameworkLookup - Do a lookup of the specified file in the current 266afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner/// DirectoryLookup, which is a framework directory. 267b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruthconst FileEntry *DirectoryLookup::DoFrameworkLookup( 2685f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Filename, 2697412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek HeaderSearch &HS, 2705f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *SearchPath, 271fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SmallVectorImpl<char> *RelativePath, 27285ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar Module **SuggestedModule, 27385ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar bool &InUserSpecifiedSystemFramework) const 274fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor{ 275afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner FileManager &FileMgr = HS.getFileMgr(); 2761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Framework names must have a '/' in the filename. 278a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner size_t SlashPos = Filename.find('/'); 2795f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (SlashPos == StringRef::npos) return 0; 2801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 281afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Find out if this is the home for the specified framework, by checking 2829ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar // HeaderSearch. Possible answers are yes/no and unknown. 2839ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar HeaderSearch::FrameworkCacheEntry &CacheEntry = 284a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner HS.LookupFrameworkCache(Filename.substr(0, SlashPos)); 2851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 286afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // If it is known and in some other directory, fail. 2879ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDir()) 2885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 2891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 290afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Otherwise, construct the path to this framework dir. 2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FrameworkName = "/System/Library/Frameworks/" 293f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<1024> FrameworkName; 294afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner FrameworkName += getFrameworkDir()->getName(); 2955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FrameworkName.empty() || FrameworkName.back() != '/') 2965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName.push_back('/'); 2971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FrameworkName = "/System/Library/Frameworks/Cocoa" 2992821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor StringRef ModuleName(Filename.begin(), SlashPos); 3002821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor FrameworkName += ModuleName; 3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/" 3035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += ".framework/"; 3041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3059ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar // If the cache entry was unresolved, populate it now. 3069ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar if (CacheEntry.Directory == 0) { 307afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner HS.IncrementFrameworkLookupCount(); 3081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the framework dir doesn't exist, we fail. 31085ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); 31185ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar if (Dir == 0) return 0; 3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, if it does, remember that this is the right direntry for this 3145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // framework. 3159ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar CacheEntry.Directory = getFrameworkDir(); 31685ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar 31785ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // If this is a user search directory, check if the framework has been 31885ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // user-specified as a system framework. 31985ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar if (getDirCharacteristic() == SrcMgr::C_User) { 32085ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar SmallString<1024> SystemFrameworkMarker(FrameworkName); 32185ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar SystemFrameworkMarker += ".system_framework"; 32285ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar if (llvm::sys::fs::exists(SystemFrameworkMarker.str())) { 32385ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar CacheEntry.IsUserSpecifiedSystemFramework = true; 32485ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar } 32585ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar } 3265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 3271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 32885ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // Set the 'user-specified system framework' flag. 32985ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework; 33085ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar 3317412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 3327412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 3337412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 3347412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 3357412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 3362821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // If we're allowed to look for modules, try to load or create the module 3372821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // corresponding to this framework. 3381a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor Module *Module = 0; 3392821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor if (SuggestedModule) { 3402821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor if (const DirectoryEntry *FrameworkDir 341a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor = FileMgr.getDirectory(FrameworkName)) { 342a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor bool IsSystem = getDirCharacteristic() != SrcMgr::C_User; 343e434ec71fccfe078906403affd641f709702d598Douglas Gregor Module = HS.loadFrameworkModule(ModuleName, FrameworkDir, IsSystem); 344a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor } 3452821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor } 3462821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 3475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h" 3485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned OrigSize = FrameworkName.size(); 3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += "Headers/"; 3517412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 3527412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 3537412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 3547412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek // Without trailing '/'. 3557412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1); 3567412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 3577412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 3582821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // Determine whether this is the module we're building or not. 35909833925a3ac68065565e9556d06e9576ec6eaa9Douglas Gregor bool AutomaticImport = Module; 360a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end()); 3613cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), 362fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor /*openFile=*/!AutomaticImport)) { 363fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor if (AutomaticImport) 36409833925a3ac68065565e9556d06e9576ec6eaa9Douglas Gregor *SuggestedModule = HS.findModuleForHeader(FE); 3655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return FE; 366b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth } 3671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h" 3695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *Private = "Private"; 3701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump FrameworkName.insert(FrameworkName.begin()+OrigSize, Private, 3715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Private+strlen(Private)); 3727412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) 3737412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->insert(SearchPath->begin()+OrigSize, Private, 3747412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek Private+strlen(Private)); 3757412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 376fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), 377fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor /*openFile=*/!AutomaticImport); 378fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor if (FE && AutomaticImport) 37909833925a3ac68065565e9556d06e9576ec6eaa9Douglas Gregor *SuggestedModule = HS.findModuleForHeader(FE); 380fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor return FE; 3815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 3825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 383dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregorvoid HeaderSearch::setTarget(const TargetInfo &Target) { 384dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor ModMap.setTarget(Target); 385dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor} 386dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor 387df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 388afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner//===----------------------------------------------------------------------===// 389afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner// Header File Location. 390afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner//===----------------------------------------------------------------------===// 391afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner 392afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner 393853519cd45716c0a0923a7b65ce7aca63cb4dae4James Dennett/// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file, 3945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// return null on failure. isAngled indicates whether the file reference is 395853519cd45716c0a0923a7b65ce7aca63cb4dae4James Dennett/// for system \#include's or not (i.e. using <> instead of ""). CurFileEnt, if 396853519cd45716c0a0923a7b65ce7aca63cb4dae4James Dennett/// non-null, indicates where the \#including file is, in case a relative search 39710fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor/// is needed. 398b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruthconst FileEntry *HeaderSearch::LookupFile( 3995f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Filename, 400b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth bool isAngled, 401b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth const DirectoryLookup *FromDir, 402b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth const DirectoryLookup *&CurDir, 403b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth const FileEntry *CurFileEnt, 4045f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *SearchPath, 405fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SmallVectorImpl<char> *RelativePath, 4061a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor Module **SuggestedModule, 4071c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor bool SkipCache) 408fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor{ 409fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor if (SuggestedModule) 410c69c42e939e6bdaa56d162cc36da4f6b6c53e8dbDouglas Gregor *SuggestedModule = 0; 411fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor 4125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If 'Filename' is absolute, check to see if it exists and no searching. 413256053b31e697fdf0cc48f17d621c82fc3b8dff0Michael J. Spencer if (llvm::sys::path::is_absolute(Filename)) { 4145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CurDir = 0; 4155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this was an #include_next "/absolute/file", fail. 4175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FromDir) return 0; 4181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4197412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) 4207412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 4217412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 4227412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 4237412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin(), Filename.end()); 4247412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 4255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, just return the file. 4263cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis return FileMgr.getFile(Filename, /*openFile=*/true); 4275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 42965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor // Unless disabled, check to see if the file is in the #includer's 43010fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // directory. This has to be based on CurFileEnt, not CurDir, because 43110fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // CurFileEnt could be a #include of a subdirectory (#include "foo/bar.h") and 432df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h". 433df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // This search is not done for <> headers. 43410fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor if (CurFileEnt && !isAngled && !NoCurDirSearch) { 435f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<1024> TmpDir; 43610fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // Concatenate the requested file onto the directory. 43710fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // FIXME: Portability. Filename concatenation should be in sys::Path. 43810fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor TmpDir += CurFileEnt->getDir()->getName(); 43910fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor TmpDir.push_back('/'); 44010fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor TmpDir.append(Filename.begin(), Filename.end()); 4413cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(TmpDir.str(),/*openFile=*/true)) { 4425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Leave CurDir unset. 44310fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // This file is a system header or C++ unfriendly if the old file is. 44410fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // 44521efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor // Note that we only use one of FromHFI/ToHFI at once, due to potential 44621efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor // reallocation of the underlying vector potentially making the first 44721efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor // reference binding dangling. 44821efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor HeaderFileInfo &FromHFI = getFileInfo(CurFileEnt); 44921efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor unsigned DirInfo = FromHFI.DirInfo; 45021efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader; 45121efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor StringRef Framework = FromHFI.Framework; 45221efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor 45321efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor HeaderFileInfo &ToHFI = getFileInfo(FE); 45421efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor ToHFI.DirInfo = DirInfo; 45521efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader; 45621efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor ToHFI.Framework = Framework; 45721efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor 4587412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 4595f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef SearchPathRef(CurFileEnt->getDir()->getName()); 4607412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 4617412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 4627412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 4637412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 4647412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 4657412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin(), Filename.end()); 4667412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 4675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return FE; 4685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CurDir = 0; 4725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this is a system #include, ignore the user #include locs. 47474a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber unsigned i = isAngled ? AngledDirIdx : 0; 4751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this is a #include_next request, start searching after the directory the 4775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // file was found in. 4785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FromDir) 4795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer i = FromDir-&SearchDirs[0]; 4801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4819960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Cache all of the lookups performed by this method. Many headers are 4829960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // multiply included, and the "pragma once" optimization prevents them from 4839960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // being relex/pp'd, but they would still have to search through a 4849960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // (potentially huge) series of SearchDirs to find it. 4859960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner std::pair<unsigned, unsigned> &CacheLookup = 486a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner LookupFileCache.GetOrCreateValue(Filename).getValue(); 4879960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner 4889960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // If the entry has been previously looked up, the first value will be 4899960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // non-zero. If the value is equal to i (the start point of our search), then 4909960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // this is a matching hit. 4911c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor if (!SkipCache && CacheLookup.first == i+1) { 4929960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Skip querying potentially lots of directories for this lookup. 4939960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner i = CacheLookup.second; 4949960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner } else { 4959960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Otherwise, this is the first query, or the previous query didn't match 4969960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // our search start. We will fill in our found location below, so prime the 4979960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // start point value. 4989960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner CacheLookup.first = i+1; 4999960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner } 5001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check each directory in sequence to see if it contains this file. 5025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer for (; i != SearchDirs.size(); ++i) { 50385ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar bool InUserSpecifiedSystemFramework = false; 5041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const FileEntry *FE = 505fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath, 50685ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar SuggestedModule, InUserSpecifiedSystemFramework); 507afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner if (!FE) continue; 5081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 509afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner CurDir = &SearchDirs[i]; 5101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 511afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // This file is a system header or C++ unfriendly if the dir is. 51265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HeaderFileInfo &HFI = getFileInfo(FE); 51365e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HFI.DirInfo = CurDir->getDirCharacteristic(); 51465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor 51585ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // If the directory characteristic is User but this framework was 51685ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // user-specified to be treated as a system framework, promote the 51785ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // characteristic. 51885ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar if (HFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework) 51985ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar HFI.DirInfo = SrcMgr::C_System; 52085ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar 521f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith // If the filename matches a known system header prefix, override 522f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith // whether the file is a system header. 5234ef2f6a95146423a1947b98458cc95c00a8b3ebdRichard Trieu for (unsigned j = SystemHeaderPrefixes.size(); j; --j) { 5244ef2f6a95146423a1947b98458cc95c00a8b3ebdRichard Trieu if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) { 5254ef2f6a95146423a1947b98458cc95c00a8b3ebdRichard Trieu HFI.DirInfo = SystemHeaderPrefixes[j-1].second ? SrcMgr::C_System 526f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith : SrcMgr::C_User; 527f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith break; 528f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith } 529f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith } 530f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith 53165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor // If this file is found in a header map and uses the framework style of 53265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor // includes, then this header is part of a framework we're building. 53365e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor if (CurDir->isIndexHeaderMap()) { 53465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor size_t SlashPos = Filename.find('/'); 53565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor if (SlashPos != StringRef::npos) { 53665e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HFI.IndexHeaderMapHeader = 1; 53765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(), 53865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor SlashPos)); 53965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor } 54065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor } 54165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor 542afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Remember this location for the next lookup we do. 543afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner CacheLookup.second = i; 544afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner return FE; 5455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 5461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5472c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // If we are including a file with a quoted include "foo.h" from inside 5482c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // a header in a framework that is currently being built, and we couldn't 5492c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where 5502c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // "Foo" is the name of the framework in which the including header was found. 5512c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor if (CurFileEnt && !isAngled && Filename.find('/') == StringRef::npos) { 5522c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor HeaderFileInfo &IncludingHFI = getFileInfo(CurFileEnt); 5532c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor if (IncludingHFI.IndexHeaderMapHeader) { 554f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> ScratchFilename; 5552c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor ScratchFilename += IncludingHFI.Framework; 5562c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor ScratchFilename += '/'; 5572c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor ScratchFilename += Filename; 5582c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor 5592c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor const FileEntry *Result = LookupFile(ScratchFilename, /*isAngled=*/true, 5602c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor FromDir, CurDir, CurFileEnt, 561fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SearchPath, RelativePath, 562fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SuggestedModule); 5632c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor std::pair<unsigned, unsigned> &CacheLookup 5642c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor = LookupFileCache.GetOrCreateValue(Filename).getValue(); 5652c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor CacheLookup.second 5662c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().second; 5672c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor return Result; 5682c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor } 5692c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor } 5702c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor 5719960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Otherwise, didn't find it. Remember we didn't find this. 5729960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner CacheLookup.second = SearchDirs.size(); 5735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 5745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 5755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// LookupSubframeworkHeader - Look up a subframework for the specified 577853519cd45716c0a0923a7b65ce7aca63cb4dae4James Dennett/// \#include file. For example, if \#include'ing <HIToolbox/HIToolbox.h> from 5785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox 5795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is a subframework within Carbon.framework. If so, return the FileEntry 5805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// for the designated file, otherwise return null. 5815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerconst FileEntry *HeaderSearch:: 5825f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerLookupSubframeworkHeader(StringRef Filename, 583b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth const FileEntry *ContextFileEnt, 5845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *SearchPath, 5855f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *RelativePath) { 5869415a0cc93117b69add4e1dc0f11146f3479ee1aChris Lattner assert(ContextFileEnt && "No context file?"); 5871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Framework names must have a '/' in the filename. Find it. 589efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor // FIXME: Should we permit '\' on Windows? 590a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner size_t SlashPos = Filename.find('/'); 5915f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (SlashPos == StringRef::npos) return 0; 5921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Look up the base framework name of the ContextFileEnt. 5945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *ContextName = ContextFileEnt->getName(); 5951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the context info wasn't a framework, couldn't be a subframework. 597efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor const unsigned DotFrameworkLen = 10; 598efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor const char *FrameworkPos = strstr(ContextName, ".framework"); 599efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor if (FrameworkPos == 0 || 600efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor (FrameworkPos[DotFrameworkLen] != '/' && 601efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor FrameworkPos[DotFrameworkLen] != '\\')) 6025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 6031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6049ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar SmallString<1024> FrameworkName(ContextName, FrameworkPos+DotFrameworkLen+1); 6055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Append Frameworks/HIToolbox.framework/ 6075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += "Frameworks/"; 608a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos); 6095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += ".framework/"; 6105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6119ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar llvm::StringMapEntry<FrameworkCacheEntry> &CacheLookup = 6126538227d51df249b07c8ab80ae376f5c1d14403cChris Lattner FrameworkMap.GetOrCreateValue(Filename.substr(0, SlashPos)); 6131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Some other location? 6159ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar if (CacheLookup.getValue().Directory && 6165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CacheLookup.getKeyLength() == FrameworkName.size() && 6175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer memcmp(CacheLookup.getKeyData(), &FrameworkName[0], 6185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CacheLookup.getKeyLength()) != 0) 6195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 6201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Cache subframework. 6229ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar if (CacheLookup.getValue().Directory == 0) { 6235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ++NumSubFrameworkLookups; 6241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the framework dir doesn't exist, we fail. 62639b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); 6275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (Dir == 0) return 0; 6281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, if it does, remember that this is the right direntry for this 6305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // framework. 6319ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar CacheLookup.getValue().Directory = Dir; 6325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 6331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const FileEntry *FE = 0; 6355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6367412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 6377412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 6387412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 6397412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 6407412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 6415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h" 642f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<1024> HeadersFilename(FrameworkName); 6435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HeadersFilename += "Headers/"; 6447412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 6457412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 6467412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek // Without trailing '/'. 6477412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 6487412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 6497412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 650a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 6513cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) { 6521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h" 6545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HeadersFilename = FrameworkName; 6555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HeadersFilename += "PrivateHeaders/"; 6567412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 6577412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 6587412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek // Without trailing '/'. 6597412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 6607412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 6617412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 662a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 6633cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) 6645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 6655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 6661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // This file is a system header or C++ unfriendly if the old file is. 668ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek // 669c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner // Note that the temporary 'DirInfo' is required here, as either call to 670c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner // getFileInfo could resize the vector and we don't want to rely on order 671c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner // of evaluation. 672c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo; 673c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner getFileInfo(FE).DirInfo = DirInfo; 6745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return FE; 6755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 6765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 677cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth/// \brief Helper static function to normalize a path for injection into 678cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth/// a synthetic header. 679cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth/*static*/ std::string 680cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler CarruthHeaderSearch::NormalizeDashIncludePath(StringRef File, FileManager &FileMgr) { 681cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // Implicit include paths should be resolved relative to the current 682cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // working directory first, and then use the regular header search 683cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // mechanism. The proper way to handle this is to have the 684cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // predefines buffer located at the current working directory, but 685cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // it has no file entry. For now, workaround this by using an 686cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // absolute path if we find the file here, and otherwise letting 687cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // header search handle it. 688f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> Path(File); 689cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth llvm::sys::fs::make_absolute(Path); 690cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth bool exists; 691cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth if (llvm::sys::fs::exists(Path.str(), exists) || !exists) 692cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth Path = File; 693cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth else if (exists) 694cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth FileMgr.getFile(File); 695cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth 696cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth return Lexer::Stringify(Path.str()); 697cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth} 698cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth 6995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 7005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// File Info Management. 7015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 7025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7038f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor/// \brief Merge the header file info provided by \p OtherHFI into the current 7048f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor/// header file info (\p HFI) 7058f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregorstatic void mergeHeaderFileInfo(HeaderFileInfo &HFI, 7068f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor const HeaderFileInfo &OtherHFI) { 7078f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.isImport |= OtherHFI.isImport; 7088f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.isPragmaOnce |= OtherHFI.isPragmaOnce; 7098f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.NumIncludes += OtherHFI.NumIncludes; 7108f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 7118f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (!HFI.ControllingMacro && !HFI.ControllingMacroID) { 7128f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.ControllingMacro = OtherHFI.ControllingMacro; 7138f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.ControllingMacroID = OtherHFI.ControllingMacroID; 7148f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor } 7158f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 7168f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (OtherHFI.External) { 7178f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.DirInfo = OtherHFI.DirInfo; 7188f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.External = OtherHFI.External; 7198f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader; 7208f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor } 7215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7228f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (HFI.Framework.empty()) 7238f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.Framework = OtherHFI.Framework; 7248f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 7258f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.Resolved = true; 7268f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor} 7278f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 72883d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff/// getFileInfo - Return the HeaderFileInfo structure for the specified 7295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// FileEntry. 73083d63c78810556d26b62ac4cbae2eda6cdd2570cSteve NaroffHeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) { 7315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FE->getUID() >= FileInfo.size()) 7325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FileInfo.resize(FE->getUID()+1); 733cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 734cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 7358f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (ExternalSource && !HFI.Resolved) 7368f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE)); 737cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor return HFI; 7381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 7395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 740dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregorbool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) { 741dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor // Check if we've ever seen this file as a header. 742dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor if (File->getUID() >= FileInfo.size()) 743dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor return false; 744dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor 745dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor // Resolve header file info from the external source, if needed. 746dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor HeaderFileInfo &HFI = FileInfo[File->getUID()]; 7478f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (ExternalSource && !HFI.Resolved) 7488f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(File)); 749dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor 750dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor return HFI.isPragmaOnce || HFI.ControllingMacro || HFI.ControllingMacroID; 751dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor} 752dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor 75383d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroffvoid HeaderSearch::setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID) { 75483d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff if (UID >= FileInfo.size()) 75583d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff FileInfo.resize(UID+1); 756cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor HFI.Resolved = true; 75783d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff FileInfo[UID] = HFI; 75883d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff} 75983d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff 7605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){ 7615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ++NumIncluded; // Count # of attempted #includes. 7625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Get information about this file. 76483d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff HeaderFileInfo &FileInfo = getFileInfo(File); 7651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this is a #import directive, check that we have not already imported 7675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // this header. 7685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (isImport) { 7695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this has already been imported, don't import it again. 7705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FileInfo.isImport = true; 7711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Has this already been #import'ed or #include'd? 7735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FileInfo.NumIncludes) return false; 7745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 7755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, if this is a #include of a file that was previously #import'd 7765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // or if this is the second #include of a #pragma once file, ignore it. 7775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FileInfo.isImport) 7785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return false; 7795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 7801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Next, check to see if the file is wrapped with #ifndef guards. If so, and 7825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // if the macro that guards it is defined, we know the #include has no effect. 7831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (const IdentifierInfo *ControllingMacro 7848c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor = FileInfo.getControllingMacro(ExternalLookup)) 7858c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor if (ControllingMacro->hasMacroDefinition()) { 7868c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor ++NumMultiIncludeFileOptzn; 7878c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor return false; 7888c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor } 7891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Increment the number of times this file has been included. 7915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ++FileInfo.NumIncludes; 7921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 7945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 7955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 796d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremeneksize_t HeaderSearch::getTotalMemory() const { 797d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek return SearchDirs.capacity() 798eabea45e23abc07e917f0d4bce15054ce75623efTed Kremenek + llvm::capacity_in_bytes(FileInfo) 799eabea45e23abc07e917f0d4bce15054ce75623efTed Kremenek + llvm::capacity_in_bytes(HeaderMaps) 800d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek + LookupFileCache.getAllocator().getTotalMemory() 801d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek + FrameworkMap.getAllocator().getTotalMemory(); 802d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek} 80365e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor 80465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas GregorStringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { 80565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor return FrameworkNames.GetOrCreateValue(Framework).getKey(); 80665e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor} 807a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 808a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorbool HeaderSearch::hasModuleMap(StringRef FileName, 809a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor const DirectoryEntry *Root) { 810a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::SmallVector<const DirectoryEntry *, 2> FixUpDirectories; 811a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 812a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringRef DirName = FileName; 813a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 814a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Get the parent directory name. 815a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DirName = llvm::sys::path::parent_path(DirName); 816a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (DirName.empty()) 817a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return false; 818a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 819a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Determine whether this directory exists. 820a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor const DirectoryEntry *Dir = FileMgr.getDirectory(DirName); 821a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Dir) 822a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return false; 823a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 824cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // Try to load the module map file in this directory. 82526697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor switch (loadModuleMapFile(Dir)) { 82626697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor case LMM_NewlyLoaded: 82726697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor case LMM_AlreadyLoaded: 828cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // Success. All of the directories we stepped through inherit this module 829cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // map file. 830a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I) 831a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DirectoryHasModuleMap[FixUpDirectories[I]] = true; 832a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 833a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return true; 83426697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor 83526697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor case LMM_NoDirectory: 83626697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor case LMM_InvalidModuleMap: 83726697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor break; 838a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 839a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 840cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // If we hit the top of our search, we're done. 841cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (Dir == Root) 842cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor return false; 843cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 844a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Keep track of all of the directories we checked, so we can mark them as 845a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // having module maps if we eventually do find a module map. 846a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor FixUpDirectories.push_back(Dir); 847a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (true); 848a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 849a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 8501a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas GregorModule *HeaderSearch::findModuleForHeader(const FileEntry *File) { 85151f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor if (Module *Mod = ModMap.findModuleForHeader(File)) 85251f564f80d9f71e175635b452ffeeeff899e9bf1Douglas Gregor return Mod; 85365f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor 854c69c42e939e6bdaa56d162cc36da4f6b6c53e8dbDouglas Gregor return 0; 855a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 856a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 857db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregorbool HeaderSearch::loadModuleMapFile(const FileEntry *File) { 858db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor const DirectoryEntry *Dir = File->getDir(); 859db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 860db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir 861db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor = DirectoryHasModuleMap.find(Dir); 862db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor if (KnownDir != DirectoryHasModuleMap.end()) 863db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor return !KnownDir->second; 864db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 865db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor bool Result = ModMap.parseModuleMapFile(File); 8664813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor if (!Result && llvm::sys::path::filename(File->getName()) == "module.map") { 8674813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor // If the file we loaded was a module.map, look for the corresponding 8684813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor // module_private.map. 869f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> PrivateFilename(Dir->getName()); 8704813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor llvm::sys::path::append(PrivateFilename, "module_private.map"); 8714813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor if (const FileEntry *PrivateFile = FileMgr.getFile(PrivateFilename)) 8724813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor Result = ModMap.parseModuleMapFile(PrivateFile); 8734813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor } 8744813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor 8754813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor DirectoryHasModuleMap[Dir] = !Result; 876db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor return Result; 877db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor} 878db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 879e434ec71fccfe078906403affd641f709702d598Douglas GregorModule *HeaderSearch::loadFrameworkModule(StringRef Name, 880e434ec71fccfe078906403affd641f709702d598Douglas Gregor const DirectoryEntry *Dir, 881e434ec71fccfe078906403affd641f709702d598Douglas Gregor bool IsSystem) { 8821a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor if (Module *Module = ModMap.findModule(Name)) 8832821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor return Module; 8842821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 8852821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // Try to load a module map file. 8862821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor switch (loadModuleMapFile(Dir)) { 8872821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor case LMM_InvalidModuleMap: 8882821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor break; 8892821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 8902821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor case LMM_AlreadyLoaded: 8912821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor case LMM_NoDirectory: 8922821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor return 0; 8932821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 8942821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor case LMM_NewlyLoaded: 8952821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor return ModMap.findModule(Name); 8962821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor } 897a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor 898a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor // The top-level framework directory, from which we'll infer a framework 899a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor // module. 900a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor const DirectoryEntry *TopFrameworkDir = Dir; 901a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor 902a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor // The path from the module we're actually looking for back to the top-level 903a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor // framework name. 904a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor llvm::SmallVector<StringRef, 2> SubmodulePath; 905a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor SubmodulePath.push_back(Name); 9062821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 907a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor // Walk the directory structure to find any enclosing frameworks. 908a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor StringRef DirName = Dir->getName(); 909a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor do { 910a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor // Get the parent directory name. 911a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor DirName = llvm::sys::path::parent_path(DirName); 912a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor if (DirName.empty()) 913a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor break; 914a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor 915a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor // Determine whether this directory exists. 916a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor Dir = FileMgr.getDirectory(DirName); 917a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor if (!Dir) 918a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor break; 919a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor 920a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor // If this is a framework directory, then we're a subframework of this 921a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor // framework. 922a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor if (llvm::sys::path::extension(DirName) == ".framework") { 923a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor SubmodulePath.push_back(llvm::sys::path::stem(DirName)); 924a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor TopFrameworkDir = Dir; 925a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor } 926a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor } while (true); 927a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor 928a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor // Try to infer a module map from the top-level framework directory. 929a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor Module *Result = ModMap.inferFrameworkModule(SubmodulePath.back(), 930a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor TopFrameworkDir, 931a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor IsSystem, 932a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor /*Parent=*/0); 933a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor 934a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor // Follow the submodule path to find the requested (sub)framework module 935a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor // within the top-level framework module. 936a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor SubmodulePath.pop_back(); 937a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor while (!SubmodulePath.empty() && Result) { 938a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor Result = ModMap.lookupModuleQualified(SubmodulePath.back(), Result); 939a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor SubmodulePath.pop_back(); 940a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor } 941a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor return Result; 9422821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor} 9432821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 944db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 94526697979fb0a4e2b720a0c8d062047edca92bc92Douglas GregorHeaderSearch::LoadModuleMapResult 94626697979fb0a4e2b720a0c8d062047edca92bc92Douglas GregorHeaderSearch::loadModuleMapFile(StringRef DirName) { 947cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName)) 948cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor return loadModuleMapFile(Dir); 949cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 95026697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor return LMM_NoDirectory; 951cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor} 952cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 95326697979fb0a4e2b720a0c8d062047edca92bc92Douglas GregorHeaderSearch::LoadModuleMapResult 95426697979fb0a4e2b720a0c8d062047edca92bc92Douglas GregorHeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir) { 955cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir 956cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor = DirectoryHasModuleMap.find(Dir); 957cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (KnownDir != DirectoryHasModuleMap.end()) 95826697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor return KnownDir->second? LMM_AlreadyLoaded : LMM_InvalidModuleMap; 959cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 960f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> ModuleMapFileName; 961cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor ModuleMapFileName += Dir->getName(); 962587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor unsigned ModuleMapDirNameLen = ModuleMapFileName.size(); 963cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor llvm::sys::path::append(ModuleMapFileName, "module.map"); 964cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (const FileEntry *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) { 965cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // We have found a module map file. Try to parse it. 966587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (ModMap.parseModuleMapFile(ModuleMapFile)) { 967587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // No suitable module map. 968587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor DirectoryHasModuleMap[Dir] = false; 969587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return LMM_InvalidModuleMap; 970cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 971587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 972587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // This directory has a module map. 973587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor DirectoryHasModuleMap[Dir] = true; 974587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 975587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Check whether there is a private module map that we need to load as well. 976587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ModuleMapFileName.erase(ModuleMapFileName.begin() + ModuleMapDirNameLen, 977587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ModuleMapFileName.end()); 978587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor llvm::sys::path::append(ModuleMapFileName, "module_private.map"); 979587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (const FileEntry *PrivateModuleMapFile 980587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor = FileMgr.getFile(ModuleMapFileName)) { 981587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (ModMap.parseModuleMapFile(PrivateModuleMapFile)) { 982587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // No suitable module map. 983587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor DirectoryHasModuleMap[Dir] = false; 984587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return LMM_InvalidModuleMap; 985587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 986587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 987587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 988587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return LMM_NewlyLoaded; 989cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 990cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 991cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // No suitable module map. 992cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor DirectoryHasModuleMap[Dir] = false; 99326697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor return LMM_InvalidModuleMap; 994cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor} 995a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 996c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregorvoid HeaderSearch::collectAllModules(llvm::SmallVectorImpl<Module *> &Modules) { 997c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor Modules.clear(); 998c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 999c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Load module maps for each of the header search directories. 1000c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 1001c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor if (SearchDirs[Idx].isFramework()) { 1002c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor llvm::error_code EC; 1003f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> DirNative; 1004c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(), 1005c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor DirNative); 1006c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1007c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Search each of the ".framework" directories to load them as modules. 1008c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor bool IsSystem = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User; 1009c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; 1010c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 1011c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor if (llvm::sys::path::extension(Dir->path()) != ".framework") 1012c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor continue; 1013c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1014c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor const DirectoryEntry *FrameworkDir = FileMgr.getDirectory(Dir->path()); 1015c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor if (!FrameworkDir) 1016c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor continue; 1017c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1018c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Load this framework module. 1019c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir, 1020c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor IsSystem); 1021c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor } 1022c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor continue; 1023c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor } 1024c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1025c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // FIXME: Deal with header maps. 1026c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor if (SearchDirs[Idx].isHeaderMap()) 1027c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor continue; 1028c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1029c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Try to load a module map file for the search directory. 1030c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor loadModuleMapFile(SearchDirs[Idx].getDir()); 1031c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1032c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Try to load module map files for immediate subdirectories of this search 1033c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // directory. 1034c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor llvm::error_code EC; 1035f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> DirNative; 1036c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor llvm::sys::path::native(SearchDirs[Idx].getDir()->getName(), DirNative); 1037c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; 1038c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 1039c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor loadModuleMapFile(Dir->path()); 1040c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor } 1041c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor } 1042c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1043c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Populate the list of modules. 1044c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor for (ModuleMap::module_iterator M = ModMap.module_begin(), 1045c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor MEnd = ModMap.module_end(); 1046c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor M != MEnd; ++M) { 1047c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor Modules.push_back(M->getValue()); 1048c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor } 1049c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor} 1050