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" 15c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#include "clang/Basic/FileManager.h" 16c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#include "clang/Basic/IdentifierTable.h" 1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/HeaderMap.h" 1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/HeaderSearchOptions.h" 19651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/Lex/LexDiagnostic.h" 2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/Lexer.h" 216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/ADT/APInt.h" 226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/ADT/Hashing.h" 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/SmallString.h" 24eabea45e23abc07e917f0d4bce15054ce75623efTed Kremenek#include "llvm/Support/Capacity.h" 2555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/FileSystem.h" 2655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/Path.h" 27ddd2dfc1d3f4a36cbe8cd775c588623a17049f9fDaniel Jasper#include "llvm/Support/raw_ostream.h" 283daed52a57d03765223021f5f921bdc280c8f3ccChris Lattner#include <cstdio> 293cc6277a3dd4986af6422e41db18ba6efddbd800Douglas Gregor#if defined(LLVM_ON_UNIX) 30adeb7822cb7947194fef0e12d2d6583ccb8240b5Dmitri Gribenko#include <limits.h> 313cc6277a3dd4986af6422e41db18ba6efddbd800Douglas Gregor#endif 325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 348c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorconst IdentifierInfo * 358c5a760b82e73ed90b560090772db97e2ae27b09Douglas GregorHeaderFileInfo::getControllingMacro(ExternalIdentifierLookup *External) { 368c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor if (ControllingMacro) 378c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor return ControllingMacro; 388c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 398c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor if (!ControllingMacroID || !External) 406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 418c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 428c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor ControllingMacro = External->GetIdentifier(ControllingMacroID); 438c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor return ControllingMacro; 448c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor} 458c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 46cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas GregorExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() {} 47cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 48cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri GribenkoHeaderSearch::HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts, 49ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek SourceManager &SourceMgr, DiagnosticsEngine &Diags, 50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const LangOptions &LangOpts, 51dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor const TargetInfo *Target) 52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : HSOpts(HSOpts), Diags(Diags), FileMgr(SourceMgr.getFileManager()), 53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FrameworkMap(64), ModMap(SourceMgr, Diags, LangOpts, Target, *this) { 5474a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber AngledDirIdx = 0; 555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SystemDirIdx = 0; 565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NoCurDirSearch = false; 571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ExternalLookup = nullptr; 596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ExternalSource = nullptr; 605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumIncluded = 0; 615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumMultiIncludeFileOptzn = 0; 625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumFrameworkLookups = NumSubFrameworkLookups = 0; 63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EnabledModules = LangOpts.Modules; 655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 67822da61b74ce14e89b3fa8774db18c833aa5748bChris LattnerHeaderSearch::~HeaderSearch() { 68822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner // Delete headermaps. 69822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i) 70822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner delete HeaderMaps[i].second; 71822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner} 721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid HeaderSearch::PrintStats() { 745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "\n*** HeaderSearch Stats:\n"); 755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "%d files tracked.\n", (int)FileInfo.size()); 765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0; 775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) { 785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumOnceOnlyFiles += FileInfo[i].isImport; 795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (MaxNumIncludes < FileInfo[i].NumIncludes) 805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer MaxNumIncludes = FileInfo[i].NumIncludes; 815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1; 825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d #import/#pragma once files.\n", NumOnceOnlyFiles); 845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d included exactly once.\n", NumSingleIncludedFiles); 855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d max times a file is included.\n", MaxNumIncludes); 861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d #include/#include_next/#import.\n", NumIncluded); 885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d #includes skipped due to" 895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer " the multi-include optimization.\n", NumMultiIncludeFileOptzn); 901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "%d framework lookups.\n", NumFrameworkLookups); 925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "%d subframework lookups.\n", NumSubFrameworkLookups); 935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 95822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner/// CreateHeaderMap - This method returns a HeaderMap for the specified 96bed28ac1d1463adca3ecf24fca5c30646fa9dbb2Sylvestre Ledru/// FileEntry, uniquing them through the 'HeaderMaps' datastructure. 971bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattnerconst HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) { 98822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner // We expect the number of headermaps to be small, and almost always empty. 99df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // If it ever grows, use of a linear search should be re-evaluated. 100822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner if (!HeaderMaps.empty()) { 101822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i) 102df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // Pointer equality comparison of FileEntries works because they are 103df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // already uniqued by inode. 1041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (HeaderMaps[i].first == FE) 105822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner return HeaderMaps[i].second; 106822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner } 1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10839b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner if (const HeaderMap *HM = HeaderMap::Create(FE, FileMgr)) { 109822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner HeaderMaps.push_back(std::make_pair(FE, HM)); 110822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner return HM; 111822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner } 1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 114822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner} 115822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner 116e434ec71fccfe078906403affd641f709702d598Douglas Gregorstd::string HeaderSearch::getModuleFileName(Module *Module) { 1176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return getModuleFileName(Module->Name, Module->ModuleMap->getName()); 118e434ec71fccfe078906403affd641f709702d598Douglas Gregor} 119e434ec71fccfe078906403affd641f709702d598Douglas Gregor 1206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstd::string HeaderSearch::getModuleFileName(StringRef ModuleName, 1216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines StringRef ModuleMapPath) { 122e434ec71fccfe078906403affd641f709702d598Douglas Gregor // If we don't have a module cache path, we can't do anything. 123e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (ModuleCachePath.empty()) 124e434ec71fccfe078906403affd641f709702d598Douglas Gregor return std::string(); 1256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 126f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<256> Result(ModuleCachePath); 1276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::sys::fs::make_absolute(Result); 1286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (HSOpts->DisableModuleHash) { 1306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::sys::path::append(Result, ModuleName + ".pcm"); 1316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else { 1326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Construct the name <ModuleName>-<hash of ModuleMapPath>.pcm which should 1336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // be globally unique to this particular module. To avoid false-negatives 1346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // on case-insensitive filesystems, we use lower-case, which is safe because 1356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // to cause a collision the modules must have the same name, which is an 1366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // error if they are imported in the same translation. 1376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SmallString<256> AbsModuleMapPath(ModuleMapPath); 1386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::sys::fs::make_absolute(AbsModuleMapPath); 1396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APInt Code(64, llvm::hash_value(AbsModuleMapPath.str().lower())); 1406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SmallString<128> HashStr; 1416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Code.toStringUnsigned(HashStr, /*Radix*/36); 1426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::sys::path::append(Result, ModuleName + "-" + HashStr.str() + ".pcm"); 1436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 144e434ec71fccfe078906403affd641f709702d598Douglas Gregor return Result.str().str(); 145e434ec71fccfe078906403affd641f709702d598Douglas Gregor} 146e434ec71fccfe078906403affd641f709702d598Douglas Gregor 147e434ec71fccfe078906403affd641f709702d598Douglas GregorModule *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) { 148cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // Look in the module map to determine if there is a module by this name. 149e434ec71fccfe078906403affd641f709702d598Douglas Gregor Module *Module = ModMap.findModule(ModuleName); 150e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (Module || !AllowSearch) 151e434ec71fccfe078906403affd641f709702d598Douglas Gregor return Module; 152e434ec71fccfe078906403affd641f709702d598Douglas Gregor 1537005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Look through the various header search paths to load any available module 154e434ec71fccfe078906403affd641f709702d598Douglas Gregor // maps, searching for a module map that describes this module. 155e434ec71fccfe078906403affd641f709702d598Douglas Gregor for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 156e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (SearchDirs[Idx].isFramework()) { 157e434ec71fccfe078906403affd641f709702d598Douglas Gregor // Search for or infer a module map for a framework. 158f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> FrameworkDirName; 159e434ec71fccfe078906403affd641f709702d598Douglas Gregor FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName(); 160e434ec71fccfe078906403affd641f709702d598Douglas Gregor llvm::sys::path::append(FrameworkDirName, ModuleName + ".framework"); 161e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (const DirectoryEntry *FrameworkDir 162e434ec71fccfe078906403affd641f709702d598Douglas Gregor = FileMgr.getDirectory(FrameworkDirName)) { 163e434ec71fccfe078906403affd641f709702d598Douglas Gregor bool IsSystem 164e434ec71fccfe078906403affd641f709702d598Douglas Gregor = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User; 165e434ec71fccfe078906403affd641f709702d598Douglas Gregor Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem); 166cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (Module) 167cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor break; 168cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 169e434ec71fccfe078906403affd641f709702d598Douglas Gregor } 170e434ec71fccfe078906403affd641f709702d598Douglas Gregor 171e434ec71fccfe078906403affd641f709702d598Douglas Gregor // FIXME: Figure out how header maps and module maps will work together. 172e434ec71fccfe078906403affd641f709702d598Douglas Gregor 173e434ec71fccfe078906403affd641f709702d598Douglas Gregor // Only deal with normal search directories. 174e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (!SearchDirs[Idx].isNormalDir()) 175e434ec71fccfe078906403affd641f709702d598Douglas Gregor continue; 1768f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor 1778f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory(); 178e434ec71fccfe078906403affd641f709702d598Douglas Gregor // Search for a module map file in this directory. 179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem, 180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /*IsFramework*/false) == LMM_NewlyLoaded) { 181e434ec71fccfe078906403affd641f709702d598Douglas Gregor // We just loaded a module map file; check whether the module is 182e434ec71fccfe078906403affd641f709702d598Douglas Gregor // available now. 183e434ec71fccfe078906403affd641f709702d598Douglas Gregor Module = ModMap.findModule(ModuleName); 184e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (Module) 185e434ec71fccfe078906403affd641f709702d598Douglas Gregor break; 186e434ec71fccfe078906403affd641f709702d598Douglas Gregor } 187e434ec71fccfe078906403affd641f709702d598Douglas Gregor 188e434ec71fccfe078906403affd641f709702d598Douglas Gregor // Search for a module map in a subdirectory with the same name as the 189e434ec71fccfe078906403affd641f709702d598Douglas Gregor // module. 190f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> NestedModuleMapDirName; 191e434ec71fccfe078906403affd641f709702d598Douglas Gregor NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName(); 192e434ec71fccfe078906403affd641f709702d598Douglas Gregor llvm::sys::path::append(NestedModuleMapDirName, ModuleName); 193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (loadModuleMapFile(NestedModuleMapDirName, IsSystem, 194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /*IsFramework*/false) == LMM_NewlyLoaded){ 195e434ec71fccfe078906403affd641f709702d598Douglas Gregor // If we just loaded a module map file, look for the module again. 196e434ec71fccfe078906403affd641f709702d598Douglas Gregor Module = ModMap.findModule(ModuleName); 197e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (Module) 198e434ec71fccfe078906403affd641f709702d598Douglas Gregor break; 199cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 200cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor 201cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor // If we've already performed the exhaustive search for module maps in this 202cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor // search directory, don't do it again. 203cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor if (SearchDirs[Idx].haveSearchedAllModuleMaps()) 204cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor continue; 205cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor 206cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor // Load all module maps in the immediate subdirectories of this search 207cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor // directory. 208cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor loadSubdirectoryModuleMaps(SearchDirs[Idx]); 209cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor 210cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor // Look again for the module. 211cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor Module = ModMap.findModule(ModuleName); 212cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor if (Module) 213cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor break; 214cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 215cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor 216e434ec71fccfe078906403affd641f709702d598Douglas Gregor return Module; 2179a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor} 2189a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor 219df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner//===----------------------------------------------------------------------===// 220df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner// File lookup within a DirectoryLookup scope 221df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner//===----------------------------------------------------------------------===// 222df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 2233af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner/// getName - Return the directory or filename corresponding to this lookup 2243af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner/// object. 2253af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattnerconst char *DirectoryLookup::getName() const { 2263af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner if (isNormalDir()) 2273af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner return getDir()->getName(); 2283af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner if (isFramework()) 2293af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner return getFrameworkDir()->getName(); 2303af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner assert(isHeaderMap() && "Unknown DirectoryLookup"); 2313af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner return getHeaderMap()->getFileName(); 2323af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner} 2333af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner 234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic const FileEntry * 235651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesgetFileAndSuggestModule(HeaderSearch &HS, StringRef FileName, 236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const DirectoryEntry *Dir, bool IsSystemHeaderDir, 237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ModuleMap::KnownHeader *SuggestedModule) { 238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If we have a module map that might map this header, load it and 239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // check whether we'll have a suggestion for a module. 240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HS.hasModuleMap(FileName, Dir, IsSystemHeaderDir); 241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (SuggestedModule) { 242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FileEntry *File = HS.getFileMgr().getFile(FileName, 243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /*OpenFile=*/false); 244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (File) { 245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If there is a module that corresponds to this header, suggest it. 246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *SuggestedModule = HS.findModuleForHeader(File); 247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // FIXME: This appears to be a no-op. We loaded the module map for this 249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // directory at the start of this function. 250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!SuggestedModule->getModule() && 251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HS.hasModuleMap(FileName, Dir, IsSystemHeaderDir)) 252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *SuggestedModule = HS.findModuleForHeader(File); 253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return File; 256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 258651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return HS.getFileMgr().getFile(FileName, /*openFile=*/true); 259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 2603af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner 261df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner/// LookupFile - Lookup the specified file in this search path, returning it 262df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner/// if it exists or returning null if not. 263b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruthconst FileEntry *DirectoryLookup::LookupFile( 264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef &Filename, 2657412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek HeaderSearch &HS, 2665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *SearchPath, 267fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SmallVectorImpl<char> *RelativePath, 268bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl ModuleMap::KnownHeader *SuggestedModule, 269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool &InUserSpecifiedSystemFramework, 270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool &HasBeenMapped, 271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SmallVectorImpl<char> &MappedName) const { 27285ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar InUserSpecifiedSystemFramework = false; 273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HasBeenMapped = false; 27485ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar 275f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<1024> TmpDir; 276afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner if (isNormalDir()) { 277afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Concatenate the requested file onto the directory. 278a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman TmpDir = getDir()->getName(); 279a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman llvm::sys::path::append(TmpDir, Filename); 2806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (SearchPath) { 2815f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef SearchPathRef(getDir()->getName()); 2827412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 2837412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 2847412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 2856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (RelativePath) { 2867412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 2877412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin(), Filename.end()); 2887412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 289651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 290651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return getFileAndSuggestModule(HS, TmpDir.str(), getDir(), 291651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines isSystemHeaderDirectory(), 292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SuggestedModule); 293afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner } 2941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 295afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner if (isFramework()) 296fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath, 29785ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar SuggestedModule, InUserSpecifiedSystemFramework); 2981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 299b09e71fd52d0e7fdf3e88b1df72ea0cee5d9b37bChris Lattner assert(isHeaderMap() && "Unknown directory lookup"); 300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const HeaderMap *HM = getHeaderMap(); 301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SmallString<1024> Path; 302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef Dest = HM->lookupFilename(Filename, Path); 303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Dest.empty()) 3046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 305651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 306651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FileEntry *Result; 307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Check if the headermap maps the filename to a framework include 309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // ("Foo.h" -> "Foo/Foo.h"), in which case continue header lookup using the 310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // framework include. 311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (llvm::sys::path::is_relative(Dest)) { 312651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MappedName.clear(); 313651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MappedName.append(Dest.begin(), Dest.end()); 314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Filename = StringRef(MappedName.begin(), MappedName.size()); 315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HasBeenMapped = true; 316651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Result = HM->LookupFile(Filename, HS.getFileMgr()); 317651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 318651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else { 319651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Result = HS.getFileMgr().getFile(Dest); 320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 321651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3227412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (Result) { 3236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (SearchPath) { 3245f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef SearchPathRef(getName()); 3257412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 3267412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 3277412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 3286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (RelativePath) { 3297412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 3307412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin(), Filename.end()); 3317412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 3327412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 3337412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek return Result; 334df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner} 335df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 3367005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor/// \brief Given a framework directory, find the top-most framework directory. 3377005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor/// 3387005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor/// \param FileMgr The file manager to use for directory lookups. 3397005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor/// \param DirName The name of the framework directory. 3407005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor/// \param SubmodulePath Will be populated with the submodule path from the 3417005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor/// returned top-level module to the originally named framework. 3427005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregorstatic const DirectoryEntry * 3437005b907ea159c8e74e81f85269777429bc18d3cDouglas GregorgetTopFrameworkDir(FileManager &FileMgr, StringRef DirName, 3447005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor SmallVectorImpl<std::string> &SubmodulePath) { 3457005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor assert(llvm::sys::path::extension(DirName) == ".framework" && 3467005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor "Not a framework directory"); 3477005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 3487005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Note: as an egregious but useful hack we use the real path here, because 3497005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // frameworks moving between top-level frameworks to embedded frameworks tend 3507005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // to be symlinked, and we base the logical structure of modules on the 3517005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // physical layout. In particular, we need to deal with crazy includes like 3527005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // 3537005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // #include <Foo/Frameworks/Bar.framework/Headers/Wibble.h> 3547005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // 3557005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // where 'Bar' used to be embedded in 'Foo', is now a top-level framework 3567005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // which one should access with, e.g., 3577005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // 3587005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // #include <Bar/Wibble.h> 3597005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // 3607005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Similar issues occur when a top-level framework has moved into an 3617005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // embedded framework. 3627005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor const DirectoryEntry *TopFrameworkDir = FileMgr.getDirectory(DirName); 363713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor DirName = FileMgr.getCanonicalName(TopFrameworkDir); 3647005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor do { 3657005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Get the parent directory name. 3667005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor DirName = llvm::sys::path::parent_path(DirName); 3677005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (DirName.empty()) 3687005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor break; 3697005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 3707005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Determine whether this directory exists. 3717005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor const DirectoryEntry *Dir = FileMgr.getDirectory(DirName); 3727005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (!Dir) 3737005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor break; 3747005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 3757005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // If this is a framework directory, then we're a subframework of this 3767005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // framework. 3777005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (llvm::sys::path::extension(DirName) == ".framework") { 3787005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor SubmodulePath.push_back(llvm::sys::path::stem(DirName)); 3797005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor TopFrameworkDir = Dir; 3807005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } 3817005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } while (true); 3827005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 3837005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor return TopFrameworkDir; 3847005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor} 385df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 386afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner/// DoFrameworkLookup - Do a lookup of the specified file in the current 387afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner/// DirectoryLookup, which is a framework directory. 388b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruthconst FileEntry *DirectoryLookup::DoFrameworkLookup( 3895f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Filename, 3907412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek HeaderSearch &HS, 3915f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *SearchPath, 392fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SmallVectorImpl<char> *RelativePath, 393bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl ModuleMap::KnownHeader *SuggestedModule, 39485ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar bool &InUserSpecifiedSystemFramework) const 395fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor{ 396afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner FileManager &FileMgr = HS.getFileMgr(); 3971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Framework names must have a '/' in the filename. 399a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner size_t SlashPos = Filename.find('/'); 4006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (SlashPos == StringRef::npos) return nullptr; 4011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 402afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Find out if this is the home for the specified framework, by checking 4039ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar // HeaderSearch. Possible answers are yes/no and unknown. 4049ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar HeaderSearch::FrameworkCacheEntry &CacheEntry = 405a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner HS.LookupFrameworkCache(Filename.substr(0, SlashPos)); 4061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 407afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // If it is known and in some other directory, fail. 4089ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDir()) 4096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 4101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 411afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Otherwise, construct the path to this framework dir. 4121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FrameworkName = "/System/Library/Frameworks/" 414f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<1024> FrameworkName; 415afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner FrameworkName += getFrameworkDir()->getName(); 4165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FrameworkName.empty() || FrameworkName.back() != '/') 4175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName.push_back('/'); 4181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FrameworkName = "/System/Library/Frameworks/Cocoa" 4202821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor StringRef ModuleName(Filename.begin(), SlashPos); 4212821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor FrameworkName += ModuleName; 4221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/" 4245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += ".framework/"; 4251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4269ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar // If the cache entry was unresolved, populate it now. 4276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!CacheEntry.Directory) { 428afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner HS.IncrementFrameworkLookupCount(); 4291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the framework dir doesn't exist, we fail. 43185ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); 4326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Dir) return nullptr; 4331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, if it does, remember that this is the right direntry for this 4355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // framework. 4369ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar CacheEntry.Directory = getFrameworkDir(); 43785ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar 43885ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // If this is a user search directory, check if the framework has been 43985ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // user-specified as a system framework. 44085ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar if (getDirCharacteristic() == SrcMgr::C_User) { 44185ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar SmallString<1024> SystemFrameworkMarker(FrameworkName); 44285ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar SystemFrameworkMarker += ".system_framework"; 44385ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar if (llvm::sys::fs::exists(SystemFrameworkMarker.str())) { 44485ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar CacheEntry.IsUserSpecifiedSystemFramework = true; 44585ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar } 44685ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar } 4475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 44985ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // Set the 'user-specified system framework' flag. 45085ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework; 45185ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar 4526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (RelativePath) { 4537412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 4547412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 4557412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 4562821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 4575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h" 4585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned OrigSize = FrameworkName.size(); 4591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += "Headers/"; 4617412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 4626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (SearchPath) { 4637412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 4647412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek // Without trailing '/'. 4657412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1); 4667412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 4677412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 468a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end()); 4697005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), 4707005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor /*openFile=*/!SuggestedModule); 4717005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (!FE) { 4727005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h" 4737005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor const char *Private = "Private"; 4747005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor FrameworkName.insert(FrameworkName.begin()+OrigSize, Private, 4757005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor Private+strlen(Private)); 4766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (SearchPath) 4777005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor SearchPath->insert(SearchPath->begin()+OrigSize, Private, 4787005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor Private+strlen(Private)); 4797005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 4807005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor FE = FileMgr.getFile(FrameworkName.str(), /*openFile=*/!SuggestedModule); 481b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth } 4821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4837005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // If we found the header and are allowed to suggest a module, do so now. 4847005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (FE && SuggestedModule) { 4857005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Find the framework in which this header occurs. 4866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines StringRef FrameworkPath = FE->getDir()->getName(); 4877005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor bool FoundFramework = false; 4887005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor do { 4897005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Determine whether this directory exists. 4907005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkPath); 4917005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (!Dir) 4927005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor break; 4937005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 4947005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // If this is a framework directory, then we're a subframework of this 4957005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // framework. 4967005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (llvm::sys::path::extension(FrameworkPath) == ".framework") { 4977005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor FoundFramework = true; 4987005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor break; 4997005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } 5006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Get the parent directory name. 5026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines FrameworkPath = llvm::sys::path::parent_path(FrameworkPath); 5036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (FrameworkPath.empty()) 5046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines break; 5057005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } while (true); 5067005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 5077005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (FoundFramework) { 5087005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Find the top-level framework based on this framework. 5097005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor SmallVector<std::string, 4> SubmodulePath; 5107005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor const DirectoryEntry *TopFrameworkDir 5117005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor = ::getTopFrameworkDir(FileMgr, FrameworkPath, SubmodulePath); 5127005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 5137005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Determine the name of the top-level framework. 5147005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName()); 5157005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 5167005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Load this framework module. If that succeeds, find the suggested module 5177005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // for this header, if any. 5187005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor bool IsSystem = getDirCharacteristic() != SrcMgr::C_User; 5197005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (HS.loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystem)) { 5207005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor *SuggestedModule = HS.findModuleForHeader(FE); 5217005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } 5227005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } else { 5237005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor *SuggestedModule = HS.findModuleForHeader(FE); 5247005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } 5257005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } 526fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor return FE; 5275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 5285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 529dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregorvoid HeaderSearch::setTarget(const TargetInfo &Target) { 530dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor ModMap.setTarget(Target); 531dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor} 532dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor 533df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 534afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner//===----------------------------------------------------------------------===// 535afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner// Header File Location. 536afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner//===----------------------------------------------------------------------===// 537afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner 538651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Return true with a diagnostic if the file that MSVC would have found 539651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// fails to match the one that Clang would have found with MSVC header search 540651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// disabled. 541651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic bool checkMSVCHeaderSearch(DiagnosticsEngine &Diags, 542651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FileEntry *MSFE, const FileEntry *FE, 543651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation IncludeLoc) { 544651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MSFE && FE != MSFE) { 545651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diags.Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->getName(); 546651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 547651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 548651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 549651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 550651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 551651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) { 552651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(!Str.empty()); 553651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines char *CopyStr = Alloc.Allocate<char>(Str.size()+1); 554651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::copy(Str.begin(), Str.end(), CopyStr); 555651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CopyStr[Str.size()] = '\0'; 556651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return CopyStr; 557651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 558afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner 559853519cd45716c0a0923a7b65ce7aca63cb4dae4James Dennett/// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file, 5605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// return null on failure. isAngled indicates whether the file reference is 561651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// for system \#include's or not (i.e. using <> instead of ""). Includers, if 562651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// non-empty, indicates where the \#including file(s) are, in case a relative 563651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// search is needed. Microsoft mode will pass all \#including files. 564b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruthconst FileEntry *HeaderSearch::LookupFile( 565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef Filename, SourceLocation IncludeLoc, bool isAngled, 566651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, 567651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArrayRef<const FileEntry *> Includers, SmallVectorImpl<char> *SearchPath, 568fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SmallVectorImpl<char> *RelativePath, 569651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ModuleMap::KnownHeader *SuggestedModule, bool SkipCache) { 570c641709607d45bf97772e925647db6c94866c50aDaniel Jasper if (!HSOpts->ModuleMapFiles.empty()) { 571c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // Preload all explicitly specified module map files. This enables modules 572c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // map files lying in a directory structure separate from the header files 573c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // that they describe. These cannot be loaded lazily upon encountering a 574651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // header file, as there is no other known mapping from a header file to its 575c641709607d45bf97772e925647db6c94866c50aDaniel Jasper // module map file. 576c641709607d45bf97772e925647db6c94866c50aDaniel Jasper for (llvm::SetVector<std::string>::iterator 577c641709607d45bf97772e925647db6c94866c50aDaniel Jasper I = HSOpts->ModuleMapFiles.begin(), 578c641709607d45bf97772e925647db6c94866c50aDaniel Jasper E = HSOpts->ModuleMapFiles.end(); 579c641709607d45bf97772e925647db6c94866c50aDaniel Jasper I != E; ++I) { 580c641709607d45bf97772e925647db6c94866c50aDaniel Jasper const FileEntry *File = FileMgr.getFile(*I); 581c641709607d45bf97772e925647db6c94866c50aDaniel Jasper if (!File) 582c641709607d45bf97772e925647db6c94866c50aDaniel Jasper continue; 583c641709607d45bf97772e925647db6c94866c50aDaniel Jasper loadModuleMapFile(File, /*IsSystem=*/false); 584c641709607d45bf97772e925647db6c94866c50aDaniel Jasper } 585c641709607d45bf97772e925647db6c94866c50aDaniel Jasper HSOpts->ModuleMapFiles.clear(); 586c641709607d45bf97772e925647db6c94866c50aDaniel Jasper } 587c641709607d45bf97772e925647db6c94866c50aDaniel Jasper 588fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor if (SuggestedModule) 589bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl *SuggestedModule = ModuleMap::KnownHeader(); 590fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor 5915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If 'Filename' is absolute, check to see if it exists and no searching. 592256053b31e697fdf0cc48f17d621c82fc3b8dff0Michael J. Spencer if (llvm::sys::path::is_absolute(Filename)) { 5936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CurDir = nullptr; 5945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this was an #include_next "/absolute/file", fail. 5966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (FromDir) return nullptr; 5971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (SearchPath) 5997412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 6006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (RelativePath) { 6017412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 6027412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin(), Filename.end()); 6037412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 6045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, just return the file. 6053cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis return FileMgr.getFile(Filename, /*openFile=*/true); 6065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 6071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 608651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // This is the header that MSVC's header search would have found. 6096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const FileEntry *MSFE = nullptr; 610651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ModuleMap::KnownHeader MSSuggestedModule; 611651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 61265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor // Unless disabled, check to see if the file is in the #includer's 613651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // directory. This cannot be based on CurDir, because each includer could be 614651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // a #include of a subdirectory (#include "foo/bar.h") and a subsequent 615651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // include of "baz.h" should resolve to "whatever/foo/baz.h". 616df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // This search is not done for <> headers. 617651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!Includers.empty() && !isAngled && !NoCurDirSearch) { 618f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<1024> TmpDir; 619651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (ArrayRef<const FileEntry *>::iterator I = Includers.begin(), 620651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines E = Includers.end(); 621651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines I != E; ++I) { 622651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FileEntry *Includer = *I; 623651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Concatenate the requested file onto the directory. 624651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // FIXME: Portability. Filename concatenation should be in sys::Path. 625651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TmpDir = Includer->getDir()->getName(); 626651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TmpDir.push_back('/'); 627651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TmpDir.append(Filename.begin(), Filename.end()); 628651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 629651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // FIXME: We don't cache the result of getFileInfo across the call to 630651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // getFileAndSuggestModule, because it's a reference to an element of 631651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // a container that could be reallocated across this call. 632651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool IncluderIsSystemHeader = 633651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getFileInfo(Includer).DirInfo != SrcMgr::C_User; 634651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const FileEntry *FE = 635651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getFileAndSuggestModule(*this, TmpDir.str(), Includer->getDir(), 636651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IncluderIsSystemHeader, 637651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SuggestedModule)) { 638651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Leave CurDir unset. 639651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // This file is a system header or C++ unfriendly if the old file is. 640651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // 641651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Note that we only use one of FromHFI/ToHFI at once, due to potential 642651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // reallocation of the underlying vector potentially making the first 643651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // reference binding dangling. 644651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HeaderFileInfo &FromHFI = getFileInfo(Includer); 645651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned DirInfo = FromHFI.DirInfo; 646651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader; 647651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef Framework = FromHFI.Framework; 648651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 649651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HeaderFileInfo &ToHFI = getFileInfo(FE); 650651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ToHFI.DirInfo = DirInfo; 651651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader; 652651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ToHFI.Framework = Framework; 653651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 6546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (SearchPath) { 655651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef SearchPathRef(Includer->getDir()->getName()); 656651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SearchPath->clear(); 657651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 658651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 6596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (RelativePath) { 660651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RelativePath->clear(); 661651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RelativePath->append(Filename.begin(), Filename.end()); 662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 663651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (I == Includers.begin()) 664651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return FE; 665651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 666651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Otherwise, we found the path via MSVC header search rules. If 667651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // -Wmsvc-include is enabled, we have to keep searching to see if we 668651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // would've found this header in -I or -isystem directories. 669ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) { 670651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return FE; 671651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else { 672651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSFE = FE; 673651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (SuggestedModule) { 674651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSSuggestedModule = *SuggestedModule; 675651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *SuggestedModule = ModuleMap::KnownHeader(); 676651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 677651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 678651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 6797412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 6805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 6815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 6821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CurDir = nullptr; 6845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this is a system #include, ignore the user #include locs. 68674a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber unsigned i = isAngled ? AngledDirIdx : 0; 6871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this is a #include_next request, start searching after the directory the 6895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // file was found in. 6905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FromDir) 6915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer i = FromDir-&SearchDirs[0]; 6921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6939960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Cache all of the lookups performed by this method. Many headers are 6949960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // multiply included, and the "pragma once" optimization prevents them from 6959960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // being relex/pp'd, but they would still have to search through a 6969960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // (potentially huge) series of SearchDirs to find it. 697651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LookupFileCacheInfo &CacheLookup = 698a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner LookupFileCache.GetOrCreateValue(Filename).getValue(); 6999960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner 7009960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // If the entry has been previously looked up, the first value will be 7019960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // non-zero. If the value is equal to i (the start point of our search), then 7029960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // this is a matching hit. 703651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!SkipCache && CacheLookup.StartIdx == i+1) { 7049960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Skip querying potentially lots of directories for this lookup. 705651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines i = CacheLookup.HitIdx; 706651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CacheLookup.MappedName) 707651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Filename = CacheLookup.MappedName; 7089960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner } else { 7099960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Otherwise, this is the first query, or the previous query didn't match 7109960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // our search start. We will fill in our found location below, so prime the 7119960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // start point value. 712651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CacheLookup.reset(/*StartIdx=*/i+1); 7139960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner } 7141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 715651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SmallString<64> MappedName; 716651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 7175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check each directory in sequence to see if it contains this file. 7185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer for (; i != SearchDirs.size(); ++i) { 71985ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar bool InUserSpecifiedSystemFramework = false; 720651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool HasBeenMapped = false; 7211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const FileEntry *FE = 722fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath, 723651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SuggestedModule, InUserSpecifiedSystemFramework, 724651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HasBeenMapped, MappedName); 725651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (HasBeenMapped) { 726651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CacheLookup.MappedName = 727651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines copyString(Filename, LookupFileCache.getAllocator()); 728651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 729afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner if (!FE) continue; 7301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 731afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner CurDir = &SearchDirs[i]; 7321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 733afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // This file is a system header or C++ unfriendly if the dir is. 73465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HeaderFileInfo &HFI = getFileInfo(FE); 73565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HFI.DirInfo = CurDir->getDirCharacteristic(); 73665e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor 73785ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // If the directory characteristic is User but this framework was 73885ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // user-specified to be treated as a system framework, promote the 73985ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // characteristic. 74085ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar if (HFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework) 74185ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar HFI.DirInfo = SrcMgr::C_System; 74285ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar 743f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith // If the filename matches a known system header prefix, override 744f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith // whether the file is a system header. 7454ef2f6a95146423a1947b98458cc95c00a8b3ebdRichard Trieu for (unsigned j = SystemHeaderPrefixes.size(); j; --j) { 7464ef2f6a95146423a1947b98458cc95c00a8b3ebdRichard Trieu if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) { 7474ef2f6a95146423a1947b98458cc95c00a8b3ebdRichard Trieu HFI.DirInfo = SystemHeaderPrefixes[j-1].second ? SrcMgr::C_System 748f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith : SrcMgr::C_User; 749f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith break; 750f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith } 751f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith } 752f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith 75365e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor // If this file is found in a header map and uses the framework style of 75465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor // includes, then this header is part of a framework we're building. 75565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor if (CurDir->isIndexHeaderMap()) { 75665e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor size_t SlashPos = Filename.find('/'); 75765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor if (SlashPos != StringRef::npos) { 75865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HFI.IndexHeaderMapHeader = 1; 75965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(), 76065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor SlashPos)); 76165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor } 76265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor } 763651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 764651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) { 765651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (SuggestedModule) 766651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *SuggestedModule = MSSuggestedModule; 767651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSFE; 768651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 769651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 770afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Remember this location for the next lookup we do. 771651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CacheLookup.HitIdx = i; 772afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner return FE; 7735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 7741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7752c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // If we are including a file with a quoted include "foo.h" from inside 7762c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // a header in a framework that is currently being built, and we couldn't 7772c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where 7782c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // "Foo" is the name of the framework in which the including header was found. 779651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!Includers.empty() && !isAngled && 780651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Filename.find('/') == StringRef::npos) { 781651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HeaderFileInfo &IncludingHFI = getFileInfo(Includers.front()); 7822c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor if (IncludingHFI.IndexHeaderMapHeader) { 783f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> ScratchFilename; 7842c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor ScratchFilename += IncludingHFI.Framework; 7852c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor ScratchFilename += '/'; 7862c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor ScratchFilename += Filename; 787651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 788651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FileEntry *FE = LookupFile( 789651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, CurDir, 790651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Includers.front(), SearchPath, RelativePath, SuggestedModule); 791651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 792651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) { 793651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (SuggestedModule) 794651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *SuggestedModule = MSSuggestedModule; 795651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSFE; 796651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 797651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 798651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LookupFileCacheInfo &CacheLookup 7992c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor = LookupFileCache.GetOrCreateValue(Filename).getValue(); 800651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CacheLookup.HitIdx 801651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().HitIdx; 802651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // FIXME: SuggestedModule. 803651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return FE; 8042c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor } 8052c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor } 8062c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor 8076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (checkMSVCHeaderSearch(Diags, MSFE, nullptr, IncludeLoc)) { 808651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (SuggestedModule) 809651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *SuggestedModule = MSSuggestedModule; 810651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MSFE; 811651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 812651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 8139960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Otherwise, didn't find it. Remember we didn't find this. 814651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CacheLookup.HitIdx = SearchDirs.size(); 8156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 8165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 8175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// LookupSubframeworkHeader - Look up a subframework for the specified 819853519cd45716c0a0923a7b65ce7aca63cb4dae4James Dennett/// \#include file. For example, if \#include'ing <HIToolbox/HIToolbox.h> from 8205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox 8215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is a subframework within Carbon.framework. If so, return the FileEntry 8225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// for the designated file, otherwise return null. 8235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerconst FileEntry *HeaderSearch:: 8245f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerLookupSubframeworkHeader(StringRef Filename, 825b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth const FileEntry *ContextFileEnt, 8265f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *SearchPath, 8271b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor SmallVectorImpl<char> *RelativePath, 828bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl ModuleMap::KnownHeader *SuggestedModule) { 8299415a0cc93117b69add4e1dc0f11146f3479ee1aChris Lattner assert(ContextFileEnt && "No context file?"); 8301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Framework names must have a '/' in the filename. Find it. 832efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor // FIXME: Should we permit '\' on Windows? 833a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner size_t SlashPos = Filename.find('/'); 8346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (SlashPos == StringRef::npos) return nullptr; 8351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Look up the base framework name of the ContextFileEnt. 8375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *ContextName = ContextFileEnt->getName(); 8381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the context info wasn't a framework, couldn't be a subframework. 840efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor const unsigned DotFrameworkLen = 10; 841efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor const char *FrameworkPos = strstr(ContextName, ".framework"); 8426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (FrameworkPos == nullptr || 843efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor (FrameworkPos[DotFrameworkLen] != '/' && 844efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor FrameworkPos[DotFrameworkLen] != '\\')) 8456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 8461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8479ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar SmallString<1024> FrameworkName(ContextName, FrameworkPos+DotFrameworkLen+1); 8485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Append Frameworks/HIToolbox.framework/ 8505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += "Frameworks/"; 851a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos); 8525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += ".framework/"; 8535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8549ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar llvm::StringMapEntry<FrameworkCacheEntry> &CacheLookup = 8556538227d51df249b07c8ab80ae376f5c1d14403cChris Lattner FrameworkMap.GetOrCreateValue(Filename.substr(0, SlashPos)); 8561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Some other location? 8589ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar if (CacheLookup.getValue().Directory && 8595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CacheLookup.getKeyLength() == FrameworkName.size() && 8605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer memcmp(CacheLookup.getKeyData(), &FrameworkName[0], 8615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CacheLookup.getKeyLength()) != 0) 8626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 8631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Cache subframework. 8656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!CacheLookup.getValue().Directory) { 8665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ++NumSubFrameworkLookups; 8671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the framework dir doesn't exist, we fail. 86939b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); 8706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Dir) return nullptr; 8711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, if it does, remember that this is the right direntry for this 8735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // framework. 8749ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar CacheLookup.getValue().Directory = Dir; 8755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 8761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const FileEntry *FE = nullptr; 8785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (RelativePath) { 8807412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 8817412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 8827412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 8837412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 8845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h" 885f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<1024> HeadersFilename(FrameworkName); 8865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HeadersFilename += "Headers/"; 8876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (SearchPath) { 8887412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 8897412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek // Without trailing '/'. 8907412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 8917412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 8927412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 893a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 8943cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) { 8951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h" 8975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HeadersFilename = FrameworkName; 8985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HeadersFilename += "PrivateHeaders/"; 8996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (SearchPath) { 9007412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 9017412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek // Without trailing '/'. 9027412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 9037412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 9047412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 905a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 9063cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) 9076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 9085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 9091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // This file is a system header or C++ unfriendly if the old file is. 911ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek // 912c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner // Note that the temporary 'DirInfo' is required here, as either call to 913c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner // getFileInfo could resize the vector and we don't want to rely on order 914c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner // of evaluation. 915c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo; 916c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner getFileInfo(FE).DirInfo = DirInfo; 9171b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor 9181b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor // If we're supposed to suggest a module, look for one now. 9191b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor if (SuggestedModule) { 9201b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor // Find the top-level framework based on this framework. 9211b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor FrameworkName.pop_back(); // remove the trailing '/' 9221b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor SmallVector<std::string, 4> SubmodulePath; 9231b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor const DirectoryEntry *TopFrameworkDir 9241b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor = ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath); 9251b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor 9261b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor // Determine the name of the top-level framework. 9271b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName()); 9281b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor 9291b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor // Load this framework module. If that succeeds, find the suggested module 9301b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor // for this header, if any. 9311b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor bool IsSystem = false; 9321b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor if (loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystem)) { 9331b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor *SuggestedModule = findModuleForHeader(FE); 9341b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor } 9351b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor } 9361b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor 9375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return FE; 9385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 9395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 940cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth/// \brief Helper static function to normalize a path for injection into 941cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth/// a synthetic header. 942cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth/*static*/ std::string 943cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler CarruthHeaderSearch::NormalizeDashIncludePath(StringRef File, FileManager &FileMgr) { 944cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // Implicit include paths should be resolved relative to the current 945cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // working directory first, and then use the regular header search 946cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // mechanism. The proper way to handle this is to have the 947cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // predefines buffer located at the current working directory, but 948cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // it has no file entry. For now, workaround this by using an 949cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // absolute path if we find the file here, and otherwise letting 950cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // header search handle it. 951f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> Path(File); 952cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth llvm::sys::fs::make_absolute(Path); 953cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth bool exists; 954cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth if (llvm::sys::fs::exists(Path.str(), exists) || !exists) 955cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth Path = File; 956cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth else if (exists) 957cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth FileMgr.getFile(File); 958cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth 959cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth return Lexer::Stringify(Path.str()); 960cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth} 961cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth 9625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 9635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// File Info Management. 9645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 9655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 9668f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor/// \brief Merge the header file info provided by \p OtherHFI into the current 9678f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor/// header file info (\p HFI) 9688f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregorstatic void mergeHeaderFileInfo(HeaderFileInfo &HFI, 9698f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor const HeaderFileInfo &OtherHFI) { 9708f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.isImport |= OtherHFI.isImport; 9718f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.isPragmaOnce |= OtherHFI.isPragmaOnce; 97255ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis HFI.isModuleHeader |= OtherHFI.isModuleHeader; 9738f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.NumIncludes += OtherHFI.NumIncludes; 9748f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 9758f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (!HFI.ControllingMacro && !HFI.ControllingMacroID) { 9768f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.ControllingMacro = OtherHFI.ControllingMacro; 9778f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.ControllingMacroID = OtherHFI.ControllingMacroID; 9788f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor } 9798f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 9808f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (OtherHFI.External) { 9818f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.DirInfo = OtherHFI.DirInfo; 9828f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.External = OtherHFI.External; 9838f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader; 9848f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor } 9855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 9868f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (HFI.Framework.empty()) 9878f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.Framework = OtherHFI.Framework; 9888f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 9898f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.Resolved = true; 9908f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor} 9918f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 99283d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff/// getFileInfo - Return the HeaderFileInfo structure for the specified 9935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// FileEntry. 99483d63c78810556d26b62ac4cbae2eda6cdd2570cSteve NaroffHeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) { 9955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FE->getUID() >= FileInfo.size()) 9965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FileInfo.resize(FE->getUID()+1); 997cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 998cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 9998f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (ExternalSource && !HFI.Resolved) 10008f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE)); 1001651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HFI.IsValid = 1; 1002cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor return HFI; 10031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 10045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1005651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesbool HeaderSearch::tryGetFileInfo(const FileEntry *FE, HeaderFileInfo &Result) const { 1006651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (FE->getUID() >= FileInfo.size()) 1007651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 1008651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 1009651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (HFI.IsValid) { 1010651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Result = HFI; 1011651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 1012651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1013651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 1014651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 1015651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1016dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregorbool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) { 1017dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor // Check if we've ever seen this file as a header. 1018dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor if (File->getUID() >= FileInfo.size()) 1019dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor return false; 1020dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor 1021dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor // Resolve header file info from the external source, if needed. 1022dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor HeaderFileInfo &HFI = FileInfo[File->getUID()]; 10238f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (ExternalSource && !HFI.Resolved) 10248f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(File)); 1025dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor 102644dfff681fdca5325bc684c46971efad1f3fedfdArgyrios Kyrtzidis return HFI.isPragmaOnce || HFI.isImport || 102744dfff681fdca5325bc684c46971efad1f3fedfdArgyrios Kyrtzidis HFI.ControllingMacro || HFI.ControllingMacroID; 1028dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor} 1029dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor 1030d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidisvoid HeaderSearch::MarkFileModuleHeader(const FileEntry *FE, 1031bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl ModuleMap::ModuleHeaderRole Role, 1032d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis bool isCompilingModuleHeader) { 103355ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis if (FE->getUID() >= FileInfo.size()) 103455ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis FileInfo.resize(FE->getUID()+1); 103555ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis 103655ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 103755ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis HFI.isModuleHeader = true; 1038d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis HFI.isCompilingModuleHeader = isCompilingModuleHeader; 1039bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl HFI.setHeaderRole(Role); 104055ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis} 104155ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis 10425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){ 10435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ++NumIncluded; // Count # of attempted #includes. 10445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 10455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Get information about this file. 104683d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff HeaderFileInfo &FileInfo = getFileInfo(File); 10471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this is a #import directive, check that we have not already imported 10495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // this header. 10505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (isImport) { 10515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this has already been imported, don't import it again. 10525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FileInfo.isImport = true; 10531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Has this already been #import'ed or #include'd? 10555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FileInfo.NumIncludes) return false; 10565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 10575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, if this is a #include of a file that was previously #import'd 10585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // or if this is the second #include of a #pragma once file, ignore it. 10595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FileInfo.isImport) 10605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return false; 10615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 10621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Next, check to see if the file is wrapped with #ifndef guards. If so, and 10645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // if the macro that guards it is defined, we know the #include has no effect. 10651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (const IdentifierInfo *ControllingMacro 10668c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor = FileInfo.getControllingMacro(ExternalLookup)) 10678c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor if (ControllingMacro->hasMacroDefinition()) { 10688c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor ++NumMultiIncludeFileOptzn; 10698c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor return false; 10708c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor } 10711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Increment the number of times this file has been included. 10735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ++FileInfo.NumIncludes; 10741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 10765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 10775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1078d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremeneksize_t HeaderSearch::getTotalMemory() const { 1079d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek return SearchDirs.capacity() 1080eabea45e23abc07e917f0d4bce15054ce75623efTed Kremenek + llvm::capacity_in_bytes(FileInfo) 1081eabea45e23abc07e917f0d4bce15054ce75623efTed Kremenek + llvm::capacity_in_bytes(HeaderMaps) 1082d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek + LookupFileCache.getAllocator().getTotalMemory() 1083d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek + FrameworkMap.getAllocator().getTotalMemory(); 1084d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek} 108565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor 108665e02fa80e1c185f18e5f81cefc30d75383a7301Douglas GregorStringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { 108765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor return FrameworkNames.GetOrCreateValue(Framework).getKey(); 108865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor} 1089a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1090a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorbool HeaderSearch::hasModuleMap(StringRef FileName, 10918f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor const DirectoryEntry *Root, 10928f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor bool IsSystem) { 1093651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!enabledModules()) 1094651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 1095651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1096cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<const DirectoryEntry *, 2> FixUpDirectories; 1097a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1098a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringRef DirName = FileName; 1099a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 1100a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Get the parent directory name. 1101a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DirName = llvm::sys::path::parent_path(DirName); 1102a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (DirName.empty()) 1103a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return false; 11041b8840ce0d7a3383915b29dc3779dfadec817458Daniel Jasper 1105a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Determine whether this directory exists. 1106a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor const DirectoryEntry *Dir = FileMgr.getDirectory(DirName); 1107a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Dir) 1108a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return false; 11091b8840ce0d7a3383915b29dc3779dfadec817458Daniel Jasper 1110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Try to load the module map file in this directory. 1111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/false)) { 111226697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor case LMM_NewlyLoaded: 111326697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor case LMM_AlreadyLoaded: 1114cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // Success. All of the directories we stepped through inherit this module 1115cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // map file. 1116a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I) 1117a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DirectoryHasModuleMap[FixUpDirectories[I]] = true; 1118a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return true; 1119c641709607d45bf97772e925647db6c94866c50aDaniel Jasper 1120c641709607d45bf97772e925647db6c94866c50aDaniel Jasper case LMM_NoDirectory: 1121c641709607d45bf97772e925647db6c94866c50aDaniel Jasper case LMM_InvalidModuleMap: 1122c641709607d45bf97772e925647db6c94866c50aDaniel Jasper break; 1123a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 1124a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1125cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // If we hit the top of our search, we're done. 1126cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (Dir == Root) 1127cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor return false; 1128cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 1129a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Keep track of all of the directories we checked, so we can mark them as 1130a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // having module maps if we eventually do find a module map. 1131a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor FixUpDirectories.push_back(Dir); 1132a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (true); 1133a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1134a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1135bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence CrowlModuleMap::KnownHeader 1136bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence CrowlHeaderSearch::findModuleForHeader(const FileEntry *File) const { 113755ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis if (ExternalSource) { 113855ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis // Make sure the external source has handled header info about this file, 113955ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis // which includes whether the file is part of a module. 114055ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis (void)getFileInfo(File); 114155ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis } 1142bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl return ModMap.findModuleForHeader(File); 1143a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 1144a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic const FileEntry *getPrivateModuleMap(StringRef ModuleMapPath, 1146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const DirectoryEntry *Directory, 1147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FileManager &FileMgr) { 1148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef Filename = llvm::sys::path::filename(ModuleMapPath); 1149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SmallString<128> PrivateFilename(Directory->getName()); 1150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Filename == "module.map") 1151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::sys::path::append(PrivateFilename, "module_private.map"); 1152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if (Filename == "module.modulemap") 1153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::sys::path::append(PrivateFilename, "module.private.modulemap"); 1154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else 1155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return nullptr; 1156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return FileMgr.getFile(PrivateFilename); 1157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 1158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 11598f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregorbool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) { 1160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines switch (loadModuleMapFileImpl(File, IsSystem)) { 1161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case LMM_AlreadyLoaded: 1162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case LMM_NewlyLoaded: 1163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 1164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case LMM_NoDirectory: 1165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case LMM_InvalidModuleMap: 1166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 1167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm_unreachable("Unknown load module map result"); 1169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 1170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1171651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesHeaderSearch::LoadModuleMapResult 1172651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesHeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem) { 1173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(File && "expected FileEntry"); 1174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1175db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor const DirectoryEntry *Dir = File->getDir(); 1176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines auto KnownDir = DirectoryHasModuleMap.find(Dir); 1177db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor if (KnownDir != DirectoryHasModuleMap.end()) 1178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap; 1179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (ModMap.parseModuleMapFile(File, IsSystem)) { 1181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DirectoryHasModuleMap[Dir] = false; 1182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return LMM_InvalidModuleMap; 11834813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor } 1184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Try to load a corresponding private module map. 1186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const FileEntry *PMMFile = 1187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getPrivateModuleMap(File->getName(), Dir, FileMgr)) { 1188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (ModMap.parseModuleMapFile(PMMFile, IsSystem)) { 1189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DirectoryHasModuleMap[Dir] = false; 1190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return LMM_InvalidModuleMap; 1191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // This directory has a module map. 1195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DirectoryHasModuleMap[Dir] = true; 1196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return LMM_NewlyLoaded; 1197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 1198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesconst FileEntry * 1200651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesHeaderSearch::lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework) { 1201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // For frameworks, the preferred spelling is Modules/module.modulemap, but 1202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // module.map at the framework root is also accepted. 1203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SmallString<128> ModuleMapFileName(Dir->getName()); 1204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (IsFramework) 1205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::sys::path::append(ModuleMapFileName, "Modules"); 1206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::sys::path::append(ModuleMapFileName, "module.modulemap"); 1207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const FileEntry *F = FileMgr.getFile(ModuleMapFileName)) 1208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return F; 1209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Continue to allow module.map 1211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ModuleMapFileName = Dir->getName(); 1212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::sys::path::append(ModuleMapFileName, "module.map"); 1213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return FileMgr.getFile(ModuleMapFileName); 1214db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor} 1215db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 1216651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesModule *HeaderSearch::loadFrameworkModule(StringRef Name, 1217e434ec71fccfe078906403affd641f709702d598Douglas Gregor const DirectoryEntry *Dir, 1218e434ec71fccfe078906403affd641f709702d598Douglas Gregor bool IsSystem) { 12191a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor if (Module *Module = ModMap.findModule(Name)) 12202821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor return Module; 12212821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 12222821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // Try to load a module map file. 1223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) { 12242821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor case LMM_InvalidModuleMap: 12252821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor break; 12262821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 12272821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor case LMM_AlreadyLoaded: 12282821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor case LMM_NoDirectory: 12296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 12306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 12312821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor case LMM_NewlyLoaded: 12322821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor return ModMap.findModule(Name); 12332821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor } 1234a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor 123582e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 1236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Try to infer a module map from the framework directory. 12376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return ModMap.inferFrameworkModule(Name, Dir, IsSystem, /*Parent=*/nullptr); 12382821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor} 12392821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 1240db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 124126697979fb0a4e2b720a0c8d062047edca92bc92Douglas GregorHeaderSearch::LoadModuleMapResult 1242651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesHeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem, 1243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool IsFramework) { 1244cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName)) 1245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return loadModuleMapFile(Dir, IsSystem, IsFramework); 1246cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 124726697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor return LMM_NoDirectory; 1248cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor} 1249cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 125026697979fb0a4e2b720a0c8d062047edca92bc92Douglas GregorHeaderSearch::LoadModuleMapResult 1251651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesHeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem, 1252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool IsFramework) { 1253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines auto KnownDir = DirectoryHasModuleMap.find(Dir); 1254cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (KnownDir != DirectoryHasModuleMap.end()) 125526697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor return KnownDir->second? LMM_AlreadyLoaded : LMM_InvalidModuleMap; 1256587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const FileEntry *ModuleMapFile = lookupModuleMapFile(Dir, IsFramework)) { 1258651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LoadModuleMapResult Result = loadModuleMapFileImpl(ModuleMapFile, IsSystem); 1259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Add Dir explicitly in case ModuleMapFile is in a subdirectory. 1260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // E.g. Foo.framework/Modules/module.modulemap 1261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // ^Dir ^ModuleMapFile 1262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Result == LMM_NewlyLoaded) 1263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DirectoryHasModuleMap[Dir] = true; 1264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Result; 1265cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 126626697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor return LMM_InvalidModuleMap; 1267cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor} 1268a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1269cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenkovoid HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) { 1270c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor Modules.clear(); 1271c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1272c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Load module maps for each of the header search directories. 1273c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 12748f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory(); 1275c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor if (SearchDirs[Idx].isFramework()) { 1276ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC; 1277f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> DirNative; 1278c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(), 1279c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor DirNative); 1280c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1281c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Search each of the ".framework" directories to load them as modules. 1282c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; 1283c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 1284c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor if (llvm::sys::path::extension(Dir->path()) != ".framework") 1285c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor continue; 1286c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1287c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor const DirectoryEntry *FrameworkDir = FileMgr.getDirectory(Dir->path()); 1288c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor if (!FrameworkDir) 1289c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor continue; 1290c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1291c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Load this framework module. 1292c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir, 1293c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor IsSystem); 1294c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor } 1295c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor continue; 1296c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor } 1297c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1298c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // FIXME: Deal with header maps. 1299c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor if (SearchDirs[Idx].isHeaderMap()) 1300c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor continue; 1301c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1302c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Try to load a module map file for the search directory. 1303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem, /*IsFramework*/false); 1304c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1305c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Try to load module map files for immediate subdirectories of this search 1306c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // directory. 1307cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor loadSubdirectoryModuleMaps(SearchDirs[Idx]); 1308c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor } 1309c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1310c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Populate the list of modules. 1311c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor for (ModuleMap::module_iterator M = ModMap.module_begin(), 1312c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor MEnd = ModMap.module_end(); 1313c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor M != MEnd; ++M) { 1314c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor Modules.push_back(M->getValue()); 1315c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor } 1316c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor} 1317cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor 131830a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregorvoid HeaderSearch::loadTopLevelSystemModules() { 131930a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor // Load module maps for each of the header search directories. 132030a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 1321701bc8ceb11c0090f61c1caa9d2efa9523006cc6Douglas Gregor // We only care about normal header directories. 1322701bc8ceb11c0090f61c1caa9d2efa9523006cc6Douglas Gregor if (!SearchDirs[Idx].isNormalDir()) { 132330a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor continue; 132430a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor } 132530a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor 132630a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor // Try to load a module map file for the search directory. 13278f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor loadModuleMapFile(SearchDirs[Idx].getDir(), 1328651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SearchDirs[Idx].isSystemHeaderDirectory(), 1329651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SearchDirs[Idx].isFramework()); 133030a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor } 133130a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor} 133230a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor 1333cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregorvoid HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) { 1334cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor if (SearchDir.haveSearchedAllModuleMaps()) 1335cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor return; 1336ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 1337ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::error_code EC; 1338cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor SmallString<128> DirNative; 1339cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative); 1340cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; 1341cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 1342651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(), 1343651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SearchDir.isFramework()); 1344cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor } 1345cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor 1346cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor SearchDir.setSearchedAllModuleMaps(true); 1347cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor} 1348